Check-in [1a0a37af7e]
Not logged in

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

Overview
Comment:Merge 9.0
Timelines: family | ancestors | descendants | both | tip-626
Files: files | file ages | folders
SHA3-256: 1a0a37af7ed6a49251fcc1b4c477ca6a22df325b181e3b5aadcfcdf4681129d7
User & Date: jan.nijtmans 2024-10-25 10:29:02.850
Context
2024-10-25
20:37
Merge 9.0 check-in: 714fb05eb4 user: jan.nijtmans tags: tip-626
10:29
Merge 9.0 check-in: 1a0a37af7e user: jan.nijtmans tags: tip-626
09:56
Merge 9.0 (9.0.0 release) check-in: 8523e01f8f user: jan.nijtmans tags: tip-626
2024-10-24
14:46
tcltest::bytestring was removed in Tcl 9.0 See: [a3e8f513cc]: tcltest(n) still mentions [encoding co... check-in: db207d7c85 user: jan.nijtmans tags: trunk, main
Changes
Unified Diff Ignore Whitespace Patch
Changes to .github/workflows/onefiledist.yml.
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
      - name: Upload
        uses: actions/upload-artifact@v4
        with:
          name: Tclsh ${{ env.TCL_PATCHLEVEL }} Linux single-file build (snapshot)
          path: 1dist/*.tar
  macos:
    name: macOS
    runs-on: macos-12
    defaults:
      run:
        shell: bash
    timeout-minutes: 10
    steps:
      - name: Checkout
        uses: actions/checkout@v4







|







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
      - name: Upload
        uses: actions/upload-artifact@v4
        with:
          name: Tclsh ${{ env.TCL_PATCHLEVEL }} Linux single-file build (snapshot)
          path: 1dist/*.tar
  macos:
    name: macOS
    runs-on: macos-13
    defaults:
      run:
        shell: bash
    timeout-minutes: 10
    steps:
      - name: Checkout
        uses: actions/checkout@v4
Deleted compat/string.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/*
 * string.h --
 *
 *	Declarations of ANSI C library procedures for string handling.
 *
 * Copyright (c) 1991-1993 The Regents of the University of California.
 * Copyright (c) 1994-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _STRING
#define _STRING

/*
 * The following #include is needed to define size_t. (This used to include
 * sys/stdtypes.h but that doesn't exist on older versions of SunOS, e.g.
 * 4.0.2, so I'm trying sys/types.h now.... hopefully it exists everywhere)
 */

#include <sys/types.h>

extern void *		memchr(const void *s, int c, size_t n);
extern int		memcmp(const void *s1, const void *s2, size_t n);
extern void *		memcpy(void *t, const void *f, size_t n);
#ifdef NO_MEMMOVE
#define memmove(d,s,n)	(bcopy((s), (d), (n)))
#else
extern char *		memmove(void *t, const void *f, size_t n);
#endif
extern void *		memset(void *s, int c, size_t n);

extern int		strcasecmp(const char *s1, const char *s2);
extern char *		strcat(char *dst, const char *src);
extern char *		strchr(const char *string, int c);
extern int		strcmp(const char *s1, const char *s2);
extern char *		strcpy(char *dst, const char *src);
extern size_t		strcspn(const char *string, const char *chars);
extern char *		strdup(const char *string);
extern char *		strerror(int error);
extern size_t		strlen(const char *string);
extern int		strncasecmp(const char *s1, const char *s2, size_t n);
extern char *		strncat(char *dst, const char *src, size_t numChars);
extern int		strncmp(const char *s1, const char *s2, size_t nChars);
extern char *		strncpy(char *dst, const char *src, size_t numChars);
extern char *		strpbrk(const char *string, const char *chars);
extern char *		strrchr(const char *string, int c);
extern size_t		strspn(const char *string, const char *chars);
extern char *		strstr(const char *string, const char *substring);
extern char *		strtok(char *s, const char *delim);

#endif /* _STRING */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































Changes to doc/array.n.
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
.TP
\fBarray exists \fIarrayName\fR
.
Returns 1 if \fIarrayName\fR is an array variable, 0 if there
is no variable by that name or if it is a scalar variable.
.\" METHOD: for
.TP
\fBarray for {\fIkeyVariable valueVariable\fB} \fIarrayName body\fP
.
The first argument is a two element list of variable names for the
key and value of each entry in the array.  The second argument is the
array name to iterate over.  The third argument is the body to execute
for each key and value returned.
The ordering of the returned keys is undefined.
If an array element is deleted or a new array element is inserted during
the \fIarray for\fP process, the command will terminate with an error.
.\" METHOD: get
.TP
\fBarray get \fIarrayName\fR ?\fIpattern\fR?
.
Returns a list containing pairs of elements.  The first
element in each pair is the name of an element in \fIarrayName\fR
and the second element of each pair is the value of the







|







|







98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
.TP
\fBarray exists \fIarrayName\fR
.
Returns 1 if \fIarrayName\fR is an array variable, 0 if there
is no variable by that name or if it is a scalar variable.
.\" METHOD: for
.TP
\fBarray for {\fIkeyVariable valueVariable\fB} \fIarrayName body\fR
.
The first argument is a two element list of variable names for the
key and value of each entry in the array.  The second argument is the
array name to iterate over.  The third argument is the body to execute
for each key and value returned.
The ordering of the returned keys is undefined.
If an array element is deleted or a new array element is inserted during
the \fIarray for\fR process, the command will terminate with an error.
.\" METHOD: get
.TP
\fBarray get \fIarrayName\fR ?\fIpattern\fR?
.
Returns a list containing pairs of elements.  The first
element in each pair is the name of an element in \fIarrayName\fR
and the second element of each pair is the value of the
Changes to doc/clock.n.
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
.PP
If the time zone begins with a colon, it is one of a
standardized list of names like \fB:America/New_York\fR
that give the rules for various locales.  A complete list
of the location names is too lengthy to be listed here.
On most Tcl installations, the definitions of the locations
are to be found in named files in the directory
.QW "\fI/no_backup/tools/lib/tcl8.5/clock/tzdata\fR" .
On some Unix systems, these files are omitted, and the definitions are
instead obtained from system files in
.QW "\fI/usr/share/zoneinfo\fR" ,
.QW "\fI/usr/share/lib/zoneinfo\fR"
or
.QW "\fI/usr/local/etc/zoneinfo\fR" .
As a special case, the name \fB:localtime\fR refers to







|







828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
.PP
If the time zone begins with a colon, it is one of a
standardized list of names like \fB:America/New_York\fR
that give the rules for various locales.  A complete list
of the location names is too lengthy to be listed here.
On most Tcl installations, the definitions of the locations
are to be found in named files in the directory
.QW "\fI/no_backup/tools/lib/tcl9.0/clock/tzdata\fR" .
On some Unix systems, these files are omitted, and the definitions are
instead obtained from system files in
.QW "\fI/usr/share/zoneinfo\fR" ,
.QW "\fI/usr/share/lib/zoneinfo\fR"
or
.QW "\fI/usr/local/etc/zoneinfo\fR" .
As a special case, the name \fB:localtime\fR refers to
Changes to doc/concat.n.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH concat n 8.3 Tcl "Tcl Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
concat \- Join lists together
.SH SYNOPSIS
\fBconcat\fI \fR?\fIarg arg ...\fR?
.BE
.SH DESCRIPTION
.PP
This command joins each of its arguments together with spaces after
trimming leading and trailing white-space from each of them.  If all of the
arguments are lists, this has the same effect as concatenating them
into a single list.







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH concat n 8.3 Tcl "Tcl Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
concat \- Join lists together
.SH SYNOPSIS
\fBconcat\fR ?\fIarg arg ...\fR?
.BE
.SH DESCRIPTION
.PP
This command joins each of its arguments together with spaces after
trimming leading and trailing white-space from each of them.  If all of the
arguments are lists, this has the same effect as concatenating them
into a single list.
Changes to doc/tcltest.n.
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
\fBtcltest::skipDirectories \fR?\fIpatternList\fR?
\fBtcltest::skipFiles \fR?\fIpatternList\fR?
\fBtcltest::temporaryDirectory \fR?\fIdirectory\fR?
\fBtcltest::testsDirectory \fR?\fIdirectory\fR?
\fBtcltest::verbose \fR?\fIlevel\fR?

\fBtcltest::test \fIname description optionList\fR
\fBtcltest::bytestring \fIstring\fR
\fBtcltest::normalizeMsg \fImsg\fR
\fBtcltest::normalizePath \fIpathVar\fR
\fBtcltest::workingDirectory \fR?\fIdir\fR?
.fi
.BE
.SH DESCRIPTION
.PP







<







54
55
56
57
58
59
60

61
62
63
64
65
66
67
\fBtcltest::skipDirectories \fR?\fIpatternList\fR?
\fBtcltest::skipFiles \fR?\fIpatternList\fR?
\fBtcltest::temporaryDirectory \fR?\fIdirectory\fR?
\fBtcltest::testsDirectory \fR?\fIdirectory\fR?
\fBtcltest::verbose \fR?\fIlevel\fR?

\fBtcltest::test \fIname description optionList\fR

\fBtcltest::normalizeMsg \fImsg\fR
\fBtcltest::normalizePath \fIpathVar\fR
\fBtcltest::workingDirectory \fR?\fIdir\fR?
.fi
.BE
.SH DESCRIPTION
.PP
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
.TP
\fBnormalizePath \fIpathVar\fR
.
Resolves symlinks in a path, thus creating a path without internal
redirection.  It is assumed that \fIpathVar\fR is absolute.
\fIpathVar\fR is modified in place.  The Tcl command \fBfile normalize\fR
is a sufficient replacement.
.\" COMMAND: bytestring
.TP
\fBbytestring \fIstring\fR
.
Construct a string that consists of the requested sequence of bytes,
as opposed to a string of properly formed UTF-8 characters using the
value supplied in \fIstring\fR.  This allows the tester to create
denormalized or improperly formed strings to pass to C procedures that
are supposed to accept strings with embedded NULL types and confirm
that a string result has a certain pattern of bytes.  This is
exactly equivalent to the Tcl command \fBencoding convertfrom\fR
\fBidentity\fR.
.SH TESTS
.PP
The \fBtest\fR command is the heart of the \fBtcltest\fR package.
Its essential function is to evaluate a Tcl script and compare
the result with an expected result.  The options of \fBtest\fR
define the test script, the environment in which to evaluate it,
the expected result, and how the compare the actual result to







<
<
<
<
<
<
<
<
<
<
<
<







450
451
452
453
454
455
456












457
458
459
460
461
462
463
.TP
\fBnormalizePath \fIpathVar\fR
.
Resolves symlinks in a path, thus creating a path without internal
redirection.  It is assumed that \fIpathVar\fR is absolute.
\fIpathVar\fR is modified in place.  The Tcl command \fBfile normalize\fR
is a sufficient replacement.












.SH TESTS
.PP
The \fBtest\fR command is the heart of the \fBtcltest\fR package.
Its essential function is to evaluate a Tcl script and compare
the result with an expected result.  The options of \fBtest\fR
define the test script, the environment in which to evaluate it,
the expected result, and how the compare the actual result to
Changes to doc/tclvars.n.
24
25
26
27
28
29
30

31
32
33
34
35
36
37
If set, then it must contain a valid Tcl list giving directories to
search during auto-load operations (including for package index
files when using the default \fBpackage unknown\fR handler).
This variable is initialized during startup to contain, in order:
the directories listed in the \fBTCLLIBPATH\fR environment variable,
the directory named by the \fBtcl_library\fR global variable,
the parent directory of \fBtcl_library\fR,

the directories listed in the \fBtcl_pkgPath\fR variable.
Additional locations to look for files and package indices should
normally be added to this variable using \fBlappend\fR.
Initialization of auto_path from the TCLLIBPATH environment
variable undergoes tilde substitution (see \fBfilename\fR) on each
path. Any tilde substitution that fails because the user is unknown
will be omitted from auto_path.







>







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
If set, then it must contain a valid Tcl list giving directories to
search during auto-load operations (including for package index
files when using the default \fBpackage unknown\fR handler).
This variable is initialized during startup to contain, in order:
the directories listed in the \fBTCLLIBPATH\fR environment variable,
the directory named by the \fBtcl_library\fR global variable,
the parent directory of \fBtcl_library\fR,
\fB[file dirname [file dirname [info nameofexecutable]]]/lib\fR,
the directories listed in the \fBtcl_pkgPath\fR variable.
Additional locations to look for files and package indices should
normally be added to this variable using \fBlappend\fR.
Initialization of auto_path from the TCLLIBPATH environment
variable undergoes tilde substitution (see \fBfilename\fR) on each
path. Any tilde substitution that fails because the user is unknown
will be omitted from auto_path.
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
.\" VARIABLE: tcl_wordchars
.TP
\fBtcl_wordchars\fR
.
The value of this variable is a regular expression that can be set to
control what are considered
.QW word
characters, for instances like
selecting a word by double-clicking in text in Tk.  It is platform
dependent.  On Windows, it defaults to \fB\eS\fR, meaning anything
but a Unicode space character.  Otherwise it defaults to \fB\ew\fR,
which is any Unicode word character (number, letter, or underscore).
.\" VARIABLE: tcl_nonwordchars
.TP
\fBtcl_nonwordchars\fR
.
The value of this variable is a regular expression that can be set to
control what are considered
.QW non-word
characters, for instances like
selecting a word by double-clicking in text in Tk.  It is platform
dependent.  On Windows, it defaults to \fB\es\fR, meaning any Unicode space
character.  Otherwise it defaults to \fB\eW\fR, which is anything but a
Unicode word character (number, letter, or underscore).
.\" VARIABLE: tcl_version
.TP
\fBtcl_version\fR
.
When an interpreter is created Tcl initializes this variable to
hold the version number for this version of Tcl in the form \fIx.y\fR.







<
<
<
|
|







<
<
<
|







393
394
395
396
397
398
399



400
401
402
403
404
405
406
407
408



409
410
411
412
413
414
415
416
.\" VARIABLE: tcl_wordchars
.TP
\fBtcl_wordchars\fR
.
The value of this variable is a regular expression that can be set to
control what are considered
.QW word



characters.  It defaults to \fB\ew\fR, which is any Unicode
word character (number, letter, or underscore).
.\" VARIABLE: tcl_nonwordchars
.TP
\fBtcl_nonwordchars\fR
.
The value of this variable is a regular expression that can be set to
control what are considered
.QW non-word



characters.  It defaults to \fB\eW\fR, which is anything but a
Unicode word character (number, letter, or underscore).
.\" VARIABLE: tcl_version
.TP
\fBtcl_version\fR
.
When an interpreter is created Tcl initializes this variable to
hold the version number for this version of Tcl in the form \fIx.y\fR.
Changes to doc/tm.n.
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
variable has been kept only for backward compatibility with the
original specification, i.e. TIP 189.
.PP
These paths are seen and therefore shared by all Tcl shells in the
\fB$::env(PATH)\fR of the user.
.PP
Note that \fIX\fR and \fIy\fR follow the general rules set out
above. In other words, Tcl 8.4, for example, will look at these 10
environment variables:
.PP
.CS
\fB$::env(TCL8.4_TM_PATH)\fR  \fB$::env(TCL8_4_TM_PATH)\fR
\fB$::env(TCL8.3_TM_PATH)\fR  \fB$::env(TCL8_3_TM_PATH)\fR
\fB$::env(TCL8.2_TM_PATH)\fR  \fB$::env(TCL8_2_TM_PATH)\fR
\fB$::env(TCL8.1_TM_PATH)\fR  \fB$::env(TCL8_1_TM_PATH)\fR
\fB$::env(TCL8.0_TM_PATH)\fR  \fB$::env(TCL8_0_TM_PATH)\fR
.CE
.PP
Paths initialized from the environment variables undergo tilde
substitution (see \fBfilename\fR). Any path whose tilde substitution
fails because the user is unknown will be omitted from search paths.
.SH "SEE ALSO"
package(n), Tcl Improvement Proposal #189







|



<
<
<
|
|







286
287
288
289
290
291
292
293
294
295
296



297
298
299
300
301
302
303
304
305
variable has been kept only for backward compatibility with the
original specification, i.e. TIP 189.
.PP
These paths are seen and therefore shared by all Tcl shells in the
\fB$::env(PATH)\fR of the user.
.PP
Note that \fIX\fR and \fIy\fR follow the general rules set out
above. In other words, Tcl 9.1, for example, will look at these 4
environment variables:
.PP
.CS



\fB$::env(TCL9.1_TM_PATH)\fR  \fB$::env(TCL9_1_TM_PATH)\fR
\fB$::env(TCL9.0_TM_PATH)\fR  \fB$::env(TCL9_0_TM_PATH)\fR
.CE
.PP
Paths initialized from the environment variables undergo tilde
substitution (see \fBfilename\fR). Any path whose tilde substitution
fails because the user is unknown will be omitted from search paths.
.SH "SEE ALSO"
package(n), Tcl Improvement Proposal #189
Changes to doc/zipfs.n.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
zipfs \- Mount and work with ZIP files within Tcl
.SH SYNOPSIS
.nf
\fBzipfs canonical\fR ?\fImountpoint\fR? \fIfilename\fR ?\fIZIPFS\fR?
\fBzipfs exists\fI filename\fR
\fBzipfs find\fI directoryName\fR
\fBzipfs info\fI filename\fR
\fBzipfs list\fR ?(\fB\-glob\fR|\fB\-regexp\fR)? ?\fIpattern\fR?
\fBzipfs lmkimg\fI outfile inlist\fR ?\fIpassword\fR? ?\fIinfile\fR?
\fBzipfs lmkzip\fI outfile inlist\fR ?\fIpassword\fR?
\fBzipfs mkimg\fI outfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? ?\fIinfile\fR?







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
zipfs \- Mount and work with ZIP files within Tcl
.SH SYNOPSIS
.nf
\fBzipfs canonical\fR ?\fImountpoint\fR? \fIfilename\fR
\fBzipfs exists\fI filename\fR
\fBzipfs find\fI directoryName\fR
\fBzipfs info\fI filename\fR
\fBzipfs list\fR ?(\fB\-glob\fR|\fB\-regexp\fR)? ?\fIpattern\fR?
\fBzipfs lmkimg\fI outfile inlist\fR ?\fIpassword\fR? ?\fIinfile\fR?
\fBzipfs lmkzip\fI outfile inlist\fR ?\fIpassword\fR?
\fBzipfs mkimg\fI outfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? ?\fIinfile\fR?
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
Files within mounted archives can be written to but new files or directories
cannot be created. Further, modifications to files are limited to the
mounted archive in memory and are not persisted to disk.
.PP
Paths in mounted archives are case-sensitive on all platforms.
.\" METHOD: canonical
.TP
\fBzipfs canonical\fR ?\fImountpoint\fR? \fIfilename\fR ?\fIinZipfs\fR?
.
This takes the name of a file, \fIfilename\fR, and produces where it would be
mapped into a zipfs mount as its result. If specified, \fImountpoint\fR says
within which mount the mapping will be done; if omitted, the main root of the
zipfs system is used. The \fIinZipfs\fR argument is a an optional boolean
which controls whether to fully canonicalize the name; it defaults to true.
.\" METHOD: exists
.TP
\fBzipfs exists\fI filename\fR
.
Return 1 if the given filename exists in the mounted zipfs and 0 if it does not.
.\" METHOD: find
.TP







|




|
<







44
45
46
47
48
49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
Files within mounted archives can be written to but new files or directories
cannot be created. Further, modifications to files are limited to the
mounted archive in memory and are not persisted to disk.
.PP
Paths in mounted archives are case-sensitive on all platforms.
.\" METHOD: canonical
.TP
\fBzipfs canonical\fR ?\fImountpoint\fR? \fIfilename\fR
.
This takes the name of a file, \fIfilename\fR, and produces where it would be
mapped into a zipfs mount as its result. If specified, \fImountpoint\fR says
within which mount the mapping will be done; if omitted, the main root of the
zipfs system is used.

.\" METHOD: exists
.TP
\fBzipfs exists\fI filename\fR
.
Return 1 if the given filename exists in the mounted zipfs and 0 if it does not.
.\" METHOD: find
.TP
Changes to generic/tcl.h.
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
 * update the version numbers:
 *
 * library/init.tcl	(1 LOC patch)
 * unix/configure.ac	(2 LOC Major, 2 LOC minor, 1 LOC patch)
 * win/configure.ac	(as above)
 * win/tcl.m4		(not patchlevel)
 * README.md		(sections 0 and 2, with and without separator)
 * macosx/Tcl-Common.xcconfig (not patchlevel) 1 LOC
 * win/README		(not patchlevel) (sections 0 and 2)
 * unix/tcl.spec	(1 LOC patch)
 */

#if !defined(TCL_MAJOR_VERSION)
#   define TCL_MAJOR_VERSION	9
#endif







<







38
39
40
41
42
43
44

45
46
47
48
49
50
51
 * update the version numbers:
 *
 * library/init.tcl	(1 LOC patch)
 * unix/configure.ac	(2 LOC Major, 2 LOC minor, 1 LOC patch)
 * win/configure.ac	(as above)
 * win/tcl.m4		(not patchlevel)
 * README.md		(sections 0 and 2, with and without separator)

 * win/README		(not patchlevel) (sections 0 and 2)
 * unix/tcl.spec	(1 LOC patch)
 */

#if !defined(TCL_MAJOR_VERSION)
#   define TCL_MAJOR_VERSION	9
#endif
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
	} while(0)
#   undef Tcl_IsShared
#   define Tcl_IsShared(objPtr) \
	((objPtr)->refCount > 1)

/*
 * Declare that obj will no longer be used or referenced.
 * This will release the obj if there is no referece count,
 * otherwise let it be.
 */
#   define Tcl_BounceRefCount(objPtr) \
    TclBounceRefCount(objPtr);

static inline void
TclBounceRefCount(
    Tcl_Obj* objPtr)







|
<







2442
2443
2444
2445
2446
2447
2448
2449

2450
2451
2452
2453
2454
2455
2456
	} while(0)
#   undef Tcl_IsShared
#   define Tcl_IsShared(objPtr) \
	((objPtr)->refCount > 1)

/*
 * Declare that obj will no longer be used or referenced.
 * This will free the obj if there are no references to the obj.

 */
#   define Tcl_BounceRefCount(objPtr) \
    TclBounceRefCount(objPtr);

static inline void
TclBounceRefCount(
    Tcl_Obj* objPtr)
Changes to generic/tclArithSeries.c.
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
    Tcl_Obj *numberObj)
{
    void *clientData;
    int tcl_number_type;

    if (Tcl_GetNumberFromObj(interp, numberObj, &clientData,
		&tcl_number_type) != TCL_OK) {
    	return TCL_ERROR;
    }
    if (tcl_number_type == TCL_NUMBER_BIG) {
    	/* bignum is not supported yet. */
    	Tcl_WideInt w;
	(void)Tcl_GetWideIntFromObj(interp, numberObj, &w);
	return TCL_ERROR;
    }
    if (useDoubles) {
	if (tcl_number_type != TCL_NUMBER_INT) {
	    *dblNumberPtr = *(double *)clientData;
	} else {







|


|
|







510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
    Tcl_Obj *numberObj)
{
    void *clientData;
    int tcl_number_type;

    if (Tcl_GetNumberFromObj(interp, numberObj, &clientData,
		&tcl_number_type) != TCL_OK) {
	return TCL_ERROR;
    }
    if (tcl_number_type == TCL_NUMBER_BIG) {
	/* bignum is not supported yet. */
	Tcl_WideInt w;
	(void)Tcl_GetWideIntFromObj(interp, numberObj, &w);
	return TCL_ERROR;
    }
    if (useDoubles) {
	if (tcl_number_type != TCL_NUMBER_INT) {
	    *dblNumberPtr = *(double *)clientData;
	} else {
Changes to generic/tclBasic.c.
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
	Tcl_Panic("%s", Tcl_GetStringResult(interp));
    }

    if (TclOOInit(interp) != TCL_OK) {
	Tcl_Panic("%s", Tcl_GetStringResult(interp));
    }

    /*
     * Only build in zlib support if we've successfully detected a library to
     * compile and link against.
     */

#ifdef HAVE_ZLIB
    if (TclZlibInit(interp) != TCL_OK) {
	Tcl_Panic("%s", Tcl_GetStringResult(interp));
    }
    if (TclZipfs_Init(interp) != TCL_OK) {
	Tcl_Panic("%s", Tcl_GetStringResult(interp));
    }
#endif

    TOP_CB(iPtr) = NULL;
    return interp;
}

static void
DeleteOpCmdClientData(







<
<
<
<
<
<
|


<
<
<
<







1331
1332
1333
1334
1335
1336
1337






1338
1339
1340




1341
1342
1343
1344
1345
1346
1347
	Tcl_Panic("%s", Tcl_GetStringResult(interp));
    }

    if (TclOOInit(interp) != TCL_OK) {
	Tcl_Panic("%s", Tcl_GetStringResult(interp));
    }







    if (TclZlibInit(interp) != TCL_OK || TclZipfs_Init(interp) != TCL_OK) {
	Tcl_Panic("%s", Tcl_GetStringResult(interp));
    }





    TOP_CB(iPtr) = NULL;
    return interp;
}

static void
DeleteOpCmdClientData(
Changes to generic/tclClock.c.
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
#define wcscmp strcmp
#define wcscpy strcpy
#endif
#define TZ_INIT_MARKER	((WCHAR *) INT2PTR(-1))

typedef struct ClockTzStatic {
    WCHAR *was;			/* Previous value of TZ. */
#if TCL_MAJOR_VERSION > 8
    long long lastRefresh;	/* Used for latency before next refresh. */
#else
    long lastRefresh;		/* Used for latency before next refresh. */
#endif
    size_t epoch;		/* Epoch, signals that TZ changed. */
    size_t envEpoch;		/* Last env epoch, for faster signaling,
				 * that TZ changed via TCL */
} ClockTzStatic;
static ClockTzStatic tz = {	/* Global timezone info; protected by
				 * clockMutex.*/
    TZ_INIT_MARKER, 0, 0, 0







<

<
<
<







4650
4651
4652
4653
4654
4655
4656

4657



4658
4659
4660
4661
4662
4663
4664
#define wcscmp strcmp
#define wcscpy strcpy
#endif
#define TZ_INIT_MARKER	((WCHAR *) INT2PTR(-1))

typedef struct ClockTzStatic {
    WCHAR *was;			/* Previous value of TZ. */

    long long lastRefresh;	/* Used for latency before next refresh. */



    size_t epoch;		/* Epoch, signals that TZ changed. */
    size_t envEpoch;		/* Last env epoch, for faster signaling,
				 * that TZ changed via TCL */
} ClockTzStatic;
static ClockTzStatic tz = {	/* Global timezone info; protected by
				 * clockMutex.*/
    TZ_INIT_MARKER, 0, 0, 0
Changes to generic/tclCmdIL.c.
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228

/*    lseq n */
    case 1:
	start = zero;
	elementCount = numValues[0];
	end = NULL;
	step = one;
        useDoubles = 0; // Can only have Integer value. If a fractional value
                        // is given, this will fail later. In other words,
                        // "3.0" is allowed and used as Integer, but "3.1"
                        // will be flagged as an error. (bug f4a4bd7f1070)
	break;

/*    lseq n n */
    case 11:
	start = numValues[0];
	end = numValues[1];
	break;







|
|
|
|







4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228

/*    lseq n */
    case 1:
	start = zero;
	elementCount = numValues[0];
	end = NULL;
	step = one;
	useDoubles = 0; // Can only have Integer value. If a fractional value
			// is given, this will fail later. In other words,
			// "3.0" is allowed and used as Integer, but "3.1"
			// will be flagged as an error. (bug f4a4bd7f1070)
	break;

/*    lseq n n */
    case 11:
	start = numValues[0];
	end = numValues[1];
	break;
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
	 goto done;
	 break;
    }

    /* Count needs to be integer, so try to convert if possible */
    if (elementCount && TclHasInternalRep(elementCount, &tclDoubleType)) {
	double d;
        // Don't consider Count type to indicate using double values in seqence
        useDoubles -= (useDoubles > 0) ? 1 : 0;
	(void)Tcl_GetDoubleFromObj(NULL, elementCount, &d);
	if (floor(d) == d) {
	    if ((d >= (double)WIDE_MAX) || (d <= (double)WIDE_MIN)) {
		mp_int big;

		if (Tcl_InitBignumFromDouble(NULL, d, &big) == TCL_OK) {
		    elementCount = Tcl_NewBignumObj(&big);







|
|







4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
	 goto done;
	 break;
    }

    /* Count needs to be integer, so try to convert if possible */
    if (elementCount && TclHasInternalRep(elementCount, &tclDoubleType)) {
	double d;
	// Don't consider Count type to indicate using double values in seqence
	useDoubles -= (useDoubles > 0) ? 1 : 0;
	(void)Tcl_GetDoubleFromObj(NULL, elementCount, &d);
	if (floor(d) == d) {
	    if ((d >= (double)WIDE_MAX) || (d <= (double)WIDE_MIN)) {
		mp_int big;

		if (Tcl_InitBignumFromDouble(NULL, d, &big) == TCL_OK) {
		    elementCount = Tcl_NewBignumObj(&big);
Changes to generic/tclEncoding.c.
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
	     * reference goes away.
	     */

	    Encoding *replaceMe = (Encoding *)Tcl_GetHashValue(hPtr);
	    replaceMe->hPtr = NULL;
	}

	name = (char *) Tcl_Alloc(strlen(typePtr->encodingName) + 1);
	encodingPtr->name	= strcpy(name, typePtr->encodingName);
	encodingPtr->hPtr	= hPtr;
	Tcl_SetHashValue(hPtr, encodingPtr);

	Tcl_MutexUnlock(&encodingMutex);
    }
    return (Tcl_Encoding) encodingPtr;







|







1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
	     * reference goes away.
	     */

	    Encoding *replaceMe = (Encoding *)Tcl_GetHashValue(hPtr);
	    replaceMe->hPtr = NULL;
	}

	name = (char *)Tcl_Alloc(strlen(typePtr->encodingName) + 1);
	encodingPtr->name	= strcpy(name, typePtr->encodingName);
	encodingPtr->hPtr	= hPtr;
	Tcl_SetHashValue(hPtr, encodingPtr);

	Tcl_MutexUnlock(&encodingMutex);
    }
    return (Tcl_Encoding) encodingPtr;
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
			    nBytesProcessed);
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "unexpected byte sequence starting at index %"
			    TCL_SIZE_MODIFIER "d: '\\x%02X'",
			    nBytesProcessed, UCHAR(srcStart[nBytesProcessed])));
		    Tcl_SetErrorCode(
			    interp, "TCL", "ENCODING", "ILLEGALSEQUENCE", buf,
			    (void *)NULL);
		}
	    }
	    if (result != TCL_OK) {
		errno = (result == TCL_CONVERT_NOSPACE) ? ENOMEM : EILSEQ;
	    }
	    return result;
	}







|







1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
			    nBytesProcessed);
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "unexpected byte sequence starting at index %"
			    TCL_SIZE_MODIFIER "d: '\\x%02X'",
			    nBytesProcessed, UCHAR(srcStart[nBytesProcessed])));
		    Tcl_SetErrorCode(
			    interp, "TCL", "ENCODING", "ILLEGALSEQUENCE", buf,
			    (char *)NULL);
		}
	    }
	    if (result != TCL_OK) {
		errno = (result == TCL_CONVERT_NOSPACE) ? ENOMEM : EILSEQ;
	    }
	    return result;
	}
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
		    snprintf(buf, sizeof(buf), "%" TCL_SIZE_MODIFIER "d",
			    nBytesProcessed);
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "unexpected character at index %" TCL_SIZE_MODIFIER
			    "u: 'U+%06X'",
			    pos, ucs4));
		    Tcl_SetErrorCode(interp, "TCL", "ENCODING", "ILLEGALSEQUENCE",
			    buf, (void *)NULL);
		}
	    }
	    if (result != TCL_OK) {
		errno = (result == TCL_CONVERT_NOSPACE) ? ENOMEM : EILSEQ;
	    }
	    return result;
	}







|







1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
		    snprintf(buf, sizeof(buf), "%" TCL_SIZE_MODIFIER "d",
			    nBytesProcessed);
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "unexpected character at index %" TCL_SIZE_MODIFIER
			    "u: 'U+%06X'",
			    pos, ucs4));
		    Tcl_SetErrorCode(interp, "TCL", "ENCODING", "ILLEGALSEQUENCE",
			    buf, (char *)NULL);
		}
	    }
	    if (result != TCL_OK) {
		errno = (result == TCL_CONVERT_NOSPACE) ? ENOMEM : EILSEQ;
	    }
	    return result;
	}
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
	    TclSetProcessGlobalValue(&encodingFileMap, map);
	}
    }

    if ((NULL == chan) && (interp != NULL)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"unknown encoding \"%s\"", name));
	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ENCODING", name,
		(void *)NULL);
    }
    Tcl_DecrRefCount(fileNameObj);
    Tcl_DecrRefCount(searchPath);

    return chan;
}








|
<







1821
1822
1823
1824
1825
1826
1827
1828

1829
1830
1831
1832
1833
1834
1835
	    TclSetProcessGlobalValue(&encodingFileMap, map);
	}
    }

    if ((NULL == chan) && (interp != NULL)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"unknown encoding \"%s\"", name));
	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ENCODING", name, (char *)NULL);

    }
    Tcl_DecrRefCount(fileNameObj);
    Tcl_DecrRefCount(searchPath);

    return chan;
}

1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
    case 'E':
	encoding = LoadEscapeEncoding(name, chan);
	break;
    }
    if ((encoding == NULL) && (interp != NULL)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"invalid encoding file \"%s\"", name));
	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ENCODING", name,
		(void *)NULL);
    }
    Tcl_CloseEx(NULL, chan, 0);

    return encoding;
}

/*







|
<







1895
1896
1897
1898
1899
1900
1901
1902

1903
1904
1905
1906
1907
1908
1909
    case 'E':
	encoding = LoadEscapeEncoding(name, chan);
	break;
    }
    if ((encoding == NULL) && (interp != NULL)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"invalid encoding file \"%s\"", name));
	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ENCODING", name, (char *)NULL);

    }
    Tcl_CloseEx(NULL, chan, 0);

    return encoding;
}

/*
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
    const char *srcStart, *srcEnd, *srcClose;
    const char *dstStart, *dstEnd;
    int result, numChars, charLimit = INT_MAX;
    int ch;
    int profile;

    if (flags & TCL_ENCODING_START) {
        /* *statePtr will hold high surrogate in a split surrogate pair */
    	*statePtr = 0;
    }
    result = TCL_OK;

    srcStart = src;
    srcEnd = src + srcLen;
    srcClose = srcEnd;
    if ((flags & TCL_ENCODING_END) == 0) {







|
|







2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
    const char *srcStart, *srcEnd, *srcClose;
    const char *dstStart, *dstEnd;
    int result, numChars, charLimit = INT_MAX;
    int ch;
    int profile;

    if (flags & TCL_ENCODING_START) {
	/* *statePtr will hold high surrogate in a split surrogate pair */
	*statePtr = 0;
    }
    result = TCL_OK;

    srcStart = src;
    srcEnd = src + srcLen;
    srcClose = srcEnd;
    if ((flags & TCL_ENCODING_END) == 0) {
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
    /*
     * Macro to output an isolated high surrogate when it is not followed
     * by a low surrogate. NOT to be called for strict profile since
     * that should raise an error.
     */
#define OUTPUT_ISOLATEDSURROGATE                                \
    do {                                                        \
        Tcl_UniChar high;                                       \
        if (PROFILE_REPLACE(profile)) {                         \
            high = UNICODE_REPLACE_CHAR;                        \
        } else {                                                \
            high = (Tcl_UniChar)(ptrdiff_t) *statePtr;          \
        }                                                       \
        assert(!(flags & ENCODING_UTF)); /* Must be CESU-8 */   \
        assert(HIGH_SURROGATE(high));                           \
        assert(!PROFILE_STRICT(profile));                       \
        dst += Tcl_UniCharToUtf(high, dst);                     \
        *statePtr = 0; /* Reset state */                        \
    } while (0) 

    /*
     * Macro to check for isolated surrogate and either break with
     * an error if profile is strict, or output an appropriate
     * character for replace and tcl8 profiles and continue.
     */
#define CHECK_ISOLATEDSURROGATE                                         \
    if (*statePtr) {                                                    \
        if (PROFILE_STRICT(profile)) {                                  \
            result = TCL_CONVERT_SYNTAX;                                \
            break;                                                      \
        }                                                               \
        OUTPUT_ISOLATEDSURROGATE;                                       \
        continue; /* Rerun loop so length checks etc. repeated */       \
    } else                                                              \
        (void) 0

    profile = ENCODING_PROFILE_GET(flags);
    for (numChars = 0; src < srcEnd && numChars <= charLimit; numChars++) {

	if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) {
	    /*
	     * If there is more string to follow, this will ensure that the
	     * last UTF-8 character in the source buffer hasn't been cut off.
	     */

	    result = TCL_CONVERT_MULTIBYTE;
	    break;
	}
	if (dst > dstEnd) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
	}
	if (UCHAR(*src) < 0x80
		&& !((UCHAR(*src) == 0) && (flags & ENCODING_INPUT))) {

            CHECK_ISOLATEDSURROGATE;
	    /*
	     * Copy 7bit characters, but skip null-bytes when we are in input
	     * mode, so that they get converted to \xC0\x80.
	     */
	    *dst++ = *src++;
	} else if ((UCHAR(*src) == 0xC0) && (src + 1 < srcEnd) &&
		 (UCHAR(src[1]) == 0x80) &&
		 (!(flags & ENCODING_INPUT) || !PROFILE_TCL8(profile))) {
	    /* Special sequence \xC0\x80 */

            CHECK_ISOLATEDSURROGATE;
	    if (!PROFILE_TCL8(profile) && (flags & ENCODING_INPUT)) {
		if (PROFILE_REPLACE(profile)) {
		    dst += Tcl_UniCharToUtf(UNICODE_REPLACE_CHAR, dst);
		    src += 2;
		} else {
		    /* PROFILE_STRICT */
		    result = TCL_CONVERT_SYNTAX;
		    break;
		}
	    } else {
		/*
		 * Convert 0xC080 to real nulls when we are in output mode,
		 * irrespective of the profile.
		 */
		*dst++ = 0;
		src += 2;
	    }

	} else if (!Tcl_UtfCharComplete(src, srcEnd - src)) {
	    /*
             * Incomplete byte sequence not because there are insufficient
             * bytes in source buffer (have already checked that above) but
             * because the UTF-8 sequence is truncated.
             */

            CHECK_ISOLATEDSURROGATE;

	    if (flags & ENCODING_INPUT) {
		/* Incomplete bytes for modified UTF-8 target */
		if (PROFILE_STRICT(profile)) {
		    result = (flags & TCL_ENCODING_CHAR_LIMIT)
			    ? TCL_CONVERT_MULTIBYTE
			    : TCL_CONVERT_SYNTAX;







|
|
|
|
|
|
|
|
|
|
|
|








|
|
|
|
|
|

|

















<
|

|










|




















|
|
|
|

|







2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528

2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
    /*
     * Macro to output an isolated high surrogate when it is not followed
     * by a low surrogate. NOT to be called for strict profile since
     * that should raise an error.
     */
#define OUTPUT_ISOLATEDSURROGATE                                \
    do {                                                        \
	Tcl_UniChar high;                                       \
	if (PROFILE_REPLACE(profile)) {                         \
	    high = UNICODE_REPLACE_CHAR;                        \
	} else {                                                \
	    high = (Tcl_UniChar)(ptrdiff_t) *statePtr;          \
	}                                                       \
	assert(!(flags & ENCODING_UTF)); /* Must be CESU-8 */   \
	assert(HIGH_SURROGATE(high));                           \
	assert(!PROFILE_STRICT(profile));                       \
	dst += Tcl_UniCharToUtf(high, dst);                     \
	*statePtr = 0; /* Reset state */                        \
    } while (0)

    /*
     * Macro to check for isolated surrogate and either break with
     * an error if profile is strict, or output an appropriate
     * character for replace and tcl8 profiles and continue.
     */
#define CHECK_ISOLATEDSURROGATE                                         \
    if (*statePtr) {                                                    \
	if (PROFILE_STRICT(profile)) {                                  \
	    result = TCL_CONVERT_SYNTAX;                                \
	    break;                                                      \
	}                                                               \
	OUTPUT_ISOLATEDSURROGATE;                                       \
	continue; /* Rerun loop so length checks etc. repeated */       \
    } else                                                              \
	(void) 0

    profile = ENCODING_PROFILE_GET(flags);
    for (numChars = 0; src < srcEnd && numChars <= charLimit; numChars++) {

	if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) {
	    /*
	     * If there is more string to follow, this will ensure that the
	     * last UTF-8 character in the source buffer hasn't been cut off.
	     */

	    result = TCL_CONVERT_MULTIBYTE;
	    break;
	}
	if (dst > dstEnd) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
	}

	if (UCHAR(*src) < 0x80 && !((UCHAR(*src) == 0) && (flags & ENCODING_INPUT))) {

	    CHECK_ISOLATEDSURROGATE;
	    /*
	     * Copy 7bit characters, but skip null-bytes when we are in input
	     * mode, so that they get converted to \xC0\x80.
	     */
	    *dst++ = *src++;
	} else if ((UCHAR(*src) == 0xC0) && (src + 1 < srcEnd) &&
		 (UCHAR(src[1]) == 0x80) &&
		 (!(flags & ENCODING_INPUT) || !PROFILE_TCL8(profile))) {
	    /* Special sequence \xC0\x80 */

	    CHECK_ISOLATEDSURROGATE;
	    if (!PROFILE_TCL8(profile) && (flags & ENCODING_INPUT)) {
		if (PROFILE_REPLACE(profile)) {
		    dst += Tcl_UniCharToUtf(UNICODE_REPLACE_CHAR, dst);
		    src += 2;
		} else {
		    /* PROFILE_STRICT */
		    result = TCL_CONVERT_SYNTAX;
		    break;
		}
	    } else {
		/*
		 * Convert 0xC080 to real nulls when we are in output mode,
		 * irrespective of the profile.
		 */
		*dst++ = 0;
		src += 2;
	    }

	} else if (!Tcl_UtfCharComplete(src, srcEnd - src)) {
	    /*
	     * Incomplete byte sequence not because there are insufficient
	     * bytes in source buffer (have already checked that above) but
	     * because the UTF-8 sequence is truncated.
	     */

	    CHECK_ISOLATEDSURROGATE;

	    if (flags & ENCODING_INPUT) {
		/* Incomplete bytes for modified UTF-8 target */
		if (PROFILE_STRICT(profile)) {
		    result = (flags & TCL_ENCODING_CHAR_LIMIT)
			    ? TCL_CONVERT_MULTIBYTE
			    : TCL_CONVERT_SYNTAX;
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
		/* TCL_ENCODING_PROFILE_TCL8 */
		char chbuf[2];
		chbuf[0] = UCHAR(*src++); chbuf[1] = 0;
		TclUtfToUniChar(chbuf, &ch);
	    }
	    dst += Tcl_UniCharToUtf(ch, dst);
	} else {
            /* Have a complete character */
	    size_t len = TclUtfToUniChar(src, &ch);

            Tcl_UniChar savedSurrogate = (Tcl_UniChar) (ptrdiff_t)*statePtr;
            *statePtr = 0; /* Reset surrogate */

	    if (flags & ENCODING_INPUT) {
		if (((len < 2) && (ch != 0))
			|| ((ch > 0xFFFF) && !(flags & ENCODING_UTF))) {
		    if (PROFILE_STRICT(profile)) {
			result = TCL_CONVERT_SYNTAX;
			break;
		    } else if (PROFILE_REPLACE(profile)) {
			ch = UNICODE_REPLACE_CHAR;
		    }
		}







|


|
|


|
<







2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597

2598
2599
2600
2601
2602
2603
2604
		/* TCL_ENCODING_PROFILE_TCL8 */
		char chbuf[2];
		chbuf[0] = UCHAR(*src++); chbuf[1] = 0;
		TclUtfToUniChar(chbuf, &ch);
	    }
	    dst += Tcl_UniCharToUtf(ch, dst);
	} else {
	    /* Have a complete character */
	    size_t len = TclUtfToUniChar(src, &ch);

	    Tcl_UniChar savedSurrogate = (Tcl_UniChar) (ptrdiff_t)*statePtr;
	    *statePtr = 0; /* Reset surrogate */

	    if (flags & ENCODING_INPUT) {
		if (((len < 2) && (ch != 0)) || ((ch > 0xFFFF) && !(flags & ENCODING_UTF))) {

		    if (PROFILE_STRICT(profile)) {
			result = TCL_CONVERT_SYNTAX;
			break;
		    } else if (PROFILE_REPLACE(profile)) {
			ch = UNICODE_REPLACE_CHAR;
		    }
		}
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
		    ch = (ch & 0x03FF) | 0xDC00;
		}
		*dst++ = (char)(((ch >> 12) | 0xE0) & 0xEF);
		*dst++ = (char)(((ch >> 6) | 0x80) & 0xBF);
		*dst++ = (char)((ch | 0x80) & 0xBF);
		continue;
	    } else if (SURROGATE(ch)) {
                if ((flags & ENCODING_UTF)) {
                    /* UTF-8, not CESU-8, so surrogates should not appear */
                    if (PROFILE_STRICT(profile)) {
                        result = (flags & ENCODING_INPUT)
			    ? TCL_CONVERT_SYNTAX : TCL_CONVERT_UNKNOWN;
                        src = saveSrc;
                        break;
                    } else if (PROFILE_REPLACE(profile)) {
                        ch = UNICODE_REPLACE_CHAR;
                    } else {
                        /* PROFILE_TCL8 - output as is */
                    }
                } else {
                    /* CESU-8 */
                    if (LOW_SURROGATE(ch)) {
                        if (savedSurrogate) {
                            assert(HIGH_SURROGATE(savedSurrogate));
                            ch = 0x10000 + ((savedSurrogate - 0xd800) << 10) + (ch - 0xdc00);
                        } else {
                            /* Isolated low surrogate */
                            if (PROFILE_STRICT(profile)) {
                                result = (flags & ENCODING_INPUT)
                                    ? TCL_CONVERT_SYNTAX : TCL_CONVERT_UNKNOWN;
                                src = saveSrc;
                                break;
                            } else if (PROFILE_REPLACE(profile)) {
                                ch = UNICODE_REPLACE_CHAR;
                            } else {
                                /* Tcl8 profile. Output low surrogate as is */
                            }
                        }
                    } else {
                        assert(HIGH_SURROGATE(ch));
                        /* Save the high surrogate */
                        *statePtr = (Tcl_EncodingState) (ptrdiff_t) ch;
                        if (savedSurrogate) {
                            assert(HIGH_SURROGATE(savedSurrogate));
                            if (PROFILE_STRICT(profile)) {
                                result = (flags & ENCODING_INPUT)
                                    ? TCL_CONVERT_SYNTAX : TCL_CONVERT_UNKNOWN;
                                src = saveSrc;
                                break;
                            } else if (PROFILE_REPLACE(profile)) {
                                ch = UNICODE_REPLACE_CHAR;
                            } else {
                                /* Output the isolated high surrogate */
                                ch = savedSurrogate;
                            }
                        } else {
                            /* High surrogate saved in *statePtr. Do not output anything just yet. */
                            --numChars; /* Cancel the increment at end of loop */
                            continue;
                        }
                    }
                }
	    } else {
                /* Normal character */
                CHECK_ISOLATEDSURROGATE;
            }

	    dst += Tcl_UniCharToUtf(ch, dst);
	}
    }

    /* Check if an high surrogate left over */
    if (*statePtr) {
        assert(!(flags & ENCODING_UTF)); /* CESU-8, Not UTF-8 */
        if (!(flags & TCL_ENCODING_END)) {
            /* More data coming */
        } else {
            /* No more data coming */
            if (PROFILE_STRICT(profile)) {
                result = (flags & ENCODING_INPUT)
                    ? TCL_CONVERT_SYNTAX : TCL_CONVERT_UNKNOWN;
            } else {
                if (PROFILE_REPLACE(profile)) {
                    ch = UNICODE_REPLACE_CHAR;
                } else {
                    ch = (Tcl_UniChar) (ptrdiff_t) *statePtr;
                }
                if (dst < dstEnd) {
                    dst += Tcl_UniCharToUtf(ch, dst);
                    ++numChars;
                } else {
                    /* No room in destination */
                    result = TCL_CONVERT_NOSPACE;
                }
            }
        }

    }

    *srcReadPtr = src - srcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = numChars;
    return result;
}







|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<







2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714

2715
2716
2717
2718
2719
2720
2721
		    ch = (ch & 0x03FF) | 0xDC00;
		}
		*dst++ = (char)(((ch >> 12) | 0xE0) & 0xEF);
		*dst++ = (char)(((ch >> 6) | 0x80) & 0xBF);
		*dst++ = (char)((ch | 0x80) & 0xBF);
		continue;
	    } else if (SURROGATE(ch)) {
		if ((flags & ENCODING_UTF)) {
		    /* UTF-8, not CESU-8, so surrogates should not appear */
		    if (PROFILE_STRICT(profile)) {
			result = (flags & ENCODING_INPUT)
			    ? TCL_CONVERT_SYNTAX : TCL_CONVERT_UNKNOWN;
			src = saveSrc;
			break;
		    } else if (PROFILE_REPLACE(profile)) {
			ch = UNICODE_REPLACE_CHAR;
		    } else {
			/* PROFILE_TCL8 - output as is */
		    }
		} else {
		    /* CESU-8 */
		    if (LOW_SURROGATE(ch)) {
			if (savedSurrogate) {
			    assert(HIGH_SURROGATE(savedSurrogate));
			    ch = 0x10000 + ((savedSurrogate - 0xd800) << 10) + (ch - 0xdc00);
			} else {
			    /* Isolated low surrogate */
			    if (PROFILE_STRICT(profile)) {
				result = (flags & ENCODING_INPUT)
				    ? TCL_CONVERT_SYNTAX : TCL_CONVERT_UNKNOWN;
				src = saveSrc;
				break;
			    } else if (PROFILE_REPLACE(profile)) {
				ch = UNICODE_REPLACE_CHAR;
			    } else {
				/* Tcl8 profile. Output low surrogate as is */
			    }
			}
		    } else {
			assert(HIGH_SURROGATE(ch));
			/* Save the high surrogate */
			*statePtr = (Tcl_EncodingState) (ptrdiff_t) ch;
			if (savedSurrogate) {
			    assert(HIGH_SURROGATE(savedSurrogate));
			    if (PROFILE_STRICT(profile)) {
				result = (flags & ENCODING_INPUT)
				    ? TCL_CONVERT_SYNTAX : TCL_CONVERT_UNKNOWN;
				src = saveSrc;
				break;
			    } else if (PROFILE_REPLACE(profile)) {
				ch = UNICODE_REPLACE_CHAR;
			    } else {
				/* Output the isolated high surrogate */
				ch = savedSurrogate;
			    }
			} else {
			    /* High surrogate saved in *statePtr. Do not output anything just yet. */
			    --numChars; /* Cancel the increment at end of loop */
			    continue;
			}
		    }
		}
	    } else {
		/* Normal character */
		CHECK_ISOLATEDSURROGATE;
	    }

	    dst += Tcl_UniCharToUtf(ch, dst);
	}
    }

    /* Check if an high surrogate left over */
    if (*statePtr) {
	assert(!(flags & ENCODING_UTF)); /* CESU-8, Not UTF-8 */
	if (!(flags & TCL_ENCODING_END)) {
	    /* More data coming */
	} else {
	    /* No more data coming */
	    if (PROFILE_STRICT(profile)) {
		result = (flags & ENCODING_INPUT)
		    ? TCL_CONVERT_SYNTAX : TCL_CONVERT_UNKNOWN;
	    } else {
		if (PROFILE_REPLACE(profile)) {
		    ch = UNICODE_REPLACE_CHAR;
		} else {
		    ch = (Tcl_UniChar) (ptrdiff_t) *statePtr;
		}
		if (dst < dstEnd) {
		    dst += Tcl_UniCharToUtf(ch, dst);
		    ++numChars;
		} else {
		    /* No room in destination */
		    result = TCL_CONVERT_NOSPACE;
		}
	    }
	}

    }

    *srcReadPtr = src - srcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = numChars;
    return result;
}
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195

    srcStart = src;
    srcEnd = src + srcLen;

    dstStart = dst;
    dstEnd = dst + dstLen - TCL_UTF_MAX;

    for (numChars = 0; src < srcEnd && numChars <= charLimit;
	    src += 2, numChars++) {
	if (dst > dstEnd && !HIGH_SURROGATE(ch)) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
	}

	unsigned short prev = ch;
	if (flags & TCL_ENCODING_LE) {
	    ch = (src[1] & 0xFF) << 8 | (src[0] & 0xFF);
	} else {
	    ch = (src[0] & 0xFF) << 8 | (src[1] & 0xFF);
	}
	if (HIGH_SURROGATE(prev)) {
            if (LOW_SURROGATE(ch)) {
                /*
                 * High surrogate was followed by a low surrogate.
                 * Tcl_UniCharToUtf would have stashed away the state in dst.
                 * Call it again to combine that state with the low surrogate.
                 * We also have to compensate the numChars as two UTF-16 units
                 * have been combined into one character.
                 */
                dst += Tcl_UniCharToUtf(ch | TCL_COMBINE, dst);
            } else {
                /* High surrogate was not followed by a low surrogate */
                if (PROFILE_STRICT(flags)) {
                    result = TCL_CONVERT_SYNTAX;
                    src -= 2;	/* Go back to beginning of high surrogate */
                    dst--;		/* Also undo writing a single byte too much */
                    break;
                }
                if (PROFILE_REPLACE(flags)) {
                    /*
                     * Previous loop wrote a single byte to mark the high surrogate.
                     * Replace it with the replacement character.
                     */
                    ch = UNICODE_REPLACE_CHAR;
                    dst--;
                    numChars++;
                    dst += Tcl_UniCharToUtf(ch, dst);
                } else {
                    /*
                     * Bug [10c2c17c32]. If Hi surrogate not followed by Lo
                     * surrogate, finish 3-byte UTF-8
                     */
                    dst += Tcl_UniCharToUtf(-1, dst);
                }
                /* Loop around again so destination space and other checks are done */
                prev = 0; /* Reset high surrogate tracker */
                src -= 2;
            }
	} else {
            /* Previous char was not a high surrogate */

            /*
             * Special case for 1-byte utf chars for speed. Make sure we work with
             * unsigned short-size data. Order checks based on expected frequency.
             */
            if ((unsigned)ch - 1 < 0x7F) {
                /* ASCII except nul */
                *dst++ = (ch & 0xFF);
            } else if (!SURROGATE(ch)) {
                /* Not ASCII, not surrogate */
                dst += Tcl_UniCharToUtf(ch, dst);
            } else if (HIGH_SURROGATE(ch)) {
                dst += Tcl_UniCharToUtf(ch | TCL_COMBINE, dst);
                /* Do not count this just yet. Compensate for numChars++ in loop counter */
                numChars--;
            } else {
                assert(LOW_SURROGATE(ch));
                if (PROFILE_STRICT(flags)) {
                    result = TCL_CONVERT_SYNTAX;
                    break;
                }
                if (PROFILE_REPLACE(flags)) {
                    ch = UNICODE_REPLACE_CHAR;
                }
                dst += Tcl_UniCharToUtf(ch, dst);
            }
        }
    }

    /*
     * When the above loop ends, result may have the following values:
     * 1. TCL_OK - full source buffer was completely processed.
     *    src, dst, numChars will hold values up to that point BUT
     *    there may be a leftover high surrogate we need to deal with.
     * 2. TCL_CONVERT_NOSPACE - Ran out of room in the destination buffer.
     *    Same considerations as (1)
     * 3. TCL_CONVERT_SYNTAX - decoding error.
     * 4. TCL_CONVERT_MULTIBYTE - the buffer passed in was not fully
     *    processed, because there was a trailing single byte. However,
     *    we *may* have processed the requested number of characters already
     *    in which case the trailing byte does not matter. We still
     *    *may* still be a leftover high surrogate as in (1) and (2).
     */
    switch (result) {
    case TCL_CONVERT_MULTIBYTE: /* FALLTHRU */
    case TCL_OK: /* FALLTHRU */
    case TCL_CONVERT_NOSPACE:
        if (HIGH_SURROGATE(ch)) {
            if (flags & TCL_ENCODING_END) {
                /*
                 * No more data expected. There will be space for output of
                 * one character (essentially overwriting the dst area holding
                 * high surrogate state)
                 */
                assert((dst-1) <= dstEnd);
                if (PROFILE_STRICT(flags)) {
                    result = TCL_CONVERT_SYNTAX;
                    src -= 2;
                    dst--;
                } else if (PROFILE_REPLACE(flags)) {
                    dst--;
                    numChars++;
                    dst += Tcl_UniCharToUtf(UNICODE_REPLACE_CHAR, dst);
                } else {
                    /* Bug [10c2c17c32]. If Hi surrogate, finish 3-byte UTF-8 */
                    numChars++;
                    dst += Tcl_UniCharToUtf(-1, dst);
                }
            } else {
                /* More data is expected. Revert the surrogate state */
                src -= 2;
                dst--;
                /* Note: leave result of TCL_CONVERT_NOSPACE as is */
                if (result == TCL_OK) {
                    result = TCL_CONVERT_MULTIBYTE;
                }
            }
        } else if ((flags & TCL_ENCODING_END) && (result == TCL_CONVERT_MULTIBYTE)) {
            /*
             * If we had a trailing byte at the end AND this is the last
             * fragment AND profile is not "strict", stick FFFD in its place.
             * Note in this case we DO need to check for room in dst.
             */
            if (dst > dstEnd) {
                result = TCL_CONVERT_NOSPACE;
            } else {
                if (PROFILE_STRICT(flags)) {
                    result = TCL_CONVERT_SYNTAX;
                } else {
                    /* PROFILE_REPLACE or PROFILE_TCL8 */
                    result = TCL_OK;
                    dst += Tcl_UniCharToUtf(UNICODE_REPLACE_CHAR, dst);
                    numChars++;
                    src++;
                }
            }
        }
        break;
    case TCL_CONVERT_SYNTAX:
        break; /* Nothing to do */
    }

    *srcReadPtr = src - srcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = numChars;
    return result;
}







|
<












|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|




















|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|







3024
3025
3026
3027
3028
3029
3030
3031

3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189

    srcStart = src;
    srcEnd = src + srcLen;

    dstStart = dst;
    dstEnd = dst + dstLen - TCL_UTF_MAX;

    for (numChars = 0; src < srcEnd && numChars <= charLimit; src += 2, numChars++) {

	if (dst > dstEnd && !HIGH_SURROGATE(ch)) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
	}

	unsigned short prev = ch;
	if (flags & TCL_ENCODING_LE) {
	    ch = (src[1] & 0xFF) << 8 | (src[0] & 0xFF);
	} else {
	    ch = (src[0] & 0xFF) << 8 | (src[1] & 0xFF);
	}
	if (HIGH_SURROGATE(prev)) {
	    if (LOW_SURROGATE(ch)) {
		/*
		 * High surrogate was followed by a low surrogate.
		 * Tcl_UniCharToUtf would have stashed away the state in dst.
		 * Call it again to combine that state with the low surrogate.
		 * We also have to compensate the numChars as two UTF-16 units
		 * have been combined into one character.
		 */
		dst += Tcl_UniCharToUtf(ch | TCL_COMBINE, dst);
	    } else {
		/* High surrogate was not followed by a low surrogate */
		if (PROFILE_STRICT(flags)) {
		    result = TCL_CONVERT_SYNTAX;
		    src -= 2;	/* Go back to beginning of high surrogate */
		    dst--;		/* Also undo writing a single byte too much */
		    break;
		}
		if (PROFILE_REPLACE(flags)) {
		    /*
		     * Previous loop wrote a single byte to mark the high surrogate.
		     * Replace it with the replacement character.
		     */
		    ch = UNICODE_REPLACE_CHAR;
		    dst--;
		    numChars++;
		    dst += Tcl_UniCharToUtf(ch, dst);
		} else {
		    /*
		     * Bug [10c2c17c32]. If Hi surrogate not followed by Lo
		     * surrogate, finish 3-byte UTF-8
		     */
		    dst += Tcl_UniCharToUtf(-1, dst);
		}
		/* Loop around again so destination space and other checks are done */
		prev = 0; /* Reset high surrogate tracker */
		src -= 2;
	    }
	} else {
	    /* Previous char was not a high surrogate */

	    /*
	     * Special case for 1-byte utf chars for speed. Make sure we work with
	     * unsigned short-size data. Order checks based on expected frequency.
	     */
	    if ((unsigned)ch - 1 < 0x7F) {
		/* ASCII except nul */
		*dst++ = (ch & 0xFF);
	    } else if (!SURROGATE(ch)) {
		/* Not ASCII, not surrogate */
		dst += Tcl_UniCharToUtf(ch, dst);
	    } else if (HIGH_SURROGATE(ch)) {
		dst += Tcl_UniCharToUtf(ch | TCL_COMBINE, dst);
		/* Do not count this just yet. Compensate for numChars++ in loop counter */
		numChars--;
	    } else {
		assert(LOW_SURROGATE(ch));
		if (PROFILE_STRICT(flags)) {
		    result = TCL_CONVERT_SYNTAX;
		    break;
		}
		if (PROFILE_REPLACE(flags)) {
		    ch = UNICODE_REPLACE_CHAR;
		}
		dst += Tcl_UniCharToUtf(ch, dst);
	    }
	}
    }

    /*
     * When the above loop ends, result may have the following values:
     * 1. TCL_OK - full source buffer was completely processed.
     *    src, dst, numChars will hold values up to that point BUT
     *    there may be a leftover high surrogate we need to deal with.
     * 2. TCL_CONVERT_NOSPACE - Ran out of room in the destination buffer.
     *    Same considerations as (1)
     * 3. TCL_CONVERT_SYNTAX - decoding error.
     * 4. TCL_CONVERT_MULTIBYTE - the buffer passed in was not fully
     *    processed, because there was a trailing single byte. However,
     *    we *may* have processed the requested number of characters already
     *    in which case the trailing byte does not matter. We still
     *    *may* still be a leftover high surrogate as in (1) and (2).
     */
    switch (result) {
    case TCL_CONVERT_MULTIBYTE: /* FALLTHRU */
    case TCL_OK: /* FALLTHRU */
    case TCL_CONVERT_NOSPACE:
	if (HIGH_SURROGATE(ch)) {
	    if (flags & TCL_ENCODING_END) {
		/*
		 * No more data expected. There will be space for output of
		 * one character (essentially overwriting the dst area holding
		 * high surrogate state)
		 */
		assert((dst-1) <= dstEnd);
		if (PROFILE_STRICT(flags)) {
		    result = TCL_CONVERT_SYNTAX;
		    src -= 2;
		    dst--;
		} else if (PROFILE_REPLACE(flags)) {
		    dst--;
		    numChars++;
		    dst += Tcl_UniCharToUtf(UNICODE_REPLACE_CHAR, dst);
		} else {
		    /* Bug [10c2c17c32]. If Hi surrogate, finish 3-byte UTF-8 */
		    numChars++;
		    dst += Tcl_UniCharToUtf(-1, dst);
		}
	    } else {
		/* More data is expected. Revert the surrogate state */
		src -= 2;
		dst--;
		/* Note: leave result of TCL_CONVERT_NOSPACE as is */
		if (result == TCL_OK) {
		    result = TCL_CONVERT_MULTIBYTE;
		}
	    }
	} else if ((flags & TCL_ENCODING_END) && (result == TCL_CONVERT_MULTIBYTE)) {
	    /*
	     * If we had a trailing byte at the end AND this is the last
	     * fragment AND profile is not "strict", stick FFFD in its place.
	     * Note in this case we DO need to check for room in dst.
	     */
	    if (dst > dstEnd) {
		result = TCL_CONVERT_NOSPACE;
	    } else {
		if (PROFILE_STRICT(flags)) {
		    result = TCL_CONVERT_SYNTAX;
		} else {
		    /* PROFILE_REPLACE or PROFILE_TCL8 */
		    result = TCL_OK;
		    dst += Tcl_UniCharToUtf(UNICODE_REPLACE_CHAR, dst);
		    numChars++;
		    src++;
		}
	    }
	}
	break;
    case TCL_CONVERT_SYNTAX:
	break; /* Nothing to do */
    }

    *srcReadPtr = src - srcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = numChars;
    return result;
}
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281










3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297

3298
3299
3300
3301
3302
3303
3304
		result = TCL_CONVERT_UNKNOWN;
		break;
	    }
	    if (PROFILE_REPLACE(flags)) {
		ch = UNICODE_REPLACE_CHAR;
	    }
	}
	src += len;
	if (flags & TCL_ENCODING_LE) {
	    if (ch <= 0xFFFF) {
		*dst++ = (ch & 0xFF);
		*dst++ = (ch >> 8);
	    } else {










		*dst++ = (((ch - 0x10000) >> 10) & 0xFF);
		*dst++ = (((ch - 0x10000) >> 18) & 0x3) | 0xD8;
		*dst++ = (ch & 0xFF);
		*dst++ = ((ch >> 8) & 0x3) | 0xDC;
	    }
	} else {
	    if (ch <= 0xFFFF) {
		*dst++ = (ch >> 8);
		*dst++ = (ch & 0xFF);
	    } else {
		*dst++ = (((ch - 0x10000) >> 18) & 0x3) | 0xD8;
		*dst++ = (((ch - 0x10000) >> 10) & 0xFF);
		*dst++ = ((ch >> 8) & 0x3) | 0xDC;
		*dst++ = (ch & 0xFF);
	    }
	}

    }
    *srcReadPtr = src - srcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = numChars;
    return result;
}








|
|
<



>
>
>
>
>
>
>
>
>
>




<
<
<
<
<







>







3263
3264
3265
3266
3267
3268
3269
3270
3271

3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288





3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
		result = TCL_CONVERT_UNKNOWN;
		break;
	    }
	    if (PROFILE_REPLACE(flags)) {
		ch = UNICODE_REPLACE_CHAR;
	    }
	}
	if (ch <= 0xFFFF) {
	    if (flags & TCL_ENCODING_LE) {

		*dst++ = (ch & 0xFF);
		*dst++ = (ch >> 8);
	    } else {
		*dst++ = (ch >> 8);
		*dst++ = (ch & 0xFF);
	    }
	} else {
	    if ((dst+2) > dstEnd) {
		/* Surrogates need 2 more bytes! Bug [66da4d4228] */
		result = TCL_CONVERT_NOSPACE;
		break;
	    }
	    if (flags & TCL_ENCODING_LE) {
		*dst++ = (((ch - 0x10000) >> 10) & 0xFF);
		*dst++ = (((ch - 0x10000) >> 18) & 0x3) | 0xD8;
		*dst++ = (ch & 0xFF);
		*dst++ = ((ch >> 8) & 0x3) | 0xDC;





	    } else {
		*dst++ = (((ch - 0x10000) >> 18) & 0x3) | 0xD8;
		*dst++ = (((ch - 0x10000) >> 10) & 0xFF);
		*dst++ = ((ch >> 8) & 0x3) | 0xDC;
		*dst++ = (ch & 0xFF);
	    }
	}
	src += len;
    }
    *srcReadPtr = src - srcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = numChars;
    return result;
}

3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
		    break;
		} else if (PROFILE_STRICT(flags)) {
		    result = TCL_CONVERT_SYNTAX;
		    break;
		} else if (PROFILE_REPLACE(flags)) {
		    ch = UNICODE_REPLACE_CHAR;
		} else {
		    /* For prefix bytes, we don't fallback to cp1252, see
		     * [1355b9a874] */
		    ch = byte;
		}
	    } else {
		ch = toUnicode[byte][*((unsigned char *)++src)];
	    }
	} else {
	    ch = pageZero[byte];







|
<







3482
3483
3484
3485
3486
3487
3488
3489

3490
3491
3492
3493
3494
3495
3496
		    break;
		} else if (PROFILE_STRICT(flags)) {
		    result = TCL_CONVERT_SYNTAX;
		    break;
		} else if (PROFILE_REPLACE(flags)) {
		    ch = UNICODE_REPLACE_CHAR;
		} else {
		    /* For prefix bytes, we don't fallback to cp1252, see [1355b9a874] */

		    ch = byte;
		}
	    } else {
		ch = toUnicode[byte][*((unsigned char *)++src)];
	    }
	} else {
	    ch = pageZero[byte];
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
	memcpy(dst, dataPtr->init, dataPtr->initLen);
	dst += dataPtr->initLen;
    } else {
	state = PTR2INT(*statePtr);
    }

    encodingPtr = GetTableEncoding(dataPtr, state);
    tableDataPtr = (TableEncodingData *) encodingPtr->clientData;
    tablePrefixBytes = tableDataPtr->prefixBytes;
    tableFromUnicode = (const unsigned short *const *)
	    tableDataPtr->fromUnicode;

    for (numChars = 0; src < srcEnd; numChars++) {
	unsigned len;
	int word;







|







4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
	memcpy(dst, dataPtr->init, dataPtr->initLen);
	dst += dataPtr->initLen;
    } else {
	state = PTR2INT(*statePtr);
    }

    encodingPtr = GetTableEncoding(dataPtr, state);
    tableDataPtr = (const TableEncodingData *)encodingPtr->clientData;
    tablePrefixBytes = tableDataPtr->prefixBytes;
    tableFromUnicode = (const unsigned short *const *)
	    tableDataPtr->fromUnicode;

    for (numChars = 0; src < srcEnd; numChars++) {
	unsigned len;
	int word;
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
	if ((word == 0) && (ch != 0)) {
	    int oldState;
	    const EscapeSubTable *subTablePtr;

	    oldState = state;
	    for (state = 0; state < dataPtr->numSubTables; state++) {
		encodingPtr = GetTableEncoding(dataPtr, state);
		tableDataPtr = (TableEncodingData *) encodingPtr->clientData;
		word = tableDataPtr->fromUnicode[(ch >> 8)][ch & 0xFF];
		if (word != 0) {
		    break;
		}
	    }

	    if (word == 0) {
		state = oldState;
		if (PROFILE_STRICT(flags)) {
		    result = TCL_CONVERT_UNKNOWN;
		    break;
		}
		encodingPtr = GetTableEncoding(dataPtr, state);
		tableDataPtr = (TableEncodingData *) encodingPtr->clientData;
		word = tableDataPtr->fallback;
	    }

	    tablePrefixBytes = (const char *) tableDataPtr->prefixBytes;
	    tableFromUnicode = (const unsigned short *const *)
		    tableDataPtr->fromUnicode;








|













|







4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
	if ((word == 0) && (ch != 0)) {
	    int oldState;
	    const EscapeSubTable *subTablePtr;

	    oldState = state;
	    for (state = 0; state < dataPtr->numSubTables; state++) {
		encodingPtr = GetTableEncoding(dataPtr, state);
		tableDataPtr = (const TableEncodingData *)encodingPtr->clientData;
		word = tableDataPtr->fromUnicode[(ch >> 8)][ch & 0xFF];
		if (word != 0) {
		    break;
		}
	    }

	    if (word == 0) {
		state = oldState;
		if (PROFILE_STRICT(flags)) {
		    result = TCL_CONVERT_UNKNOWN;
		    break;
		}
		encodingPtr = GetTableEncoding(dataPtr, state);
		tableDataPtr = (const TableEncodingData *)encodingPtr->clientData;
		word = tableDataPtr->fallback;
	    }

	    tablePrefixBytes = (const char *) tableDataPtr->prefixBytes;
	    tableFromUnicode = (const unsigned short *const *)
		    tableDataPtr->fromUnicode;

4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
    }
    if (interp) {
	/* This code assumes at least two profiles :-) */
	Tcl_Obj *errorObj = Tcl_ObjPrintf("bad profile name \"%s\": must be",
		profileName);
	for (i = 0; i < (numProfiles - 1); ++i) {
	    Tcl_AppendStringsToObj(
		    errorObj, " ", encodingProfiles[i].name, ",",
		    (void *)NULL);
	}
	Tcl_AppendStringsToObj(
		errorObj, " or ", encodingProfiles[numProfiles-1].name,
		(void *)NULL);

	Tcl_SetObjResult(interp, errorObj);
	Tcl_SetErrorCode(
		interp, "TCL", "ENCODING", "PROFILE", profileName,
		(void *)NULL);
    }
    return TCL_ERROR;
}

/*
 *------------------------------------------------------------------------
 *







|
<


|
<



|
<







4529
4530
4531
4532
4533
4534
4535
4536

4537
4538
4539

4540
4541
4542
4543

4544
4545
4546
4547
4548
4549
4550
    }
    if (interp) {
	/* This code assumes at least two profiles :-) */
	Tcl_Obj *errorObj = Tcl_ObjPrintf("bad profile name \"%s\": must be",
		profileName);
	for (i = 0; i < (numProfiles - 1); ++i) {
	    Tcl_AppendStringsToObj(
		    errorObj, " ", encodingProfiles[i].name, ",", (char *)NULL);

	}
	Tcl_AppendStringsToObj(
		errorObj, " or ", encodingProfiles[numProfiles-1].name, (char *)NULL);


	Tcl_SetObjResult(interp, errorObj);
	Tcl_SetErrorCode(
		interp, "TCL", "ENCODING", "PROFILE", profileName, (char *)NULL);

    }
    return TCL_ERROR;
}

/*
 *------------------------------------------------------------------------
 *
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
const char *
TclEncodingProfileIdToName(
    Tcl_Interp *interp,		/* For error messages. May be NULL */
    int profileValue)		/* Profile #define value */
{
    size_t i;

    for (i = 0; i < sizeof(encodingProfiles) / sizeof(encodingProfiles[0]);
	    ++i) {
	if (profileValue == encodingProfiles[i].value) {
	    return encodingProfiles[i].name;
	}
    }
    if (interp) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"Internal error. Bad profile id \"%d\".",
		profileValue));
	Tcl_SetErrorCode(
		interp, "TCL", "ENCODING", "PROFILEID", (void *)NULL);
    }
    return NULL;
}

/*
 *------------------------------------------------------------------------
 *







|
<






|
<

|







4563
4564
4565
4566
4567
4568
4569
4570

4571
4572
4573
4574
4575
4576
4577

4578
4579
4580
4581
4582
4583
4584
4585
4586
const char *
TclEncodingProfileIdToName(
    Tcl_Interp *interp,		/* For error messages. May be NULL */
    int profileValue)		/* Profile #define value */
{
    size_t i;

    for (i = 0; i < sizeof(encodingProfiles) / sizeof(encodingProfiles[0]); ++i) {

	if (profileValue == encodingProfiles[i].value) {
	    return encodingProfiles[i].name;
	}
    }
    if (interp) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"Internal error. Bad profile id \"%d\".", profileValue));

	Tcl_SetErrorCode(
		interp, "TCL", "ENCODING", "PROFILEID", (char *)NULL);
    }
    return NULL;
}

/*
 *------------------------------------------------------------------------
 *
Changes to generic/tclEnsemble.c.
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
    Tcl_Command token,		/* The ensemble to configure. */
    int objc,			/* The count of option-related arguments. */
    Tcl_Obj *const objv[])	/* Option-related arguments. */
{
    Tcl_Size len;
    int allocatedMapFlag = 0;
    Tcl_Obj *subcmdObj = NULL, *mapObj = NULL, *paramObj = NULL,
	    *unknownObj = NULL; 	/* Defaults, silence gcc 4 warnings */
    Tcl_Obj *listObj;
    Tcl_DictSearch search;
    int permitPrefix, flags = 0;	/* silence gcc 4 warning */
    enum EnsConfigOpts index;
    int done;

    Tcl_GetEnsembleSubcommandList(NULL, token, &subcmdObj);







|







587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
    Tcl_Command token,		/* The ensemble to configure. */
    int objc,			/* The count of option-related arguments. */
    Tcl_Obj *const objv[])	/* Option-related arguments. */
{
    Tcl_Size len;
    int allocatedMapFlag = 0;
    Tcl_Obj *subcmdObj = NULL, *mapObj = NULL, *paramObj = NULL,
	    *unknownObj = NULL;	/* Defaults, silence gcc 4 warnings */
    Tcl_Obj *listObj;
    Tcl_DictSearch search;
    int permitPrefix, flags = 0;	/* silence gcc 4 warning */
    enum EnsConfigOpts index;
    int done;

    Tcl_GetEnsembleSubcommandList(NULL, token, &subcmdObj);
Changes to generic/tclEvent.c.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tclInt.h"
#include "tclUuid.h"
#if defined(HAVE_ZLIB) && defined(TCL_WITH_INTERNAL_ZLIB)
#include "zlib.h"
#endif /* HAVE_ZLIB */

/*
 * The data structure below is used to report background errors. One such
 * structure is allocated for each error; it holds information about the
 * interpreter and the error until an idle handler command can be invoked.
 */








|

|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tclInt.h"
#include "tclUuid.h"
#ifdef TCL_WITH_INTERNAL_ZLIB
#include "zlib.h"
#endif /* TCL_WITH_INTERNAL_ZLIB */

/*
 * The data structure below is used to report background errors. One such
 * structure is allocated for each error; it holds information about the
 * interpreter and the error until an idle handler command can be invoked.
 */

1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
#endif
#ifdef STATIC_BUILD
	    ".static"
#endif
#ifndef TCL_WITH_EXTERNAL_TOMMATH
	    ".tommath-0103"
#endif
#if defined(HAVE_ZLIB) && defined(TCL_WITH_INTERNAL_ZLIB)
	    ".zlib-"
#if ZLIB_VER_MAJOR < 10
	    "0"
#endif
	    STRINGIFY(ZLIB_VER_MAJOR)
#if ZLIB_VER_MINOR < 10
	    "0"
#endif
	    STRINGIFY(ZLIB_VER_MINOR)
#endif
}};

const char *
Tcl_InitSubsystems(void)
{
    if (inExit != 0) {
	Tcl_Panic("Tcl_InitSubsystems called while exiting");







|









|







1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
#endif
#ifdef STATIC_BUILD
	    ".static"
#endif
#ifndef TCL_WITH_EXTERNAL_TOMMATH
	    ".tommath-0103"
#endif
#ifdef TCL_WITH_INTERNAL_ZLIB
	    ".zlib-"
#if ZLIB_VER_MAJOR < 10
	    "0"
#endif
	    STRINGIFY(ZLIB_VER_MAJOR)
#if ZLIB_VER_MINOR < 10
	    "0"
#endif
	    STRINGIFY(ZLIB_VER_MINOR)
#endif // TCL_WITH_INTERNAL_ZLIB
}};

const char *
Tcl_InitSubsystems(void)
{
    if (inExit != 0) {
	Tcl_Panic("Tcl_InitSubsystems called while exiting");
Changes to generic/tclExecute.c.
9110
9111
9112
9113
9114
9115
9116
9117
9118
9119
9120
9121
9122
9123
9124
9125


9126


9127
9128
9129
9130
9131
9132
9133
	op = operatorStrings[opcode - INST_BITOR];
    }

    if (GetNumberFromObj(NULL, opndPtr, &ptr, &type) != TCL_OK) {
	Tcl_Size length;
	if (TclHasInternalRep(opndPtr, &tclDictType)) {
	    Tcl_DictObjSize(NULL, opndPtr, &length);
	    if (length > 1) {
	    listRep:
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"cannot use a list as %soperand of \"%s\"", ord, op));
		Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", "list", (char *)NULL);
		return;
	    }
	}
	Tcl_ObjTypeLengthProc *lengthProc = TclObjTypeHasProc(opndPtr, lengthProc);


	if (lengthProc && lengthProc(opndPtr) > 1) {


	    goto listRep;
	}
	description = "non-numeric string";
    } else if (type == TCL_NUMBER_NAN) {
	description = "non-numeric floating-point value";
    } else if (type == TCL_NUMBER_DOUBLE) {
	description = "floating-point value";







|








>
>
|
>
>







9110
9111
9112
9113
9114
9115
9116
9117
9118
9119
9120
9121
9122
9123
9124
9125
9126
9127
9128
9129
9130
9131
9132
9133
9134
9135
9136
9137
	op = operatorStrings[opcode - INST_BITOR];
    }

    if (GetNumberFromObj(NULL, opndPtr, &ptr, &type) != TCL_OK) {
	Tcl_Size length;
	if (TclHasInternalRep(opndPtr, &tclDictType)) {
	    Tcl_DictObjSize(NULL, opndPtr, &length);
	    if (length > 0) {
	    listRep:
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"cannot use a list as %soperand of \"%s\"", ord, op));
		Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", "list", (char *)NULL);
		return;
	    }
	}
	Tcl_ObjTypeLengthProc *lengthProc = TclObjTypeHasProc(opndPtr, lengthProc);
	Tcl_Size objcPtr;
	Tcl_Obj **objvPtr;
	if ((lengthProc && lengthProc(opndPtr) > 1)
		|| ((TclMaxListLength(TclGetString(opndPtr), TCL_INDEX_NONE, NULL) > 1)
		&& (Tcl_ListObjGetElements(NULL, opndPtr, &objcPtr, &objvPtr) == TCL_OK))) {
	    goto listRep;
	}
	description = "non-numeric string";
    } else if (type == TCL_NUMBER_NAN) {
	description = "non-numeric floating-point value";
    } else if (type == TCL_NUMBER_DOUBLE) {
	description = "floating-point value";
Changes to generic/tclIcu.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16



17
18
19
20
21
22
23
24
25

26
27

28
29
30
31
32








33






34
35
36
37
38
39
40















41
42
43
44
45




























46

47
48


49
50

















51
52
53
54
55
56
57
/*
 * tclIcu.c --
 *
 * 	tclIcu.c implements various Tcl commands that make use of
 *	the ICU library if present on the system.
 *	(Adapted from tkIcu.c)
 *
 * Copyright © 2021 Jan Nijtmans
 * Copyright © 2024 Ashok P. Nadkarni
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tclInt.h"




/*
 * Runtime linking of libicu.
 */
typedef enum UBreakIteratorTypex {
    UBRK_CHARACTERX = 0,
    UBRK_WORDX = 1
} UBreakIteratorTypex;

typedef enum UErrorCodex {

    U_AMBIGUOUS_ALIAS_WARNING = -122,
    U_ZERO_ERRORZ =  0,		/**< No error, no warning. */

} UErrorCodex;

#define U_SUCCESS(x) ((x)<=U_ZERO_ERRORZ)
#define U_FAILURE(x) ((x)>U_ZERO_ERRORZ)









struct UEnumeration;






typedef struct UEnumeration UEnumeration;
struct UCharsetDetector;
typedef struct UCharsetDetector UCharsetDetector;
struct UCharsetMatch;
typedef struct UCharsetMatch UCharsetMatch;
typedef struct UBreakIterator UBreakIterator;
















/*
 * Prototypes for ICU functions sorted by category.
 */
typedef void        (*fn_u_cleanup)(void);
typedef const char *(*fn_u_errorName)(UErrorCodex);






























typedef uint16_t    (*fn_ucnv_countAliases)(const char *, UErrorCodex *);
typedef int32_t     (*fn_ucnv_countAvailable)(void);


typedef const char *(*fn_ucnv_getAlias)(const char *, uint16_t, UErrorCodex *);
typedef const char *(*fn_ucnv_getAvailableName)(int32_t);


















typedef UBreakIterator *(*fn_ubrk_open)(
	UBreakIteratorTypex, const char *, const uint16_t *, int32_t,
	UErrorCodex *);
typedef void	(*fn_ubrk_close)(UBreakIterator *);
typedef int32_t	(*fn_ubrk_preceding)(UBreakIterator *, int32_t);
typedef int32_t	(*fn_ubrk_following)(UBreakIterator *, int32_t);



|












>
>
>









>

|
>





>
>
>
>
>
>
>
>
|
>
>
>
>
>
>

<

<


|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>


>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

54

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
 * tclIcu.c --
 *
 *	tclIcu.c implements various Tcl commands that make use of
 *	the ICU library if present on the system.
 *	(Adapted from tkIcu.c)
 *
 * Copyright © 2021 Jan Nijtmans
 * Copyright © 2024 Ashok P. Nadkarni
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tclInt.h"

typedef uint16_t UCharx;
typedef uint32_t UChar32x;

/*
 * Runtime linking of libicu.
 */
typedef enum UBreakIteratorTypex {
    UBRK_CHARACTERX = 0,
    UBRK_WORDX = 1
} UBreakIteratorTypex;

typedef enum UErrorCodex {
    U_STRING_NOT_TERMINATED_WARNING = -124,
    U_AMBIGUOUS_ALIAS_WARNING = -122,
    U_ZERO_ERRORZ = 0, /**< No error, no warning. */
    U_BUFFER_OVERFLOW_ERROR = 15,
} UErrorCodex;

#define U_SUCCESS(x) ((x)<=U_ZERO_ERRORZ)
#define U_FAILURE(x) ((x)>U_ZERO_ERRORZ)

typedef enum {
    UCNV_UNASSIGNED = 0,
    UCNV_ILLEGAL = 1,
    UCNV_IRREGULAR = 2,
    UCNV_RESET = 3,
    UCNV_CLOSE = 4,
    UCNV_CLONE = 5
} UConverterCallbackReasonx;

typedef enum UNormalizationCheckResultx {
  UNORM_NO,
  UNORM_YES,
  UNORM_MAYBE
} UNormalizationCheckResultx;

typedef struct UEnumeration UEnumeration;

typedef struct UCharsetDetector UCharsetDetector;

typedef struct UCharsetMatch UCharsetMatch;
typedef struct UBreakIterator UBreakIterator;
typedef struct UNormalizer2 UNormalizer2;
typedef struct UConverter UConverter;
typedef struct UConverterFromUnicodeArgs UConverterFromUnicodeArgs;
typedef struct UConverterToUnicodeArgs UConverterToUnicodeArgs;
typedef void   (*UConverterFromUCallback)(const void *context,
                                          UConverterFromUnicodeArgs *args,
                                          const UCharx *codeUnits,
                                          int32_t length, UChar32x codePoint,
                                          UConverterCallbackReasonx reason,
                                          UErrorCodex *pErrorCode);
typedef void   (*UConverterToUCallback)(const void *context,
                                        UConverterToUnicodeArgs *args,
                                        const char *codeUnits,
                                        int32_t length,
                                        UConverterCallbackReasonx reason,
                                        UErrorCodex *pErrorCode);
/*
 * Prototypes for ICU functions sorted by category.
 */
typedef void        (*fn_u_cleanup)(void);
typedef const char *(*fn_u_errorName)(UErrorCodex);
typedef UCharx *(*fn_u_strFromUTF32)(UCharx *dest,
				     int32_t destCapacity,
				     int32_t *pDestLength,
				     const UChar32x *src,
				     int32_t srcLength,
				     UErrorCodex *pErrorCode);
typedef UCharx *(*fn_u_strFromUTF32WithSub)(UCharx *dest,
					    int32_t destCapacity,
					    int32_t *pDestLength,
					    const UChar32x *src,
					    int32_t srcLength,
					    UChar32x subchar,
					    int32_t *pNumSubstitutions,
					    UErrorCodex *pErrorCode);
typedef UChar32x *(*fn_u_strToUTF32)(UChar32x *dest,
				     int32_t destCapacity,
				     int32_t *pDestLength,
				     const UCharx *src,
				     int32_t srcLength,
				     UErrorCodex *pErrorCode);
typedef UChar32x *(*fn_u_strToUTF32WithSub)(UChar32x *dest,
					    int32_t destCapacity,
					    int32_t *pDestLength,
					    const UCharx *src,
					    int32_t srcLength,
					    UChar32x subchar,
					    int32_t *pNumSubstitutions,
					    UErrorCodex *pErrorCode);

typedef void        (*fn_ucnv_close)(UConverter *);
typedef uint16_t    (*fn_ucnv_countAliases)(const char *, UErrorCodex *);
typedef int32_t     (*fn_ucnv_countAvailable)(void);
typedef int32_t     (*fn_ucnv_fromUChars)(UConverter *, char *dest,
	int32_t destCapacity, const UCharx *src, int32_t srcLen, UErrorCodex *);
typedef const char *(*fn_ucnv_getAlias)(const char *, uint16_t, UErrorCodex *);
typedef const char *(*fn_ucnv_getAvailableName)(int32_t);
typedef UConverter *(*fn_ucnv_open)(const char *converterName, UErrorCodex *);
typedef void        (*fn_ucnv_setFromUCallBack)(UConverter *,
                                                UConverterFromUCallback newAction,
                                                const void *newContext,
                                                UConverterFromUCallback *oldAction,
                                                const void **oldContext,
                                                UErrorCodex *err);
typedef void        (*fn_ucnv_setToUCallBack)(UConverter *,
                                                UConverterToUCallback newAction,
                                                const void *newContext,
                                                UConverterToUCallback *oldAction,
                                                const void **oldContext,
                                                UErrorCodex *err);
typedef int32_t     (*fn_ucnv_toUChars)(UConverter *, UCharx *dest,
                                        int32_t destCapacity, const char *src, int32_t srcLen, UErrorCodex *);
typedef UConverterFromUCallback fn_UCNV_FROM_U_CALLBACK_STOP;
typedef UConverterToUCallback   fn_UCNV_TO_U_CALLBACK_STOP;

typedef UBreakIterator *(*fn_ubrk_open)(
	UBreakIteratorTypex, const char *, const uint16_t *, int32_t,
	UErrorCodex *);
typedef void	(*fn_ubrk_close)(UBreakIterator *);
typedef int32_t	(*fn_ubrk_preceding)(UBreakIterator *, int32_t);
typedef int32_t	(*fn_ubrk_following)(UBreakIterator *, int32_t);
72
73
74
75
76
77
78











79
80
81
82
83
84
85
86
87
88
89
90
91
92




93
94
95
96
97
98
99
100
101

102
103

104
105






106
107
108
109
110
111
112
113
114
115
116
117





118
119
120
121
122

123
124

125
126
127
128




129
130
131
132
133
134
135
136
137

138
139

140
141






142
143
144
145
146
147
148
149
150
151
152
153
154





155
156





157
158
159
160
161
162
163
	UCharsetDetector *ucsd, UErrorCodex *status);
typedef const UCharsetMatch ** (*fn_ucsdet_detectAll)(
	UCharsetDetector *ucsd, int32_t *matchesFound, UErrorCodex *status);

typedef void        (*fn_uenum_close)(UEnumeration *);
typedef int32_t     (*fn_uenum_count)(UEnumeration *, UErrorCodex *);
typedef const char *(*fn_uenum_next)(UEnumeration *, int32_t *, UErrorCodex *);












#define FIELD(name) fn_ ## name _ ## name

static struct {
    size_t nopen;		/* Total number of references to ALL libraries */
    /*
     * Depending on platform, ICU symbols may be distributed amongst
     * multiple libraries. For current functionality at most 2 needed.
     * Order of library loading is not guaranteed.
     */
    Tcl_LoadHandle      libs[2];

    FIELD(u_cleanup);
    FIELD(u_errorName);





    FIELD(ubrk_open);
    FIELD(ubrk_close);
    FIELD(ubrk_preceding);
    FIELD(ubrk_following);
    FIELD(ubrk_previous);
    FIELD(ubrk_next);
    FIELD(ubrk_setText);


    FIELD(ucnv_countAliases);
    FIELD(ucnv_countAvailable);

    FIELD(ucnv_getAlias);
    FIELD(ucnv_getAvailableName);







    FIELD(ucsdet_close);
    FIELD(ucsdet_detect);
    FIELD(ucsdet_detectAll);
    FIELD(ucsdet_getAllDetectableCharsets);
    FIELD(ucsdet_getName);
    FIELD(ucsdet_open);
    FIELD(ucsdet_setText);

    FIELD(uenum_close);
    FIELD(uenum_count);
    FIELD(uenum_next);





} icu_fns = {
    0, {NULL, NULL}, /* Reference count, library handles */
    NULL, NULL, /* u_* */
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* ubrk* */
    NULL, NULL, NULL, NULL, /* ucnv_* */

    NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* ucsdet* */
    NULL, NULL, NULL, /* uenum_* */

};

#define u_cleanup        icu_fns._u_cleanup
#define u_errorName      icu_fns._u_errorName





#define ubrk_open        icu_fns._ubrk_open
#define ubrk_close       icu_fns._ubrk_close
#define ubrk_preceding   icu_fns._ubrk_preceding
#define ubrk_following   icu_fns._ubrk_following
#define ubrk_previous    icu_fns._ubrk_previous
#define ubrk_next        icu_fns._ubrk_next
#define ubrk_setText     icu_fns._ubrk_setText


#define ucnv_countAliases     icu_fns._ucnv_countAliases
#define ucnv_countAvailable   icu_fns._ucnv_countAvailable

#define ucnv_getAlias         icu_fns._ucnv_getAlias
#define ucnv_getAvailableName icu_fns._ucnv_getAvailableName







#define ucsdet_close     icu_fns._ucsdet_close
#define ucsdet_detect    icu_fns._ucsdet_detect
#define ucsdet_detectAll icu_fns._ucsdet_detectAll
#define ucsdet_getAllDetectableCharsets icu_fns._ucsdet_getAllDetectableCharsets
#define ucsdet_getName   icu_fns._ucsdet_getName
#define ucsdet_open      icu_fns._ucsdet_open
#define ucsdet_setText   icu_fns._ucsdet_setText

#define uenum_next       icu_fns._uenum_next
#define uenum_close      icu_fns._uenum_close
#define uenum_count      icu_fns._uenum_count







TCL_DECLARE_MUTEX(icu_mutex);






/* Error handlers. */

static int
FunctionNotAvailableError(
    Tcl_Interp *interp)
{







>
>
>
>
>
>
>
>
>
>
>














>
>
>
>









>


>


>
>
>
>
>
>












>
>
>
>
>

|
|
|
|
>
|
|
>




>
>
>
>









>


>


>
>
>
>
>
>













>
>
>
>
>


>
>
>
>
>







152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
	UCharsetDetector *ucsd, UErrorCodex *status);
typedef const UCharsetMatch ** (*fn_ucsdet_detectAll)(
	UCharsetDetector *ucsd, int32_t *matchesFound, UErrorCodex *status);

typedef void        (*fn_uenum_close)(UEnumeration *);
typedef int32_t     (*fn_uenum_count)(UEnumeration *, UErrorCodex *);
typedef const char *(*fn_uenum_next)(UEnumeration *, int32_t *, UErrorCodex *);

typedef UNormalizer2 *(*fn_unorm2_getNFCInstance)(UErrorCodex *);
typedef UNormalizer2 *(*fn_unorm2_getNFDInstance)(UErrorCodex *);
typedef UNormalizer2 *(*fn_unorm2_getNFKCInstance)(UErrorCodex *);
typedef UNormalizer2 *(*fn_unorm2_getNFKDInstance)(UErrorCodex *);
typedef int32_t (*fn_unorm2_normalize)(const UNormalizer2 *,
				       const UCharx *,
				       int32_t,
				       UCharx *,
				       int32_t,
				       UErrorCodex *);

#define FIELD(name) fn_ ## name _ ## name

static struct {
    size_t nopen;		/* Total number of references to ALL libraries */
    /*
     * Depending on platform, ICU symbols may be distributed amongst
     * multiple libraries. For current functionality at most 2 needed.
     * Order of library loading is not guaranteed.
     */
    Tcl_LoadHandle      libs[2];

    FIELD(u_cleanup);
    FIELD(u_errorName);
    FIELD(u_strFromUTF32);
    FIELD(u_strFromUTF32WithSub);
    FIELD(u_strToUTF32);
    FIELD(u_strToUTF32WithSub);

    FIELD(ubrk_open);
    FIELD(ubrk_close);
    FIELD(ubrk_preceding);
    FIELD(ubrk_following);
    FIELD(ubrk_previous);
    FIELD(ubrk_next);
    FIELD(ubrk_setText);

    FIELD(ucnv_close);
    FIELD(ucnv_countAliases);
    FIELD(ucnv_countAvailable);
    FIELD(ucnv_fromUChars);
    FIELD(ucnv_getAlias);
    FIELD(ucnv_getAvailableName);
    FIELD(ucnv_open);
    FIELD(ucnv_setFromUCallBack);
    FIELD(ucnv_setToUCallBack);
    FIELD(ucnv_toUChars);
    FIELD(UCNV_FROM_U_CALLBACK_STOP);
    FIELD(UCNV_TO_U_CALLBACK_STOP);

    FIELD(ucsdet_close);
    FIELD(ucsdet_detect);
    FIELD(ucsdet_detectAll);
    FIELD(ucsdet_getAllDetectableCharsets);
    FIELD(ucsdet_getName);
    FIELD(ucsdet_open);
    FIELD(ucsdet_setText);

    FIELD(uenum_close);
    FIELD(uenum_count);
    FIELD(uenum_next);
    FIELD(unorm2_getNFCInstance);
    FIELD(unorm2_getNFDInstance);
    FIELD(unorm2_getNFKCInstance);
    FIELD(unorm2_getNFKDInstance);
    FIELD(unorm2_normalize);
} icu_fns = {
    0,    {NULL, NULL}, /* Reference count, library handles */
    NULL, NULL, NULL, NULL, NULL, NULL,                     /* u_* */
    NULL, NULL, NULL, NULL, NULL, NULL, NULL,               /* ubrk* */
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,   /* ucnv_* .. */
    NULL, NULL, NULL,                                       /* .. ucnv_ */
    NULL, NULL, NULL, NULL, NULL, NULL, NULL,               /* ucsdet* */
    NULL, NULL, NULL,                                       /* uenum_* */
    NULL, NULL, NULL, NULL, NULL,                           /* unorm2_* */
};

#define u_cleanup        icu_fns._u_cleanup
#define u_errorName      icu_fns._u_errorName
#define u_strFromUTF32   icu_fns._u_strFromUTF32
#define u_strFromUTF32WithSub icu_fns._u_strFromUTF32WithSub
#define u_strToUTF32          icu_fns._u_strToUTF32
#define u_strToUTF32WithSub   icu_fns._u_strToUTF32WithSub

#define ubrk_open        icu_fns._ubrk_open
#define ubrk_close       icu_fns._ubrk_close
#define ubrk_preceding   icu_fns._ubrk_preceding
#define ubrk_following   icu_fns._ubrk_following
#define ubrk_previous    icu_fns._ubrk_previous
#define ubrk_next        icu_fns._ubrk_next
#define ubrk_setText     icu_fns._ubrk_setText

#define ucnv_close            icu_fns._ucnv_close
#define ucnv_countAliases     icu_fns._ucnv_countAliases
#define ucnv_countAvailable   icu_fns._ucnv_countAvailable
#define ucnv_fromUChars       icu_fns._ucnv_fromUChars
#define ucnv_getAlias         icu_fns._ucnv_getAlias
#define ucnv_getAvailableName icu_fns._ucnv_getAvailableName
#define ucnv_open             icu_fns._ucnv_open
#define ucnv_setFromUCallBack icu_fns._ucnv_setFromUCallBack
#define ucnv_setToUCallBack   icu_fns._ucnv_setToUCallBack
#define ucnv_toUChars         icu_fns._ucnv_toUChars
#define UCNV_FROM_U_CALLBACK_STOP icu_fns._UCNV_FROM_U_CALLBACK_STOP
#define UCNV_TO_U_CALLBACK_STOP   icu_fns._UCNV_TO_U_CALLBACK_STOP

#define ucsdet_close     icu_fns._ucsdet_close
#define ucsdet_detect    icu_fns._ucsdet_detect
#define ucsdet_detectAll icu_fns._ucsdet_detectAll
#define ucsdet_getAllDetectableCharsets icu_fns._ucsdet_getAllDetectableCharsets
#define ucsdet_getName   icu_fns._ucsdet_getName
#define ucsdet_open      icu_fns._ucsdet_open
#define ucsdet_setText   icu_fns._ucsdet_setText

#define uenum_next       icu_fns._uenum_next
#define uenum_close      icu_fns._uenum_close
#define uenum_count      icu_fns._uenum_count

#define unorm2_getNFCInstance  icu_fns._unorm2_getNFCInstance
#define unorm2_getNFDInstance  icu_fns._unorm2_getNFDInstance
#define unorm2_getNFKCInstance icu_fns._unorm2_getNFKCInstance
#define unorm2_getNFKDInstance icu_fns._unorm2_getNFKDInstance
#define unorm2_normalize       icu_fns._unorm2_normalize

TCL_DECLARE_MUTEX(icu_mutex);

/* Options used by multiple normalization functions */
static const char *normalizationForms[] = {"nfc", "nfd", "nfkc", "nfkd", NULL};
typedef enum { MODE_NFC, MODE_NFD, MODE_NFKC, MODE_NFKD } NormalizationMode;


/* Error handlers. */

static int
FunctionNotAvailableError(
    Tcl_Interp *interp)
{
177
178
179
180
181
182
183
184



185
186
187
188
189
190
191
192
{
    if (interp) {
	const char *codeMessage = NULL;
	if (u_errorName) {
	    codeMessage = u_errorName(code);
	}
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"%s. ICU error (%d): %s",



		message, code, codeMessage ? codeMessage : ""));
	Tcl_SetErrorCode(interp, "TCL", "ICU", codeMessage, NULL);
    }
    return TCL_ERROR;
}

/*
 * Detect the likely encoding of the string encoded in the given byte array.







|
>
>
>
|







309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
{
    if (interp) {
	const char *codeMessage = NULL;
	if (u_errorName) {
	    codeMessage = u_errorName(code);
	}
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"%s%sICU error (%d): %s",
		message ? message : "",
                message ? ". " : "",
                code,
                codeMessage ? codeMessage : ""));
	Tcl_SetErrorCode(interp, "TCL", "ICU", codeMessage, NULL);
    }
    return TCL_ERROR;
}

/*
 * Detect the likely encoding of the string encoded in the given byte array.
316
317
318
319
320
321
322














































































































323
324
325
326
327
328
329
	}
	uenum_close(enumerator);
    }

    ucsdet_close(csd);
    return ret;
}















































































































/*
 *------------------------------------------------------------------------
 *
 * EncodingDetectObjCmd --
 *
 *	Implements the Tcl command EncodingDetect.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
	}
	uenum_close(enumerator);
    }

    ucsdet_close(csd);
    return ret;
}

/*
 *------------------------------------------------------------------------
 *
 * IcuObjToUCharDString --
 *
 *    Encodes a Tcl_Obj value in ICU UChars and stores in dsPtr.
 *
 * Results:
 *    Return TCL_OK / TCL_ERROR.
 *
 * Side effects:
 *    *dsPtr should be cleared by caller only if return code is TCL_OK.
 *
 *------------------------------------------------------------------------
 */
static int
IcuObjToUCharDString(
    Tcl_Interp *interp,
    Tcl_Obj *objPtr,
    int strict,
    Tcl_DString *dsPtr)
{
    Tcl_Encoding encoding;

    /*
     * TODO - not the most efficient to get an encoding every time.
     * However, we cannot use Tcl_UtfToChar16DString as that blithely
     * ignores invalid or ill-formed UTF8 strings.
     */
    encoding = Tcl_GetEncoding(interp, "utf-16");
    if (encoding == NULL) {
	return TCL_ERROR;
    }

    int result;
    char *s;
    Tcl_Size len;
    s = Tcl_GetStringFromObj(objPtr, &len);
    result = Tcl_UtfToExternalDStringEx(interp,
					encoding,
					s,
					len,
					strict ? TCL_ENCODING_PROFILE_STRICT
					       : TCL_ENCODING_PROFILE_REPLACE,
					dsPtr,
					NULL);
    if (result != TCL_OK) {
	Tcl_DStringFree(dsPtr); /* Must be done on error */
	/* TCL_CONVER_* errors -> TCL_ERROR */
	result = TCL_ERROR;
    }

    Tcl_FreeEncoding(encoding);
    return result;
}

/*
 *------------------------------------------------------------------------
 *
 * IcuObjFromUCharDString --
 *
 *    Stores a Tcl_Obj value by decoding ICU UChars in dsPtr.
 *
 * Results:
 *    Return Tcl_Obj or NULL on error.
 *
 * Side effects:
 *    None.
 *
 *------------------------------------------------------------------------
 */
static Tcl_Obj *
IcuObjFromUCharDString(
    Tcl_Interp *interp,
    Tcl_DString *dsPtr,
    int strict)
{
    Tcl_Encoding encoding;

    /*
     * TODO - not the most efficient to get an encoding every time.
     * However, we cannot use Tcl_UtfToChar16DString as that blithely
     * ignores invalid or ill-formed UTF8 strings.
     */
    encoding = Tcl_GetEncoding(interp, "utf-16");
    if (encoding == NULL) {
	return NULL;
    }
    Tcl_Obj *objPtr = NULL;
    char *s = Tcl_DStringValue(dsPtr);
    Tcl_Size len = Tcl_DStringLength(dsPtr);
    Tcl_DString dsOut;
    int result;
    result  = Tcl_ExternalToUtfDStringEx(interp,
					encoding,
					s,
					len,
					strict ? TCL_ENCODING_PROFILE_STRICT
					       : TCL_ENCODING_PROFILE_REPLACE,
					&dsOut,
					NULL);

    if (result == TCL_OK) {
	objPtr = Tcl_DStringToObj(&dsOut); /* Clears dsPtr! */
    }

    Tcl_FreeEncoding(encoding);
    return objPtr;
}

/*
 *------------------------------------------------------------------------
 *
 * EncodingDetectObjCmd --
 *
 *	Implements the Tcl command EncodingDetect.
479
480
481
482
483
484
485


















































































































































































































































































































































































































































































































486
487
488
489
490
491
492
    Tcl_SetObjResult(interp, resultObj);
    return TCL_OK;
}

/*
 *------------------------------------------------------------------------
 *


















































































































































































































































































































































































































































































































 * TclIcuCleanup --
 *
 *	Called whenever a command referencing the ICU function table is
 *	deleted. When the reference count drops to zero, the table is released
 *	and the ICU shared libraries are unloaded.
 *
 *------------------------------------------------------------------------







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
    Tcl_SetObjResult(interp, resultObj);
    return TCL_OK;
}

/*
 *------------------------------------------------------------------------
 *
 * IcuConverttoDString --
 *
 *    Converts a string in ICU default encoding to the specified encoding.
 *
 * Results:
 *    TCL_OK / TCL_ERROR
 *
 * Side effects:
 *    On success, encoded string is stored in output dsOutPtr
 *
 *------------------------------------------------------------------------
 */
static int
IcuConverttoDString(
    Tcl_Interp *interp,
    Tcl_DString *dsInPtr,  /* Input UTF16 */
    const char *icuEncName,
    int strict,
    Tcl_DString *dsOutPtr) /* Output encoded string. */
{
    if (ucnv_open == NULL || ucnv_close == NULL ||
        ucnv_fromUChars == NULL || UCNV_FROM_U_CALLBACK_STOP == NULL) {
	return FunctionNotAvailableError(interp);
    }

    UErrorCodex status = U_ZERO_ERRORZ;
    UConverter *ucnvPtr = ucnv_open(icuEncName, &status);
    if (ucnvPtr == NULL) {
	return IcuError(interp, "Could not get encoding converter", status);
    }
    if (strict) {
        ucnv_setFromUCallBack(ucnvPtr, UCNV_FROM_U_CALLBACK_STOP, NULL, NULL, NULL, &status);
        if (U_FAILURE(status)) {
            /* TODO - use ucnv_getInvalidUChars to retrieve failing chars */
            ucnv_close(ucnvPtr);
            return IcuError(interp, "Could not set conversion callback", status);
        }
    }

    UCharx *utf16 = (UCharx *) Tcl_DStringValue(dsInPtr);
    Tcl_Size utf16len = Tcl_DStringLength(dsInPtr) / sizeof(UCharx);
    Tcl_Size dstLen, dstCapacity;
    if (utf16len > INT_MAX) {
	Tcl_SetResult(
	    interp, "Max length supported by ICU exceeded.", TCL_STATIC);
	return TCL_ERROR;
    }

    dstCapacity = utf16len;
    Tcl_DStringInit(dsOutPtr);
    Tcl_DStringSetLength(dsOutPtr, dstCapacity);
    dstLen = ucnv_fromUChars(ucnvPtr, Tcl_DStringValue(dsOutPtr), dstCapacity,
                             utf16, utf16len, &status);
    if (U_FAILURE(status)) {
        switch (status) {
        case U_STRING_NOT_TERMINATED_WARNING:
            break; /* We don't care */
        case U_BUFFER_OVERFLOW_ERROR:
            Tcl_DStringSetLength(dsOutPtr, dstLen);
            status = U_ZERO_ERRORZ; /* Reset before call */
            dstLen = ucnv_fromUChars(ucnvPtr, Tcl_DStringValue(dsOutPtr), dstLen,
                                     utf16, utf16len, &status);
            if (U_SUCCESS(status)) {
                break;
            }
            /* FALLTHRU */
        default:
            Tcl_DStringFree(dsOutPtr);
            ucnv_close(ucnvPtr);
            return IcuError(interp, "ICU error while encoding", status);
        }
    }
    Tcl_DStringSetLength(dsOutPtr, dstLen);
    ucnv_close(ucnvPtr);
    return TCL_OK;
}

/*
 *------------------------------------------------------------------------
 *
 * IcuBytesToUCharDString --
 *
 *    Converts encoded bytes to ICU UChars in a Tcl_DString
 *
 * Results:
 *    TCL_OK / TCL_ERROR
 *
 * Side effects:
 *    On success, encoded string is stored in output dsOutPtr
 *
 *------------------------------------------------------------------------
 */
static int
IcuBytesToUCharDString(
    Tcl_Interp *interp,
    const unsigned char *bytes,
    Tcl_Size nbytes,
    const char *icuEncName,
    int strict,
    Tcl_DString *dsOutPtr) /* Output UChar string. */
{
    if (ucnv_open == NULL || ucnv_close == NULL ||
        ucnv_toUChars == NULL || UCNV_TO_U_CALLBACK_STOP == NULL) {
	return FunctionNotAvailableError(interp);
    }

    if (nbytes > INT_MAX) {
	Tcl_SetResult(
	    interp, "Max length supported by ICU exceeded.", TCL_STATIC);
	return TCL_ERROR;
    }

    UErrorCodex status = U_ZERO_ERRORZ;
    UConverter *ucnvPtr = ucnv_open(icuEncName, &status);
    if (ucnvPtr == NULL) {
	return IcuError(interp, "Could not get encoding converter", status);
    }
    if (strict) {
        ucnv_setToUCallBack(ucnvPtr, UCNV_TO_U_CALLBACK_STOP, NULL, NULL, NULL, &status);
        if (U_FAILURE(status)) {
            /* TODO - use ucnv_getInvalidUChars to retrieve failing chars */
            ucnv_close(ucnvPtr);
            return IcuError(interp, "Could not set conversion callback", status);
        }
    }

    int dstLen;
    int dstCapacity = (int) nbytes; /* In UChar's  */
    Tcl_DStringInit(dsOutPtr);
    Tcl_DStringSetLength(dsOutPtr, dstCapacity);
    dstLen = ucnv_toUChars(ucnvPtr, (UCharx *)Tcl_DStringValue(dsOutPtr), dstCapacity,
                           (const char *)bytes, nbytes, &status);
    if (U_FAILURE(status)) {
        switch (status) {
        case U_STRING_NOT_TERMINATED_WARNING:
            break; /* We don't care */
        case U_BUFFER_OVERFLOW_ERROR:
            dstCapacity = sizeof(UCharx) * dstLen;
            Tcl_DStringSetLength(dsOutPtr, dstCapacity);
            status = U_ZERO_ERRORZ; /* Reset before call */
            dstLen = ucnv_toUChars(ucnvPtr, (UCharx *)Tcl_DStringValue(dsOutPtr), dstCapacity,
                                   (const char *)bytes, nbytes, &status);
            if (U_SUCCESS(status)) {
                break;
            }
            /* FALLTHRU */
        default:
            Tcl_DStringFree(dsOutPtr);
            ucnv_close(ucnvPtr);
            return IcuError(interp, "ICU error while decoding", status);
        }
    }
    Tcl_DStringSetLength(dsOutPtr, sizeof(UCharx)*dstLen);
    ucnv_close(ucnvPtr);
    return TCL_OK;
}


/*
 *------------------------------------------------------------------------
 *
 * IcuNormalizeUCharDString --
 *
 *    Normalizes the UTF-16 encoded data
 *
 * Results:
 *    TCL_OK / TCL_ERROR
 *
 * Side effects:
 *    Normalized data is stored in dsOutPtr which should only be
 *    Tcl_DStringFree-ed if return code is TCL_OK.
 *
 *------------------------------------------------------------------------
 */
static int
IcuNormalizeUCharDString(
    Tcl_Interp *interp,
    Tcl_DString *dsInPtr, /* Input UTF16 */
    NormalizationMode mode,
    Tcl_DString *dsOutPtr) /* Output normalized UTF16. */
{
    typedef UNormalizer2 *(*normFn)(UErrorCodex *);
    normFn fn = NULL;

    switch (mode) {
    case MODE_NFC:
	fn = unorm2_getNFCInstance;
	break;
    case MODE_NFD:
	fn = unorm2_getNFDInstance;
	break;
    case MODE_NFKC:
	fn = unorm2_getNFKCInstance;
	break;
    case MODE_NFKD:
	fn = unorm2_getNFKDInstance;
	break;
    }
    if (fn == NULL || unorm2_normalize == NULL) {
	return FunctionNotAvailableError(interp);
    }

    UErrorCodex status = U_ZERO_ERRORZ;
    UNormalizer2 *normalizer = fn(&status);
    if (U_FAILURE(status)) {
	return IcuError(interp, "Could not get ICU normalizer", status);
    }

    UCharx *utf16;
    Tcl_Size utf16len;
    UCharx *normPtr;
    int32_t normLen;

    utf16 = (UCharx *) Tcl_DStringValue(dsInPtr);
    utf16len = Tcl_DStringLength(dsInPtr) / sizeof(UCharx);
    if (utf16len > INT_MAX) {
	Tcl_SetResult(
	    interp, "Max length supported by ICU exceeded.", TCL_STATIC);
	return TCL_ERROR;
    }
    Tcl_DStringInit(dsOutPtr);
    Tcl_DStringSetLength(dsOutPtr, utf16len * sizeof(UCharx));
    normPtr = (UCharx *) Tcl_DStringValue(dsOutPtr);

    normLen = unorm2_normalize(
	normalizer, utf16, utf16len, normPtr, utf16len, &status);
    if (U_FAILURE(status)) {
	switch (status) {
	case U_STRING_NOT_TERMINATED_WARNING:
	    /* No problem, don't need it terminated */
	    break;
	case U_BUFFER_OVERFLOW_ERROR:
	    /* Expand buffer */
	    Tcl_DStringSetLength(dsOutPtr, normLen * sizeof(UCharx));
	    normPtr = (UCharx *) Tcl_DStringValue(dsOutPtr);
	    status = U_ZERO_ERRORZ; /* Need to clear error! */
	    normLen = unorm2_normalize(
		normalizer, utf16, utf16len, normPtr, normLen, &status);
	    if (U_SUCCESS(status)) {
		break;
	    }
	    /* FALLTHRU */
	default:
	    Tcl_DStringFree(dsOutPtr);
	    return IcuError(interp, "String normalization failed", status);
	}
    }

    Tcl_DStringSetLength(dsOutPtr, normLen * sizeof(UCharx));
    return TCL_OK;
}

/*
 * Common function for parsing convert options.
 */
static int IcuParseConvertOptions(
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[],
    int *strictPtr,
    Tcl_Obj **failindexVarPtr)
{
    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "?-profile PROFILE? ICUENCNAME STRING");
	return TCL_ERROR;
    }
    objc -= 2; /* truncate fixed arguments */

    /* Use GetIndexFromObj for option parsing so -failindex can be added later */

    static const char *optNames[] = {"-profile", "-failindex", NULL};
    enum { OPT_PROFILE, OPT_FAILINDEX } opt;
    int i;
    int strict = 1;
    for (i = 1; i < objc; ++i) {
	if (Tcl_GetIndexFromObj(
		interp, objv[i], optNames, "option", 0, &opt) != TCL_OK) {
	    return TCL_ERROR;
	}
	++i;
	if (i == objc) {
	    Tcl_SetObjResult(interp,
			     Tcl_ObjPrintf("Missing value for option %s.",
					   Tcl_GetString(objv[i - 1])));
	    return TCL_ERROR;
	}
	const char *s = Tcl_GetString(objv[i]);
	switch (opt) {
	case OPT_PROFILE:
	    if (!strcmp(s, "replace")) {
		strict = 0;
	    } else if (strcmp(s, "strict")) {
		Tcl_SetObjResult(
		    interp,
		    Tcl_ObjPrintf("Invalid value \"%s\" supplied for option"
                         " \"-profile\". Must be \"strict\" or \"replace\".",
                         s));
		return TCL_ERROR;
	    }
	    break;
        case OPT_FAILINDEX:
            /* TBD */
            Tcl_SetResult(interp,
                "Option -failindex not implemented.", TCL_STATIC);
            return TCL_ERROR;
	}
    }
    *strictPtr = strict;
    *failindexVarPtr = NULL;
    return TCL_OK;
}

/*
 *------------------------------------------------------------------------
 *
 * IcuConvertfromObjCmd --
 *
 *    Implements the Tcl command "icu convertfrom"
 *        icu convertfrom ?-profile replace|strict? encoding string
 *
 * Results:
 *    TCL_OK    - Success.
 *    TCL_ERROR - Error.
 *
 * Side effects:
 *    Interpreter result holds result or error message.
 *
 *------------------------------------------------------------------------
 */
static int
IcuConvertfromObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,    /* Current interpreter. */
    int objc,              /* Number of arguments. */
    Tcl_Obj *const objv[]) /* Argument objects. */
{
    int strict;
    Tcl_Obj *failindexVar;

    if (IcuParseConvertOptions(interp, objc, objv, &strict, &failindexVar) != TCL_OK) {
        return TCL_ERROR;
    }

    Tcl_Size nbytes;
    const unsigned char *bytes = Tcl_GetBytesFromObj(interp, objv[objc-1], &nbytes);
    if (bytes == NULL) {
        return TCL_ERROR;
    }

    Tcl_DString ds;
    if (IcuBytesToUCharDString(interp, bytes, nbytes,
            Tcl_GetString(objv[objc-2]), strict, &ds) != TCL_OK) {
        return TCL_ERROR;
    }
    Tcl_Obj *resultObj = IcuObjFromUCharDString(interp, &ds, strict);
    if (resultObj) {
        Tcl_SetObjResult(interp, resultObj);
        return TCL_OK;
    } else {
        return TCL_ERROR;
    }
}

/*
 *------------------------------------------------------------------------
 *
 * IcuConverttoObjCmd --
 *
 *    Implements the Tcl command "icu convertto"
 *        icu convertto ?-profile replace|strict? encoding string
 *
 * Results:
 *    TCL_OK    - Success.
 *    TCL_ERROR - Error.
 *
 * Side effects:
 *    Interpreter result holds result or error message.
 *
 *------------------------------------------------------------------------
 */
static int
IcuConverttoObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,    /* Current interpreter. */
    int objc,              /* Number of arguments. */
    Tcl_Obj *const objv[]) /* Argument objects. */
{
    int strict;
    Tcl_Obj *failindexVar;

    if (IcuParseConvertOptions(interp, objc, objv, &strict, &failindexVar) != TCL_OK) {
        return TCL_ERROR;
    }

    Tcl_DString dsIn;
    Tcl_DString dsOut;
    if (IcuObjToUCharDString(interp, objv[objc - 1], strict, &dsIn) != TCL_OK ||
        IcuConverttoDString(interp, &dsIn,
            Tcl_GetString(objv[objc-2]), strict, &dsOut) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp,
        Tcl_NewByteArrayObj((unsigned char *)Tcl_DStringValue(&dsOut),
                            Tcl_DStringLength(&dsOut)));
    Tcl_DStringFree(&dsOut);
    return TCL_OK;
}

/*
 *------------------------------------------------------------------------
 *
 * IcuNormalizeObjCmd --
 *
 *    Implements the Tcl command "icu normalize"
 *        icu normalize ?-profile replace|strict? ?-mode nfc|nfd|nfkc|nfkd? string
 *
 * Results:
 *    TCL_OK    - Success.
 *    TCL_ERROR - Error.
 *
 * Side effects:
 *    Interpreter result holds result or error message.
 *
 *------------------------------------------------------------------------
 */
static int
IcuNormalizeObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,    /* Current interpreter. */
    int objc,              /* Number of arguments. */
    Tcl_Obj *const objv[]) /* Argument objects. */
{
    static const char *optNames[] = {"-profile", "-mode", NULL};
    enum { OPT_PROFILE, OPT_MODE } opt;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "?-profile PROFILE? ?-mode MODE? STRING");
	return TCL_ERROR;
    }

    int i;
    int strict = 1;
    NormalizationMode mode = MODE_NFC;
    for (i = 1; i < objc - 1; ++i) {
	if (Tcl_GetIndexFromObj(
		interp, objv[i], optNames, "option", 0, &opt) != TCL_OK) {
	    return TCL_ERROR;
	}
	++i;
	if (i == (objc-1)) {
	    Tcl_SetObjResult(interp,
			     Tcl_ObjPrintf("Missing value for option %s.",
					   Tcl_GetString(objv[i - 1])));
	    return TCL_ERROR;
	}
	const char *s = Tcl_GetString(objv[i]);
	switch (opt) {
	case OPT_PROFILE:
	    if (!strcmp(s, "replace")) {
		strict = 0;
	    } else if (strcmp(s, "strict")) {
		Tcl_SetObjResult(
		    interp,
		    Tcl_ObjPrintf("Invalid value \"%s\" supplied for option \"-profile\". Must be "
				  "\"strict\" or \"replace\".",
				  s));
		return TCL_ERROR;
	    }
	    break;
	case OPT_MODE:
	    if (Tcl_GetIndexFromObj(interp, objv[i], normalizationForms, "normalization mode", 0, &mode) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	}
    }

    Tcl_DString dsIn;
    Tcl_DString dsNorm;
    if (IcuObjToUCharDString(interp, objv[objc - 1], strict, &dsIn) != TCL_OK ||
	IcuNormalizeUCharDString(interp, &dsIn, mode, &dsNorm) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_DStringFree(&dsIn);
    Tcl_Obj *objPtr = IcuObjFromUCharDString(interp, &dsNorm, strict);
    Tcl_DStringFree(&dsNorm);
    if (objPtr) {
	Tcl_SetObjResult(interp, objPtr);
	return TCL_OK;
    }
    else {
	return TCL_ERROR;
    }
}

/*
 *------------------------------------------------------------------------
 *
 * TclIcuCleanup --
 *
 *	Called whenever a command referencing the ICU function table is
 *	deleted. When the reference count drops to zero, the table is released
 *	and the ICU shared libraries are unloaded.
 *
 *------------------------------------------------------------------------
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
TclIcuInit(
    Tcl_Interp *interp)
{
    Tcl_MutexLock(&icu_mutex);
    char icuversion[4] = "_80"; /* Highest ICU version + 1 */

    /*
     * The initialization below clones the existing one from Tk. May need
     * revisiting.
     * ICU shared library names as well as function names *may* be versioned.
     * See https://unicode-org.github.io/icu/userguide/icu4c/packaging.html
     * for the gory details.
     */
    if (icu_fns.nopen == 0) {
	int i = 0;
	Tcl_Obj *nameobj;







|
<







1323
1324
1325
1326
1327
1328
1329
1330

1331
1332
1333
1334
1335
1336
1337
TclIcuInit(
    Tcl_Interp *interp)
{
    Tcl_MutexLock(&icu_mutex);
    char icuversion[4] = "_80"; /* Highest ICU version + 1 */

    /*
     * The initialization below clones the one from Tk. May need revisiting.

     * ICU shared library names as well as function names *may* be versioned.
     * See https://unicode-org.github.io/icu/userguide/icu4c/packaging.html
     * for the gory details.
     */
    if (icu_fns.nopen == 0) {
	int i = 0;
	Tcl_Obj *nameobj;
699
700
701
702
703
704
705




706

707
708

709
710






711
712
713
714
715
716
717
718
719
720
721
722
723





724
725
726
727
728
729
730
	icu_fns._##name =                                                 \
	    (fn_##name)IcuFindSymbol(icu_fns.libs[0], #name, icuversion); \
    } while (0)

	if (icu_fns.libs[0] != NULL) {
	    ICUUC_SYM(u_cleanup);
	    ICUUC_SYM(u_errorName);






	    ICUUC_SYM(ucnv_countAliases);
	    ICUUC_SYM(ucnv_countAvailable);

	    ICUUC_SYM(ucnv_getAlias);
	    ICUUC_SYM(ucnv_getAvailableName);







	    ICUUC_SYM(ubrk_open);
	    ICUUC_SYM(ubrk_close);
	    ICUUC_SYM(ubrk_preceding);
	    ICUUC_SYM(ubrk_following);
	    ICUUC_SYM(ubrk_previous);
	    ICUUC_SYM(ubrk_next);
	    ICUUC_SYM(ubrk_setText);

	    ICUUC_SYM(uenum_close);
	    ICUUC_SYM(uenum_count);
	    ICUUC_SYM(uenum_next);






#undef ICUUC_SYM
	}

#define ICUIN_SYM(name)                                                   \
    do {                                                                  \
	icu_fns._##name =                                                 \
	    (fn_##name)IcuFindSymbol(icu_fns.libs[1], #name, icuversion); \







>
>
>
>

>


>


>
>
>
>
>
>













>
>
>
>
>







1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
	icu_fns._##name =                                                 \
	    (fn_##name)IcuFindSymbol(icu_fns.libs[0], #name, icuversion); \
    } while (0)

	if (icu_fns.libs[0] != NULL) {
	    ICUUC_SYM(u_cleanup);
	    ICUUC_SYM(u_errorName);
	    ICUUC_SYM(u_strFromUTF32);
	    ICUUC_SYM(u_strFromUTF32WithSub);
	    ICUUC_SYM(u_strToUTF32);
	    ICUUC_SYM(u_strToUTF32WithSub);

	    ICUUC_SYM(ucnv_close);
	    ICUUC_SYM(ucnv_countAliases);
	    ICUUC_SYM(ucnv_countAvailable);
	    ICUUC_SYM(ucnv_fromUChars);
	    ICUUC_SYM(ucnv_getAlias);
	    ICUUC_SYM(ucnv_getAvailableName);
	    ICUUC_SYM(ucnv_open);
            ICUUC_SYM(ucnv_setFromUCallBack);
            ICUUC_SYM(ucnv_setToUCallBack);
	    ICUUC_SYM(ucnv_toUChars);
            ICUUC_SYM(UCNV_FROM_U_CALLBACK_STOP);
            ICUUC_SYM(UCNV_TO_U_CALLBACK_STOP);

	    ICUUC_SYM(ubrk_open);
	    ICUUC_SYM(ubrk_close);
	    ICUUC_SYM(ubrk_preceding);
	    ICUUC_SYM(ubrk_following);
	    ICUUC_SYM(ubrk_previous);
	    ICUUC_SYM(ubrk_next);
	    ICUUC_SYM(ubrk_setText);

	    ICUUC_SYM(uenum_close);
	    ICUUC_SYM(uenum_count);
	    ICUUC_SYM(uenum_next);

	    ICUUC_SYM(unorm2_getNFCInstance);
	    ICUUC_SYM(unorm2_getNFDInstance);
	    ICUUC_SYM(unorm2_getNFKCInstance);
	    ICUUC_SYM(unorm2_getNFKDInstance);
	    ICUUC_SYM(unorm2_normalize);
#undef ICUUC_SYM
	}

#define ICUIN_SYM(name)                                                   \
    do {                                                                  \
	icu_fns._##name =                                                 \
	    (fn_##name)IcuFindSymbol(icu_fns.libs[1], #name, icuversion); \
747
748
749
750
751
752
753
754




755
756
757

758
759
760
761
762
763
764
765


766
767
768
769
770
771
772
	 * Note refcounts updated BEFORE command definition to protect
	 * against self redefinition.
	 */
	if (icu_fns.libs[1] != NULL) {
	    /* Commands needing both libraries */

	    /* Ref count number of commands */
	    icu_fns.nopen += 1;




	    Tcl_CreateObjCommand2(interp,  "::tcl::unsupported::icu::detect",
		    IcuDetectObjCmd, 0, TclIcuCleanup);
	}

	/* Commands needing only libs[0] (icuuc) */

	/* Ref count number of commands */
	icu_fns.nopen += 2;
	Tcl_CreateObjCommand2(interp, "::tcl::unsupported::icu::converters",
		IcuConverterNamesObjCmd, 0, TclIcuCleanup);
	Tcl_CreateObjCommand2(interp, "::tcl::unsupported::icu::aliases",
		IcuConverterAliasesObjCmd, 0, TclIcuCleanup);


    }

    Tcl_MutexUnlock(&icu_mutex);
}

/*
 *------------------------------------------------------------------------







|
>
>
>
>



>



|




>
>







1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
	 * Note refcounts updated BEFORE command definition to protect
	 * against self redefinition.
	 */
	if (icu_fns.libs[1] != NULL) {
	    /* Commands needing both libraries */

	    /* Ref count number of commands */
	    icu_fns.nopen += 3;
	    Tcl_CreateObjCommand(interp,  "::tcl::unsupported::icu::convertto",
                                 IcuConverttoObjCmd, 0, TclIcuCleanup);
	    Tcl_CreateObjCommand(interp,  "::tcl::unsupported::icu::convertfrom",
                                 IcuConvertfromObjCmd, 0, TclIcuCleanup);
	    Tcl_CreateObjCommand2(interp,  "::tcl::unsupported::icu::detect",
		    IcuDetectObjCmd, 0, TclIcuCleanup);
	}

	/* Commands needing only libs[0] (icuuc) */

	/* Ref count number of commands */
	icu_fns.nopen += 3; /* UPDATE AS CMDS ADDED/DELETED BELOW */
	Tcl_CreateObjCommand2(interp, "::tcl::unsupported::icu::converters",
		IcuConverterNamesObjCmd, 0, TclIcuCleanup);
	Tcl_CreateObjCommand2(interp, "::tcl::unsupported::icu::aliases",
		IcuConverterAliasesObjCmd, 0, TclIcuCleanup);
	Tcl_CreateObjCommand(interp, "::tcl::unsupported::icu::normalize",
		IcuNormalizeObjCmd, 0, TclIcuCleanup);
    }

    Tcl_MutexUnlock(&icu_mutex);
}

/*
 *------------------------------------------------------------------------
Changes to generic/tclInt.h.
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

#include <stdio.h>

#include <ctype.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdint.h>
#ifdef NO_STRING_H
#include "../compat/string.h"
#else
#include <string.h>
#endif
#include <locale.h>

/*
 * Ensure WORDS_BIGENDIAN is defined correctly:
 * Needs to happen here in addition to configure to work with fat compiles on
 * Darwin (where configure runs only once for multiple architectures).
 */







<
<
<

<







64
65
66
67
68
69
70



71

72
73
74
75
76
77
78

#include <stdio.h>

#include <ctype.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdint.h>



#include <string.h>

#include <locale.h>

/*
 * Ensure WORDS_BIGENDIAN is defined correctly:
 * Needs to happen here in addition to configure to work with fat compiles on
 * Darwin (where configure runs only once for multiple architectures).
 */
Changes to generic/tclLink.c.
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
    case TCL_LINK_STRING:
	linkPtr->bytes = size * sizeof(char);
	size = 1;		/* This is a variable length string, no need
				 * to check last value. */

	/*
	 * If no address is given create one and use as address the
         * not needed linkPtr->lastValue
	 */

	if (addr == NULL) {
	    linkPtr->lastValue.aryPtr = Tcl_Alloc(linkPtr->bytes);
	    linkPtr->flags |= LINK_ALLOC_LAST;
	    addr = (char *) &linkPtr->lastValue.cPtr;
	}







|







296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
    case TCL_LINK_STRING:
	linkPtr->bytes = size * sizeof(char);
	size = 1;		/* This is a variable length string, no need
				 * to check last value. */

	/*
	 * If no address is given create one and use as address the
	 * not needed linkPtr->lastValue
	 */

	if (addr == NULL) {
	    linkPtr->lastValue.aryPtr = Tcl_Alloc(linkPtr->bytes);
	    linkPtr->flags |= LINK_ALLOC_LAST;
	    addr = (char *) &linkPtr->lastValue.cPtr;
	}
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
	if (linkPtr->flags & LINK_ALLOC_LAST) {
	    for (i = 0; i < objc; i++) {
		int *varPtr = &linkPtr->lastValue.iPtr[i];

		if (GetInt(objv[i], varPtr)) {
		    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			    ObjValue(linkPtr), TCL_GLOBAL_ONLY);
	            return (char *) "variable array must have integer values";
		}
	    }
	} else {
	    int *varPtr = &linkPtr->lastValue.i;

	    if (GetInt(valueObj, varPtr)) {
		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,







|







887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
	if (linkPtr->flags & LINK_ALLOC_LAST) {
	    for (i = 0; i < objc; i++) {
		int *varPtr = &linkPtr->lastValue.iPtr[i];

		if (GetInt(objv[i], varPtr)) {
		    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			    ObjValue(linkPtr), TCL_GLOBAL_ONLY);
		    return (char *) "variable array must have integer values";
		}
	    }
	} else {
	    int *varPtr = &linkPtr->lastValue.i;

	    if (GetInt(valueObj, varPtr)) {
		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
	if (linkPtr->flags & LINK_ALLOC_LAST) {
	    for (i=0; i < objc; i++) {
		int *varPtr = &linkPtr->lastValue.iPtr[i];

		if (Tcl_GetBooleanFromObj(NULL, objv[i], varPtr) != TCL_OK) {
		    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			    ObjValue(linkPtr), TCL_GLOBAL_ONLY);
	            return (char *) "variable array must have boolean value";
		}
	    }
	} else {
	    int *varPtr = &linkPtr->lastValue.i;

	    if (Tcl_GetBooleanFromObj(NULL, valueObj, varPtr) != TCL_OK) {
		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			ObjValue(linkPtr), TCL_GLOBAL_ONLY);
		return (char *) "variable must have boolean value";
	    }
	    LinkedVar(int) = *varPtr;
	}
	break;

    case TCL_LINK_CHAR:
	if (linkPtr->flags & LINK_ALLOC_LAST) {
	    for (i=0; i < objc; i++) {
		if (GetInt(objv[i], &valueInt)
		        || !InRange(SCHAR_MIN, valueInt, SCHAR_MAX)) {
		    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			    ObjValue(linkPtr), TCL_GLOBAL_ONLY);
	            return (char *) "variable array must have char value";
		}
		linkPtr->lastValue.cPtr[i] = (char) valueInt;
	    }
	} else {
	    if (GetInt(valueObj, &valueInt)
		    || !InRange(SCHAR_MIN, valueInt, SCHAR_MAX)) {
		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			ObjValue(linkPtr), TCL_GLOBAL_ONLY);
		return (char *) "variable must have char value";
	    }
	    LinkedVar(char) = linkPtr->lastValue.c = (char) valueInt;
	}
	break;

    case TCL_LINK_UCHAR:
	if (linkPtr->flags & LINK_ALLOC_LAST) {
	    for (i=0; i < objc; i++) {
		if (GetInt(objv[i], &valueInt)
		        || !InRange(0, valueInt, (int)UCHAR_MAX)) {
		    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			    ObjValue(linkPtr), TCL_GLOBAL_ONLY);
		    return (char *)
			    "variable array must have unsigned char value";
		}
		linkPtr->lastValue.ucPtr[i] = (unsigned char) valueInt;
	    }







|


















|


|


















|







955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
	if (linkPtr->flags & LINK_ALLOC_LAST) {
	    for (i=0; i < objc; i++) {
		int *varPtr = &linkPtr->lastValue.iPtr[i];

		if (Tcl_GetBooleanFromObj(NULL, objv[i], varPtr) != TCL_OK) {
		    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			    ObjValue(linkPtr), TCL_GLOBAL_ONLY);
		    return (char *) "variable array must have boolean value";
		}
	    }
	} else {
	    int *varPtr = &linkPtr->lastValue.i;

	    if (Tcl_GetBooleanFromObj(NULL, valueObj, varPtr) != TCL_OK) {
		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			ObjValue(linkPtr), TCL_GLOBAL_ONLY);
		return (char *) "variable must have boolean value";
	    }
	    LinkedVar(int) = *varPtr;
	}
	break;

    case TCL_LINK_CHAR:
	if (linkPtr->flags & LINK_ALLOC_LAST) {
	    for (i=0; i < objc; i++) {
		if (GetInt(objv[i], &valueInt)
			|| !InRange(SCHAR_MIN, valueInt, SCHAR_MAX)) {
		    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			    ObjValue(linkPtr), TCL_GLOBAL_ONLY);
		    return (char *) "variable array must have char value";
		}
		linkPtr->lastValue.cPtr[i] = (char) valueInt;
	    }
	} else {
	    if (GetInt(valueObj, &valueInt)
		    || !InRange(SCHAR_MIN, valueInt, SCHAR_MAX)) {
		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			ObjValue(linkPtr), TCL_GLOBAL_ONLY);
		return (char *) "variable must have char value";
	    }
	    LinkedVar(char) = linkPtr->lastValue.c = (char) valueInt;
	}
	break;

    case TCL_LINK_UCHAR:
	if (linkPtr->flags & LINK_ALLOC_LAST) {
	    for (i=0; i < objc; i++) {
		if (GetInt(objv[i], &valueInt)
			|| !InRange(0, valueInt, (int)UCHAR_MAX)) {
		    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			    ObjValue(linkPtr), TCL_GLOBAL_ONLY);
		    return (char *)
			    "variable array must have unsigned char value";
		}
		linkPtr->lastValue.ucPtr[i] = (unsigned char) valueInt;
	    }
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
    case TCL_LINK_SHORT:
	if (linkPtr->flags & LINK_ALLOC_LAST) {
	    for (i=0; i < objc; i++) {
		if (GetInt(objv[i], &valueInt)
			|| !InRange(SHRT_MIN, valueInt, SHRT_MAX)) {
		    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			    ObjValue(linkPtr), TCL_GLOBAL_ONLY);
	            return (char *) "variable array must have short value";
		}
		linkPtr->lastValue.sPtr[i] = (short) valueInt;
	    }
	} else {
	    if (GetInt(valueObj, &valueInt)
		    || !InRange(SHRT_MIN, valueInt, SHRT_MAX)) {
		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			ObjValue(linkPtr), TCL_GLOBAL_ONLY);
		return (char *) "variable must have short value";
	    }
	    LinkedVar(short) = linkPtr->lastValue.s = (short) valueInt;
	}
	break;

    case TCL_LINK_USHORT:
	if (linkPtr->flags & LINK_ALLOC_LAST) {
	    for (i=0; i < objc; i++) {
		if (GetInt(objv[i], &valueInt)
		        || !InRange(0, valueInt, (int)USHRT_MAX)) {
		    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			    ObjValue(linkPtr), TCL_GLOBAL_ONLY);
	            return (char *)
			"variable array must have unsigned short value";
		}
		linkPtr->lastValue.usPtr[i] = (unsigned short) valueInt;
	    }
	} else {
	    if (GetInt(valueObj, &valueInt)
		    || !InRange(0, valueInt, (int)USHRT_MAX)) {







|


















|


|







1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
    case TCL_LINK_SHORT:
	if (linkPtr->flags & LINK_ALLOC_LAST) {
	    for (i=0; i < objc; i++) {
		if (GetInt(objv[i], &valueInt)
			|| !InRange(SHRT_MIN, valueInt, SHRT_MAX)) {
		    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			    ObjValue(linkPtr), TCL_GLOBAL_ONLY);
		    return (char *) "variable array must have short value";
		}
		linkPtr->lastValue.sPtr[i] = (short) valueInt;
	    }
	} else {
	    if (GetInt(valueObj, &valueInt)
		    || !InRange(SHRT_MIN, valueInt, SHRT_MAX)) {
		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			ObjValue(linkPtr), TCL_GLOBAL_ONLY);
		return (char *) "variable must have short value";
	    }
	    LinkedVar(short) = linkPtr->lastValue.s = (short) valueInt;
	}
	break;

    case TCL_LINK_USHORT:
	if (linkPtr->flags & LINK_ALLOC_LAST) {
	    for (i=0; i < objc; i++) {
		if (GetInt(objv[i], &valueInt)
			|| !InRange(0, valueInt, (int)USHRT_MAX)) {
		    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			    ObjValue(linkPtr), TCL_GLOBAL_ONLY);
		    return (char *)
			"variable array must have unsigned short value";
		}
		linkPtr->lastValue.usPtr[i] = (unsigned short) valueInt;
	    }
	} else {
	    if (GetInt(valueObj, &valueInt)
		    || !InRange(0, valueInt, (int)USHRT_MAX)) {
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
    case TCL_LINK_UINT:
	if (linkPtr->flags & LINK_ALLOC_LAST) {
	    for (i=0; i < objc; i++) {
		if (GetWide(objv[i], &valueWide)
			|| !InRange(0, valueWide, (Tcl_WideInt)UINT_MAX)) {
		    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			    ObjValue(linkPtr), TCL_GLOBAL_ONLY);
	            return (char *)
			    "variable array must have unsigned int value";
		}
		linkPtr->lastValue.uiPtr[i] = (unsigned int) valueWide;
	    }
	} else {
	    if (GetWide(valueObj, &valueWide)
		    || !InRange(0, valueWide, (Tcl_WideInt)UINT_MAX)) {







|







1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
    case TCL_LINK_UINT:
	if (linkPtr->flags & LINK_ALLOC_LAST) {
	    for (i=0; i < objc; i++) {
		if (GetWide(objv[i], &valueWide)
			|| !InRange(0, valueWide, (Tcl_WideInt)UINT_MAX)) {
		    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			    ObjValue(linkPtr), TCL_GLOBAL_ONLY);
		    return (char *)
			    "variable array must have unsigned int value";
		}
		linkPtr->lastValue.uiPtr[i] = (unsigned int) valueWide;
	    }
	} else {
	    if (GetWide(valueObj, &valueWide)
		    || !InRange(0, valueWide, (Tcl_WideInt)UINT_MAX)) {
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
	break;
    case TCL_LINK_WIDE_UINT:
	if (linkPtr->flags & LINK_ALLOC_LAST) {
	    for (i=0; i < objc; i++) {
		if (GetUWide(objv[i], &valueUWide)) {
		    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			    ObjValue(linkPtr), TCL_GLOBAL_ONLY);
	            return (char *)
			    "variable array must have unsigned wide int value";
		}
		linkPtr->lastValue.uwPtr[i] = valueUWide;
	    }
	} else {
	    if (GetUWide(valueObj, &valueUWide)) {
		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			ObjValue(linkPtr), TCL_GLOBAL_ONLY);
		return (char *) "variable must have unsigned wide int value";
	    }
	    LinkedVar(Tcl_WideUInt) = linkPtr->lastValue.uw = valueUWide;
	}
	break;

    case TCL_LINK_FLOAT:
	if (linkPtr->flags & LINK_ALLOC_LAST) {
	    for (i=0; i < objc; i++) {
		if (GetDouble(objv[i], &valueDouble)
			&& !InRange(FLT_MIN, fabs(valueDouble), FLT_MAX)
		        && !IsSpecial(valueDouble)) {
		    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			    ObjValue(linkPtr), TCL_GLOBAL_ONLY);
	            return (char *) "variable array must have float value";
		}
		linkPtr->lastValue.fPtr[i] = (float) valueDouble;
	    }
	} else {
	    if (GetDouble(valueObj, &valueDouble)
		    && !InRange(FLT_MIN, fabs(valueDouble), FLT_MAX)
		    && !IsSpecial(valueDouble)) {
		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			ObjValue(linkPtr), TCL_GLOBAL_ONLY);
		return (char *) "variable must have float value";
	    }
	    LinkedVar(float) = linkPtr->lastValue.f = (float) valueDouble;
	}
	break;

    default:
	return (char *) "internal error: bad linked variable type";







|



















|


|









|







1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
	break;
    case TCL_LINK_WIDE_UINT:
	if (linkPtr->flags & LINK_ALLOC_LAST) {
	    for (i=0; i < objc; i++) {
		if (GetUWide(objv[i], &valueUWide)) {
		    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			    ObjValue(linkPtr), TCL_GLOBAL_ONLY);
		    return (char *)
			    "variable array must have unsigned wide int value";
		}
		linkPtr->lastValue.uwPtr[i] = valueUWide;
	    }
	} else {
	    if (GetUWide(valueObj, &valueUWide)) {
		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			ObjValue(linkPtr), TCL_GLOBAL_ONLY);
		return (char *) "variable must have unsigned wide int value";
	    }
	    LinkedVar(Tcl_WideUInt) = linkPtr->lastValue.uw = valueUWide;
	}
	break;

    case TCL_LINK_FLOAT:
	if (linkPtr->flags & LINK_ALLOC_LAST) {
	    for (i=0; i < objc; i++) {
		if (GetDouble(objv[i], &valueDouble)
			&& !InRange(FLT_MIN, fabs(valueDouble), FLT_MAX)
			&& !IsSpecial(valueDouble)) {
		    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			    ObjValue(linkPtr), TCL_GLOBAL_ONLY);
		    return (char *)"variable array must have float value";
		}
		linkPtr->lastValue.fPtr[i] = (float) valueDouble;
	    }
	} else {
	    if (GetDouble(valueObj, &valueDouble)
		    && !InRange(FLT_MIN, fabs(valueDouble), FLT_MAX)
		    && !IsSpecial(valueDouble)) {
		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
			ObjValue(linkPtr), TCL_GLOBAL_ONLY);
		return (char *)"variable must have float value";
	    }
	    LinkedVar(float) = linkPtr->lastValue.f = (float) valueDouble;
	}
	break;

    default:
	return (char *) "internal error: bad linked variable type";
Changes to generic/tclLiteral.c.
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
Tcl_Obj *
TclCreateLiteral(
    Interp *iPtr,
    const char *bytes,	/* The start of the string. Note that this is
				 * not a NUL-terminated string. */
    Tcl_Size length,	/* Number of bytes in the string. */
    size_t hash, /* The string's hash. If the value is
				         * TCL_INDEX_NONE, it will be computed here. */
    int *newPtr,
    Namespace *nsPtr,
    int flags,
    LiteralEntry **globalPtrPtr)
{
    LiteralTable *globalTablePtr = &iPtr->literalTable;
    LiteralEntry *globalPtr;







|







176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
Tcl_Obj *
TclCreateLiteral(
    Interp *iPtr,
    const char *bytes,	/* The start of the string. Note that this is
				 * not a NUL-terminated string. */
    Tcl_Size length,	/* Number of bytes in the string. */
    size_t hash, /* The string's hash. If the value is
					 * TCL_INDEX_NONE, it will be computed here. */
    int *newPtr,
    Namespace *nsPtr,
    int flags,
    LiteralEntry **globalPtrPtr)
{
    LiteralTable *globalTablePtr = &iPtr->literalTable;
    LiteralEntry *globalPtr;
Changes to generic/tclNamesp.c.
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
     * problems of just using Tcl_FirstHashEntry over and over, [Bug
     * f97d4ee020]) we copy to a temporary array and then delete all those
     * commands.
     */

    while (nsPtr->cmdTable.numEntries > 0) {
	Tcl_Size length = nsPtr->cmdTable.numEntries;
	Command **cmds = (Command **)
		TclStackAlloc(interp, sizeof(Command *) * length);

	i = 0;
	for (entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
		entryPtr != NULL;
		entryPtr = Tcl_NextHashEntry(&search)) {
	    cmds[i] = (Command *) Tcl_GetHashValue(entryPtr);
	    cmds[i]->refCount++;







|
|







1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
     * problems of just using Tcl_FirstHashEntry over and over, [Bug
     * f97d4ee020]) we copy to a temporary array and then delete all those
     * commands.
     */

    while (nsPtr->cmdTable.numEntries > 0) {
	Tcl_Size length = nsPtr->cmdTable.numEntries;
	Command **cmds = (Command **)TclStackAlloc(interp,
		sizeof(Command *) * length);

	i = 0;
	for (entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
		entryPtr != NULL;
		entryPtr = Tcl_NextHashEntry(&search)) {
	    cmds[i] = (Command *) Tcl_GetHashValue(entryPtr);
	    cmds[i]->refCount++;
Changes to generic/tclOO.c.
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
    }

    /*
     * Make the configurable class and install its standard defined method.
     */

    Tcl_Object cfgCls = Tcl_NewObjectInstance(interp,
	    (Tcl_Class) fPtr->classCls,
	    "::oo::configuresupport::configurable", NULL, -1, NULL, 0);
    for (i = 0 ; cfgMethods[i].name ; i++) {
	TclOONewBasicMethod(((Object *) cfgCls)->classPtr, &cfgMethods[i]);
    }

    /*
     * Don't have handles to these namespaces, so use Tcl_CreateObjCommand.
     */







|
|







452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
    }

    /*
     * Make the configurable class and install its standard defined method.
     */

    Tcl_Object cfgCls = Tcl_NewObjectInstance(interp,
	    (Tcl_Class) fPtr->classCls, "::oo::configuresupport::configurable",
	    NULL, TCL_INDEX_NONE, NULL, 0);
    for (i = 0 ; cfgMethods[i].name ; i++) {
	TclOONewBasicMethod(((Object *) cfgCls)->classPtr, &cfgMethods[i]);
    }

    /*
     * Don't have handles to these namespaces, so use Tcl_CreateObjCommand.
     */
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
    /*
     * Ensure an error if the object was deleted in the constructor. Don't
     * want to lose errors by accident. [Bug 2903011]
     */

    if (result != TCL_ERROR && Destructing(oPtr)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"object deleted in constructor", -1));
	Tcl_SetErrorCode(interp, "TCL", "OO", "STILLBORN", (char *)NULL);
	result = TCL_ERROR;
    }
    if (result != TCL_OK) {
	Tcl_DiscardInterpState(state);

	/*







|







1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
    /*
     * Ensure an error if the object was deleted in the constructor. Don't
     * want to lose errors by accident. [Bug 2903011]
     */

    if (result != TCL_ERROR && Destructing(oPtr)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"object deleted in constructor", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "STILLBORN", (char *)NULL);
	result = TCL_ERROR;
    }
    if (result != TCL_OK) {
	Tcl_DiscardInterpState(state);

	/*
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035

    /*
     * Sanity check.
     */

    if (IsRootClass(oPtr)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"may not clone the class of classes", -1));
	Tcl_SetErrorCode(interp, "TCL", "OO", "CLONING_CLASS", (char *)NULL);
	return NULL;
    }

    /*
     * Build the instance. Note that this does not run any constructors.
     */

    o2Ptr = (Object *) Tcl_NewObjectInstance(interp,
	    (Tcl_Class) oPtr->selfCls, targetName, targetNamespaceName, TCL_INDEX_NONE,
	    NULL, -1);
    if (o2Ptr == NULL) {
	return NULL;
    }

    /*
     * Copy the object-local methods to the new object.
     */







|









|
|







2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035

    /*
     * Sanity check.
     */

    if (IsRootClass(oPtr)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"may not clone the class of classes", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "CLONING_CLASS", (char *)NULL);
	return NULL;
    }

    /*
     * Build the instance. Note that this does not run any constructors.
     */

    o2Ptr = (Object *) Tcl_NewObjectInstance(interp,
	    (Tcl_Class) oPtr->selfCls, targetName, targetNamespaceName,
	    TCL_INDEX_NONE, NULL, 0);
    if (o2Ptr == NULL) {
	return NULL;
    }

    /*
     * Copy the object-local methods to the new object.
     */
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
	    }
	    if (miPtr->mPtr->declaringClassPtr == startCls) {
		break;
	    }
	}
	if (contextPtr->index >= contextPtr->callPtr->numChain) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "no valid method implementation", -1));
	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
		    TclGetString(methodNamePtr), (char *)NULL);
	    TclOODeleteContext(contextPtr);
	    return TCL_ERROR;
	}
    }








|







2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
	    }
	    if (miPtr->mPtr->declaringClassPtr == startCls) {
		break;
	    }
	}
	if (contextPtr->index >= contextPtr->callPtr->numChain) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "no valid method implementation", TCL_AUTO_LENGTH));
	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
		    TclGetString(methodNamePtr), (char *)NULL);
	    TclOODeleteContext(contextPtr);
	    return TCL_ERROR;
	}
    }

Changes to generic/tclOO.h.
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
 * and to allow the attachment of arbitrary data to objects and classes.
 */

#ifndef TCL_NO_DEPRECATED
typedef int (Tcl_MethodCallProc)(void *clientData, Tcl_Interp *interp,
	Tcl_ObjectContext objectContext, int objc, Tcl_Obj *const *objv);
#endif /* TCL_NO_DEPRECATED */
#if TCL_MAJOR_VERSION > 8
typedef int (Tcl_MethodCallProc2)(void *clientData, Tcl_Interp *interp,
	Tcl_ObjectContext objectContext, Tcl_Size objc, Tcl_Obj *const *objv);
#else
#define Tcl_MethodCallProc2 Tcl_MethodCallProc
#endif
typedef void (Tcl_MethodDeleteProc)(void *clientData);
typedef int (Tcl_CloneProc)(Tcl_Interp *interp, void *oldClientData,
	void **newClientData);
typedef void (Tcl_ObjectMetadataDeleteProc)(void *clientData);
typedef int (Tcl_ObjectMapMethodNameProc)(Tcl_Interp *interp,
	Tcl_Object object, Tcl_Class *startClsPtr, Tcl_Obj *methodNameObj);








<


<
<
<







60
61
62
63
64
65
66

67
68



69
70
71
72
73
74
75
 * and to allow the attachment of arbitrary data to objects and classes.
 */

#ifndef TCL_NO_DEPRECATED
typedef int (Tcl_MethodCallProc)(void *clientData, Tcl_Interp *interp,
	Tcl_ObjectContext objectContext, int objc, Tcl_Obj *const *objv);
#endif /* TCL_NO_DEPRECATED */

typedef int (Tcl_MethodCallProc2)(void *clientData, Tcl_Interp *interp,
	Tcl_ObjectContext objectContext, Tcl_Size objc, Tcl_Obj *const *objv);



typedef void (Tcl_MethodDeleteProc)(void *clientData);
typedef int (Tcl_CloneProc)(Tcl_Interp *interp, void *oldClientData,
	void **newClientData);
typedef void (Tcl_ObjectMetadataDeleteProc)(void *clientData);
typedef int (Tcl_ObjectMapMethodNameProc)(Tcl_Interp *interp,
	Tcl_Object object, Tcl_Class *startClsPtr, Tcl_Obj *methodNameObj);

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
				 * does not need deleting. */
    Tcl_CloneProc *cloneProc;	/* How to copy this method's type-specific
				 * data, or NULL if the type-specific data can
				 * be copied directly. */
} Tcl_MethodType;
#endif /* TCL_NO_DEPRECATED */

#if TCL_MAJOR_VERSION > 8
typedef struct Tcl_MethodType2 {
    int version;		/* Structure version field. Always to be equal
				 * to TCL_OO_METHOD_VERSION_2 in
				 * declarations. */
    const char *name;		/* Name of this type of method, mostly for
				 * debugging purposes. */
    Tcl_MethodCallProc2 *callProc;
				/* How to invoke this method. */
    Tcl_MethodDeleteProc *deleteProc;
				/* How to delete this method's type-specific
				 * data, or NULL if the type-specific data
				 * does not need deleting. */
    Tcl_CloneProc *cloneProc;	/* How to copy this method's type-specific
				 * data, or NULL if the type-specific data can
				 * be copied directly. */
} Tcl_MethodType2;
#else
#define Tcl_MethodType2 Tcl_MethodType
#endif

/*
 * The correct value for the version field of the Tcl_MethodType structure.
 * This allows new versions of the structure to be introduced without breaking
 * binary compatibility.
 */
enum TclOOMethodVersion {







<
















<
<
<







94
95
96
97
98
99
100

101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116



117
118
119
120
121
122
123
				 * does not need deleting. */
    Tcl_CloneProc *cloneProc;	/* How to copy this method's type-specific
				 * data, or NULL if the type-specific data can
				 * be copied directly. */
} Tcl_MethodType;
#endif /* TCL_NO_DEPRECATED */


typedef struct Tcl_MethodType2 {
    int version;		/* Structure version field. Always to be equal
				 * to TCL_OO_METHOD_VERSION_2 in
				 * declarations. */
    const char *name;		/* Name of this type of method, mostly for
				 * debugging purposes. */
    Tcl_MethodCallProc2 *callProc;
				/* How to invoke this method. */
    Tcl_MethodDeleteProc *deleteProc;
				/* How to delete this method's type-specific
				 * data, or NULL if the type-specific data
				 * does not need deleting. */
    Tcl_CloneProc *cloneProc;	/* How to copy this method's type-specific
				 * data, or NULL if the type-specific data can
				 * be copied directly. */
} Tcl_MethodType2;




/*
 * The correct value for the version field of the Tcl_MethodType structure.
 * This allows new versions of the structure to be introduced without breaking
 * binary compatibility.
 */
enum TclOOMethodVersion {
Changes to generic/tclOOBasic.c.
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
		"?definitionScript?");
	return TCL_ERROR;
    }

    /*
     * Make the class definition delegate. This is special; it doesn't reenter
     * here (and the class definition delegate doesn't run any constructors).
     * 
     * This needs to be done before consideration of whether to pass the script
     * argument to [oo::define]. [Bug 680503]
     */

    nameObj = Tcl_ObjPrintf("%s:: oo ::delegate",
	    oPtr->namespacePtr->fullName);
    Tcl_NewObjectInstance(interp, (Tcl_Class) oPtr->fPtr->classCls,
	    TclGetString(nameObj), NULL, -1, NULL, -1);
    Tcl_BounceRefCount(nameObj);

    /*
     * If there's nothing else to do, we're done.
     */

    if ((size_t) objc == skip) {
	return TCL_OK;
    }

    /*
     * Delegate to [oo::define] to do the work.
     */

    invoke = (Tcl_Obj **) TclStackAlloc(interp, 3 * sizeof(Tcl_Obj *));
    invoke[0] = oPtr->fPtr->defineName;
    invoke[1] = TclOOObjectName(interp, oPtr);
    invoke[2] = objv[objc-1];

    /*
     * Must add references or errors in configuration script will cause
     * trouble.
     */

    Tcl_IncrRefCount(invoke[0]);







|







|

















|







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
		"?definitionScript?");
	return TCL_ERROR;
    }

    /*
     * Make the class definition delegate. This is special; it doesn't reenter
     * here (and the class definition delegate doesn't run any constructors).
     *
     * This needs to be done before consideration of whether to pass the script
     * argument to [oo::define]. [Bug 680503]
     */

    nameObj = Tcl_ObjPrintf("%s:: oo ::delegate",
	    oPtr->namespacePtr->fullName);
    Tcl_NewObjectInstance(interp, (Tcl_Class) oPtr->fPtr->classCls,
	    TclGetString(nameObj), NULL, TCL_INDEX_NONE, NULL, 0);
    Tcl_BounceRefCount(nameObj);

    /*
     * If there's nothing else to do, we're done.
     */

    if ((size_t) objc == skip) {
	return TCL_OK;
    }

    /*
     * Delegate to [oo::define] to do the work.
     */

    invoke = (Tcl_Obj **) TclStackAlloc(interp, 3 * sizeof(Tcl_Obj *));
    invoke[0] = oPtr->fPtr->defineName;
    invoke[1] = TclOOObjectName(interp, oPtr);
    invoke[2] = objv[objc - 1];

    /*
     * Must add references or errors in configuration script will cause
     * trouble.
     */

    Tcl_IncrRefCount(invoke[0]);
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
    Object *oPtr = (Object *) data[1];
    Tcl_InterpState saved;
    int code;

    TclDecrRefCount(invoke[0]);
    TclDecrRefCount(invoke[1]);
    TclDecrRefCount(invoke[2]);
    invoke[0] = Tcl_NewStringObj("::oo::MixinClassDelegates", -1);
    invoke[1] = TclOOObjectName(interp, oPtr);
    Tcl_IncrRefCount(invoke[0]);
    Tcl_IncrRefCount(invoke[1]);
    saved = Tcl_SaveInterpState(interp, result);
    code = Tcl_EvalObjv(interp, 2, invoke, 0);
    TclDecrRefCount(invoke[0]);
    TclDecrRefCount(invoke[1]);







|







153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
    Object *oPtr = (Object *) data[1];
    Tcl_InterpState saved;
    int code;

    TclDecrRefCount(invoke[0]);
    TclDecrRefCount(invoke[1]);
    TclDecrRefCount(invoke[2]);
    invoke[0] = Tcl_NewStringObj("::oo::MixinClassDelegates", TCL_AUTO_LENGTH);
    invoke[1] = TclOOObjectName(interp, oPtr);
    Tcl_IncrRefCount(invoke[0]);
    Tcl_IncrRefCount(invoke[1]);
    saved = Tcl_SaveInterpState(interp, result);
    code = Tcl_EvalObjv(interp, 2, invoke, 0);
    TclDecrRefCount(invoke[0]);
    TclDecrRefCount(invoke[1]);
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
		"objectName ?arg ...?");
	return TCL_ERROR;
    }
    objName = Tcl_GetStringFromObj(
	    objv[Tcl_ObjectContextSkippedArgs(context)], &len);
    if (len == 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"object name must not be empty", -1));
	Tcl_SetErrorCode(interp, "TCL", "OO", "EMPTY_NAME", (char *)NULL);
	return TCL_ERROR;
    }

    /*
     * Make the object and return its name.
     */







|







219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
		"objectName ?arg ...?");
	return TCL_ERROR;
    }
    objName = Tcl_GetStringFromObj(
	    objv[Tcl_ObjectContextSkippedArgs(context)], &len);
    if (len == 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"object name must not be empty", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "EMPTY_NAME", (char *)NULL);
	return TCL_ERROR;
    }

    /*
     * Make the object and return its name.
     */
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
		"objectName namespaceName ?arg ...?");
	return TCL_ERROR;
    }
    objName = Tcl_GetStringFromObj(
	    objv[Tcl_ObjectContextSkippedArgs(context)], &len);
    if (len == 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"object name must not be empty", -1));
	Tcl_SetErrorCode(interp, "TCL", "OO", "EMPTY_NAME", (char *)NULL);
	return TCL_ERROR;
    }
    nsName = Tcl_GetStringFromObj(
	    objv[Tcl_ObjectContextSkippedArgs(context)+1], &len);
    if (len == 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"namespace name must not be empty", -1));
	Tcl_SetErrorCode(interp, "TCL", "OO", "EMPTY_NAME", (char *)NULL);
	return TCL_ERROR;
    }

    /*
     * Make the object and return its name.
     */

    return TclNRNewObjectInstance(interp, (Tcl_Class) oPtr->classPtr,
	    objName, nsName, objc, objv,
	    Tcl_ObjectContextSkippedArgs(context)+2,
	    AddConstructionFinalizer(interp));
}

/*
 * ----------------------------------------------------------------------
 *
 * TclOO_Class_New --







|




|


|










|







284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
		"objectName namespaceName ?arg ...?");
	return TCL_ERROR;
    }
    objName = Tcl_GetStringFromObj(
	    objv[Tcl_ObjectContextSkippedArgs(context)], &len);
    if (len == 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"object name must not be empty", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "EMPTY_NAME", (char *)NULL);
	return TCL_ERROR;
    }
    nsName = Tcl_GetStringFromObj(
	    objv[Tcl_ObjectContextSkippedArgs(context) + 1], &len);
    if (len == 0) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"namespace name must not be empty", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "EMPTY_NAME", (char *)NULL);
	return TCL_ERROR;
    }

    /*
     * Make the object and return its name.
     */

    return TclNRNewObjectInstance(interp, (Tcl_Class) oPtr->classPtr,
	    objName, nsName, objc, objv,
	    Tcl_ObjectContextSkippedArgs(context) + 2,
	    AddConstructionFinalizer(interp));
}

/*
 * ----------------------------------------------------------------------
 *
 * TclOO_Class_New --
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
	return TCL_ERROR;
    }

    errorMsg = Tcl_ObjPrintf("unknown method \"%s\": must be ",
	    TclGetString(objv[skip]));
    for (i=0 ; i<numMethodNames-1 ; i++) {
	if (i) {
	    Tcl_AppendToObj(errorMsg, ", ", -1);
	}
	Tcl_AppendToObj(errorMsg, methodNames[i], -1);
    }
    if (i) {
	Tcl_AppendToObj(errorMsg, " or ", -1);
    }
    Tcl_AppendToObj(errorMsg, methodNames[i], -1);
    Tcl_Free((void *) methodNames);
    Tcl_SetObjResult(interp, errorMsg);
    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
	    TclGetString(objv[skip]), (char *)NULL);
    return TCL_ERROR;
}








|

|


|

|







606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
	return TCL_ERROR;
    }

    errorMsg = Tcl_ObjPrintf("unknown method \"%s\": must be ",
	    TclGetString(objv[skip]));
    for (i=0 ; i<numMethodNames-1 ; i++) {
	if (i) {
	    Tcl_AppendToObj(errorMsg, ", ", TCL_AUTO_LENGTH);
	}
	Tcl_AppendToObj(errorMsg, methodNames[i], TCL_AUTO_LENGTH);
    }
    if (i) {
	Tcl_AppendToObj(errorMsg, " or ", TCL_AUTO_LENGTH);
    }
    Tcl_AppendToObj(errorMsg, methodNames[i], TCL_AUTO_LENGTH);
    Tcl_Free((void *) methodNames);
    Tcl_SetObjResult(interp, errorMsg);
    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
	    TclGetString(objv[skip]), (char *)NULL);
    return TCL_ERROR;
}

1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
	    /*
	     * Invoke the (advanced) method call context in the caller
	     * context. Note that this is like [uplevel 1] and not [eval].
	     */

	    TclNRAddCallback(interp, NextRestoreFrame, framePtr,
		    contextPtr, INT2PTR(contextPtr->index), NULL);
	    contextPtr->index = i-1;
	    iPtr->varFramePtr = framePtr->callerVarPtr;
	    return TclNRObjectContextInvokeNext(interp,
		    (Tcl_ObjectContext) contextPtr, objc, objv, 2);
	}
    }

    /*







|







1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
	    /*
	     * Invoke the (advanced) method call context in the caller
	     * context. Note that this is like [uplevel 1] and not [eval].
	     */

	    TclNRAddCallback(interp, NextRestoreFrame, framePtr,
		    contextPtr, INT2PTR(contextPtr->index), NULL);
	    contextPtr->index = i - 1;
	    iPtr->varFramePtr = framePtr->callerVarPtr;
	    return TclNRObjectContextInvokeNext(interp,
		    (Tcl_ObjectContext) contextPtr, objc, objv, 2);
	}
    }

    /*
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
		TclNewNamespaceObj(contextPtr->oPtr->namespacePtr));
	return TCL_OK;
    case SELF_CLASS: {
	Class *clsPtr = CurrentlyInvoked(contextPtr).mPtr->declaringClassPtr;

	if (clsPtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "method not defined by a class", -1));
	    Tcl_SetErrorCode(interp, "TCL", "OO", "UNMATCHED_CONTEXT", (char *)NULL);
	    return TCL_ERROR;
	}

	Tcl_SetObjResult(interp, TclOOObjectName(interp, clsPtr->thisPtr));
	return TCL_OK;
    }
    case SELF_METHOD:
	if (contextPtr->callPtr->flags & CONSTRUCTOR) {
	    Tcl_SetObjResult(interp, contextPtr->oPtr->fPtr->constructorName);
	} else if (contextPtr->callPtr->flags & DESTRUCTOR) {
	    Tcl_SetObjResult(interp, contextPtr->oPtr->fPtr->destructorName);
	} else {
	    Tcl_SetObjResult(interp,
		    CurrentlyInvoked(contextPtr).mPtr->namePtr);
	}
	return TCL_OK;
    case SELF_FILTER:
	if (!CurrentlyInvoked(contextPtr).isFilter) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "not inside a filtering context", -1));
	    Tcl_SetErrorCode(interp, "TCL", "OO", "UNMATCHED_CONTEXT", (char *)NULL);
	    return TCL_ERROR;
	} else {
	    MInvoke *miPtr = &CurrentlyInvoked(contextPtr);
	    Object *oPtr;
	    const char *type;

	    if (miPtr->filterDeclarer != NULL) {
		oPtr = miPtr->filterDeclarer->thisPtr;
		type = "class";
	    } else {
		oPtr = contextPtr->oPtr;
		type = "object";
	    }

	    result[0] = TclOOObjectName(interp, oPtr);
	    result[1] = Tcl_NewStringObj(type, -1);
	    result[2] = miPtr->mPtr->namePtr;
	    Tcl_SetObjResult(interp, Tcl_NewListObj(3, result));
	    return TCL_OK;
	}
    case SELF_CALLER:
	if ((framePtr->callerVarPtr == NULL) ||
		!(framePtr->callerVarPtr->isProcCallFrame & FRAME_IS_METHOD)){
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "caller is not an object", -1));
	    Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", (char *)NULL);
	    return TCL_ERROR;
	} else {
	    CallContext *callerPtr = (CallContext *)
		    framePtr->callerVarPtr->clientData;
	    Method *mPtr = callerPtr->callPtr->chain[callerPtr->index].mPtr;
	    Object *declarerPtr;

	    if (mPtr->declaringClassPtr != NULL) {
		declarerPtr = mPtr->declaringClassPtr->thisPtr;
	    } else if (mPtr->declaringObjectPtr != NULL) {
		declarerPtr = mPtr->declaringObjectPtr;
	    } else {
		/*
		 * This should be unreachable code.
		 */

		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"method without declarer!", -1));
		return TCL_ERROR;
	    }

	    result[0] = TclOOObjectName(interp, declarerPtr);
	    result[1] = TclOOObjectName(interp, callerPtr->oPtr);
	    if (callerPtr->callPtr->flags & CONSTRUCTOR) {
		result[2] = declarerPtr->fPtr->constructorName;
	    } else if (callerPtr->callPtr->flags & DESTRUCTOR) {
		result[2] = declarerPtr->fPtr->destructorName;
	    } else {
		result[2] = mPtr->namePtr;
	    }
	    Tcl_SetObjResult(interp, Tcl_NewListObj(3, result));
	    return TCL_OK;
	}
    case SELF_NEXT:
	if (contextPtr->index < contextPtr->callPtr->numChain-1) {
	    Method *mPtr =
		    contextPtr->callPtr->chain[contextPtr->index+1].mPtr;
	    Object *declarerPtr;

	    if (mPtr->declaringClassPtr != NULL) {
		declarerPtr = mPtr->declaringClassPtr->thisPtr;
	    } else if (mPtr->declaringObjectPtr != NULL) {
		declarerPtr = mPtr->declaringObjectPtr;
	    } else {
		/*
		 * This should be unreachable code.
		 */

		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"method without declarer!", -1));
		return TCL_ERROR;
	    }

	    result[0] = TclOOObjectName(interp, declarerPtr);
	    if (contextPtr->callPtr->flags & CONSTRUCTOR) {
		result[1] = declarerPtr->fPtr->constructorName;
	    } else if (contextPtr->callPtr->flags & DESTRUCTOR) {
		result[1] = declarerPtr->fPtr->destructorName;
	    } else {
		result[1] = mPtr->namePtr;
	    }
	    Tcl_SetObjResult(interp, Tcl_NewListObj(2, result));
	}
	return TCL_OK;
    case SELF_TARGET:
	if (!CurrentlyInvoked(contextPtr).isFilter) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "not inside a filtering context", -1));
	    Tcl_SetErrorCode(interp, "TCL", "OO", "UNMATCHED_CONTEXT", (char *)NULL);
	    return TCL_ERROR;
	} else {
	    Method *mPtr;
	    Object *declarerPtr;
	    Tcl_Size i;

	    for (i=contextPtr->index ; i<contextPtr->callPtr->numChain ; i++){
		if (!contextPtr->callPtr->chain[i].isFilter) {
		    break;
		}
	    }
	    if (i == contextPtr->callPtr->numChain) {
		Tcl_Panic("filtering call chain without terminal non-filter");
	    }
	    mPtr = contextPtr->callPtr->chain[i].mPtr;
	    if (mPtr->declaringClassPtr != NULL) {
		declarerPtr = mPtr->declaringClassPtr->thisPtr;
	    } else if (mPtr->declaringObjectPtr != NULL) {
		declarerPtr = mPtr->declaringObjectPtr;
	    } else {
		/*
		 * This should be unreachable code.
		 */

		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"method without declarer!", -1));
		return TCL_ERROR;
	    }
	    result[0] = TclOOObjectName(interp, declarerPtr);
	    result[1] = mPtr->namePtr;
	    Tcl_SetObjResult(interp, Tcl_NewListObj(2, result));
	    return TCL_OK;
	}







|




















|
















|








|


















|
















|

|












|

















|







|


















|







1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
		TclNewNamespaceObj(contextPtr->oPtr->namespacePtr));
	return TCL_OK;
    case SELF_CLASS: {
	Class *clsPtr = CurrentlyInvoked(contextPtr).mPtr->declaringClassPtr;

	if (clsPtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "method not defined by a class", TCL_AUTO_LENGTH));
	    Tcl_SetErrorCode(interp, "TCL", "OO", "UNMATCHED_CONTEXT", (char *)NULL);
	    return TCL_ERROR;
	}

	Tcl_SetObjResult(interp, TclOOObjectName(interp, clsPtr->thisPtr));
	return TCL_OK;
    }
    case SELF_METHOD:
	if (contextPtr->callPtr->flags & CONSTRUCTOR) {
	    Tcl_SetObjResult(interp, contextPtr->oPtr->fPtr->constructorName);
	} else if (contextPtr->callPtr->flags & DESTRUCTOR) {
	    Tcl_SetObjResult(interp, contextPtr->oPtr->fPtr->destructorName);
	} else {
	    Tcl_SetObjResult(interp,
		    CurrentlyInvoked(contextPtr).mPtr->namePtr);
	}
	return TCL_OK;
    case SELF_FILTER:
	if (!CurrentlyInvoked(contextPtr).isFilter) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "not inside a filtering context", TCL_AUTO_LENGTH));
	    Tcl_SetErrorCode(interp, "TCL", "OO", "UNMATCHED_CONTEXT", (char *)NULL);
	    return TCL_ERROR;
	} else {
	    MInvoke *miPtr = &CurrentlyInvoked(contextPtr);
	    Object *oPtr;
	    const char *type;

	    if (miPtr->filterDeclarer != NULL) {
		oPtr = miPtr->filterDeclarer->thisPtr;
		type = "class";
	    } else {
		oPtr = contextPtr->oPtr;
		type = "object";
	    }

	    result[0] = TclOOObjectName(interp, oPtr);
	    result[1] = Tcl_NewStringObj(type, TCL_AUTO_LENGTH);
	    result[2] = miPtr->mPtr->namePtr;
	    Tcl_SetObjResult(interp, Tcl_NewListObj(3, result));
	    return TCL_OK;
	}
    case SELF_CALLER:
	if ((framePtr->callerVarPtr == NULL) ||
		!(framePtr->callerVarPtr->isProcCallFrame & FRAME_IS_METHOD)){
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "caller is not an object", TCL_AUTO_LENGTH));
	    Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", (char *)NULL);
	    return TCL_ERROR;
	} else {
	    CallContext *callerPtr = (CallContext *)
		    framePtr->callerVarPtr->clientData;
	    Method *mPtr = callerPtr->callPtr->chain[callerPtr->index].mPtr;
	    Object *declarerPtr;

	    if (mPtr->declaringClassPtr != NULL) {
		declarerPtr = mPtr->declaringClassPtr->thisPtr;
	    } else if (mPtr->declaringObjectPtr != NULL) {
		declarerPtr = mPtr->declaringObjectPtr;
	    } else {
		/*
		 * This should be unreachable code.
		 */

		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"method without declarer!", TCL_AUTO_LENGTH));
		return TCL_ERROR;
	    }

	    result[0] = TclOOObjectName(interp, declarerPtr);
	    result[1] = TclOOObjectName(interp, callerPtr->oPtr);
	    if (callerPtr->callPtr->flags & CONSTRUCTOR) {
		result[2] = declarerPtr->fPtr->constructorName;
	    } else if (callerPtr->callPtr->flags & DESTRUCTOR) {
		result[2] = declarerPtr->fPtr->destructorName;
	    } else {
		result[2] = mPtr->namePtr;
	    }
	    Tcl_SetObjResult(interp, Tcl_NewListObj(3, result));
	    return TCL_OK;
	}
    case SELF_NEXT:
	if (contextPtr->index < contextPtr->callPtr->numChain - 1) {
	    Method *mPtr =
		    contextPtr->callPtr->chain[contextPtr->index + 1].mPtr;
	    Object *declarerPtr;

	    if (mPtr->declaringClassPtr != NULL) {
		declarerPtr = mPtr->declaringClassPtr->thisPtr;
	    } else if (mPtr->declaringObjectPtr != NULL) {
		declarerPtr = mPtr->declaringObjectPtr;
	    } else {
		/*
		 * This should be unreachable code.
		 */

		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"method without declarer!", TCL_AUTO_LENGTH));
		return TCL_ERROR;
	    }

	    result[0] = TclOOObjectName(interp, declarerPtr);
	    if (contextPtr->callPtr->flags & CONSTRUCTOR) {
		result[1] = declarerPtr->fPtr->constructorName;
	    } else if (contextPtr->callPtr->flags & DESTRUCTOR) {
		result[1] = declarerPtr->fPtr->destructorName;
	    } else {
		result[1] = mPtr->namePtr;
	    }
	    Tcl_SetObjResult(interp, Tcl_NewListObj(2, result));
	}
	return TCL_OK;
    case SELF_TARGET:
	if (!CurrentlyInvoked(contextPtr).isFilter) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "not inside a filtering context", TCL_AUTO_LENGTH));
	    Tcl_SetErrorCode(interp, "TCL", "OO", "UNMATCHED_CONTEXT", (char *)NULL);
	    return TCL_ERROR;
	} else {
	    Method *mPtr;
	    Object *declarerPtr;
	    Tcl_Size i;

	    for (i=contextPtr->index ; i<contextPtr->callPtr->numChain ; i++) {
		if (!contextPtr->callPtr->chain[i].isFilter) {
		    break;
		}
	    }
	    if (i == contextPtr->callPtr->numChain) {
		Tcl_Panic("filtering call chain without terminal non-filter");
	    }
	    mPtr = contextPtr->callPtr->chain[i].mPtr;
	    if (mPtr->declaringClassPtr != NULL) {
		declarerPtr = mPtr->declaringClassPtr->thisPtr;
	    } else if (mPtr->declaringObjectPtr != NULL) {
		declarerPtr = mPtr->declaringObjectPtr;
	    } else {
		/*
		 * This should be unreachable code.
		 */

		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"method without declarer!", TCL_AUTO_LENGTH));
		return TCL_ERROR;
	    }
	    result[0] = TclOOObjectName(interp, declarerPtr);
	    result[1] = mPtr->namePtr;
	    Tcl_SetObjResult(interp, Tcl_NewListObj(2, result));
	    return TCL_OK;
	}
Changes to generic/tclOOCall.c.
1893
1894
1895
1896
1897
1898
1899
1900

1901
1902
1903
1904
1905
1906
1907
	    callPtr->flags & CONSTRUCTOR ? fPtr->constructorName :
	    callPtr->flags & DESTRUCTOR ? fPtr->destructorName :
		    miPtr->mPtr->namePtr;
	descObjs[2] = miPtr->mPtr->declaringClassPtr
		? Tcl_GetObjectName(interp,
			(Tcl_Object) miPtr->mPtr->declaringClassPtr->thisPtr)
		: objectLiteral;
	descObjs[3] = Tcl_NewStringObj(miPtr->mPtr->type2Ptr->name, -1);


	objv[i] = Tcl_NewListObj(4, descObjs);
    }

    /*
     * Drop the local references to the literals; if they're actually used,
     * they'll live on the description itself.







|
>







1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
	    callPtr->flags & CONSTRUCTOR ? fPtr->constructorName :
	    callPtr->flags & DESTRUCTOR ? fPtr->destructorName :
		    miPtr->mPtr->namePtr;
	descObjs[2] = miPtr->mPtr->declaringClassPtr
		? Tcl_GetObjectName(interp,
			(Tcl_Object) miPtr->mPtr->declaringClassPtr->thisPtr)
		: objectLiteral;
	descObjs[3] = Tcl_NewStringObj(miPtr->mPtr->type2Ptr->name,
		TCL_AUTO_LENGTH);

	objv[i] = Tcl_NewListObj(4, descObjs);
    }

    /*
     * Drop the local references to the literals; if they're actually used,
     * they'll live on the description itself.
Changes to generic/tclOODefineCmds.c.
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
	}
	if (toPtr) {
	    newHPtr = Tcl_CreateHashEntry(oPtr->methodsPtr, toPtr,
		    &isNew);
	    if (hPtr == newHPtr) {
	    renameToSelf:
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"cannot rename method to itself", -1));
		Tcl_SetErrorCode(interp, "TCL", "OO", "RENAME_TO_SELF", (char *)NULL);
		return TCL_ERROR;
	    } else if (!isNew) {
	    renameToExisting:
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"method called %s already exists",
			TclGetString(toPtr)));







|







714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
	}
	if (toPtr) {
	    newHPtr = Tcl_CreateHashEntry(oPtr->methodsPtr, toPtr,
		    &isNew);
	    if (hPtr == newHPtr) {
	    renameToSelf:
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"cannot rename method to itself", TCL_AUTO_LENGTH));
		Tcl_SetErrorCode(interp, "TCL", "OO", "RENAME_TO_SELF", (char *)NULL);
		return TCL_ERROR;
	    } else if (!isNew) {
	    renameToExisting:
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"method called %s already exists",
			TclGetString(toPtr)));
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
TclOOUnknownDefinition(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    Tcl_Size objc,
    Tcl_Obj *const *objv)
{
    Namespace *nsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
    Tcl_HashSearch search;
    Tcl_HashEntry *hPtr;
    Tcl_Size soughtLen;
    const char *soughtStr, *matchedStr = NULL;

    if (objc < 2) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"bad call of unknown handler", -1));
	Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_UNKNOWN", (char *)NULL);
	return TCL_ERROR;
    }
    if (TclOOGetDefineCmdContext(interp) == NULL) {
	return TCL_ERROR;
    }

    soughtStr = TclGetStringFromObj(objv[1], &soughtLen);
    if (soughtLen == 0) {
	goto noMatch;
    }
    hPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
    while (hPtr != NULL) {
	const char *nameStr = (const char *)
		Tcl_GetHashKey(&nsPtr->cmdTable, hPtr);

	if (strncmp(soughtStr, nameStr, soughtLen) == 0) {
	    if (matchedStr != NULL) {
		goto noMatch;
	    }
	    matchedStr = nameStr;
	}
	hPtr = Tcl_NextHashEntry(&search);
    }

    if (matchedStr != NULL) {
	/*
	 * Got one match, and only one match!
	 */

	Tcl_Obj **newObjv = (Tcl_Obj **)
		TclStackAlloc(interp, sizeof(Tcl_Obj*) * (objc - 1));
	int result;

	newObjv[0] = Tcl_NewStringObj(matchedStr, -1);
	Tcl_IncrRefCount(newObjv[0]);
	if (objc > 2) {
	    memcpy(newObjv + 1, objv + 2, sizeof(Tcl_Obj *) * (objc - 2));
	}
	result = Tcl_EvalObjv(interp, objc - 1, newObjv, 0);
	Tcl_DecrRefCount(newObjv[0]);
	TclStackFree(interp, newObjv);







|
<

|



|











<
<
<
|
<






<











|







783
784
785
786
787
788
789
790

791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807



808

809
810
811
812
813
814

815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
TclOOUnknownDefinition(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    Tcl_Size objc,
    Tcl_Obj *const *objv)
{
    Namespace *nsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
    FOREACH_HASH_DECLS;

    Tcl_Size soughtLen;
    const char *soughtStr, *nameStr, *matchedStr = NULL;

    if (objc < 2) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"bad call of unknown handler", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_UNKNOWN", (char *)NULL);
	return TCL_ERROR;
    }
    if (TclOOGetDefineCmdContext(interp) == NULL) {
	return TCL_ERROR;
    }

    soughtStr = TclGetStringFromObj(objv[1], &soughtLen);
    if (soughtLen == 0) {
	goto noMatch;
    }



    FOREACH_HASH_KEY(nameStr, &nsPtr->cmdTable) {

	if (strncmp(soughtStr, nameStr, soughtLen) == 0) {
	    if (matchedStr != NULL) {
		goto noMatch;
	    }
	    matchedStr = nameStr;
	}

    }

    if (matchedStr != NULL) {
	/*
	 * Got one match, and only one match!
	 */

	Tcl_Obj **newObjv = (Tcl_Obj **)
		TclStackAlloc(interp, sizeof(Tcl_Obj*) * (objc - 1));
	int result;

	newObjv[0] = Tcl_NewStringObj(matchedStr, TCL_AUTO_LENGTH);
	Tcl_IncrRefCount(newObjv[0]);
	if (objc > 2) {
	    memcpy(newObjv + 1, objv + 2, sizeof(Tcl_Obj *) * (objc - 2));
	}
	result = Tcl_EvalObjv(interp, objc - 1, newObjv, 0);
	Tcl_DecrRefCount(newObjv[0]);
	TclStackFree(interp, newObjv);
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
    Tcl_Size objc,
    Tcl_Obj *const objv[])
{
    CallFrame *framePtr, **framePtrPtr = &framePtr;

    if (namespacePtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"no definition namespace available", -1));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }

    /*
     * framePtrPtr is needed to satisfy GCC 3.3's strict aliasing rules.
     */







|







922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
    Tcl_Size objc,
    Tcl_Obj *const objv[])
{
    CallFrame *framePtr, **framePtrPtr = &framePtr;

    if (namespacePtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"no definition namespace available", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }

    /*
     * framePtrPtr is needed to satisfy GCC 3.3's strict aliasing rules.
     */
969
970
971
972
973
974
975
976

977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
    Tcl_Object object;

    if ((iPtr->varFramePtr == NULL)
	    || (iPtr->varFramePtr->isProcCallFrame != FRAME_IS_OO_DEFINE
	    && iPtr->varFramePtr->isProcCallFrame != PRIVATE_FRAME)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"this command may only be called from within the context of"
		" an ::oo::define or ::oo::objdefine command", -1));

	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return NULL;
    }
    object = (Tcl_Object) iPtr->varFramePtr->clientData;
    if (Tcl_ObjectDeleted(object)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"this command cannot be called when the object has been"
		" deleted", -1));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return NULL;
    }
    return object;
}

Class *
TclOOGetClassDefineCmdContext(
    Tcl_Interp *interp)
{
    Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
    if (oPtr == NULL) {
	return NULL;
    }
    if (!oPtr->classPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"attempt to misuse API", -1));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
	return NULL;
    }
    return oPtr->classPtr;
}

/*







|
>







|
















|







963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
    Tcl_Object object;

    if ((iPtr->varFramePtr == NULL)
	    || (iPtr->varFramePtr->isProcCallFrame != FRAME_IS_OO_DEFINE
	    && iPtr->varFramePtr->isProcCallFrame != PRIVATE_FRAME)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"this command may only be called from within the context of"
		" an ::oo::define or ::oo::objdefine command",
		TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return NULL;
    }
    object = (Tcl_Object) iPtr->varFramePtr->clientData;
    if (Tcl_ObjectDeleted(object)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"this command cannot be called when the object has been"
		" deleted", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return NULL;
    }
    return object;
}

Class *
TclOOGetClassDefineCmdContext(
    Tcl_Interp *interp)
{
    Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
    if (oPtr == NULL) {
	return NULL;
    }
    if (!oPtr->classPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"attempt to misuse API", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
	return NULL;
    }
    return oPtr->classPtr;
}

/*
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
    }
    oPtr = (Object *) Tcl_GetObjectFromObj(interp, className);
    iPtr->varFramePtr = savedFramePtr;
    if (oPtr == NULL) {
	return NULL;
    }
    if (oPtr->classPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(errMsg, -1));
	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS",
		TclGetString(className), (char *)NULL);
	return NULL;
    }
    return oPtr->classPtr;
}








|







1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
    }
    oPtr = (Object *) Tcl_GetObjectFromObj(interp, className);
    iPtr->varFramePtr = savedFramePtr;
    if (oPtr == NULL) {
	return NULL;
    }
    if (oPtr->classPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(errMsg, TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS",
		TclGetString(className), (char *)NULL);
	return NULL;
    }
    return oPtr->classPtr;
}

1536
1537
1538
1539
1540
1541
1542
1543

1544
1545
1546
1547
1548
1549

1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569

1570
1571
1572
1573
1574
1575
1576

    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
    if (oPtr == NULL) {
	return TCL_ERROR;
    }
    if (oPtr->flags & ROOT_OBJECT) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"may not modify the class of the root object class", -1));

	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }
    if (oPtr->flags & ROOT_CLASS) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"may not modify the class of the class of classes", -1));

	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }

    /*
     * Parse the argument to get the class to set the object's class to.
     */

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "className");
	return TCL_ERROR;
    }
    clsPtr = GetClassInOuterContext(interp, objv[1],
	    "the class of an object must be a class");
    if (clsPtr == NULL) {
	return TCL_ERROR;
    }
    if (oPtr == clsPtr->thisPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"may not change classes into an instance of themselves", -1));

	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }

    /*
     * Set the object's class.
     */







|
>





|
>



















|
>







1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574

    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
    if (oPtr == NULL) {
	return TCL_ERROR;
    }
    if (oPtr->flags & ROOT_OBJECT) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"may not modify the class of the root object class",
		TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }
    if (oPtr->flags & ROOT_CLASS) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"may not modify the class of the class of classes",
		TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }

    /*
     * Parse the argument to get the class to set the object's class to.
     */

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "className");
	return TCL_ERROR;
    }
    clsPtr = GetClassInOuterContext(interp, objv[1],
	    "the class of an object must be a class");
    if (clsPtr == NULL) {
	return TCL_ERROR;
    }
    if (oPtr == clsPtr->thisPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"may not change classes into an instance of themselves",
		TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }

    /*
     * Set the object's class.
     */
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
    Tcl_Obj *nsNamePtr, **storagePtr;

    if (clsPtr == NULL) {
	return TCL_ERROR;
    } else if (clsPtr->thisPtr->flags & (ROOT_OBJECT | ROOT_CLASS)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"may not modify the definition namespace of the root classes",
		-1));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }

    /*
     * Parse the arguments and work out what the user wants to do.
     */







|







1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
    Tcl_Obj *nsNamePtr, **storagePtr;

    if (clsPtr == NULL) {
	return TCL_ERROR;
    } else if (clsPtr->thisPtr->flags & (ROOT_OBJECT | ROOT_CLASS)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"may not modify the definition namespace of the root classes",
		TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }

    /*
     * Parse the arguments and work out what the user wants to do.
     */
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795

    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
    if (oPtr == NULL) {
	return TCL_ERROR;
    }
    if (!isInstanceDeleteMethod && !oPtr->classPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"attempt to misuse API", -1));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }

    for (i = 1; i < objc; i++) {
	/*
	 * Delete the method structure from the appropriate hash table.







|







1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793

    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
    if (oPtr == NULL) {
	return TCL_ERROR;
    }
    if (!isInstanceDeleteMethod && !oPtr->classPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"attempt to misuse API", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }

    for (i = 1; i < objc; i++) {
	/*
	 * Delete the method structure from the appropriate hash table.
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
    if (oPtr == NULL) {
	return TCL_ERROR;
    }
    clsPtr = oPtr->classPtr;
    if (!isInstanceExport && !clsPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"attempt to misuse API", -1));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }

    for (i = 1; i < objc; i++) {
	/*
	 * Exporting is done by adding the PUBLIC_METHOD flag to the method







|







1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
    if (oPtr == NULL) {
	return TCL_ERROR;
    }
    clsPtr = oPtr->classPtr;
    if (!isInstanceExport && !clsPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"attempt to misuse API", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }

    for (i = 1; i < objc; i++) {
	/*
	 * Exporting is done by adding the PUBLIC_METHOD flag to the method
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012

    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
    if (oPtr == NULL) {
	return TCL_ERROR;
    }
    if (!isInstanceForward && !oPtr->classPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"attempt to misuse API", -1));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }
    isPublic = Tcl_StringMatch(TclGetString(objv[1]), PUBLIC_PATTERN)
	    ? PUBLIC_METHOD : 0;
    if (IsPrivateDefine(interp)) {
	isPublic = TRUE_PRIVATE_METHOD;







|







1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010

    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
    if (oPtr == NULL) {
	return TCL_ERROR;
    }
    if (!isInstanceForward && !oPtr->classPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"attempt to misuse API", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }
    isPublic = Tcl_StringMatch(TclGetString(objv[1]), PUBLIC_PATTERN)
	    ? PUBLIC_METHOD : 0;
    if (IsPrivateDefine(interp)) {
	isPublic = TRUE_PRIVATE_METHOD;
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090

    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
    if (oPtr == NULL) {
	return TCL_ERROR;
    }
    if (!isInstanceMethod && !oPtr->classPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"attempt to misuse API", -1));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }
    if (objc == 5) {
	if (Tcl_GetIndexFromObj(interp, objv[2], exportModes, "export flag",
		0, &exportMode) != TCL_OK) {
	    return TCL_ERROR;







|







2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088

    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
    if (oPtr == NULL) {
	return TCL_ERROR;
    }
    if (!isInstanceMethod && !oPtr->classPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"attempt to misuse API", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }
    if (objc == 5) {
	if (Tcl_GetIndexFromObj(interp, objv[2], exportModes, "export flag",
		0, &exportMode) != TCL_OK) {
	    return TCL_ERROR;
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169

    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
    if (oPtr == NULL) {
	return TCL_ERROR;
    }
    if (!isInstanceRenameMethod && !oPtr->classPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"attempt to misuse API", -1));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }

    /*
     * Delete the method entry from the appropriate hash table, and transfer
     * the thing it points to to its new entry. To do this, we first need to







|







2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167

    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
    if (oPtr == NULL) {
	return TCL_ERROR;
    }
    if (!isInstanceRenameMethod && !oPtr->classPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"attempt to misuse API", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }

    /*
     * Delete the method entry from the appropriate hash table, and transfer
     * the thing it points to to its new entry. To do this, we first need to
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
    if (oPtr == NULL) {
	return TCL_ERROR;
    }
    clsPtr = oPtr->classPtr;
    if (!isInstanceUnexport && !clsPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"attempt to misuse API", -1));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }

    for (i = 1; i < objc; i++) {
	/*
	 * Unexporting is done by removing the PUBLIC_METHOD flag from the







|







2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
    if (oPtr == NULL) {
	return TCL_ERROR;
    }
    clsPtr = oPtr->classPtr;
    if (!isInstanceUnexport && !clsPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"attempt to misuse API", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }

    for (i = 1; i < objc; i++) {
	/*
	 * Unexporting is done by removing the PUBLIC_METHOD flag from the
2542
2543
2544
2545
2546
2547
2548
2549

2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
	if (mixins[i] == NULL) {
	    i--;
	    goto freeAndError;
	}
	(void) Tcl_CreateHashEntry(&uniqueCheck, (void *) mixins[i], &isNew);
	if (!isNew) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "class should only be a direct mixin once", -1));

	    Tcl_SetErrorCode(interp, "TCL", "OO", "REPETITIOUS", (char *)NULL);
	    goto freeAndError;
	}
	if (TclOOIsReachable(clsPtr, mixins[i])) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "may not mix a class into itself", -1));
	    Tcl_SetErrorCode(interp, "TCL", "OO", "SELF_MIXIN", (char *)NULL);
	    goto freeAndError;
	}
    }

    TclOOClassSetMixins(interp, clsPtr, mixinc, mixins);
    Tcl_DeleteHashTable(&uniqueCheck);







|
>





|







2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
	if (mixins[i] == NULL) {
	    i--;
	    goto freeAndError;
	}
	(void) Tcl_CreateHashEntry(&uniqueCheck, (void *) mixins[i], &isNew);
	if (!isNew) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "class should only be a direct mixin once",
		    TCL_AUTO_LENGTH));
	    Tcl_SetErrorCode(interp, "TCL", "OO", "REPETITIOUS", (char *)NULL);
	    goto freeAndError;
	}
	if (TclOOIsReachable(clsPtr, mixins[i])) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "may not mix a class into itself", TCL_AUTO_LENGTH));
	    Tcl_SetErrorCode(interp, "TCL", "OO", "SELF_MIXIN", (char *)NULL);
	    goto freeAndError;
	}
    }

    TclOOClassSetMixins(interp, clsPtr, mixinc, mixins);
    Tcl_DeleteHashTable(&uniqueCheck);
2632
2633
2634
2635
2636
2637
2638
2639

2640
2641
2642
2643
2644
2645
2646
	return TCL_ERROR;
    }
    objv += Tcl_ObjectContextSkippedArgs(context);

    Foundation *fPtr = clsPtr->thisPtr->fPtr;
    if (clsPtr == fPtr->objectCls) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"may not modify the superclass of the root object", -1));

	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    } else if (TclListObjGetElements(interp, objv[0], &superc,
	    &superv) != TCL_OK) {
	return TCL_ERROR;
    }








|
>







2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
	return TCL_ERROR;
    }
    objv += Tcl_ObjectContextSkippedArgs(context);

    Foundation *fPtr = clsPtr->thisPtr->fPtr;
    if (clsPtr == fPtr->objectCls) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"may not modify the superclass of the root object",
		TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    } else if (TclListObjGetElements(interp, objv[0], &superc,
	    &superv) != TCL_OK) {
	return TCL_ERROR;
    }

2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687

2688
2689
2690
2691
2692
2693
2694
	    if (superclasses[i] == NULL) {
		goto failedAfterAlloc;
	    }
	    for (j = 0; j < i; j++) {
		if (superclasses[j] == superclasses[i]) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "class should only be a direct superclass once",
			    -1));
		    Tcl_SetErrorCode(interp, "TCL", "OO", "REPETITIOUS",(char *)NULL);
		    goto failedAfterAlloc;
		}
	    }
	    if (TclOOIsReachable(clsPtr, superclasses[i])) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"attempt to form circular dependency graph", -1));

		Tcl_SetErrorCode(interp, "TCL", "OO", "CIRCULARITY", (char *)NULL);
	    failedAfterAlloc:
		for (; i-- > 0 ;) {
		    TclOODecrRefCount(superclasses[i]->thisPtr);
		}
		Tcl_Free(superclasses);
		return TCL_ERROR;







|






|
>







2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
	    if (superclasses[i] == NULL) {
		goto failedAfterAlloc;
	    }
	    for (j = 0; j < i; j++) {
		if (superclasses[j] == superclasses[i]) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "class should only be a direct superclass once",
			    TCL_AUTO_LENGTH));
		    Tcl_SetErrorCode(interp, "TCL", "OO", "REPETITIOUS",(char *)NULL);
		    goto failedAfterAlloc;
		}
	    }
	    if (TclOOIsReachable(clsPtr, superclasses[i])) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"attempt to form circular dependency graph",
			TCL_AUTO_LENGTH));
		Tcl_SetErrorCode(interp, "TCL", "OO", "CIRCULARITY", (char *)NULL);
	    failedAfterAlloc:
		for (; i-- > 0 ;) {
		    TclOODecrRefCount(superclasses[i]->thisPtr);
		}
		Tcl_Free(superclasses);
		return TCL_ERROR;
2978
2979
2980
2981
2982
2983
2984
2985

2986
2987
2988
2989
2990
2991
2992
		"may only mix in classes");
	if (mixins[i] == NULL) {
	    goto freeAndError;
	}
	(void) Tcl_CreateHashEntry(&uniqueCheck, (void *) mixins[i], &isNew);
	if (!isNew) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "class should only be a direct mixin once", -1));

	    Tcl_SetErrorCode(interp, "TCL", "OO", "REPETITIOUS", (char *)NULL);
	    goto freeAndError;
	}
    }

    TclOOObjectSetMixins(oPtr, mixinc, mixins);
    TclStackFree(interp, mixins);







|
>







2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
		"may only mix in classes");
	if (mixins[i] == NULL) {
	    goto freeAndError;
	}
	(void) Tcl_CreateHashEntry(&uniqueCheck, (void *) mixins[i], &isNew);
	if (!isNew) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "class should only be a direct mixin once",
		    TCL_AUTO_LENGTH));
	    Tcl_SetErrorCode(interp, "TCL", "OO", "REPETITIOUS", (char *)NULL);
	    goto freeAndError;
	}
    }

    TclOOObjectSetMixins(oPtr, mixinc, mixins);
    TclStackFree(interp, mixins);
Changes to generic/tclOOInfo.c.
308
309
310
311
312
313
314
315

316
317
318
319
320
321
322
	    "unknown method \"%s\"", TclGetString(objv[2])));
    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
	    TclGetString(objv[2]), (char *)NULL);
    return TCL_ERROR;

  wrongType:
    Tcl_SetObjResult(interp, Tcl_NewStringObj(
	    "definition not available for this kind of method", -1));

    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
	    TclGetString(objv[2]), (char *)NULL);
    return TCL_ERROR;
}

/*
 * ----------------------------------------------------------------------







|
>







308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
	    "unknown method \"%s\"", TclGetString(objv[2])));
    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
	    TclGetString(objv[2]), (char *)NULL);
    return TCL_ERROR;

  wrongType:
    Tcl_SetObjResult(interp, Tcl_NewStringObj(
	    "definition not available for this kind of method",
	    TCL_AUTO_LENGTH));
    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
	    TclGetString(objv[2]), (char *)NULL);
    return TCL_ERROR;
}

/*
 * ----------------------------------------------------------------------
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
	    TclGetString(objv[2]), (char *)NULL);
    return TCL_ERROR;

  wrongType:
    Tcl_SetObjResult(interp, Tcl_NewStringObj(
	    "prefix argument list not available for this kind of method",
	    -1));
    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
	    TclGetString(objv[2]), (char *)NULL);
    return TCL_ERROR;
}

/*
 * ----------------------------------------------------------------------







|







418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
	    TclGetString(objv[2]), (char *)NULL);
    return TCL_ERROR;

  wrongType:
    Tcl_SetObjResult(interp, Tcl_NewStringObj(
	    "prefix argument list not available for this kind of method",
	    TCL_AUTO_LENGTH));
    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
	    TclGetString(objv[2]), (char *)NULL);
    return TCL_ERROR;
}

/*
 * ----------------------------------------------------------------------
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583

584





585
586
587
588
589
590
591
static int
InfoObjectMethodsCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    Tcl_Size objc,
    Tcl_Obj *const objv[])
{
    Object *oPtr;
    int flag = PUBLIC_METHOD, recurse = 0, scope = -1;
    FOREACH_HASH_DECLS;
    Tcl_Obj *namePtr, *resultObj;
    Method *mPtr;
    static const char *const options[] = {
	"-all", "-localprivate", "-private", "-scope", NULL
    };
    enum Options {
	OPT_ALL, OPT_LOCALPRIVATE, OPT_PRIVATE, OPT_SCOPE
    } idx;
    static const char *const scopes[] = {
	"private", "public", "unexported"
    };
    enum Scopes {
	SCOPE_PRIVATE, SCOPE_PUBLIC, SCOPE_UNEXPORTED,
	SCOPE_LOCALPRIVATE

    };






    /*
     * Parse arguments.
     */

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "objName ?-option value ...?");







<
<
<
<
<











|
>

>
>
>
>
>







561
562
563
564
565
566
567





568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
static int
InfoObjectMethodsCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    Tcl_Size objc,
    Tcl_Obj *const objv[])
{





    static const char *const options[] = {
	"-all", "-localprivate", "-private", "-scope", NULL
    };
    enum Options {
	OPT_ALL, OPT_LOCALPRIVATE, OPT_PRIVATE, OPT_SCOPE
    } idx;
    static const char *const scopes[] = {
	"private", "public", "unexported"
    };
    enum Scopes {
	SCOPE_PRIVATE, SCOPE_PUBLIC, SCOPE_UNEXPORTED,
	SCOPE_LOCALPRIVATE,
	SCOPE_DEFAULT = -1
    };
    Object *oPtr;
    int flag = PUBLIC_METHOD, recurse = 0, scope = SCOPE_DEFAULT;
    FOREACH_HASH_DECLS;
    Tcl_Obj *namePtr, *resultObj;
    Method *mPtr;

    /*
     * Parse arguments.
     */

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "objName ?-option value ...?");
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
			&scope) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    }
	}
    }
    if (scope != -1) {
	recurse = 0;
	switch (scope) {
	case SCOPE_PRIVATE:
	    flag = TRUE_PRIVATE_METHOD;
	    break;
	case SCOPE_PUBLIC:
	    flag = PUBLIC_METHOD;







|







627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
			&scope) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    }
	}
    }
    if (scope != SCOPE_DEFAULT) {
	recurse = 0;
	switch (scope) {
	case SCOPE_PRIVATE:
	    flag = TRUE_PRIVATE_METHOD;
	    break;
	case SCOPE_PUBLIC:
	    flag = PUBLIC_METHOD;
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
    if (recurse) {
	const char **names;
	int i, numNames = TclOOGetSortedMethodList(oPtr, NULL, NULL, flag,
		&names);

	for (i=0 ; i<numNames ; i++) {
	    Tcl_ListObjAppendElement(NULL, resultObj,
		    Tcl_NewStringObj(names[i], -1));
	}
	if (numNames > 0) {
	    Tcl_Free((void *) names);
	}
    } else if (oPtr->methodsPtr) {
	if (scope == -1) {
	    /*
	     * Handle legacy-mode matching. [Bug 36e5517a6850]
	     */
	    int scopeFilter = flag | TRUE_PRIVATE_METHOD;

	    FOREACH_HASH(namePtr, mPtr, oPtr->methodsPtr) {
		if (mPtr->type2Ptr && (mPtr->flags & scopeFilter) == flag) {







|





|







657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
    if (recurse) {
	const char **names;
	int i, numNames = TclOOGetSortedMethodList(oPtr, NULL, NULL, flag,
		&names);

	for (i=0 ; i<numNames ; i++) {
	    Tcl_ListObjAppendElement(NULL, resultObj,
		    Tcl_NewStringObj(names[i], TCL_AUTO_LENGTH));
	}
	if (numNames > 0) {
	    Tcl_Free((void *) names);
	}
    } else if (oPtr->methodsPtr) {
	if (scope == SCOPE_DEFAULT) {
	    /*
	     * Handle legacy-mode matching. [Bug 36e5517a6850]
	     */
	    int scopeFilter = flag | TRUE_PRIVATE_METHOD;

	    FOREACH_HASH(namePtr, mPtr, oPtr->methodsPtr) {
		if (mPtr->type2Ptr && (mPtr->flags & scopeFilter) == flag) {
732
733
734
735
736
737
738
739

740
741
742
743
744
745
746
	 * Special entry for visibility control: pretend the method doesnt
	 * exist.
	 */

	goto unknownMethod;
    }

    Tcl_SetObjResult(interp, Tcl_NewStringObj(mPtr->type2Ptr->name, -1));

    return TCL_OK;

  unknownMethod:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "unknown method \"%s\"", TclGetString(objv[2])));
    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
	    TclGetString(objv[2]), (char *)NULL);







|
>







734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
	 * Special entry for visibility control: pretend the method doesnt
	 * exist.
	 */

	goto unknownMethod;
    }

    Tcl_SetObjResult(interp,
	    Tcl_NewStringObj(mPtr->type2Ptr->name, TCL_AUTO_LENGTH));
    return TCL_OK;

  unknownMethod:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "unknown method \"%s\"", TclGetString(objv[2])));
    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
	    TclGetString(objv[2]), (char *)NULL);
1006
1007
1008
1009
1010
1011
1012
1013

1014
1015
1016
1017
1018
1019
1020
    }
    if (clsPtr->constructorPtr == NULL) {
	return TCL_OK;
    }
    procPtr = TclOOGetProcFromMethod(clsPtr->constructorPtr);
    if (procPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"definition not available for this kind of method", -1));

	Tcl_SetErrorCode(interp, "TCL", "OO", "METHOD_TYPE", (char *)NULL);
	return TCL_ERROR;
    }

    TclNewObj(resultObjs[0]);
    for (localPtr=procPtr->firstLocalPtr; localPtr!=NULL;
	    localPtr=localPtr->nextPtr) {







|
>







1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
    }
    if (clsPtr->constructorPtr == NULL) {
	return TCL_OK;
    }
    procPtr = TclOOGetProcFromMethod(clsPtr->constructorPtr);
    if (procPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"definition not available for this kind of method",
		TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "METHOD_TYPE", (char *)NULL);
	return TCL_ERROR;
    }

    TclNewObj(resultObjs[0]);
    for (localPtr=procPtr->firstLocalPtr; localPtr!=NULL;
	    localPtr=localPtr->nextPtr) {
1072
1073
1074
1075
1076
1077
1078
1079

1080
1081
1082
1083
1084
1085
1086
	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
		TclGetString(objv[2]), (char *)NULL);
	return TCL_ERROR;
    }
    procPtr = TclOOGetProcFromMethod((Method *) Tcl_GetHashValue(hPtr));
    if (procPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"definition not available for this kind of method", -1));

	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
		TclGetString(objv[2]), (char *)NULL);
	return TCL_ERROR;
    }

    TclNewObj(resultObjs[0]);
    for (localPtr=procPtr->firstLocalPtr; localPtr!=NULL;







|
>







1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
		TclGetString(objv[2]), (char *)NULL);
	return TCL_ERROR;
    }
    procPtr = TclOOGetProcFromMethod((Method *) Tcl_GetHashValue(hPtr));
    if (procPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"definition not available for this kind of method",
		TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
		TclGetString(objv[2]), (char *)NULL);
	return TCL_ERROR;
    }

    TclNewObj(resultObjs[0]);
    for (localPtr=procPtr->firstLocalPtr; localPtr!=NULL;
1182
1183
1184
1185
1186
1187
1188
1189

1190
1191
1192
1193
1194
1195
1196

    if (clsPtr->destructorPtr == NULL) {
	return TCL_OK;
    }
    procPtr = TclOOGetProcFromMethod(clsPtr->destructorPtr);
    if (procPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"definition not available for this kind of method", -1));

	Tcl_SetErrorCode(interp, "TCL", "OO", "METHOD_TYPE", (char *)NULL);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, TclOOGetMethodBody(clsPtr->destructorPtr));
    return TCL_OK;
}







|
>







1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202

    if (clsPtr->destructorPtr == NULL) {
	return TCL_OK;
    }
    procPtr = TclOOGetProcFromMethod(clsPtr->destructorPtr);
    if (procPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"definition not available for this kind of method",
		TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "METHOD_TYPE", (char *)NULL);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, TclOOGetMethodBody(clsPtr->destructorPtr));
    return TCL_OK;
}
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
		TclGetString(objv[2]), (char *)NULL);
	return TCL_ERROR;
    }
    prefixObj = TclOOGetFwdFromMethod((Method *) Tcl_GetHashValue(hPtr));
    if (prefixObj == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"prefix argument list not available for this kind of method",
		-1));
	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
		TclGetString(objv[2]), (char *)NULL);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, prefixObj);
    return TCL_OK;







|







1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
		TclGetString(objv[2]), (char *)NULL);
	return TCL_ERROR;
    }
    prefixObj = TclOOGetFwdFromMethod((Method *) Tcl_GetHashValue(hPtr));
    if (prefixObj == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"prefix argument list not available for this kind of method",
		TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
		TclGetString(objv[2]), (char *)NULL);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, prefixObj);
    return TCL_OK;
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366

1367




1368
1369
1370
1371
1372
1373
1374
static int
InfoClassMethodsCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    Tcl_Size objc,
    Tcl_Obj *const objv[])
{
    int flag = PUBLIC_METHOD, recurse = 0, scope = -1;
    Tcl_Obj *namePtr, *resultObj;
    Method *mPtr;
    Class *clsPtr;
    static const char *const options[] = {
	"-all", "-localprivate", "-private", "-scope", NULL
    };
    enum Options {
	OPT_ALL, OPT_LOCALPRIVATE, OPT_PRIVATE, OPT_SCOPE
    } idx;
    static const char *const scopes[] = {
	"private", "public", "unexported"
    };
    enum Scopes {
	SCOPE_PRIVATE, SCOPE_PUBLIC, SCOPE_UNEXPORTED

    };





    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "className ?-option value ...?");
	return TCL_ERROR;
    }
    clsPtr = TclOOGetClassFromObj(interp, objv[1]);
    if (clsPtr == NULL) {







<
<
<
<










|
>

>
>
>
>







1351
1352
1353
1354
1355
1356
1357




1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
static int
InfoClassMethodsCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    Tcl_Size objc,
    Tcl_Obj *const objv[])
{




    static const char *const options[] = {
	"-all", "-localprivate", "-private", "-scope", NULL
    };
    enum Options {
	OPT_ALL, OPT_LOCALPRIVATE, OPT_PRIVATE, OPT_SCOPE
    } idx;
    static const char *const scopes[] = {
	"private", "public", "unexported"
    };
    enum Scopes {
	SCOPE_PRIVATE, SCOPE_PUBLIC, SCOPE_UNEXPORTED,
	SCOPE_DEFAULT = -1
    };
    int flag = PUBLIC_METHOD, recurse = 0, scope = SCOPE_DEFAULT;
    Tcl_Obj *namePtr, *resultObj;
    Method *mPtr;
    Class *clsPtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "className ?-option value ...?");
	return TCL_ERROR;
    }
    clsPtr = TclOOGetClassFromObj(interp, objv[1]);
    if (clsPtr == NULL) {
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
			&scope) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    }
	}
    }
    if (scope != -1) {
	recurse = 0;
	switch (scope) {
	case SCOPE_PRIVATE:
	    flag = TRUE_PRIVATE_METHOD;
	    break;
	case SCOPE_PUBLIC:
	    flag = PUBLIC_METHOD;







|







1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
			&scope) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    }
	}
    }
    if (scope != SCOPE_DEFAULT) {
	recurse = 0;
	switch (scope) {
	case SCOPE_PRIVATE:
	    flag = TRUE_PRIVATE_METHOD;
	    break;
	case SCOPE_PUBLIC:
	    flag = PUBLIC_METHOD;
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
    TclNewObj(resultObj);
    if (recurse) {
	const char **names;
	Tcl_Size i, numNames = TclOOGetSortedClassMethodList(clsPtr, flag, &names);

	for (i=0 ; i<numNames ; i++) {
	    Tcl_ListObjAppendElement(NULL, resultObj,
		    Tcl_NewStringObj(names[i], -1));
	}
	if (numNames > 0) {
	    Tcl_Free((void *) names);
	}
    } else {
	FOREACH_HASH_DECLS;

	if (scope == -1) {
	    /*
	     * Handle legacy-mode matching. [Bug 36e5517a6850]
	     */
	    int scopeFilter = flag | TRUE_PRIVATE_METHOD;

	    FOREACH_HASH(namePtr, mPtr, &clsPtr->classMethods) {
		if (mPtr->type2Ptr && (mPtr->flags & scopeFilter) == flag) {







|







|







1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
    TclNewObj(resultObj);
    if (recurse) {
	const char **names;
	Tcl_Size i, numNames = TclOOGetSortedClassMethodList(clsPtr, flag, &names);

	for (i=0 ; i<numNames ; i++) {
	    Tcl_ListObjAppendElement(NULL, resultObj,
		    Tcl_NewStringObj(names[i], TCL_AUTO_LENGTH));
	}
	if (numNames > 0) {
	    Tcl_Free((void *) names);
	}
    } else {
	FOREACH_HASH_DECLS;

	if (scope == SCOPE_DEFAULT) {
	    /*
	     * Handle legacy-mode matching. [Bug 36e5517a6850]
	     */
	    int scopeFilter = flag | TRUE_PRIVATE_METHOD;

	    FOREACH_HASH(namePtr, mPtr, &clsPtr->classMethods) {
		if (mPtr->type2Ptr && (mPtr->flags & scopeFilter) == flag) {
1500
1501
1502
1503
1504
1505
1506
1507

1508
1509
1510
1511
1512
1513
1514
	/*
	 * Special entry for visibility control: pretend the method doesnt
	 * exist.
	 */

	goto unknownMethod;
    }
    Tcl_SetObjResult(interp, Tcl_NewStringObj(mPtr->type2Ptr->name, -1));

    return TCL_OK;

  unknownMethod:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "unknown method \"%s\"", TclGetString(objv[2])));
    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
	    TclGetString(objv[2]), (char *)NULL);







|
>







1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
	/*
	 * Special entry for visibility control: pretend the method doesnt
	 * exist.
	 */

	goto unknownMethod;
    }
    Tcl_SetObjResult(interp,
	    Tcl_NewStringObj(mPtr->type2Ptr->name, TCL_AUTO_LENGTH));
    return TCL_OK;

  unknownMethod:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "unknown method \"%s\"", TclGetString(objv[2])));
    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
	    TclGetString(objv[2]), (char *)NULL);
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
     * Get the call context and render its call chain.
     */

    contextPtr = TclOOGetCallContext(oPtr, objv[2], PUBLIC_METHOD, NULL, NULL,
	    NULL);
    if (contextPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"cannot construct any call chain", -1));
	Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_CALL_CHAIN");
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp,
	    TclOORenderCallChain(interp, contextPtr->callPtr));
    TclOODeleteContext(contextPtr);
    return TCL_OK;







|







1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
     * Get the call context and render its call chain.
     */

    contextPtr = TclOOGetCallContext(oPtr, objv[2], PUBLIC_METHOD, NULL, NULL,
	    NULL);
    if (contextPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"cannot construct any call chain", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_CALL_CHAIN");
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp,
	    TclOORenderCallChain(interp, contextPtr->callPtr));
    TclOODeleteContext(contextPtr);
    return TCL_OK;
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
    /*
     * Get an render the stereotypical call chain.
     */

    callPtr = TclOOGetStereotypeCallChain(clsPtr, objv[2], PUBLIC_METHOD);
    if (callPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"cannot construct any call chain", -1));
	Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_CALL_CHAIN");
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, TclOORenderCallChain(interp, callPtr));
    TclOODeleteChain(callPtr);
    return TCL_OK;
}







|







1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
    /*
     * Get an render the stereotypical call chain.
     */

    callPtr = TclOOGetStereotypeCallChain(clsPtr, objv[2], PUBLIC_METHOD);
    if (callPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"cannot construct any call chain", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_CALL_CHAIN");
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, TclOORenderCallChain(interp, callPtr));
    TclOODeleteChain(callPtr);
    return TCL_OK;
}
Changes to generic/tclOOInt.h.
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685

686




687
688

689
690
691
692
693
694
695
696

#define FOREACH_STRUCT(var,ary) \
    if (i=0, (ary).num>0) for(; var=&((ary).list[i]), i<(ary).num; i++)

/*
 * Convenience macros for iterating through hash tables. FOREACH_HASH_DECLS
 * sets up the declarations needed for the main macro, FOREACH_HASH, which
 * does the actual iteration. FOREACH_HASH_VALUE is a restricted version that
 * only iterates over values.
 * REQUIRES DECLARATION: FOREACH_HASH_DECLS;
 */

#define FOREACH_HASH_DECLS \
    Tcl_HashEntry *hPtr;Tcl_HashSearch search
#define FOREACH_HASH(key,val,tablePtr) \
    for(hPtr=Tcl_FirstHashEntry((tablePtr),&search); hPtr!=NULL ? \
	    (*(void **)&(key)=Tcl_GetHashKey((tablePtr),hPtr),\

	    *(void **)&(val)=Tcl_GetHashValue(hPtr),1):0; hPtr=Tcl_NextHashEntry(&search))




#define FOREACH_HASH_VALUE(val,tablePtr) \
    for(hPtr=Tcl_FirstHashEntry((tablePtr),&search); hPtr!=NULL ? \

	    (*(void **)&(val)=Tcl_GetHashValue(hPtr),1):0;hPtr=Tcl_NextHashEntry(&search))

/*
 * Convenience macro for duplicating a list. Needs no external declaration,
 * but all arguments are used multiple times and so must have no side effects.
 */

#undef DUPLICATE /* prevent possible conflict with definition in WINAPI nb30.h */







|
|





|
|
|
>
|
>
>
>
>
|
|
>
|







669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702

#define FOREACH_STRUCT(var,ary) \
    if (i=0, (ary).num>0) for(; var=&((ary).list[i]), i<(ary).num; i++)

/*
 * Convenience macros for iterating through hash tables. FOREACH_HASH_DECLS
 * sets up the declarations needed for the main macro, FOREACH_HASH, which
 * does the actual iteration. FOREACH_HASH_KEY and FOREACH_HASH_VALUE are
 * restricted versions that only iterate over keys or values respectively.
 * REQUIRES DECLARATION: FOREACH_HASH_DECLS;
 */

#define FOREACH_HASH_DECLS \
    Tcl_HashEntry *hPtr;Tcl_HashSearch search
#define FOREACH_HASH(key, val, tablePtr) \
    for(hPtr = Tcl_FirstHashEntry((tablePtr), &search); hPtr != NULL ? \
	    (*(void **)&(key) = Tcl_GetHashKey((tablePtr), hPtr), \
	    *(void **)&(val) = Tcl_GetHashValue(hPtr), 1) : 0; \
	    hPtr = Tcl_NextHashEntry(&search))
#define FOREACH_HASH_KEY(key, tablePtr) \
    for(hPtr = Tcl_FirstHashEntry((tablePtr), &search); hPtr != NULL ? \
	    (*(void **)&(key) = Tcl_GetHashKey((tablePtr), hPtr), 1) : 0; \
	    hPtr = Tcl_NextHashEntry(&search))
#define FOREACH_HASH_VALUE(val, tablePtr) \
    for(hPtr = Tcl_FirstHashEntry((tablePtr), &search); hPtr != NULL ? \
	    (*(void **)&(val) = Tcl_GetHashValue(hPtr), 1) : 0; \
	    hPtr = Tcl_NextHashEntry(&search))

/*
 * Convenience macro for duplicating a list. Needs no external declaration,
 * but all arguments are used multiple times and so must have no side effects.
 */

#undef DUPLICATE /* prevent possible conflict with definition in WINAPI nb30.h */
Changes to generic/tclOOMethod.c.
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
void
TclOONewBasicMethod(
    Class *clsPtr,		/* Class to attach the method to. */
    const DeclaredClassMethod *dcm)
				/* Name of the method, whether it is public,
				 * and the function to implement it. */
{
    Tcl_Obj *namePtr = Tcl_NewStringObj(dcm->name, -1);

    TclNewMethod((Tcl_Class) clsPtr, namePtr,
	    (dcm->isPublic ? PUBLIC_METHOD : 0), &dcm->definition, NULL);
    Tcl_BounceRefCount(namePtr);
}

/*







|







391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
void
TclOONewBasicMethod(
    Class *clsPtr,		/* Class to attach the method to. */
    const DeclaredClassMethod *dcm)
				/* Name of the method, whether it is public,
				 * and the function to implement it. */
{
    Tcl_Obj *namePtr = Tcl_NewStringObj(dcm->name, TCL_AUTO_LENGTH);

    TclNewMethod((Tcl_Class) clsPtr, namePtr,
	    (dcm->isPublic ? PUBLIC_METHOD : 0), &dcm->definition, NULL);
    Tcl_BounceRefCount(namePtr);
}

/*
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
    for (localPtr=pmPtr->procPtr->firstLocalPtr; localPtr!=NULL;
	    localPtr=localPtr->nextPtr) {
	if (TclIsVarArgument(localPtr)) {
	    Tcl_Obj *argObj;

	    TclNewObj(argObj);
	    Tcl_ListObjAppendElement(NULL, argObj,
		    Tcl_NewStringObj(localPtr->name, -1));
	    if (localPtr->defValuePtr != NULL) {
		Tcl_ListObjAppendElement(NULL, argObj, localPtr->defValuePtr);
	    }
	    Tcl_ListObjAppendElement(NULL, argsObj, argObj);
	}
    }








|







1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
    for (localPtr=pmPtr->procPtr->firstLocalPtr; localPtr!=NULL;
	    localPtr=localPtr->nextPtr) {
	if (TclIsVarArgument(localPtr)) {
	    Tcl_Obj *argObj;

	    TclNewObj(argObj);
	    Tcl_ListObjAppendElement(NULL, argObj,
		    Tcl_NewStringObj(localPtr->name, TCL_AUTO_LENGTH));
	    if (localPtr->defValuePtr != NULL) {
		Tcl_ListObjAppendElement(NULL, argObj, localPtr->defValuePtr);
	    }
	    Tcl_ListObjAppendElement(NULL, argsObj, argObj);
	}
    }

1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
    ForwardMethod *fmPtr;

    if (TclListObjLength(interp, prefixObj, &prefixLen) != TCL_OK) {
	return NULL;
    }
    if (prefixLen < 1) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"method forward prefix must be non-empty", -1));
	Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_FORWARD", (char *)NULL);
	return NULL;
    }

    fmPtr = (ForwardMethod *) Tcl_Alloc(sizeof(ForwardMethod));
    fmPtr->prefixObj = prefixObj;
    Tcl_IncrRefCount(prefixObj);







|







1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
    ForwardMethod *fmPtr;

    if (TclListObjLength(interp, prefixObj, &prefixLen) != TCL_OK) {
	return NULL;
    }
    if (prefixLen < 1) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"method forward prefix must be non-empty", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_FORWARD", (char *)NULL);
	return NULL;
    }

    fmPtr = (ForwardMethod *) Tcl_Alloc(sizeof(ForwardMethod));
    fmPtr->prefixObj = prefixObj;
    Tcl_IncrRefCount(prefixObj);
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
    ForwardMethod *fmPtr;

    if (TclListObjLength(interp, prefixObj, &prefixLen) != TCL_OK) {
	return NULL;
    }
    if (prefixLen < 1) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"method forward prefix must be non-empty", -1));
	Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_FORWARD", (char *)NULL);
	return NULL;
    }

    fmPtr = (ForwardMethod *) Tcl_Alloc(sizeof(ForwardMethod));
    fmPtr->prefixObj = prefixObj;
    Tcl_IncrRefCount(prefixObj);







|







1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
    ForwardMethod *fmPtr;

    if (TclListObjLength(interp, prefixObj, &prefixLen) != TCL_OK) {
	return NULL;
    }
    if (prefixLen < 1) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"method forward prefix must be non-empty", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_FORWARD", (char *)NULL);
	return NULL;
    }

    fmPtr = (ForwardMethod *) Tcl_Alloc(sizeof(ForwardMethod));
    fmPtr->prefixObj = prefixObj;
    Tcl_IncrRefCount(prefixObj);
Changes to generic/tclOOProp.c.
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
    Tcl_IncrRefCount(args[0]);
    Tcl_IncrRefCount(args[1]);
    code = TclOOPrivateObjectCmd(oPtr, interp, 2, args);
    Tcl_DecrRefCount(args[0]);
    Tcl_DecrRefCount(args[1]);
    switch (code) {
    case TCL_BREAK:
        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"property getter for %s did a break", propName));
	return TCL_ERROR;
    case TCL_CONTINUE:
        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"property getter for %s did a continue", propName));
	return TCL_ERROR;
    default:
	return code;
    }
}








|



|







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
    Tcl_IncrRefCount(args[0]);
    Tcl_IncrRefCount(args[1]);
    code = TclOOPrivateObjectCmd(oPtr, interp, 2, args);
    Tcl_DecrRefCount(args[0]);
    Tcl_DecrRefCount(args[1]);
    switch (code) {
    case TCL_BREAK:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"property getter for %s did a break", propName));
	return TCL_ERROR;
    case TCL_CONTINUE:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"property getter for %s did a continue", propName));
	return TCL_ERROR;
    default:
	return code;
    }
}

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
    Tcl_IncrRefCount(args[2]);
    code = TclOOPrivateObjectCmd(oPtr, interp, 3, args);
    Tcl_DecrRefCount(args[0]);
    Tcl_DecrRefCount(args[1]);
    Tcl_DecrRefCount(args[2]);
    switch (code) {
    case TCL_BREAK:
        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"property setter for %s did a break", propName));
	return TCL_ERROR;
    case TCL_CONTINUE:
        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"property setter for %s did a continue", propName));
	return TCL_ERROR;
    default:
	return code;
    }
}








|



|







140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
    Tcl_IncrRefCount(args[2]);
    code = TclOOPrivateObjectCmd(oPtr, interp, 3, args);
    Tcl_DecrRefCount(args[0]);
    Tcl_DecrRefCount(args[1]);
    Tcl_DecrRefCount(args[2]);
    switch (code) {
    case TCL_BREAK:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"property setter for %s did a break", propName));
	return TCL_ERROR;
    case TCL_CONTINUE:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"property setter for %s did a continue", propName));
	return TCL_ERROR;
    default:
	return code;
    }
}

635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
    int *allocated)		/* Address of variable to set to true if a
				 * Tcl_Obj was allocated and may be safely
				 * modified by the caller. */
{
    Tcl_HashTable hashTable;
    FOREACH_HASH_DECLS;
    Tcl_Obj *propName, *result;
    void *dummy;

    /*
     * Look in the cache.
     */

    if (clsPtr->properties.epoch == clsPtr->thisPtr->fPtr->epoch) {
	if (writable) {







<







635
636
637
638
639
640
641

642
643
644
645
646
647
648
    int *allocated)		/* Address of variable to set to true if a
				 * Tcl_Obj was allocated and may be safely
				 * modified by the caller. */
{
    Tcl_HashTable hashTable;
    FOREACH_HASH_DECLS;
    Tcl_Obj *propName, *result;


    /*
     * Look in the cache.
     */

    if (clsPtr->properties.epoch == clsPtr->thisPtr->fPtr->epoch) {
	if (writable) {
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
     * Gather the information. Unsorted! (Caller will sort.)
     */

    *allocated = 1;
    Tcl_InitObjHashTable(&hashTable);
    FindClassProps(clsPtr, writable, &hashTable);
    TclNewObj(result);
    FOREACH_HASH(propName, dummy, &hashTable) {
	Tcl_ListObjAppendElement(NULL, result, propName);
    }
    Tcl_DeleteHashTable(&hashTable);

    /*
     * Cache the information. Also purges the cache.
     */







|







662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
     * Gather the information. Unsorted! (Caller will sort.)
     */

    *allocated = 1;
    Tcl_InitObjHashTable(&hashTable);
    FindClassProps(clsPtr, writable, &hashTable);
    TclNewObj(result);
    FOREACH_HASH_KEY(propName, &hashTable) {
	Tcl_ListObjAppendElement(NULL, result, propName);
    }
    Tcl_DeleteHashTable(&hashTable);

    /*
     * Cache the information. Also purges the cache.
     */
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
    int writable)		/* Whether to get writable properties. If
				 * false, readable properties will be returned
				 * instead. */
{
    Tcl_HashTable hashTable;
    FOREACH_HASH_DECLS;
    Tcl_Obj *propName, *result;
    void *dummy;

    /*
     * Look in the cache.
     */

    if (oPtr->properties.epoch == oPtr->fPtr->epoch) {
	if (writable) {







<







749
750
751
752
753
754
755

756
757
758
759
760
761
762
    int writable)		/* Whether to get writable properties. If
				 * false, readable properties will be returned
				 * instead. */
{
    Tcl_HashTable hashTable;
    FOREACH_HASH_DECLS;
    Tcl_Obj *propName, *result;


    /*
     * Look in the cache.
     */

    if (oPtr->properties.epoch == oPtr->fPtr->epoch) {
	if (writable) {
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
    /*
     * Gather the information. Unsorted! (Caller will sort.)
     */

    Tcl_InitObjHashTable(&hashTable);
    FindObjectProps(oPtr, writable, &hashTable);
    TclNewObj(result);
    FOREACH_HASH(propName, dummy, &hashTable) {
	Tcl_ListObjAppendElement(NULL, result, propName);
    }
    Tcl_DeleteHashTable(&hashTable);
    SortPropList(result);

    /*
     * Cache the information.







|







773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
    /*
     * Gather the information. Unsorted! (Caller will sort.)
     */

    Tcl_InitObjHashTable(&hashTable);
    FindObjectProps(oPtr, writable, &hashTable);
    TclNewObj(result);
    FOREACH_HASH_KEY(propName, &hashTable) {
	Tcl_ListObjAppendElement(NULL, result, propName);
    }
    Tcl_DeleteHashTable(&hashTable);
    SortPropList(result);

    /*
     * Cache the information.
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
    Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);

    if (oPtr == NULL) {
	return TCL_ERROR;
    }
    if (!useInstance && !oPtr->classPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"attempt to misuse API", -1));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }

    for (i = 1; i < objc; i++) {
	Tcl_Obj *propObj = objv[i], *nextObj, *argObj, *hyphenated;
	Tcl_Obj *getterScript = NULL, *setterScript = NULL;







|







1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
    Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);

    if (oPtr == NULL) {
	return TCL_ERROR;
    }
    if (!useInstance && !oPtr->classPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"attempt to misuse API", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", (char *)NULL);
	return TCL_ERROR;
    }

    for (i = 1; i < objc; i++) {
	Tcl_Obj *propObj = objv[i], *nextObj, *argObj, *hyphenated;
	Tcl_Obj *getterScript = NULL, *setterScript = NULL;
Changes to generic/tclObj.c.
2002
2003
2004
2005
2006
2007
2008

2009
2010
2011
2012
2013
2014
2015
Tcl_GetBoolFromObj(
    Tcl_Interp *interp,         /* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr,	/* The object from which to get boolean. */
    int flags,
    char *charPtr)	/* Place to store resulting boolean. */
{
    int result;


    if ((flags & TCL_NULL_OK) && (objPtr == NULL || Tcl_GetString(objPtr)[0] == '\0')) {
	result = -1;
	goto boolEnd;
    } else if (objPtr == NULL) {
	if (interp) {
	    TclNewObj(objPtr);







>







2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
Tcl_GetBoolFromObj(
    Tcl_Interp *interp,         /* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr,	/* The object from which to get boolean. */
    int flags,
    char *charPtr)	/* Place to store resulting boolean. */
{
    int result;
    Tcl_Size length;

    if ((flags & TCL_NULL_OK) && (objPtr == NULL || Tcl_GetString(objPtr)[0] == '\0')) {
	result = -1;
	goto boolEnd;
    } else if (objPtr == NULL) {
	if (interp) {
	    TclNewObj(objPtr);
2056
2057
2058
2059
2060
2061
2062
















2063
2064
2065
2066
2067
2068
2069
		    } else {
			Tcl_Panic("Wrong bool var for %s", "Tcl_GetBoolFromObj");
		    }
		}
		*charPtr = result;
	    }
	    return TCL_OK;
















	}
    } while ((ParseBoolean(objPtr) == TCL_OK) || (TCL_OK ==
	    TclParseNumber(interp, objPtr, (flags & TCL_NULL_OK)
		    ? "boolean value or \"\"" : "boolean value", NULL,-1,NULL,0)));
    return TCL_ERROR;
}








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
		    } else {
			Tcl_Panic("Wrong bool var for %s", "Tcl_GetBoolFromObj");
		    }
		}
		*charPtr = result;
	    }
	    return TCL_OK;
	}
	/* Handle dict separately, because it doesn't have a lengthProc */
	if (TclHasInternalRep(objPtr, &tclDictType)) {
	    Tcl_DictObjSize(NULL, objPtr, &length);
	    if (length > 0) {
	    listRep:
		if (interp) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf("expected boolean value%s but got a list",
			    (flags & TCL_NULL_OK) ? " or \"\"" : ""));
		}
		return TCL_ERROR;
	    }
	}
	Tcl_ObjTypeLengthProc *lengthProc = TclObjTypeHasProc(objPtr, lengthProc);
	if (lengthProc && lengthProc(objPtr) != 1) {
	    goto listRep;
	}
    } while ((ParseBoolean(objPtr) == TCL_OK) || (TCL_OK ==
	    TclParseNumber(interp, objPtr, (flags & TCL_NULL_OK)
		    ? "boolean value or \"\"" : "boolean value", NULL,-1,NULL,0)));
    return TCL_ERROR;
}

2417
2418
2419
2420
2421
2422
2423

2424
2425
2426
2427
2428
2429
2430

int
Tcl_GetDoubleFromObj(
    Tcl_Interp *interp,         /* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr,	/* The object from which to get a double. */
    double *dblPtr)	/* Place to store resulting double. */
{

    do {
	if (TclHasInternalRep(objPtr, &tclDoubleType)) {
	    if (isnan(objPtr->internalRep.doubleValue)) {
		if (interp != NULL) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "floating point value is Not a Number", -1));
		    Tcl_SetErrorCode(interp, "TCL", "VALUE", "DOUBLE", "NAN",







>







2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448

int
Tcl_GetDoubleFromObj(
    Tcl_Interp *interp,         /* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr,	/* The object from which to get a double. */
    double *dblPtr)	/* Place to store resulting double. */
{
    Tcl_Size length;
    do {
	if (TclHasInternalRep(objPtr, &tclDoubleType)) {
	    if (isnan(objPtr->internalRep.doubleValue)) {
		if (interp != NULL) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "floating point value is Not a Number", -1));
		    Tcl_SetErrorCode(interp, "TCL", "VALUE", "DOUBLE", "NAN",
2441
2442
2443
2444
2445
2446
2447
















2448
2449
2450
2451
2452
2453
2454
	}
	if (TclHasInternalRep(objPtr, &tclBignumType)) {
	    mp_int big;

	    TclUnpackBignum(objPtr, big);
	    *dblPtr = TclBignumToDouble(&big);
	    return TCL_OK;
















	}
    } while (SetDoubleFromAny(interp, objPtr) == TCL_OK);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
	}
	if (TclHasInternalRep(objPtr, &tclBignumType)) {
	    mp_int big;

	    TclUnpackBignum(objPtr, big);
	    *dblPtr = TclBignumToDouble(&big);
	    return TCL_OK;
	}
	/* Handle dict separately, because it doesn't have a lengthProc */
	if (TclHasInternalRep(objPtr, &tclDictType)) {
	    Tcl_DictObjSize(NULL, objPtr, &length);
	    if (length > 0) {
	    listRep:
		if (interp) {
		    Tcl_SetObjResult(interp,
			    Tcl_NewStringObj("expected floating-point number but got a list", TCL_INDEX_NONE));
		}
		return TCL_ERROR;
	    }
	}
	Tcl_ObjTypeLengthProc *lengthProc = TclObjTypeHasProc(objPtr, lengthProc);
	if (lengthProc && lengthProc(objPtr) != 1) {
	    goto listRep;
	}
    } while (SetDoubleFromAny(interp, objPtr) == TCL_OK);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
2646
2647
2648
2649
2650
2651
2652

2653
2654
2655
2656
2657
2658
2659

int
Tcl_GetLongFromObj(
    Tcl_Interp *interp,         /* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr,	/* The object from which to get a long. */
    long *longPtr)	/* Place to store resulting long. */
{

    do {
#ifdef TCL_WIDE_INT_IS_LONG
	if (TclHasInternalRep(objPtr, &tclIntType)) {
	    *longPtr = objPtr->internalRep.wideValue;
	    return TCL_OK;
	}
#else







>







2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694

int
Tcl_GetLongFromObj(
    Tcl_Interp *interp,         /* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr,	/* The object from which to get a long. */
    long *longPtr)	/* Place to store resulting long. */
{
    Tcl_Size length;
    do {
#ifdef TCL_WIDE_INT_IS_LONG
	if (TclHasInternalRep(objPtr, &tclIntType)) {
	    *longPtr = objPtr->internalRep.wideValue;
	    return TCL_OK;
	}
#else
2724
2725
2726
2727
2728
2729
2730















2731
2732
2733
2734
2735
2736
2737
		const char *s = "integer value too large to represent";
		Tcl_Obj *msg = Tcl_NewStringObj(s, -1);

		Tcl_SetObjResult(interp, msg);
		Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, (char *)NULL);
	    }
	    return TCL_ERROR;















	}
    } while (TclParseNumber(interp, objPtr, "integer", NULL, -1, NULL,
	    TCL_PARSE_INTEGER_ONLY)==TCL_OK);
    return TCL_ERROR;
}

/*







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
		const char *s = "integer value too large to represent";
		Tcl_Obj *msg = Tcl_NewStringObj(s, -1);

		Tcl_SetObjResult(interp, msg);
		Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, (char *)NULL);
	    }
	    return TCL_ERROR;
	}
	/* Handle dict separately, because it doesn't have a lengthProc */
	if (TclHasInternalRep(objPtr, &tclDictType)) {
	    Tcl_DictObjSize(NULL, objPtr, &length);
	    if (length > 0) {
	    listRep:
		if (interp) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj("expected integer but got a list", -1));
		}
		return TCL_ERROR;
	    }
	}
	Tcl_ObjTypeLengthProc *lengthProc = TclObjTypeHasProc(objPtr, lengthProc);
	if (lengthProc && lengthProc(objPtr) != 1) {
	    goto listRep;
	}
    } while (TclParseNumber(interp, objPtr, "integer", NULL, -1, NULL,
	    TCL_PARSE_INTEGER_ONLY)==TCL_OK);
    return TCL_ERROR;
}

/*
2975
2976
2977
2978
2979
2980
2981

2982
2983
2984
2985
2986
2987
2988
int
Tcl_GetWideIntFromObj(
    Tcl_Interp *interp,         /* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr,	/* Object from which to get a wide int. */
    Tcl_WideInt *wideIntPtr)
				/* Place to store resulting long. */
{

    do {
	if (TclHasInternalRep(objPtr, &tclIntType)) {
	    *wideIntPtr = objPtr->internalRep.wideValue;
	    return TCL_OK;
	}
	if (TclHasInternalRep(objPtr, &tclDoubleType)) {
	    if (interp != NULL) {







>







3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
int
Tcl_GetWideIntFromObj(
    Tcl_Interp *interp,         /* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr,	/* Object from which to get a wide int. */
    Tcl_WideInt *wideIntPtr)
				/* Place to store resulting long. */
{
    Tcl_Size length;
    do {
	if (TclHasInternalRep(objPtr, &tclIntType)) {
	    *wideIntPtr = objPtr->internalRep.wideValue;
	    return TCL_OK;
	}
	if (TclHasInternalRep(objPtr, &tclDoubleType)) {
	    if (interp != NULL) {
3026
3027
3028
3029
3030
3031
3032















3033
3034
3035
3036
3037
3038
3039
		const char *s = "integer value too large to represent";
		Tcl_Obj *msg = Tcl_NewStringObj(s, -1);

		Tcl_SetObjResult(interp, msg);
		Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, (char *)NULL);
	    }
	    return TCL_ERROR;















	}
    } while (TclParseNumber(interp, objPtr, "integer", NULL, -1, NULL,
	    TCL_PARSE_INTEGER_ONLY)==TCL_OK);
    return TCL_ERROR;
}

/*







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
		const char *s = "integer value too large to represent";
		Tcl_Obj *msg = Tcl_NewStringObj(s, -1);

		Tcl_SetObjResult(interp, msg);
		Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, (char *)NULL);
	    }
	    return TCL_ERROR;
	}
	/* Handle dict separately, because it doesn't have a lengthProc */
	if (TclHasInternalRep(objPtr, &tclDictType)) {
	    Tcl_DictObjSize(NULL, objPtr, &length);
	    if (length > 0) {
	    listRep:
		if (interp) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj("expected integer but got a list", -1));
		}
		return TCL_ERROR;
	    }
	}
	Tcl_ObjTypeLengthProc *lengthProc = TclObjTypeHasProc(objPtr, lengthProc);
	if (lengthProc && lengthProc(objPtr) != 1) {
	    goto listRep;
	}
    } while (TclParseNumber(interp, objPtr, "integer", NULL, -1, NULL,
	    TCL_PARSE_INTEGER_ONLY)==TCL_OK);
    return TCL_ERROR;
}

/*
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
	    *typePtr = TCL_NUMBER_BIG;
	    *clientDataPtr = bigPtr;
	    return TCL_OK;
	}
	/* Handle dict separately, because it doesn't have a lengthProc */
	if (TclHasInternalRep(objPtr, &tclDictType)) {
	    Tcl_DictObjSize(NULL, objPtr, &length);
	    if (length > 1) {
	    listRep:
		if (interp) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj("expected number but got a list", -1));
		}
		return TCL_ERROR;
	    }
	}
	Tcl_ObjTypeLengthProc *lengthProc = TclObjTypeHasProc(objPtr, lengthProc);
	if (lengthProc && lengthProc(objPtr) != 1) {
	    goto listRep;
	}
    } while (TCL_OK ==
	    TclParseNumber(interp, objPtr, "number", NULL, -1, NULL, 0));
    /* Don't try to convert index or boolean's to a list */
    if (!TclHasInternalRep(objPtr, &tclIndexType)
	    && !TclHasInternalRep(objPtr, &tclBooleanType)
	    && (TclMaxListLength(TclGetString(objPtr), TCL_INDEX_NONE, NULL) > 1)) {
	goto listRep;
    }
    return TCL_ERROR;
}

int
Tcl_GetNumber(
    Tcl_Interp *interp,
    const char *bytes,







|













<
<
<
<
<
<







3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790






3791
3792
3793
3794
3795
3796
3797
	    *typePtr = TCL_NUMBER_BIG;
	    *clientDataPtr = bigPtr;
	    return TCL_OK;
	}
	/* Handle dict separately, because it doesn't have a lengthProc */
	if (TclHasInternalRep(objPtr, &tclDictType)) {
	    Tcl_DictObjSize(NULL, objPtr, &length);
	    if (length > 0) {
	    listRep:
		if (interp) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj("expected number but got a list", -1));
		}
		return TCL_ERROR;
	    }
	}
	Tcl_ObjTypeLengthProc *lengthProc = TclObjTypeHasProc(objPtr, lengthProc);
	if (lengthProc && lengthProc(objPtr) != 1) {
	    goto listRep;
	}
    } while (TCL_OK ==
	    TclParseNumber(interp, objPtr, "number", NULL, -1, NULL, 0));






    return TCL_ERROR;
}

int
Tcl_GetNumber(
    Tcl_Interp *interp,
    const char *bytes,
Changes to generic/tclPathObj.c.
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
	 * Tcl_FSSplitPath preserves the "~",  but this code computes the
	 * actual full path name, if we had just a single component.
	 */

	splitPtr = Tcl_FSSplitPath(pathPtr, &splitElements);
	Tcl_IncrRefCount(splitPtr);

        if (portion == TCL_PATH_TAIL) {
	    /*
	     * Return the last component, unless it is the only component, and
	     * it is the root of an absolute path.
	     */

	    if ((splitElements > 0) && ((splitElements > 1) ||
		    (Tcl_FSGetPathType(pathPtr) == TCL_PATH_RELATIVE))) {







|







722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
	 * Tcl_FSSplitPath preserves the "~",  but this code computes the
	 * actual full path name, if we had just a single component.
	 */

	splitPtr = Tcl_FSSplitPath(pathPtr, &splitElements);
	Tcl_IncrRefCount(splitPtr);

	if (portion == TCL_PATH_TAIL) {
	    /*
	     * Return the last component, unless it is the only component, and
	     * it is the root of an absolute path.
	     */

	    if ((splitElements > 0) && ((splitElements > 1) ||
		    (Tcl_FSGetPathType(pathPtr) == TCL_PATH_RELATIVE))) {
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065

    noQuickReturn:
	if (res == NULL) {
	    TclNewObj(res);
	}
	ptr = TclGetStringFromObj(res, &length);

        /*
         * A NULL value for fsPtr at this stage basically means we're trying
	 * to join a relative path onto something which is also relative (or
	 * empty). There's nothing particularly wrong with that.
	 */

	if (*strElt == '\0') {
	    continue;
	}







|
|







1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065

    noQuickReturn:
	if (res == NULL) {
	    TclNewObj(res);
	}
	ptr = TclGetStringFromObj(res, &length);

	/*
	 * A NULL value for fsPtr at this stage basically means we're trying
	 * to join a relative path onto something which is also relative (or
	 * empty). There's nothing particularly wrong with that.
	 */

	if (*strElt == '\0') {
	    continue;
	}
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
    const char *dir;
    Tcl_DString dirString;

    Tcl_DStringInit(dsPtr);
    Tcl_DStringInit(&dirString);

    if (user == NULL || user[0] == 0) {
        /* No user name specified -> current user */

	dir = TclGetEnv("HOME", &dirString);
	if (dir == NULL) {
            if (interp) {
                Tcl_SetObjResult(interp, Tcl_NewStringObj(
                        "couldn't find HOME environment variable to expand path",
			-1));
                Tcl_SetErrorCode(interp, "TCL", "VALUE", "PATH",
                        "HOMELESS", (void *)NULL);
            }
            return TCL_ERROR;
        }
    } else {
        /* User name specified - ~user */
	dir = TclpGetUserHome(user, &dirString);
	if (dir == NULL) {
	    if (interp != NULL) {
                Tcl_SetObjResult(interp, Tcl_ObjPrintf(
                        "user \"%s\" doesn't exist", user));
                Tcl_SetErrorCode(interp, "TCL", "VALUE", "PATH", "NOUSER",
                        (void *)NULL);
            }
            return TCL_ERROR;
	}
    }
    if (subPath) {
	const char *parts[2];
	parts[0] = dir;
	parts[1] = subPath;
	Tcl_JoinPath(2, parts, dsPtr);







|



|
|
|

|
|
|
|
|

|



|
|
|
|
|
|







2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
    const char *dir;
    Tcl_DString dirString;

    Tcl_DStringInit(dsPtr);
    Tcl_DStringInit(&dirString);

    if (user == NULL || user[0] == 0) {
	/* No user name specified -> current user */

	dir = TclGetEnv("HOME", &dirString);
	if (dir == NULL) {
	    if (interp) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"couldn't find HOME environment variable to expand path",
			-1));
		Tcl_SetErrorCode(interp, "TCL", "VALUE", "PATH",
			"HOMELESS", (void *)NULL);
	    }
	    return TCL_ERROR;
	}
    } else {
	/* User name specified - ~user */
	dir = TclpGetUserHome(user, &dirString);
	if (dir == NULL) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"user \"%s\" doesn't exist", user));
		Tcl_SetErrorCode(interp, "TCL", "VALUE", "PATH", "NOUSER",
			(void *)NULL);
	    }
	    return TCL_ERROR;
	}
    }
    if (subPath) {
	const char *parts[2];
	parts[0] = dir;
	parts[1] = subPath;
	Tcl_JoinPath(2, parts, dsPtr);
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
     * split becomes value 1 for '~/...' as well as for '~'. Note on
     * Windows FindSplitPos will implicitly check for '\' as separator
     * in addition to what is passed.
     */
    split = FindSplitPos(path, '/');

    if (split == 1) {
        /* No user name specified -> current user */
	if (MakeTildeRelativePath(interp, NULL, path[1] ? 2 + path : NULL,
		&resolvedPath) != TCL_OK) {
	    return NULL;
	}
    } else {
        /* User name specified - ~user */
        const char *expandedUser;
        Tcl_DString userName;

        Tcl_DStringInit(&userName);
        Tcl_DStringAppend(&userName, path+1, split-1);
        expandedUser = Tcl_DStringValue(&userName);

	/* path[split] is / or \0 */
	if (MakeTildeRelativePath(interp, expandedUser,
		path[split] ? &path[split+1] : NULL,
		&resolvedPath) != TCL_OK) {
	    Tcl_DStringFree(&userName);
	    return NULL;







|





|
|
|

|
|
|







2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
     * split becomes value 1 for '~/...' as well as for '~'. Note on
     * Windows FindSplitPos will implicitly check for '\' as separator
     * in addition to what is passed.
     */
    split = FindSplitPos(path, '/');

    if (split == 1) {
	/* No user name specified -> current user */
	if (MakeTildeRelativePath(interp, NULL, path[1] ? 2 + path : NULL,
		&resolvedPath) != TCL_OK) {
	    return NULL;
	}
    } else {
	/* User name specified - ~user */
	const char *expandedUser;
	Tcl_DString userName;

	Tcl_DStringInit(&userName);
	Tcl_DStringAppend(&userName, path+1, split-1);
	expandedUser = Tcl_DStringValue(&userName);

	/* path[split] is / or \0 */
	if (MakeTildeRelativePath(interp, expandedUser,
		path[split] ? &path[split+1] : NULL,
		&resolvedPath) != TCL_OK) {
	    Tcl_DStringFree(&userName);
	    return NULL;
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
    Tcl_Obj **objv;
    Tcl_Size objc;
    Tcl_Size i;
    Tcl_Obj *resolvedPaths;
    const char *path;

    if (pathsObj == NULL) {
        return NULL;
    }
    if (Tcl_ListObjGetElements(NULL, pathsObj, &objc, &objv) != TCL_OK) {
        return NULL; /* Not a list */
    }

    /*
     * Figure out if any paths need resolving to avoid unnecessary allocations.
     */
    for (i = 0; i < objc; ++i) {
        path = Tcl_GetString(objv[i]);
        if (path[0] == '~') {
            break; /* At least one path needs resolution */
        }
    }
    if (i == objc) {
        return pathsObj; /* No paths needed to be resolved */
    }

    resolvedPaths = Tcl_NewListObj(objc, NULL);
    for (i = 0; i < objc; ++i) {
	Tcl_Obj *resolvedPath;
        path = Tcl_GetString(objv[i]);
	if (path[0] == 0) {
	    continue; /* Skip empty strings */
	}
	resolvedPath = TclResolveTildePath(NULL, objv[i]);
	if (resolvedPath) {
	    /* Paths that cannot be resolved are skipped */
	    Tcl_ListObjAppendElement(NULL, resolvedPaths, resolvedPath);







|


|






|
|
|
|


|





|







2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
    Tcl_Obj **objv;
    Tcl_Size objc;
    Tcl_Size i;
    Tcl_Obj *resolvedPaths;
    const char *path;

    if (pathsObj == NULL) {
	return NULL;
    }
    if (Tcl_ListObjGetElements(NULL, pathsObj, &objc, &objv) != TCL_OK) {
	return NULL; /* Not a list */
    }

    /*
     * Figure out if any paths need resolving to avoid unnecessary allocations.
     */
    for (i = 0; i < objc; ++i) {
	path = Tcl_GetString(objv[i]);
	if (path[0] == '~') {
	    break; /* At least one path needs resolution */
	}
    }
    if (i == objc) {
	return pathsObj; /* No paths needed to be resolved */
    }

    resolvedPaths = Tcl_NewListObj(objc, NULL);
    for (i = 0; i < objc; ++i) {
	Tcl_Obj *resolvedPath;
	path = Tcl_GetString(objv[i]);
	if (path[0] == 0) {
	    continue; /* Skip empty strings */
	}
	resolvedPath = TclResolveTildePath(NULL, objv[i]);
	if (resolvedPath) {
	    /* Paths that cannot be resolved are skipped */
	    Tcl_ListObjAppendElement(NULL, resolvedPaths, resolvedPath);
Changes to generic/tclStrToD.c.
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530







1531
1532

1533
1534
1535
1536
1537
1538
1539

    /*
     * Format an error message when an invalid number is encountered.
     */

    if (status != TCL_OK) {
	if (interp != NULL) {
	    Tcl_Obj *msg = Tcl_ObjPrintf("expected %s but got \"",
		    expected);








	    Tcl_AppendLimitedToObj(msg, bytes, numBytes, 50, "");
	    Tcl_AppendToObj(msg, "\"", -1);

	    Tcl_SetObjResult(interp, msg);
	    Tcl_SetErrorCode(interp, "TCL", "VALUE", "NUMBER", (char *)NULL);
	}
    }

    /*
     * Free memory.







|

|
>
>
>
>
>
>
>
|
|
>







1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547

    /*
     * Format an error message when an invalid number is encountered.
     */

    if (status != TCL_OK) {
	if (interp != NULL) {
	    Tcl_Obj *msg = Tcl_ObjPrintf("expected %s but got ",
		    expected);
	    Tcl_Size argc;
	    const char **argv;
	    if ((TclMaxListLength(bytes, TCL_INDEX_NONE, NULL) > 1)
		    && Tcl_SplitList(NULL, bytes, &argc, &argv) == TCL_OK) {
		Tcl_Free(argv);
		Tcl_AppendToObj(msg, "a list", -1);
	    } else {
		Tcl_AppendToObj(msg, "\"", -1);
		Tcl_AppendLimitedToObj(msg, bytes, numBytes, 50, "");
		Tcl_AppendToObj(msg, "\"", -1);
	    }
	    Tcl_SetObjResult(interp, msg);
	    Tcl_SetErrorCode(interp, "TCL", "VALUE", "NUMBER", (char *)NULL);
	}
    }

    /*
     * Free memory.
Changes to generic/tclTest.c.
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
    Tcl_AsyncHandler handler;	/* Tcl's token for the handler. */
    char *command;		/* Command to invoke when the handler is
				 * invoked. */
    struct TestAsyncHandler *nextPtr;
				/* Next is list of handlers. */
} TestAsyncHandler;

#if TCL_MAJOR_VERSION < 9 || !defined(TCL_NO_DEPRECATED)
#   undef Tcl_CreateObjCommand2
#   define Tcl_CreateObjCommand2 Tcl_CreateObjCommand
#   define Tcl_ObjCmdProc2 Tcl_ObjCmdProc
#   undef Tcl_CreateObjTrace2
#   define Tcl_CreateObjTrace2 Tcl_CreateObjTrace
#   define TclSizeT int
#else







|







78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
    Tcl_AsyncHandler handler;	/* Tcl's token for the handler. */
    char *command;		/* Command to invoke when the handler is
				 * invoked. */
    struct TestAsyncHandler *nextPtr;
				/* Next is list of handlers. */
} TestAsyncHandler;

#if !defined(TCL_NO_DEPRECATED)
#   undef Tcl_CreateObjCommand2
#   define Tcl_CreateObjCommand2 Tcl_CreateObjCommand
#   define Tcl_ObjCmdProc2 Tcl_ObjCmdProc
#   undef Tcl_CreateObjTrace2
#   define Tcl_CreateObjTrace2 Tcl_CreateObjTrace
#   define TclSizeT int
#else
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
	return TCL_ERROR;
    }
    if (Tcl_OOInitStubs(interp) == NULL) {
	return TCL_ERROR;
    }

    if (Tcl_GetCommandInfo(interp, "::tcl::build-info", &info)) {
#if TCL_MAJOR_VERSION > 8 && defined(TCL_NO_DEPRECATED)
	Tcl_CreateObjCommand2(interp, "::tcl::test::build-info",
			info.objProc2, (void *)version, NULL);
#else
	Tcl_CreateObjCommand(interp, "::tcl::test::build-info",
		info.objProc, (void *)version, NULL);
#endif
    }







|







544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
	return TCL_ERROR;
    }
    if (Tcl_OOInitStubs(interp) == NULL) {
	return TCL_ERROR;
    }

    if (Tcl_GetCommandInfo(interp, "::tcl::build-info", &info)) {
#if defined(TCL_NO_DEPRECATED)
	Tcl_CreateObjCommand2(interp, "::tcl::test::build-info",
			info.objProc2, (void *)version, NULL);
#else
	Tcl_CreateObjCommand(interp, "::tcl::test::build-info",
		info.objProc, (void *)version, NULL);
#endif
    }
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
{
    Tcl_CmdInfo info;

    if (Tcl_InitStubs(interp, "8.7-", 0) == NULL) {
	return TCL_ERROR;
    }
    if (Tcl_GetCommandInfo(interp, "::tcl::build-info", &info)) {
#if TCL_MAJOR_VERSION > 8 && defined(TCL_NO_DEPRECATED)
	Tcl_CreateObjCommand2(interp, "::tcl::test::build-info",
		info.objProc2, (void *)version, NULL);
#else
	Tcl_CreateObjCommand2(interp, "::tcl::test::build-info",
		info.objProc, (void *)version, NULL);
#endif
    }
    if (Tcl_PkgProvideEx(interp, "tcl::test", TCL_PATCH_LEVEL, NULL) == TCL_ERROR) {
	return TCL_ERROR;
    }
    return Procbodytest_SafeInit(interp);







|



|







808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
{
    Tcl_CmdInfo info;

    if (Tcl_InitStubs(interp, "8.7-", 0) == NULL) {
	return TCL_ERROR;
    }
    if (Tcl_GetCommandInfo(interp, "::tcl::build-info", &info)) {
#if defined(TCL_NO_DEPRECATED)
	Tcl_CreateObjCommand2(interp, "::tcl::test::build-info",
		info.objProc2, (void *)version, NULL);
#else
	Tcl_CreateObjCommand(interp, "::tcl::test::build-info",
		info.objProc, (void *)version, NULL);
#endif
    }
    if (Tcl_PkgProvideEx(interp, "tcl::test", TCL_PATCH_LEVEL, NULL) == TCL_ERROR) {
	return TCL_ERROR;
    }
    return Procbodytest_SafeInit(interp);
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
    bytes = Tcl_GetByteArrayFromObj(objv[3], &srcLen); /* Last! to avoid shimmering */
    result = (*transformer)(interp, encoding, (const char *)bytes, srcLen, flags,
	    encStatePtr, (char *) bufPtr, dstLen,
	    srcReadVar ? &srcRead : NULL,
	    &dstWrote,
	    dstCharsVar ? &dstChars : NULL);
    if (memcmp(bufPtr + bufLen - 4, "\xAB\xCD\xEF\xAB", 4)) {
        Tcl_SetObjResult(interp,
                         Tcl_ObjPrintf("%s wrote past output buffer",
                                       transformer == Tcl_ExternalToUtf ?
                                       "Tcl_ExternalToUtf" : "Tcl_UtfToExternal"));
	result = TCL_ERROR;
    } else if (result != TCL_ERROR) {
	Tcl_Obj *resultObjs[3];
	switch (result) {
	case TCL_OK:
	    resultObjs[0] = Tcl_NewStringObj("ok", TCL_INDEX_NONE);
	    break;







|
|
|
|







2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
    bytes = Tcl_GetByteArrayFromObj(objv[3], &srcLen); /* Last! to avoid shimmering */
    result = (*transformer)(interp, encoding, (const char *)bytes, srcLen, flags,
	    encStatePtr, (char *) bufPtr, dstLen,
	    srcReadVar ? &srcRead : NULL,
	    &dstWrote,
	    dstCharsVar ? &dstChars : NULL);
    if (memcmp(bufPtr + bufLen - 4, "\xAB\xCD\xEF\xAB", 4)) {
	Tcl_SetObjResult(interp,
			 Tcl_ObjPrintf("%s wrote past output buffer",
				       transformer == Tcl_ExternalToUtf ?
				       "Tcl_ExternalToUtf" : "Tcl_UtfToExternal"));
	result = TCL_ERROR;
    } else if (result != TCL_ERROR) {
	Tcl_Obj *resultObjs[3];
	switch (result) {
	case TCL_OK:
	    resultObjs[0] = Tcl_NewStringObj("ok", TCL_INDEX_NONE);
	    break;
Changes to generic/tclVar.c.
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
/*
 *----------------------------------------------------------------------
 *
 * TclLookupVar --
 *
 *	This function is used to locate a variable given its name(s). It has
 *	been mostly superseded by TclObjLookupVar, it is now only used by the
 *	trace code. It is kept in tcl8.5 mainly because it is in the internal
 *	stubs table, so that some extension may be calling it.
 *
 * Results:
 *	The return value is a pointer to the variable structure indicated by
 *	part1 and part2, or NULL if the variable couldn't be found. If the
 *	variable is found, *arrayPtrPtr is filled in with the address of the
 *	variable structure for the array that contains the variable (or NULL







|







414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
/*
 *----------------------------------------------------------------------
 *
 * TclLookupVar --
 *
 *	This function is used to locate a variable given its name(s). It has
 *	been mostly superseded by TclObjLookupVar, it is now only used by the
 *	trace code. It is kept in tcl9.0 mainly because it is in the internal
 *	stubs table, so that some extension may be calling it.
 *
 * Results:
 *	The return value is a pointer to the variable structure indicated by
 *	part1 and part2, or NULL if the variable couldn't be found. If the
 *	variable is found, *arrayPtrPtr is filled in with the address of the
 *	variable structure for the array that contains the variable (or NULL
Changes to generic/tclZipfs.c.
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#define ZIPFS_ERROR_CODE(interp,errcode) \
    do {								\
	if (interp) {							\
	    Tcl_SetErrorCode(interp, "TCL", "ZIPFS", errcode, (char *)NULL);	\
	}								\
    } while (0)

#ifdef HAVE_ZLIB
#include "zlib.h"
#include "crypt.h"
#include "zutil.h"
#include "crc32.h"

static const z_crc_t* crc32tab;








<







69
70
71
72
73
74
75

76
77
78
79
80
81
82
#define ZIPFS_ERROR_CODE(interp,errcode) \
    do {								\
	if (interp) {							\
	    Tcl_SetErrorCode(interp, "TCL", "ZIPFS", errcode, (char *)NULL);	\
	}								\
    } while (0)


#include "zlib.h"
#include "crypt.h"
#include "zutil.h"
#include "crc32.h"

static const z_crc_t* crc32tab;

6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
    }
    if (altPath) {
	Tcl_DecrRefCount(altPath);
    }
    return ret;
#endif /* ANDROID */
}

#endif /* HAVE_ZLIB */

/*
 *-------------------------------------------------------------------------
 *
 * TclZipfs_Init --
 *
 *	Perform per interpreter initialization of this module.







<
<







6199
6200
6201
6202
6203
6204
6205


6206
6207
6208
6209
6210
6211
6212
    }
    if (altPath) {
	Tcl_DecrRefCount(altPath);
    }
    return ret;
#endif /* ANDROID */
}



/*
 *-------------------------------------------------------------------------
 *
 * TclZipfs_Init --
 *
 *	Perform per interpreter initialization of this module.
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
 *-------------------------------------------------------------------------
 */

int
TclZipfs_Init(
    Tcl_Interp *interp)		/* Current interpreter. */
{
#ifdef HAVE_ZLIB
    static const EnsembleImplMap initMap[] = {
	{"mkimg",	ZipFSMkImgObjCmd,	NULL, NULL, NULL, 1},
	{"mkzip",	ZipFSMkZipObjCmd,	NULL, NULL, NULL, 1},
	{"lmkimg",	ZipFSLMkImgObjCmd,	NULL, NULL, NULL, 1},
	{"lmkzip",	ZipFSLMkZipObjCmd,	NULL, NULL, NULL, 1},
	{"mount",	ZipFSMountObjCmd,	NULL, NULL, NULL, 1},
	{"mountdata",	ZipFSMountBufferObjCmd,	NULL, NULL, NULL, 1},







<







6221
6222
6223
6224
6225
6226
6227

6228
6229
6230
6231
6232
6233
6234
 *-------------------------------------------------------------------------
 */

int
TclZipfs_Init(
    Tcl_Interp *interp)		/* Current interpreter. */
{

    static const EnsembleImplMap initMap[] = {
	{"mkimg",	ZipFSMkImgObjCmd,	NULL, NULL, NULL, 1},
	{"mkzip",	ZipFSMkZipObjCmd,	NULL, NULL, NULL, 1},
	{"lmkimg",	ZipFSLMkImgObjCmd,	NULL, NULL, NULL, 1},
	{"lmkzip",	ZipFSLMkZipObjCmd,	NULL, NULL, NULL, 1},
	{"mount",	ZipFSMountObjCmd,	NULL, NULL, NULL, 1},
	{"mountdata",	ZipFSMountBufferObjCmd,	NULL, NULL, NULL, 1},
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
	{NULL, NULL, NULL, NULL, NULL, 0}
    };
    static const char findproc[] =
	"namespace eval ::tcl::zipfs {}\n"
	"proc ::tcl::zipfs::Find dir {\n"
	"    set result {}\n"
	"    if {[catch {\n"
        "        concat [glob -directory $dir -nocomplain *] [glob -directory $dir -types hidden -nocomplain *]\n"
        "    } list]} {\n"
	"        return $result\n"
	"    }\n"
	"    foreach file $list {\n"
	"        if {[file tail $file] in {. ..}} {\n"
	"            continue\n"
	"        }\n"
	"        lappend result $file {*}[Find $file]\n"







|
|







6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
	{NULL, NULL, NULL, NULL, NULL, 0}
    };
    static const char findproc[] =
	"namespace eval ::tcl::zipfs {}\n"
	"proc ::tcl::zipfs::Find dir {\n"
	"    set result {}\n"
	"    if {[catch {\n"
	"        concat [glob -directory $dir -nocomplain *] [glob -directory $dir -types hidden -nocomplain *]\n"
	"    } list]} {\n"
	"        return $result\n"
	"    }\n"
	"    foreach file $list {\n"
	"        if {[file tail $file] in {. ..}} {\n"
	"            continue\n"
	"        }\n"
	"        lappend result $file {*}[Find $file]\n"
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318

	Tcl_GetEnsembleMappingDict(NULL, ensemble, &mapObj);
	TclDictPutString(NULL, mapObj, "find", "::tcl::zipfs::find");
	Tcl_CreateObjCommand2(interp, "::tcl::zipfs::tcl_library_init",
		ZipFSTclLibraryObjCmd, NULL, NULL);
    }
    return TCL_OK;
#else /* !HAVE_ZLIB */
    ZIPFS_ERROR(interp, "no zlib available");
    ZIPFS_ERROR_CODE(interp, "NO_ZLIB");
    return TCL_ERROR;
#endif /* HAVE_ZLIB */
}

#ifdef HAVE_ZLIB

#if !defined(STATIC_BUILD)
static int
ZipfsAppHookFindTclInit(
    const char *archive)
{
    Tcl_Obj *vfsInitScript;
    int found;







<
<
<
<
<


<
<







6292
6293
6294
6295
6296
6297
6298





6299
6300


6301
6302
6303
6304
6305
6306
6307

	Tcl_GetEnsembleMappingDict(NULL, ensemble, &mapObj);
	TclDictPutString(NULL, mapObj, "find", "::tcl::zipfs::find");
	Tcl_CreateObjCommand2(interp, "::tcl::zipfs::tcl_library_init",
		ZipFSTclLibraryObjCmd, NULL, NULL);
    }
    return TCL_OK;





}



#if !defined(STATIC_BUILD)
static int
ZipfsAppHookFindTclInit(
    const char *archive)
{
    Tcl_Obj *vfsInitScript;
    int found;
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
	Tcl_DStringFree(&ds);
#endif /* _WIN32 */
#endif /* SUPPORT_BUILTIN_ZIP_INSTALL */
    }
    return result;
}

#else /* !HAVE_ZLIB */

/*
 *-------------------------------------------------------------------------
 *
 * TclZipfs_Mount, TclZipfs_MountBuffer, TclZipfs_Unmount --
 *
 *	Dummy version when no ZLIB support available.
 *
 *-------------------------------------------------------------------------
 */

int
TclZipfs_Mount(
    Tcl_Interp *interp,		/* Current interpreter. */
    TCL_UNUSED(const char *),	/* Path to ZIP file to mount. */
    TCL_UNUSED(const char *),	/* Mount point path. */
    TCL_UNUSED(const char *))		/* Password for opening the ZIP, or NULL if
				 * the ZIP is unprotected. */
{
    ZIPFS_ERROR(interp, "no zlib available");
    ZIPFS_ERROR_CODE(interp, "NO_ZLIB");
    return TCL_ERROR;
}

int
TclZipfs_MountBuffer(
    Tcl_Interp *interp,		/* Current interpreter. NULLable. */
    TCL_UNUSED(const void *),
    TCL_UNUSED(size_t),
    TCL_UNUSED(const char *),	/* Mount point path. */
    TCL_UNUSED(int))
{
    ZIPFS_ERROR(interp, "no zlib available");
    ZIPFS_ERROR_CODE(interp, "NO_ZLIB");
    return TCL_ERROR;
}

int
TclZipfs_Unmount(
    Tcl_Interp *interp,		/* Current interpreter. */
    TCL_UNUSED(const char *))	/* Mount point path. */
{
    ZIPFS_ERROR(interp, "no zlib available");
    ZIPFS_ERROR_CODE(interp, "NO_ZLIB");
    return TCL_ERROR;
}

const char *
TclZipfs_AppHook(
    TCL_UNUSED(int *), /*argcPtr*/
#ifdef _WIN32
    TCL_UNUSED(WCHAR ***)) /* argvPtr */
#else /* !_WIN32 */
    TCL_UNUSED(char ***))		/* Pointer to argv */
#endif /* _WIN32 */
{
    return NULL;
}

Tcl_Obj *
TclZipfs_TclLibrary(void)
{
    return NULL;
}

int
TclIsZipfsPath(
    TCL_UNUSED(const char *)) /* path */
{
    return 0;
}

#endif /* !HAVE_ZLIB */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






6517
6518
6519
6520
6521
6522
6523


6524









































































6525
6526
6527
6528
6529
6530
	Tcl_DStringFree(&ds);
#endif /* _WIN32 */
#endif /* SUPPORT_BUILTIN_ZIP_INSTALL */
    }
    return result;
}



/*









































































 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to generic/tclZlib.c.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 * public domain March 2003.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tclInt.h"
#ifdef HAVE_ZLIB
#include "zlib.h"
#include "tclIO.h"

/*
 * The version of the zlib "package" that this implements. Note that this
 * thoroughly supersedes the versions included with tclkit, which are "1.1",
 * so this is at least "2.0" (there's no general *commitment* to have the same







<







11
12
13
14
15
16
17

18
19
20
21
22
23
24
 * public domain March 2003.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tclInt.h"

#include "zlib.h"
#include "tclIO.h"

/*
 * The version of the zlib "package" that this implements. Note that this
 * thoroughly supersedes the versions included with tclkit, which are "1.1",
 * so this is at least "2.0" (there's no general *commitment* to have the same
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
    /*
     * Formally provide the package as a Tcl built-in.
     */

    return Tcl_PkgProvideEx(interp, "tcl::zlib", TCL_ZLIB_VERSION, NULL);
}

/*
 *----------------------------------------------------------------------
 *	Stubs used when a suitable zlib installation was not found during
 *	configure.
 *----------------------------------------------------------------------
 */

#else /* !HAVE_ZLIB */
int
Tcl_ZlibStreamInit(
    Tcl_Interp *interp,
    int mode,
    int format,
    int level,
    Tcl_Obj *dictObj,
    Tcl_ZlibStream *zshandle)
{
    if (interp) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"unimplemented", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", (char *)NULL);
    }
    return TCL_ERROR;
}

int
Tcl_ZlibStreamClose(
    Tcl_ZlibStream zshandle)
{
    return TCL_OK;
}

int
Tcl_ZlibStreamReset(
    Tcl_ZlibStream zshandle)
{
    return TCL_OK;
}

Tcl_Obj *
Tcl_ZlibStreamGetCommandName(
    Tcl_ZlibStream zshandle)
{
    return NULL;
}

int
Tcl_ZlibStreamEof(
    Tcl_ZlibStream zshandle)
{
    return 1;
}

int
Tcl_ZlibStreamChecksum(
    Tcl_ZlibStream zshandle)
{
    return 0;
}

int
Tcl_ZlibStreamPut(
    Tcl_ZlibStream zshandle,
    Tcl_Obj *data,
    int flush)
{
    return TCL_OK;
}

int
Tcl_ZlibStreamGet(
    Tcl_ZlibStream zshandle,
    Tcl_Obj *data,
    size_t count)
{
    return TCL_OK;
}

int
Tcl_ZlibDeflate(
    Tcl_Interp *interp,
    int format,
    Tcl_Obj *data,
    int level,
    Tcl_Obj *gzipHeaderDictObj)
{
    if (interp) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"unimplemented", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", (char *)NULL);
    }
    return TCL_ERROR;
}

int
Tcl_ZlibInflate(
    Tcl_Interp *interp,
    int format,
    Tcl_Obj *data,
    size_t bufferSize,
    Tcl_Obj *gzipHeaderDictObj)
{
    if (interp) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"unimplemented", TCL_AUTO_LENGTH));
	Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", (char *)NULL);
    }
    return TCL_ERROR;
}

unsigned int
Tcl_ZlibCRC32(
    TCL_UNUSED(unsigned int),
    TCL_UNUSED(const unsigned char *),
    TCL_UNUSED(size_t))
{
    return 0;
}

unsigned int
Tcl_ZlibAdler32(
    TCL_UNUSED(unsigned int),
    TCL_UNUSED(const unsigned char *),
    TCL_UNUSED(size_t))
{
    return 0;
}

void
Tcl_ZlibStreamSetCompressionDictionary(
    Tcl_ZlibStream zshandle,
    Tcl_Obj *compressionDictionaryObj)
{
    /* Do nothing. */
}
#endif /* HAVE_ZLIB */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






4037
4038
4039
4040
4041
4042
4043
4044









































































































































4045
4046
4047
4048
4049
4050
    /*
     * Formally provide the package as a Tcl built-in.
     */

    return Tcl_PkgProvideEx(interp, "tcl::zlib", TCL_ZLIB_VERSION, NULL);
}

/*









































































































































 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to library/install.tcl.
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
      ###
      set fin [open $file r]
      fconfigure $fin -encoding utf-8 -eofchar \x1A
      set dat [read $fin]
      close $fin
      # Look for a teapot style Package statement
      foreach line [split $dat \n] {
        set line [string trim $line]
        if { [string range $line 0 9] != "# Package " } continue
        set package [lindex $line 2]
        set version [lindex $line 3]
        break
      }
      # Look for a package provide statement
      foreach line [split $dat \n] {
        set line [string trim $line]
        if { [string range $line 0 14] != "package provide" } continue
        set package [lindex $line 2]
        set version [lindex $line 3]
        break
      }
      append buffer "package ifneeded $package $version \[list source \[file join \$dir [file tail $file]\]\]" \n
    }
    foreach file [glob -nocomplain $path/*.tcl] {
      if { [file tail $file] == "version_info.tcl" } continue
      set fin [open $file r]
      fconfigure $fin -encoding utf-8 -eofchar \x1A
      set dat [read $fin]
      close $fin
      if {![regexp "package provide" $dat]} continue
      set fname [file rootname [file tail $file]]
      # Look for a package provide statement
      foreach line [split $dat \n] {
        set line [string trim $line]
        if { [string range $line 0 14] != "package provide" } continue
        set package [lindex $line 2]
        set version [lindex $line 3]
        if {[string index $package 0] in "\$ \[ @"} continue
        if {[string index $version 0] in "\$ \[ @"} continue
        append buffer "package ifneeded $package $version \[list source \[file join \$dir [file tail $file]\]\]" \n
        break
      }
    }
    return $buffer
  }
  set fin [open $pkgidxfile r]
  fconfigure $fin -encoding utf-8 -eofchar \x1A
  set dat [read $fin]







|
|
|
|
|



|
|
|
|
|













|
|
|
|
|
|
|
|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
      ###
      set fin [open $file r]
      fconfigure $fin -encoding utf-8 -eofchar \x1A
      set dat [read $fin]
      close $fin
      # Look for a teapot style Package statement
      foreach line [split $dat \n] {
	set line [string trim $line]
	if { [string range $line 0 9] != "# Package " } continue
	set package [lindex $line 2]
	set version [lindex $line 3]
	break
      }
      # Look for a package provide statement
      foreach line [split $dat \n] {
	set line [string trim $line]
	if { [string range $line 0 14] != "package provide" } continue
	set package [lindex $line 2]
	set version [lindex $line 3]
	break
      }
      append buffer "package ifneeded $package $version \[list source \[file join \$dir [file tail $file]\]\]" \n
    }
    foreach file [glob -nocomplain $path/*.tcl] {
      if { [file tail $file] == "version_info.tcl" } continue
      set fin [open $file r]
      fconfigure $fin -encoding utf-8 -eofchar \x1A
      set dat [read $fin]
      close $fin
      if {![regexp "package provide" $dat]} continue
      set fname [file rootname [file tail $file]]
      # Look for a package provide statement
      foreach line [split $dat \n] {
	set line [string trim $line]
	if { [string range $line 0 14] != "package provide" } continue
	set package [lindex $line 2]
	set version [lindex $line 3]
	if {[string index $package 0] in "\$ \[ @"} continue
	if {[string index $version 0] in "\$ \[ @"} continue
	append buffer "package ifneeded $package $version \[list source \[file join \$dir [file tail $file]\]\]" \n
	break
      }
    }
    return $buffer
  }
  set fin [open $pkgidxfile r]
  fconfigure $fin -encoding utf-8 -eofchar \x1A
  set dat [read $fin]
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
      if {[file tail $dir] eq "teapot"} continue
      lappend paths $dir {*}[::practcl::_pkgindex_path_subdir $dir]
    }
    set i    [string length  $base]
    # Build a list of all of the paths
    if {[llength $paths]} {
      foreach path $paths {
        if {$path eq $base} continue
        set path_indexed($path) 0
      }
    } else {
      puts [list WARNING: NO PATHS FOUND IN $base]
    }
    set path_indexed($base) 1
    set path_indexed([file join $base boot tcl]) 1
    foreach teapath [glob -nocomplain [file join $base teapot *]] {







|
|







145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
      if {[file tail $dir] eq "teapot"} continue
      lappend paths $dir {*}[::practcl::_pkgindex_path_subdir $dir]
    }
    set i    [string length  $base]
    # Build a list of all of the paths
    if {[llength $paths]} {
      foreach path $paths {
	if {$path eq $base} continue
	set path_indexed($path) 0
      }
    } else {
      puts [list WARNING: NO PATHS FOUND IN $base]
    }
    set path_indexed($base) 1
    set path_indexed([file join $base boot tcl]) 1
    foreach teapath [glob -nocomplain [file join $base teapot *]] {
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
}
    }
    foreach path $paths {
      if {$path_indexed($path)} continue
      set thisdir [file_relative $base $path]
      set idxbuf [::practcl::_pkgindex_directory $path]
      if {[string length $idxbuf]} {
        incr path_indexed($path)
        append buffer "set dir \[set PKGDIR \[file join \[lindex \$::PATHSTACK end\] $thisdir\]\]" \n
        append buffer [string map {$dir $PKGDIR} [string trimright $idxbuf]] \n
      }
    }
  }
  append buffer {
set dir [lindex $::PATHSTACK end]
set ::PATHSTACK [lrange $::PATHSTACK 0 end-1]
}







|
|
|







168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
}
    }
    foreach path $paths {
      if {$path_indexed($path)} continue
      set thisdir [file_relative $base $path]
      set idxbuf [::practcl::_pkgindex_directory $path]
      if {[string length $idxbuf]} {
	incr path_indexed($path)
	append buffer "set dir \[set PKGDIR \[file join \[lindex \$::PATHSTACK end\] $thisdir\]\]" \n
	append buffer [string map {$dir $PKGDIR} [string trimright $idxbuf]] \n
      }
    }
  }
  append buffer {
set dir [lindex $::PATHSTACK end]
set ::PATHSTACK [lrange $::PATHSTACK 0 end-1]
}
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
  foreach ftail [glob -directory $d1 -nocomplain -tails *] {
    set f [file join $d1 $ftail]
    if {[file isdirectory $f] && [string compare CVS $ftail]} {
      installDir $f [file join $d2 $ftail]
    } elseif {[file isfile $f]} {
	    file copy -force $f [file join $d2 $ftail]
	    if {$::tcl_platform(platform) eq {unix}} {
        file attributes [file join $d2 $ftail] -permissions 0o644
	    } else {
        file attributes [file join $d2 $ftail] -readonly 1
	    }
    }
  }

  if {$::tcl_platform(platform) eq {unix}} {
    file attributes $d2 -permissions 0o755
  } else {







|

|







198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
  foreach ftail [glob -directory $d1 -nocomplain -tails *] {
    set f [file join $d1 $ftail]
    if {[file isdirectory $f] && [string compare CVS $ftail]} {
      installDir $f [file join $d2 $ftail]
    } elseif {[file isfile $f]} {
	    file copy -force $f [file join $d2 $ftail]
	    if {$::tcl_platform(platform) eq {unix}} {
	file attributes [file join $d2 $ftail] -permissions 0o644
	    } else {
	file attributes [file join $d2 $ftail] -readonly 1
	    }
    }
  }

  if {$::tcl_platform(platform) eq {unix}} {
    file attributes $d2 -permissions 0o755
  } else {
Changes to library/manifest.txt.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
###
# Package manifest for all Tcl packages included in the /library file system
###
apply {{dir} {
  set isafe [interp issafe]
  foreach {safe package version file} {
    0 http            2.10.0 {http http.tcl}
    1 msgcat          1.7.1  {msgcat msgcat.tcl}
    1 opt             0.4.9  {opt optparse.tcl}
    0 cookiejar       0.2.0  {cookiejar cookiejar.tcl}
    0 tcl::idna       1.0.1  {cookiejar idna.tcl}
    0 platform        1.0.19 {platform platform.tcl}
    0 platform::shell 1.1.4  {platform shell.tcl}
    1 tcltest         2.5.8  {tcltest tcltest.tcl}
  } {
    if {$isafe && !$safe} continue
    package ifneeded $package $version  [list source [file join $dir {*}$file]]
  }
}} $dir













|





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
###
# Package manifest for all Tcl packages included in the /library file system
###
apply {{dir} {
  set isafe [interp issafe]
  foreach {safe package version file} {
    0 http            2.10.0 {http http.tcl}
    1 msgcat          1.7.1  {msgcat msgcat.tcl}
    1 opt             0.4.9  {opt optparse.tcl}
    0 cookiejar       0.2.0  {cookiejar cookiejar.tcl}
    0 tcl::idna       1.0.1  {cookiejar idna.tcl}
    0 platform        1.0.19 {platform platform.tcl}
    0 platform::shell 1.1.4  {platform shell.tcl}
    1 tcltest         2.5.9  {tcltest tcltest.tcl}
  } {
    if {$isafe && !$safe} continue
    package ifneeded $package $version  [list source [file join $dir {*}$file]]
  }
}} $dir
Changes to library/tcltest/pkgIndex.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
# Tcl package index file, version 1.1
# This file is generated by the "pkg_mkIndex -direct" command
# and sourced either when an application starts up or
# by a "package unknown" script.  It invokes the
# "package ifneeded" command to set up package-related
# information so that packages will be loaded automatically
# in response to "package require" commands.  When this
# script is sourced, the variable $dir must contain the
# full path name of this file's directory.

if {![package vsatisfies [package provide Tcl] 8.5-]} {return}
package ifneeded tcltest 2.5.8 [list source -encoding utf-8 [file join $dir tcltest.tcl]]











|
1
2
3
4
5
6
7
8
9
10
11
12
# Tcl package index file, version 1.1
# This file is generated by the "pkg_mkIndex -direct" command
# and sourced either when an application starts up or
# by a "package unknown" script.  It invokes the
# "package ifneeded" command to set up package-related
# information so that packages will be loaded automatically
# in response to "package require" commands.  When this
# script is sourced, the variable $dir must contain the
# full path name of this file's directory.

if {![package vsatisfies [package provide Tcl] 8.5-]} {return}
package ifneeded tcltest 2.5.9 [list source -encoding utf-8 [file join $dir tcltest.tcl]]
Changes to library/tcltest/tcltest.tcl.
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# All rights reserved.

namespace eval tcltest {

    # When the version number changes, be sure to update the pkgIndex.tcl file,
    # and the install directory in the Makefiles.  When the minor version
    # changes (new feature) be sure to update the man page as well.
    variable Version 2.5.8

    # Compatibility support for dumb variables defined in tcltest 1
    # Do not use these.  Call [package require] and [info patchlevel]
    # yourself.  You don't need tcltest to wrap it for you.
    variable version [package require Tcl 8.5-]
    variable patchLevel [info patchlevel]








|







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# All rights reserved.

namespace eval tcltest {

    # When the version number changes, be sure to update the pkgIndex.tcl file,
    # and the install directory in the Makefiles.  When the minor version
    # changes (new feature) be sure to update the man page as well.
    variable Version 2.5.9

    # Compatibility support for dumb variables defined in tcltest 1
    # Do not use these.  Call [package require] and [info patchlevel]
    # yourself.  You don't need tcltest to wrap it for you.
    variable version [package require Tcl 8.5-]
    variable patchLevel [info patchlevel]

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
	makeFile removeDirectory removeFile runAllTests test

    # Export configuration commands that control the functional commands
    namespace export configure customMatch errorChannel interpreter \
	    outputChannel testConstraint

    # Export commands that are duplication (candidates for deprecation)
    if {!$fullutf} {
	namespace export bytestring	;# dups [encoding convertfrom identity]
    }
    namespace export debug		;#	[configure -debug]
    namespace export errorFile		;#	[configure -errfile]
    namespace export limitConstraints	;#	[configure -limitconstraints]
    namespace export loadFile		;#	[configure -loadfile]
    namespace export loadScript		;#	[configure -load]







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
	makeFile removeDirectory removeFile runAllTests test

    # Export configuration commands that control the functional commands
    namespace export configure customMatch errorChannel interpreter \
	    outputChannel testConstraint

    # Export commands that are duplication (candidates for deprecation)
    if {![package vsatisfies [package provide Tcl] 9.0-]} {
	namespace export bytestring	;# dups [encoding convertfrom identity]
    }
    namespace export debug		;#	[configure -debug]
    namespace export errorFile		;#	[configure -errfile]
    namespace export limitConstraints	;#	[configure -limitconstraints]
    namespace export loadFile		;#	[configure -loadfile]
    namespace export loadScript		;#	[configure -load]
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
#
# Results:
#	result fom encoding
#
# Side effects:
#	None

if {!$::tcltest::fullutf} {
    proc tcltest::bytestring {string} {
	return [encoding convertfrom identity $string]
    }
}

# tcltest::OpenFiles --
#







|







3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
#
# Results:
#	result fom encoding
#
# Side effects:
#	None

if {![package vsatisfies [package provide Tcl] 9.0-]} {
    proc tcltest::bytestring {string} {
	return [encoding convertfrom identity $string]
    }
}

# tcltest::OpenFiles --
#
Changes to library/tm.tcl.
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
    # Note that we're using [::list], not [list] because [list] means
    # something other than [::list] in this namespace.
    roots [::list \
	    [file dirname [info library]] \
	    [file join [file dirname [file dirname $exe]] lib] \
	    ]

    if {$tcl_platform(platform) eq "windows"} {
	set sep ";"
    } else {
	set sep ":"
    }
    for {set n $minor} {$n >= 0} {incr n -1} {
	foreach ev [::list \
			TCL${major}.${n}_TM_PATH \
			TCL${major}_${n}_TM_PATH \
	] {
	    if {![info exists env($ev)]} continue
	    foreach p [split $env($ev) $sep] {
		# Paths relative to unresolvable home dirs are ignored
		if {![catch {file tildeexpand $p} expanded_path]} {
		    path add $expanded_path
		}
	    }
	}
    }







<
<
<
<
<






|







322
323
324
325
326
327
328





329
330
331
332
333
334
335
336
337
338
339
340
341
342
    # Note that we're using [::list], not [list] because [list] means
    # something other than [::list] in this namespace.
    roots [::list \
	    [file dirname [info library]] \
	    [file join [file dirname [file dirname $exe]] lib] \
	    ]






    for {set n $minor} {$n >= 0} {incr n -1} {
	foreach ev [::list \
			TCL${major}.${n}_TM_PATH \
			TCL${major}_${n}_TM_PATH \
	] {
	    if {![info exists env($ev)]} continue
	    foreach p [split $env($ev) $::tcl_platform(pathSeparator)] {
		# Paths relative to unresolvable home dirs are ignored
		if {![catch {file tildeexpand $p} expanded_path]} {
		    path add $expanded_path
		}
	    }
	}
    }
Changes to macosx/README.
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
(see below for details), but can also be built with the standard unix configure
and make buildsystem in tcl/unix as on any other unix platform (indeed, the
GNUmakefile is just a wrapper around the unix buildsystem).
The Mac OS X specific configure flags are --enable-framework and
--disable-corefoundation (which disables CF and notably reverts to the standard
select based notifier).

- It is also possible to build with the Xcode IDE via the projects in
tcl/macosx, take care to use the project matching your DevTools and OS version:
	Tcl.xcodeproj:		    for Xcode 3.2 on 10.6
These have the following targets:
	Tcl:			    calls through to tcl/macosx/GNUMakefile.
	tcltest:		    static build of tcltest for debugging.
	tests:			    build tcltest target and run tcl testsuite.
The following build configurations are available:
	Debug:			    debug build for the active architecture,
				    with Fix & Continue enabled.
	Debug clang:		    use clang compiler.
	Debug llvm-gcc:		    use llvm-gcc compiler.
	Debug gcc40:		    use gcc 4.0 compiler.
	DebugNoFixAndContinue:      disable Fix & Continue.
	DebugNoCF:		    disable corefoundation.
	DebugMemCompile:	    enable memory and bytecode debugging.
	DebugLeaks:		    define PURIFY.
	DebugGCov:		    enable generation of gcov data files.
	Release:		    release build for the active architecture.
	ReleaseUniversal:	    32/64-bit universal build.
	ReleaseUniversal clang:	    use clang compiler.
	ReleaseUniversal llvm-gcc:  use llvm-gcc compiler.
	ReleaseUniversal gcc40:	    use gcc 4.0 compiler.
	ReleaseUniversal10.5SDK:    build against the 10.5 SDK (with 10.5
				    deployment target).
	Note that the non-SDK configurations have their deployment target set to
	10.6 (Tcl.xcodeproj).
The Xcode projects refer to the toplevel tcl source directory via the
TCL_SRCROOT user build setting, by default this is set to the project-relative
path '../../tcl', if your tcl source directory is named differently, e.g.
'../../tcl9.1', you need to manually change the TCL_SRCROOT setting by editing
your ${USER}.pbxuser file (located inside the Tcl.xcodeproj bundle directory)
with a text editor.

- To build universal binaries outside of the Xcode IDE, set CFLAGS as follows:
	export CFLAGS="-arch x86_64 -arch arm64"
This requires Mac OS X 10.6 and Xcode 10.2 and will work on any architecture.
Note that configure requires CFLAGS to contain a least one architecture that can
be run on the build machine (i.e. x86_64 on Core2/Xeon).
Universal builds of Tcl TEA extensions are also possible with CFLAGS set as
above, they will be [load]able by universal as well as thin binaries of Tcl.

Detailed Instructions for building with macosx/GNUmakefile
----------------------------------------------------------

- Unpack the Tcl source release archive.

- The following instructions assume the Tcl source tree is named "tcl${ver}",
(where ${ver} is a shell variable containing the Tcl version number e.g. '9.1').
Setup this shell variable as follows:
	ver="9.1"

- Setup environment variables as desired, e.g. for a universal build on 10.5:
	CFLAGS="-arch x86_64 -arch arm64 -mmacosx-version-min=10.5"
	export CFLAGS

- Change to the directory containing the Tcl source tree and build:
	make -C tcl${ver}/macosx

- Install Tcl onto the root volume (admin password required):
	sudo make -C tcl${ver}/macosx install







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















|
|







74
75
76
77
78
79
80


































81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
(see below for details), but can also be built with the standard unix configure
and make buildsystem in tcl/unix as on any other unix platform (indeed, the
GNUmakefile is just a wrapper around the unix buildsystem).
The Mac OS X specific configure flags are --enable-framework and
--disable-corefoundation (which disables CF and notably reverts to the standard
select based notifier).



































- To build universal binaries outside of the Xcode IDE, set CFLAGS as follows:
	export CFLAGS="-arch x86_64 -arch arm64"
This requires Mac OS X 10.6 and Xcode 10.2 and will work on any architecture.
Note that configure requires CFLAGS to contain a least one architecture that can
be run on the build machine (i.e. x86_64 on Core2/Xeon).
Universal builds of Tcl TEA extensions are also possible with CFLAGS set as
above, they will be [load]able by universal as well as thin binaries of Tcl.

Detailed Instructions for building with macosx/GNUmakefile
----------------------------------------------------------

- Unpack the Tcl source release archive.

- The following instructions assume the Tcl source tree is named "tcl${ver}",
(where ${ver} is a shell variable containing the Tcl version number e.g. '9.1').
Setup this shell variable as follows:
	ver="9.1"

- Setup environment variables as desired, e.g. for a universal build on 10.9:
	CFLAGS="-arch x86_64 -arch arm64 -mmacosx-version-min=10.9"
	export CFLAGS

- Change to the directory containing the Tcl source tree and build:
	make -C tcl${ver}/macosx

- Install Tcl onto the root volume (admin password required):
	sudo make -C tcl${ver}/macosx install
Deleted macosx/Tcl-Common.xcconfig.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//
// Tcl-Common.xcconfig --
//
//	This file contains the Xcode build settings comon to all
//	project configurations in Tcl.xcodeproj.
//
// Copyright (c) 2007-2008 Daniel A. Steffen <das@users.sourceforge.net>
//
// See the file "license.terms" for information on usage and redistribution
// of this file, and for a DISCLAIMER OF ALL WARRANTIES.

HEADER_SEARCH_PATHS = "$(DERIVED_FILE_DIR)/tcl" $(HEADER_SEARCH_PATHS)
OTHER_LDFLAGS = -headerpad_max_install_names -sectcreate __TEXT __info_plist "$(DERIVED_FILE_DIR)/tcl/Tclsh-Info.plist" $(OTHER_LDFLAGS)
INSTALL_PATH = $(BINDIR)
INSTALL_MODE_FLAG = go-w,a+rX
GCC_PREFIX_HEADER = $(DERIVED_FILE_DIR)/tcl/tclConfig.h
GCC_GENERATE_DEBUGGING_SYMBOLS = YES
GCC_NO_COMMON_BLOCKS = YES
GCC_DYNAMIC_NO_PIC = YES
GCC_VERSION = 4.2
GCC = gcc-$(GCC_VERSION)
WARNING_CFLAGS = -Wall -Wextra -Wshadow -Wwrite-strings -Wpointer-arith -Wc++-compat -Winit-self -Wcast-align -Wdisabled-optimization -Winline $(WARNING_CFLAGS)
BINDIR = $(PREFIX)/bin
CFLAGS = $(CFLAGS)
CPPFLAGS = -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET) $(CPPFLAGS)
FRAMEWORK_INSTALL_PATH = /Library/Frameworks
INCLUDEDIR = $(PREFIX)/include
LIBDIR = $(PREFIX)/lib
MANDIR = $(PREFIX)/man
PREFIX = /usr/local
TCL_CONFIGURE_ARGS = --enable-dtrace
TCL_LIBRARY = $(LIBDIR)/tcl$(VERSION)
TCL_PACKAGE_PATH = "$(LIBDIR)"
TCL_DEFS = HAVE_TCL_CONFIG_H
VERSION = 9.1
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































Deleted macosx/Tcl-Debug.xcconfig.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//
// Tcl-Debug.xcconfig --
//
//	This file contains the Xcode build settings for all Debug
//	project configurations in Tcl.xcodeproj.
//
// Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
//
// See the file "license.terms" for information on usage and redistribution
// of this file, and for a DISCLAIMER OF ALL WARRANTIES.

#include "Tcl-Common.xcconfig"

DEBUG_INFORMATION_FORMAT = dwarf
DEAD_CODE_STRIPPING = NO
DEPLOYMENT_POSTPROCESSING = NO
GCC_OPTIMIZATION_LEVEL = 0
GCC_PREPROCESSOR_DEFINITIONS = $(TCL_DEFS) $(GCC_PREPROCESSOR_DEFINITIONS)
CONFIGURE_ARGS = --enable-symbols $(TCL_CONFIGURE_ARGS) $(CONFIGURE_ARGS)
MAKE_TARGET = develop
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted macosx/Tcl-Release.xcconfig.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//
// Tcl-Release.xcconfig --
//
//	This file contains the Xcode build settings for all Release
//	project configurations in Tcl.xcodeproj.
//
// Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
//
// See the file "license.terms" for information on usage and redistribution
// of this file, and for a DISCLAIMER OF ALL WARRANTIES.

#include "Tcl-Common.xcconfig"

DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
DEAD_CODE_STRIPPING = YES
DEPLOYMENT_POSTPROCESSING = YES
GCC_OPTIMIZATION_LEVEL = 2
GCC_PREPROCESSOR_DEFINITIONS = NDEBUG $(TCL_DEFS) $(GCC_PREPROCESSOR_DEFINITIONS)
CONFIGURE_ARGS = --disable-symbols $(TCL_CONFIGURE_ARGS) $(CONFIGURE_ARGS)
MAKE_TARGET = deploy
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted macosx/Tcl.xcodeproj/default.pbxuser.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
// !$*UTF8*$!
{
	08FB7793FE84155DC02AAC07 /* Project object */ = {
		activeBuildConfigurationName = Debug;
		activeExecutable = F9E61D1C090A4282002B3151 /* tclsh */;
		activeTarget = F9E61D16090A3E94002B3151 /* Tcl */;
		codeSenseManager = F944EB9D08F798180049FDD4 /* Code sense */;
		executables = (
			F9E61D1C090A4282002B3151 /* tclsh */,
			F944EB8F08F798100049FDD4 /* tcltest */,
		);
		perUserDictionary = {
			com.apple.ide.smrt.PBXUserSmartGroupsKey.Rev10 = <040b73747265616d747970656481e8038401408484840e4e534d757461626c654172726179008484074e534172726179008484084e534f626a65637400858401690192848484134e534d757461626c6544696374696f6e6172790084840c4e5344696374696f6e6172790095960792848484084e53537472696e67019584012b046e616d658692849a9a14496d706c656d656e746174696f6e2046696c65738692849a9a195042585472616e7369656e744c6f636174696f6e4174546f708692849a9a06626f74746f6d8692849a9a0b707265666572656e63657386928497960892849a9a0669734c6561668692848484084e534e756d626572008484074e5356616c7565009584012a849696008692849a9a04726f6f748692849a9a093c50524f4a4543543e8692849a9a09726563757273697665869284a29da496018692849a9a05696d6167658692849a9a0b536d617274466f6c6465728692849a9a0763616e536176658692a892849a9a1250425850726f6a65637453636f70654b65798692849a9a035945538692849a9a0572656765788692849a9a065c2e286329248692849a9a07666e6d617463688692849a9a00868692849a9a146162736f6c75746550617468546f42756e646c658692849a9a008692849a9a0b6465736372697074696f6e8692849a9a103c6e6f206465736372697074696f6e3e8692849a9a08676c6f62616c49448692849a9a183143433045413430303433353045463930303434343130428692849a9a03636c7a8692849a9a1550425846696c656e616d65536d61727447726f7570868686>;
		};
		sourceControlManager = F944EB9C08F798180049FDD4 /* Source Control */;
		userBuildSettings = {
			SYMROOT = "${SRCROOT}/../../build/tcl";
			TCL_SRCROOT = "${SRCROOT}/../../tcl";
		};
	};
	8DD76FA90486AB0100D96B5E /* tcltest */ = {
		activeExec = 0;
		executables = (
			F944EB8F08F798100049FDD4 /* tcltest */,
		);
	};
	F944EB8F08F798100049FDD4 /* tcltest */ = {
		isa = PBXExecutable;
		activeArgIndices = (
			NO,
			NO,
			NO,
		);
		argumentStrings = (
			"${TCL_SRCROOT}/tests/all.tcl",
			"-singleproc 1",
			"-verbose \"bet\"",
		);
		autoAttachOnCrash = 1;
		breakpointsEnabled = 1;
		configStateDict = {
			"PBXLSLaunchAction-0" = {
				PBXLSLaunchAction = 0;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXLSRunLaunchConfig;
				displayName = "Executable Runner";
				identifier = com.apple.Xcode.launch.runConfig;
				remoteHostInfo = "";
				startActionInfo = "";
			};
			"PBXLSLaunchAction-1" = {
				PBXLSLaunchAction = 1;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXGDB_LaunchConfig;
				displayName = GDB;
				identifier = com.apple.Xcode.launch.GDBMI_Config;
				remoteHostInfo = "";
				startActionInfo = "";
			};
		};
		customDataFormattersEnabled = 1;
		dataTipCustomDataFormattersEnabled = 1;
		dataTipShowTypeColumn = 1;
		dataTipSortType = 0;
		debuggerPlugin = GDBDebugging;
		disassemblyDisplayState = 0;
		dylibVariantSuffix = "";
		enableDebugStr = 0;
		environmentEntries = (
			{
				active = YES;
				name = TCL_LIBRARY;
				value = "${TCL_SRCROOT}/library";
			},
			{
				active = YES;
				name = TCLLIBPATH;
				value = /Library/Tcl;
			},
			{
				active = NO;
				name = DYLD_PRINT_LIBRARIES;
			},
			{
				active = NO;
				name = MallocBadFreeAbort;
				value = 1;
			},
			{
				active = NO;
				name = MallocLogFile;
				value = /tmp/malloc.log;
			},
			{
				active = NO;
				name = MallocStackLogging;
				value = 1;
			},
			{
				active = NO;
				name = MallocStackLoggingNoCompact;
				value = 1;
			},
			{
				active = NO;
				name = MallocPreScribble;
				value = 1;
			},
			{
				active = NO;
				name = MallocScribble;
				value = 1;
			},
		);
		executableSystemSymbolLevel = 0;
		executableUserSymbolLevel = 0;
		libgmallocEnabled = 0;
		name = tcltest;
		showTypeColumn = 0;
		sourceDirectories = (
		);
	};
	F944EB9C08F798180049FDD4 /* Source Control */ = {
		isa = PBXSourceControlManager;
		fallbackIsa = XCSourceControlManager;
		isSCMEnabled = 0;
		repositoryNamesForRoots = {
			.. = "";
		};
		scmConfiguration = {
			CVSToolPath = /usr/bin/cvs;
			CVSUseSSH = NO;
			SubversionToolPath = /usr/bin/svn;
			repositoryNamesForRoots = {
				.. = "";
			};
		};
		scmType = scm.cvs;
	};
	F944EB9D08F798180049FDD4 /* Code sense */ = {
		isa = PBXCodeSenseManager;
		indexTemplatePath = "";
	};
	F97258A50A86873C00096C78 /* tests */ = {
		activeExec = 0;
	};
	F9E61D16090A3E94002B3151 /* Tcl */ = {
		activeExec = 0;
		executables = (
			F9E61D1C090A4282002B3151 /* tclsh */,
		);
	};
	F9E61D1C090A4282002B3151 /* tclsh */ = {
		isa = PBXExecutable;
		activeArgIndices = (
		);
		argumentStrings = (
		);
		autoAttachOnCrash = 1;
		breakpointsEnabled = 1;
		configStateDict = {
			"PBXLSLaunchAction-0" = {
				PBXLSLaunchAction = 0;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXLSRunLaunchConfig;
				displayName = "Executable Runner";
				identifier = com.apple.Xcode.launch.runConfig;
				remoteHostInfo = "";
				startActionInfo = "";
			};
			"PBXLSLaunchAction-1" = {
				PBXLSLaunchAction = 1;
				PBXLSLaunchStartAction = 1;
				PBXLSLaunchStdioStyle = 2;
				PBXLSLaunchStyle = 0;
				class = PBXGDB_LaunchConfig;
				displayName = GDB;
				identifier = com.apple.Xcode.launch.GDBMI_Config;
				remoteHostInfo = "";
				startActionInfo = "";
			};
		};
		customDataFormattersEnabled = 1;
		dataTipCustomDataFormattersEnabled = 1;
		dataTipShowTypeColumn = 1;
		dataTipSortType = 0;
		debuggerPlugin = GDBDebugging;
		disassemblyDisplayState = 0;
		dylibVariantSuffix = _debug;
		enableDebugStr = 0;
		environmentEntries = (
			{
				active = NO;
				name = DYLD_PRINT_LIBRARIES;
			},
		);
		executableSystemSymbolLevel = 0;
		executableUserSymbolLevel = 0;
		libgmallocEnabled = 0;
		name = tclsh;
		showTypeColumn = 0;
		sourceDirectories = (
		);
	};
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































Deleted macosx/Tcl.xcodeproj/project.pbxproj.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
// !$*UTF8*$!
{
	archiveVersion = 1;
	classes = {
	};
	objectVersion = 46;
	objects = {

/* Begin PBXBuildFile section */
		F90509300913A72400327603 /* tclAppInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445508F272B9004A47F5 /* tclAppInit.c */; settings = {COMPILER_FLAGS = "-DTCL_TEST -DTCL_BUILDTIME_LIBRARY=\\\"$(TCL_SRCROOT)/library\\\""; }; };
		F93599B30DF1F75400E04F67 /* tclOO.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B20DF1F75400E04F67 /* tclOO.c */; };
		F93599B70DF1F76100E04F67 /* tclOOBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B60DF1F76100E04F67 /* tclOOBasic.c */; };
		F93599B90DF1F76600E04F67 /* tclOOCall.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B80DF1F76600E04F67 /* tclOOCall.c */; };
		F93599BC0DF1F77000E04F67 /* tclOODefineCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599BB0DF1F77000E04F67 /* tclOODefineCmds.c */; };
		F93599BE0DF1F77400E04F67 /* tclOOInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599BD0DF1F77400E04F67 /* tclOOInfo.c */; };
		F93599C20DF1F78300E04F67 /* tclOOMethod.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C10DF1F78300E04F67 /* tclOOMethod.c */; };
		F93599C40DF1F78800E04F67 /* tclOOStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C30DF1F78800E04F67 /* tclOOStubInit.c */; };
		F93599C60DF1F78D00E04F67 /* tclOOStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C50DF1F78D00E04F67 /* tclOOStubLib.c */; };
		F95D77EA0DFD820D00A8BF6F /* tclIORTrans.c in Sources */ = {isa = PBXBuildFile; fileRef = F95D77E90DFD820D00A8BF6F /* tclIORTrans.c */; };
		F96437CA0EF0D4B2003F468E /* tclZlib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96437C90EF0D4B2003F468E /* tclZlib.c */; };
		F96437E70EF0D652003F468E /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F96437E60EF0D652003F468E /* libz.dylib */; };
		F966C07508F2820D005CB29B /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07408F2820D005CB29B /* CoreFoundation.framework */; };
		F96D456F08F272BB004A47F5 /* regcomp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED008F272A7004A47F5 /* regcomp.c */; };
		F96D457208F272BB004A47F5 /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED308F272A7004A47F5 /* regerror.c */; };
		F96D457508F272BB004A47F5 /* regexec.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED608F272A7004A47F5 /* regexec.c */; };
		F96D457608F272BB004A47F5 /* regfree.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED708F272A7004A47F5 /* regfree.c */; };
		F96D457B08F272BB004A47F5 /* tclAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDC08F272A7004A47F5 /* tclAlloc.c */; settings = {COMPILER_FLAGS = "-DUSE_TCLALLOC=0"; }; };
		F96D457C08F272BB004A47F5 /* tclAsync.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDD08F272A7004A47F5 /* tclAsync.c */; };
		F96D457D08F272BB004A47F5 /* tclBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDE08F272A7004A47F5 /* tclBasic.c */; };
		F96D457E08F272BC004A47F5 /* tclBinary.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDF08F272A7004A47F5 /* tclBinary.c */; };
		F96D457F08F272BC004A47F5 /* tclCkalloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE008F272A7004A47F5 /* tclCkalloc.c */; };
		F96D458008F272BC004A47F5 /* tclClock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE108F272A7004A47F5 /* tclClock.c */; };
		F96D458108F272BC004A47F5 /* tclCmdAH.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE208F272A7004A47F5 /* tclCmdAH.c */; };
		F96D458208F272BC004A47F5 /* tclCmdIL.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE308F272A7004A47F5 /* tclCmdIL.c */; };
		F96D458308F272BC004A47F5 /* tclCmdMZ.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */; };
		F96D458408F272BC004A47F5 /* tclCompCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE508F272A7004A47F5 /* tclCompCmds.c */; };
		F96D458508F272BC004A47F5 /* tclCompExpr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE608F272A7004A47F5 /* tclCompExpr.c */; };
		F96D458608F272BC004A47F5 /* tclCompile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE708F272A7004A47F5 /* tclCompile.c */; };
		F96D458808F272BC004A47F5 /* tclConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE908F272A7004A47F5 /* tclConfig.c */; };
		F96D458908F272BC004A47F5 /* tclDate.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEA08F272A7004A47F5 /* tclDate.c */; };
		F96D458B08F272BC004A47F5 /* tclDictObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEC08F272A7004A47F5 /* tclDictObj.c */; };
		F96D458C08F272BC004A47F5 /* tclEncoding.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EED08F272A7004A47F5 /* tclEncoding.c */; };
		F96D458D08F272BC004A47F5 /* tclEnv.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEE08F272A7004A47F5 /* tclEnv.c */; };
		F96D458E08F272BC004A47F5 /* tclEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEF08F272A7004A47F5 /* tclEvent.c */; };
		F96D458F08F272BC004A47F5 /* tclExecute.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF008F272A7004A47F5 /* tclExecute.c */; };
		F96D459008F272BC004A47F5 /* tclFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF108F272A7004A47F5 /* tclFCmd.c */; };
		F96D459108F272BC004A47F5 /* tclFileName.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF208F272A7004A47F5 /* tclFileName.c */; };
		F96D459308F272BC004A47F5 /* tclGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF408F272A7004A47F5 /* tclGet.c */; };
		F96D459508F272BC004A47F5 /* tclHash.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF608F272A7004A47F5 /* tclHash.c */; };
		F96D459608F272BC004A47F5 /* tclHistory.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF708F272A7004A47F5 /* tclHistory.c */; };
		F96D459708F272BC004A47F5 /* tclIndexObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF808F272A7004A47F5 /* tclIndexObj.c */; };
		F96D459B08F272BC004A47F5 /* tclInterp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFC08F272A7004A47F5 /* tclInterp.c */; };
		F96D459D08F272BC004A47F5 /* tclIO.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFE08F272A7004A47F5 /* tclIO.c */; };
		F96D459F08F272BC004A47F5 /* tclIOCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0008F272A7004A47F5 /* tclIOCmd.c */; };
		F96D45A008F272BC004A47F5 /* tclIOGT.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0108F272A7004A47F5 /* tclIOGT.c */; };
		F96D45A108F272BC004A47F5 /* tclIORChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0208F272A7004A47F5 /* tclIORChan.c */; };
		F96D45A208F272BC004A47F5 /* tclIOSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0308F272A7004A47F5 /* tclIOSock.c */; };
		F96D45A308F272BC004A47F5 /* tclIOUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0408F272A7004A47F5 /* tclIOUtil.c */; };
		F96D45A408F272BC004A47F5 /* tclLink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0508F272A7004A47F5 /* tclLink.c */; };
		F96D45A508F272BC004A47F5 /* tclListObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0608F272A7004A47F5 /* tclListObj.c */; };
		F96D45A608F272BC004A47F5 /* tclLiteral.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0708F272A7004A47F5 /* tclLiteral.c */; };
		F96D45A708F272BC004A47F5 /* tclLoad.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0808F272A7004A47F5 /* tclLoad.c */; };
		F96D45A908F272BC004A47F5 /* tclMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0A08F272A7004A47F5 /* tclMain.c */; };
		F96D45AA08F272BC004A47F5 /* tclNamesp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0B08F272A7004A47F5 /* tclNamesp.c */; };
		F96D45AB08F272BC004A47F5 /* tclNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0C08F272A7004A47F5 /* tclNotify.c */; };
		F96D45AC08F272BC004A47F5 /* tclObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0D08F272A7004A47F5 /* tclObj.c */; };
		F96D45AD08F272BC004A47F5 /* tclPanic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0E08F272A7004A47F5 /* tclPanic.c */; };
		F96D45AE08F272BC004A47F5 /* tclParse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0F08F272A7004A47F5 /* tclParse.c */; };
		F96D45B008F272BC004A47F5 /* tclPathObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1108F272A7004A47F5 /* tclPathObj.c */; };
		F96D45B108F272BC004A47F5 /* tclPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1208F272A7004A47F5 /* tclPipe.c */; };
		F96D45B208F272BC004A47F5 /* tclPkg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1308F272A7004A47F5 /* tclPkg.c */; };
		F96D45B308F272BC004A47F5 /* tclPkgConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */; settings = {COMPILER_FLAGS = "-DCFG_INSTALL_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_INSTALL_BINDIR=\\\"$(BINDIR)\\\" -DCFG_INSTALL_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_INSTALL_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_INSTALL_DOCDIR=\\\"$(MANDIR)\\\" -DCFG_RUNTIME_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_RUNTIME_BINDIR=\\\"$(BINDIR)\\\" -DCFG_RUNTIME_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_RUNTIME_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_RUNTIME_DOCDIR=\\\"$(MANDIR)\\\""; }; };
		F96D45B608F272BC004A47F5 /* tclPosixStr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1708F272A7004A47F5 /* tclPosixStr.c */; };
		F96D45B708F272BC004A47F5 /* tclPreserve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1808F272A7004A47F5 /* tclPreserve.c */; };
		F96D45B808F272BC004A47F5 /* tclProc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1908F272A7004A47F5 /* tclProc.c */; };
		F96D45B908F272BC004A47F5 /* tclRegexp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1A08F272A7004A47F5 /* tclRegexp.c */; };
		F96D45BB08F272BC004A47F5 /* tclResolve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1C08F272A7004A47F5 /* tclResolve.c */; };
		F96D45BC08F272BC004A47F5 /* tclResult.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1D08F272A7004A47F5 /* tclResult.c */; };
		F96D45BD08F272BC004A47F5 /* tclScan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1E08F272A7004A47F5 /* tclScan.c */; };
		F96D45BE08F272BC004A47F5 /* tclStringObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1F08F272A7004A47F5 /* tclStringObj.c */; };
		F96D45C308F272BC004A47F5 /* tclStrToD.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2408F272A7004A47F5 /* tclStrToD.c */; };
		F96D45C408F272BC004A47F5 /* tclStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2508F272A7004A47F5 /* tclStubInit.c */; };
		F96D45C508F272BC004A47F5 /* tclStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2608F272A7004A47F5 /* tclStubLib.c */; };
		F96D45C608F272BC004A47F5 /* tclTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2708F272A7004A47F5 /* tclTest.c */; };
		F96D45C708F272BC004A47F5 /* tclTestObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2808F272A7004A47F5 /* tclTestObj.c */; };
		F96D45C808F272BC004A47F5 /* tclTestProcBodyObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2908F272A7004A47F5 /* tclTestProcBodyObj.c */; };
		F96D45C908F272BC004A47F5 /* tclThread.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2A08F272A7004A47F5 /* tclThread.c */; };
		F96D45CA08F272BC004A47F5 /* tclThreadAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */; };
		F96D45CB08F272BC004A47F5 /* tclThreadJoin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */; };
		F96D45CC08F272BC004A47F5 /* tclThreadStorage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */; };
		F96D45CD08F272BC004A47F5 /* tclThreadTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2E08F272A7004A47F5 /* tclThreadTest.c */; };
		F96D45CE08F272BC004A47F5 /* tclTimer.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2F08F272A7004A47F5 /* tclTimer.c */; };
		F96D45D008F272BC004A47F5 /* tclTomMathInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */; };
		F96D45D108F272BC004A47F5 /* tclTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3208F272A7004A47F5 /* tclTrace.c */; };
		F96D45D308F272BC004A47F5 /* tclUtf.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3408F272A7004A47F5 /* tclUtf.c */; };
		F96D45D408F272BC004A47F5 /* tclUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3508F272A7004A47F5 /* tclUtil.c */; };
		F96D45D508F272BC004A47F5 /* tclVar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3608F272A7004A47F5 /* tclVar.c */; };
		F96D48E208F272C3004A47F5 /* bn_fast_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */; };
		F96D48E408F272C3004A47F5 /* bn_fast_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */; };
		F96D48E708F272C3004A47F5 /* bn_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426908F272B3004A47F5 /* bn_mp_add.c */; };
		F96D48E808F272C3004A47F5 /* bn_mp_add_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */; };
		F96D48EB08F272C3004A47F5 /* bn_mp_clamp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */; };
		F96D48EC08F272C3004A47F5 /* bn_mp_clear.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426E08F272B3004A47F5 /* bn_mp_clear.c */; };
		F96D48ED08F272C3004A47F5 /* bn_mp_clear_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */; };
		F96D48EE08F272C3004A47F5 /* bn_mp_cmp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427008F272B3004A47F5 /* bn_mp_cmp.c */; };
		F96D48F008F272C3004A47F5 /* bn_mp_cmp_mag.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */; };
		F96D48F208F272C3004A47F5 /* bn_mp_cnt_lsb.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427408F272B3004A47F5 /* bn_mp_cnt_lsb.c */; };
		F96D48F208F272C3004A47F5 /* bn_mp_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427408F272B3004A47F5 /* bn_mp_copy.c */; };
		F96D48F308F272C3004A47F5 /* bn_mp_count_bits.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */; };
		F96D48F408F272C3004A47F5 /* bn_mp_div.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427608F272B3004A47F5 /* bn_mp_div.c */; };
		F96D48F508F272C3004A47F5 /* bn_mp_div_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427708F272B3004A47F5 /* bn_mp_div_2.c */; };
		F96D48F608F272C3004A47F5 /* bn_mp_div_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */; };
		F96D48F708F272C3004A47F5 /* bn_s_mp_div_3.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427908F272B3004A47F5 /* bn_s_mp_div_3.c */; };
		F96D48F808F272C3004A47F5 /* bn_mp_div_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */; };
		F96D48FC08F272C3004A47F5 /* bn_mp_exch.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427E08F272B3004A47F5 /* bn_mp_exch.c */; };
		F96D490508F272C3004A47F5 /* bn_mp_grow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428708F272B3004A47F5 /* bn_mp_grow.c */; };
		F96D490608F272C3004A47F5 /* bn_mp_init.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428808F272B3004A47F5 /* bn_mp_init.c */; };
		F96D490708F272C3004A47F5 /* bn_mp_init_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */; };
		F96D490808F272C3004A47F5 /* bn_mp_init_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */; };
		F96D490908F272C3004A47F5 /* bn_mp_init_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */; };
		F96D490B08F272C3004A47F5 /* bn_mp_init_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */; };
		F96D491008F272C3004A47F5 /* bn_mp_karatsuba_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */; };
		F96D491108F272C3004A47F5 /* bn_mp_karatsuba_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */; };
		F96D491308F272C3004A47F5 /* bn_mp_lshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429508F272B3004A47F5 /* bn_mp_lshd.c */; };
		F96D491408F272C3004A47F5 /* bn_mp_mod.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429608F272B3004A47F5 /* bn_mp_mod.c */; };
		F96D491508F272C3004A47F5 /* bn_mp_mod_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */; };
		F96D491A08F272C3004A47F5 /* bn_mp_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429C08F272B3004A47F5 /* bn_mp_mul.c */; };
		F96D491B08F272C3004A47F5 /* bn_mp_mul_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */; };
		F96D491C08F272C3004A47F5 /* bn_mp_mul_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */; };
		F96D491D08F272C3004A47F5 /* bn_mp_mul_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */; };
		F96D492908F272C3004A47F5 /* bn_mp_radix_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */; };
		F96D492A08F272C3004A47F5 /* bn_mp_radix_smap.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */; };
		F96D492C08F272C3004A47F5 /* bn_mp_read_radix.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */; };
		F96D493708F272C3004A47F5 /* bn_mp_rshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */; };
		F96D493808F272C3004A47F5 /* bn_mp_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BA08F272B3004A47F5 /* bn_mp_set.c */; };
		F96D493C08F272C3004A47F5 /* bn_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */; };
		F96D493F08F272C3004A47F5 /* bn_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C108F272B3004A47F5 /* bn_mp_sub.c */; };
		F96D494008F272C3004A47F5 /* bn_mp_sub_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */; };
		F96D494608F272C3004A47F5 /* bn_mp_toom_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */; };
		F96D494708F272C3004A47F5 /* bn_mp_toom_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */; };
		F96D494908F272C3004A47F5 /* bn_mp_to_radix.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CB08F272B3004A47F5 /* bn_mp_to_radix.c */; };
		F96D494C08F272C3004A47F5 /* bn_mp_zero.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */; };
		F96D494F08F272C3004A47F5 /* bn_s_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */; };
		F96D495108F272C3004A47F5 /* bn_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */; };
		F96D495308F272C3004A47F5 /* bn_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */; };
		F96D495408F272C3004A47F5 /* bn_s_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */; };
		F96D49A908F272C4004A47F5 /* tclMacOSXBundle.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */; };
		F96D49AD08F272C4004A47F5 /* tclMacOSXFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */; };
		F96D49AE08F272C4004A47F5 /* tclMacOSXNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */; };
		F96D4AC608F272C9004A47F5 /* tclLoadDyld.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445B08F272B9004A47F5 /* tclLoadDyld.c */; settings = {COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; };
		F96D4ACA08F272C9004A47F5 /* tclUnixChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445F08F272B9004A47F5 /* tclUnixChan.c */; };
		F96D4ACB08F272C9004A47F5 /* tclUnixEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446008F272B9004A47F5 /* tclUnixEvent.c */; };
		F96D4ACC08F272C9004A47F5 /* tclUnixFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446108F272B9004A47F5 /* tclUnixFCmd.c */; };
		F96D4ACD08F272C9004A47F5 /* tclUnixFile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446208F272B9004A47F5 /* tclUnixFile.c */; };
		F96D4ACE08F272C9004A47F5 /* tclUnixInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446308F272B9004A47F5 /* tclUnixInit.c */; settings = {COMPILER_FLAGS = "-DTCL_LIBRARY=\\\"$(TCL_LIBRARY)\\\" -DTCL_PACKAGE_PATH=\\\"$(TCL_PACKAGE_PATH)\\\""; }; };
		F96D4ACF08F272C9004A47F5 /* tclUnixNotfy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446408F272B9004A47F5 /* tclUnixNotfy.c */; };
		F96D4AD008F272C9004A47F5 /* tclUnixPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446508F272B9004A47F5 /* tclUnixPipe.c */; };
		F96D4AD208F272CA004A47F5 /* tclUnixSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446708F272B9004A47F5 /* tclUnixSock.c */; };
		F96D4AD308F272CA004A47F5 /* tclUnixTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446808F272B9004A47F5 /* tclUnixTest.c */; };
		F96D4AD408F272CA004A47F5 /* tclUnixThrd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446908F272B9004A47F5 /* tclUnixThrd.c */; };
		F96D4AD608F272CA004A47F5 /* tclUnixTime.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446B08F272B9004A47F5 /* tclUnixTime.c */; };
		F9E61D28090A481F002B3151 /* bn_mp_cmp_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */; };
		F9E61D29090A486C002B3151 /* bn_mp_neg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A208F272B3004A47F5 /* bn_mp_neg.c */; };
		F9E61D2A090A4891002B3151 /* bn_mp_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */; };
		F9E61D2B090A48A4002B3151 /* bn_mp_and.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426C08F272B3004A47F5 /* bn_mp_and.c */; };
		F9E61D2C090A48AC002B3151 /* bn_mp_expt_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427F08F272B3004A47F5 /* bn_mp_expt_n.c */; };
		F9E61D2D090A48BB002B3151 /* bn_mp_xor.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */; };
		F9E61D2E090A48BF002B3151 /* bn_mp_or.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A308F272B3004A47F5 /* bn_mp_or.c */; };
		F9E61D2F090A48C7002B3151 /* bn_mp_shrink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */; };
		F9E61D31090A48F9002B3151 /* bn_mp_to_ubin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C608F272B3004A47F5 /* bn_mp_to_ubin.c */; };
		F9E61D32090A48FA002B3151 /* bn_mp_ubin_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CC08F272B3004A47F5 /* bn_mp_ubin_size.c */; };
		F9F4415E0C8BAE6F00BCCD67 /* tclDTrace.d in Sources */ = {isa = PBXBuildFile; fileRef = F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */; };
		F9FC77B80AB29E9100B7077D /* tclUnixCompat.c in Sources */ = {isa = PBXBuildFile; fileRef = F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
		F97258D20A868C6F00096C78 /* PBXContainerItemProxy */ = {
			isa = PBXContainerItemProxy;
			containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
			proxyType = 1;
			remoteGlobalIDString = 8DD76FA90486AB0100D96B5E;
			remoteInfo = tcltest;
		};
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
		8DD76FB20486AB0100D96B5E /* tcltest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = tcltest; sourceTree = BUILT_PRODUCTS_DIR; };
		F915432A0EF201CF0032D1E8 /* zlib.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = zlib.test; sourceTree = "<group>"; };
		F915432D0EF201EE0032D1E8 /* zlib.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = zlib.n; sourceTree = "<group>"; };
		F9183E640EFC80CD0030B814 /* throw.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = throw.n; sourceTree = "<group>"; };
		F9183E650EFC80D70030B814 /* try.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = try.n; sourceTree = "<group>"; };
		F9183E6A0EFC81560030B814 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F9183E8F0EFC817B0030B814 /* tdbc */ = {isa = PBXFileReference; lastKnownFileType = folder; path = tdbc; sourceTree = "<group>"; };
		F91DC23C0E44C51B002CB8D1 /* nre.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = nre.test; sourceTree = "<group>"; };
		F91E62260C1AE686006C9D96 /* Tclsh-Info.plist.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "Tclsh-Info.plist.in"; sourceTree = "<group>"; };
		F92D7F100DE777240033A13A /* tsdPerf.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tsdPerf.tcl; sourceTree = "<group>"; };
		F93599B20DF1F75400E04F67 /* tclOO.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOO.c; sourceTree = "<group>"; };
		F93599B40DF1F75900E04F67 /* tclOO.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclOO.decls; sourceTree = "<group>"; };
		F93599B50DF1F75D00E04F67 /* tclOO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOO.h; sourceTree = "<group>"; };
		F93599B60DF1F76100E04F67 /* tclOOBasic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOBasic.c; sourceTree = "<group>"; };
		F93599B80DF1F76600E04F67 /* tclOOCall.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOCall.c; sourceTree = "<group>"; };
		F93599BA0DF1F76A00E04F67 /* tclOODecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOODecls.h; sourceTree = "<group>"; };
		F93599BB0DF1F77000E04F67 /* tclOODefineCmds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOODefineCmds.c; sourceTree = "<group>"; };
		F93599BD0DF1F77400E04F67 /* tclOOInfo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOInfo.c; sourceTree = "<group>"; };
		F93599BF0DF1F77900E04F67 /* tclOOInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOOInt.h; sourceTree = "<group>"; };
		F93599C00DF1F77D00E04F67 /* tclOOIntDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOOIntDecls.h; sourceTree = "<group>"; };
		F93599C10DF1F78300E04F67 /* tclOOMethod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOMethod.c; sourceTree = "<group>"; };
		F93599C30DF1F78800E04F67 /* tclOOStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOStubInit.c; sourceTree = "<group>"; };
		F93599C50DF1F78D00E04F67 /* tclOOStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOStubLib.c; sourceTree = "<group>"; };
		F93599C80DF1F81900E04F67 /* oo.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = oo.test; sourceTree = "<group>"; };
		F93599CF0DF1F87F00E04F67 /* Class.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Class.3; sourceTree = "<group>"; };
		F93599D00DF1F89E00E04F67 /* class.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = class.n; sourceTree = "<group>"; };
		F93599D20DF1F8DF00E04F67 /* copy.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = copy.n; sourceTree = "<group>"; };
		F93599D30DF1F8F500E04F67 /* define.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = define.n; sourceTree = "<group>"; };
		F93599D40DF1F91900E04F67 /* Method.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Method.3; sourceTree = "<group>"; };
		F93599D50DF1F93700E04F67 /* my.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = my.n; sourceTree = "<group>"; };
		F93599D60DF1F95000E04F67 /* next.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = next.n; sourceTree = "<group>"; };
		F93599D70DF1F96800E04F67 /* object.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = object.n; sourceTree = "<group>"; };
		F93599D80DF1F98300E04F67 /* self.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = self.n; sourceTree = "<group>"; };
		F946FB8B0FBE3AED00CD6495 /* itcl */ = {isa = PBXFileReference; lastKnownFileType = folder; path = itcl; sourceTree = "<group>"; };
		F95D77E90DFD820D00A8BF6F /* tclIORTrans.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIORTrans.c; sourceTree = "<group>"; };
		F95FAFF90B34F1130072E431 /* macOSXLoad.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = macOSXLoad.test; sourceTree = "<group>"; };
		F96437C90EF0D4B2003F468E /* tclZlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclZlib.c; sourceTree = "<group>"; };
		F96437E60EF0D652003F468E /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = "<absolute>"; };
		F966C07408F2820D005CB29B /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
		F96D3DFB08F272A4004A47F5 /* changes.md */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = changes.md; sourceTree = "<group>"; };
		F96D3DFD08F272A4004A47F5 /* Access.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Access.3; sourceTree = "<group>"; };
		F96D3DFE08F272A4004A47F5 /* AddErrInfo.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AddErrInfo.3; sourceTree = "<group>"; };
		F96D3DFF08F272A4004A47F5 /* after.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = after.n; sourceTree = "<group>"; };
		F96D3E0008F272A4004A47F5 /* Alloc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Alloc.3; sourceTree = "<group>"; };
		F96D3E0108F272A4004A47F5 /* AllowExc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AllowExc.3; sourceTree = "<group>"; };
		F96D3E0208F272A4004A47F5 /* append.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = append.n; sourceTree = "<group>"; };
		F96D3E0308F272A4004A47F5 /* AppInit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AppInit.3; sourceTree = "<group>"; };
		F96D3E0408F272A5004A47F5 /* array.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = array.n; sourceTree = "<group>"; };
		F96D3E0508F272A5004A47F5 /* AssocData.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AssocData.3; sourceTree = "<group>"; };
		F96D3E0608F272A5004A47F5 /* Async.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Async.3; sourceTree = "<group>"; };
		F96D3E0708F272A5004A47F5 /* BackgdErr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BackgdErr.3; sourceTree = "<group>"; };
		F96D3E0808F272A5004A47F5 /* Backslash.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Backslash.3; sourceTree = "<group>"; };
		F96D3E0908F272A5004A47F5 /* bgerror.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bgerror.n; sourceTree = "<group>"; };
		F96D3E0A08F272A5004A47F5 /* binary.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = binary.n; sourceTree = "<group>"; };
		F96D3E0B08F272A5004A47F5 /* BoolObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BoolObj.3; sourceTree = "<group>"; };
		F96D3E0C08F272A5004A47F5 /* break.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = break.n; sourceTree = "<group>"; };
		F96D3E0D08F272A5004A47F5 /* ByteArrObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ByteArrObj.3; sourceTree = "<group>"; };
		F96D3E0E08F272A5004A47F5 /* CallDel.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CallDel.3; sourceTree = "<group>"; };
		F96D3E1008F272A5004A47F5 /* catch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = catch.n; sourceTree = "<group>"; };
		F96D3E1108F272A5004A47F5 /* cd.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = cd.n; sourceTree = "<group>"; };
		F96D3E1208F272A5004A47F5 /* chan.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = chan.n; sourceTree = "<group>"; };
		F96D3E1308F272A5004A47F5 /* ChnlStack.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ChnlStack.3; sourceTree = "<group>"; };
		F96D3E1408F272A5004A47F5 /* clock.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = clock.n; sourceTree = "<group>"; };
		F96D3E1508F272A5004A47F5 /* close.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = close.n; sourceTree = "<group>"; };
		F96D3E1608F272A5004A47F5 /* CmdCmplt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CmdCmplt.3; sourceTree = "<group>"; };
		F96D3E1708F272A5004A47F5 /* Concat.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Concat.3; sourceTree = "<group>"; };
		F96D3E1808F272A5004A47F5 /* concat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = concat.n; sourceTree = "<group>"; };
		F96D3E1908F272A5004A47F5 /* continue.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = continue.n; sourceTree = "<group>"; };
		F96D3E1A08F272A5004A47F5 /* CrtChannel.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtChannel.3; sourceTree = "<group>"; };
		F96D3E1B08F272A5004A47F5 /* CrtChnlHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtChnlHdlr.3; sourceTree = "<group>"; };
		F96D3E1C08F272A5004A47F5 /* CrtCloseHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCloseHdlr.3; sourceTree = "<group>"; };
		F96D3E1D08F272A5004A47F5 /* CrtCommand.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCommand.3; sourceTree = "<group>"; };
		F96D3E1E08F272A5004A47F5 /* CrtFileHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtFileHdlr.3; sourceTree = "<group>"; };
		F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtInterp.3; sourceTree = "<group>"; };
		F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtMathFnc.3; sourceTree = "<group>"; };
		F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtObjCmd.3; sourceTree = "<group>"; };
		F96D3E2208F272A5004A47F5 /* CrtAlias.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtAlias.3; sourceTree = "<group>"; };
		F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTimerHdlr.3; sourceTree = "<group>"; };
		F96D3E2408F272A5004A47F5 /* CrtTrace.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTrace.3; sourceTree = "<group>"; };
		F96D3E2508F272A5004A47F5 /* dde.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dde.n; sourceTree = "<group>"; };
		F96D3E2608F272A5004A47F5 /* DetachPids.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DetachPids.3; sourceTree = "<group>"; };
		F96D3E2708F272A5004A47F5 /* dict.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dict.n; sourceTree = "<group>"; };
		F96D3E2808F272A5004A47F5 /* DictObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DictObj.3; sourceTree = "<group>"; };
		F96D3E2908F272A5004A47F5 /* DoOneEvent.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoOneEvent.3; sourceTree = "<group>"; };
		F96D3E2A08F272A5004A47F5 /* DoubleObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoubleObj.3; sourceTree = "<group>"; };
		F96D3E2B08F272A5004A47F5 /* DoWhenIdle.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoWhenIdle.3; sourceTree = "<group>"; };
		F96D3E2C08F272A5004A47F5 /* DString.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DString.3; sourceTree = "<group>"; };
		F96D3E2D08F272A5004A47F5 /* DumpActiveMemory.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DumpActiveMemory.3; sourceTree = "<group>"; };
		F96D3E2E08F272A5004A47F5 /* Encoding.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Encoding.3; sourceTree = "<group>"; };
		F96D3E2F08F272A5004A47F5 /* encoding.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = encoding.n; sourceTree = "<group>"; };
		F96D3E3008F272A5004A47F5 /* Ensemble.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Ensemble.3; sourceTree = "<group>"; };
		F96D3E3108F272A5004A47F5 /* Environment.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Environment.3; sourceTree = "<group>"; };
		F96D3E3208F272A5004A47F5 /* eof.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = eof.n; sourceTree = "<group>"; };
		F96D3E3308F272A5004A47F5 /* error.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = error.n; sourceTree = "<group>"; };
		F96D3E3408F272A5004A47F5 /* Eval.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Eval.3; sourceTree = "<group>"; };
		F96D3E3508F272A5004A47F5 /* eval.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = eval.n; sourceTree = "<group>"; };
		F96D3E3608F272A5004A47F5 /* exec.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = exec.n; sourceTree = "<group>"; };
		F96D3E3708F272A5004A47F5 /* Exit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Exit.3; sourceTree = "<group>"; };
		F96D3E3808F272A5004A47F5 /* exit.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = exit.n; sourceTree = "<group>"; };
		F96D3E3908F272A5004A47F5 /* expr.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = expr.n; sourceTree = "<group>"; };
		F96D3E3A08F272A5004A47F5 /* ExprLong.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ExprLong.3; sourceTree = "<group>"; };
		F96D3E3B08F272A5004A47F5 /* ExprLongObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ExprLongObj.3; sourceTree = "<group>"; };
		F96D3E3C08F272A5004A47F5 /* fblocked.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fblocked.n; sourceTree = "<group>"; };
		F96D3E3D08F272A5004A47F5 /* fconfigure.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fconfigure.n; sourceTree = "<group>"; };
		F96D3E3E08F272A5004A47F5 /* fcopy.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fcopy.n; sourceTree = "<group>"; };
		F96D3E3F08F272A5004A47F5 /* file.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = file.n; sourceTree = "<group>"; };
		F96D3E4008F272A5004A47F5 /* fileevent.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fileevent.n; sourceTree = "<group>"; };
		F96D3E4108F272A5004A47F5 /* filename.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = filename.n; sourceTree = "<group>"; };
		F96D3E4208F272A5004A47F5 /* FileSystem.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FileSystem.3; sourceTree = "<group>"; };
		F96D3E4308F272A5004A47F5 /* FindExec.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FindExec.3; sourceTree = "<group>"; };
		F96D3E4408F272A5004A47F5 /* flush.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = flush.n; sourceTree = "<group>"; };
		F96D3E4508F272A5004A47F5 /* for.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = for.n; sourceTree = "<group>"; };
		F96D3E4608F272A5004A47F5 /* foreach.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = foreach.n; sourceTree = "<group>"; };
		F96D3E4708F272A5004A47F5 /* format.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = format.n; sourceTree = "<group>"; };
		F96D3E4808F272A5004A47F5 /* GetCwd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetCwd.3; sourceTree = "<group>"; };
		F96D3E4908F272A5004A47F5 /* GetHostName.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetHostName.3; sourceTree = "<group>"; };
		F96D3E4A08F272A5004A47F5 /* GetIndex.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetIndex.3; sourceTree = "<group>"; };
		F96D3E4B08F272A5004A47F5 /* GetInt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetInt.3; sourceTree = "<group>"; };
		F96D3E4C08F272A5004A47F5 /* GetOpnFl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetOpnFl.3; sourceTree = "<group>"; };
		F96D3E4D08F272A5004A47F5 /* gets.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = gets.n; sourceTree = "<group>"; };
		F96D3E4E08F272A5004A47F5 /* GetStdChan.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetStdChan.3; sourceTree = "<group>"; };
		F96D3E4F08F272A5004A47F5 /* GetTime.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetTime.3; sourceTree = "<group>"; };
		F96D3E5008F272A5004A47F5 /* GetVersion.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetVersion.3; sourceTree = "<group>"; };
		F96D3E5108F272A5004A47F5 /* glob.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = glob.n; sourceTree = "<group>"; };
		F96D3E5208F272A6004A47F5 /* global.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = global.n; sourceTree = "<group>"; };
		F96D3E5308F272A6004A47F5 /* Hash.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Hash.3; sourceTree = "<group>"; };
		F96D3E5408F272A6004A47F5 /* history.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = history.n; sourceTree = "<group>"; };
		F96D3E5508F272A6004A47F5 /* http.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = http.n; sourceTree = "<group>"; };
		F96D3E5608F272A6004A47F5 /* if.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = if.n; sourceTree = "<group>"; };
		F96D3E5708F272A6004A47F5 /* incr.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = incr.n; sourceTree = "<group>"; };
		F96D3E5808F272A6004A47F5 /* info.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = info.n; sourceTree = "<group>"; };
		F96D3E5908F272A6004A47F5 /* Init.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Init.3; sourceTree = "<group>"; };
		F96D3E5A08F272A6004A47F5 /* InitStubs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = InitStubs.3; sourceTree = "<group>"; };
		F96D3E5B08F272A6004A47F5 /* Interp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Interp.3; sourceTree = "<group>"; };
		F96D3E5C08F272A6004A47F5 /* interp.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = interp.n; sourceTree = "<group>"; };
		F96D3E5D08F272A6004A47F5 /* IntObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = IntObj.3; sourceTree = "<group>"; };
		F96D3E5E08F272A6004A47F5 /* join.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = join.n; sourceTree = "<group>"; };
		F96D3E5F08F272A6004A47F5 /* lappend.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lappend.n; sourceTree = "<group>"; };
		F96D3E6008F272A6004A47F5 /* lassign.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lassign.n; sourceTree = "<group>"; };
		F96D3E6108F272A6004A47F5 /* library.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = library.n; sourceTree = "<group>"; };
		F96D3E6208F272A6004A47F5 /* Limit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Limit.3; sourceTree = "<group>"; };
		F96D3E6308F272A6004A47F5 /* lindex.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lindex.n; sourceTree = "<group>"; };
		F96D3E6408F272A6004A47F5 /* LinkVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = LinkVar.3; sourceTree = "<group>"; };
		F96D3E6508F272A6004A47F5 /* linsert.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = linsert.n; sourceTree = "<group>"; };
		F96D3E6608F272A6004A47F5 /* list.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = list.n; sourceTree = "<group>"; };
		F96D3E6708F272A6004A47F5 /* ListObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ListObj.3; sourceTree = "<group>"; };
		F96D3E6808F272A6004A47F5 /* llength.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = llength.n; sourceTree = "<group>"; };
		F96D3E6908F272A6004A47F5 /* load.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = load.n; sourceTree = "<group>"; };
		F96D3E6A08F272A6004A47F5 /* lrange.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lrange.n; sourceTree = "<group>"; };
		F96D3E6B08F272A6004A47F5 /* lrepeat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lrepeat.n; sourceTree = "<group>"; };
		F96D3E6C08F272A6004A47F5 /* lreplace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lreplace.n; sourceTree = "<group>"; };
		F96D3E6D08F272A6004A47F5 /* lsearch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lsearch.n; sourceTree = "<group>"; };
		F96D3E6E08F272A6004A47F5 /* lset.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lset.n; sourceTree = "<group>"; };
		F96D3E6F08F272A6004A47F5 /* lsort.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lsort.n; sourceTree = "<group>"; };
		F96D3E7008F272A6004A47F5 /* man.macros */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = man.macros; sourceTree = "<group>"; };
		F96D3E7108F272A6004A47F5 /* mathfunc.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = mathfunc.n; sourceTree = "<group>"; };
		F96D3E7208F272A6004A47F5 /* memory.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = memory.n; sourceTree = "<group>"; };
		F96D3E7308F272A6004A47F5 /* msgcat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = msgcat.n; sourceTree = "<group>"; };
		F96D3E7408F272A6004A47F5 /* Namespace.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Namespace.3; sourceTree = "<group>"; };
		F96D3E7508F272A6004A47F5 /* namespace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = namespace.n; sourceTree = "<group>"; };
		F96D3E7608F272A6004A47F5 /* Notifier.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Notifier.3; sourceTree = "<group>"; };
		F96D3E7708F272A6004A47F5 /* Object.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Object.3; sourceTree = "<group>"; };
		F96D3E7808F272A6004A47F5 /* ObjectType.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ObjectType.3; sourceTree = "<group>"; };
		F96D3E7908F272A6004A47F5 /* open.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = open.n; sourceTree = "<group>"; };
		F96D3E7A08F272A6004A47F5 /* OpenFileChnl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OpenFileChnl.3; sourceTree = "<group>"; };
		F96D3E7B08F272A6004A47F5 /* OpenTcp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OpenTcp.3; sourceTree = "<group>"; };
		F96D3E7C08F272A6004A47F5 /* package.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = package.n; sourceTree = "<group>"; };
		F96D3E7D08F272A6004A47F5 /* packagens.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = packagens.n; sourceTree = "<group>"; };
		F96D3E7E08F272A6004A47F5 /* Panic.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Panic.3; sourceTree = "<group>"; };
		F96D3E7F08F272A6004A47F5 /* ParseCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ParseCmd.3; sourceTree = "<group>"; };
		F96D3E8008F272A6004A47F5 /* pid.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pid.n; sourceTree = "<group>"; };
		F96D3E8108F272A6004A47F5 /* pkgMkIndex.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pkgMkIndex.n; sourceTree = "<group>"; };
		F96D3E8208F272A6004A47F5 /* PkgRequire.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = PkgRequire.3; sourceTree = "<group>"; };
		F96D3E8308F272A6004A47F5 /* Preserve.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Preserve.3; sourceTree = "<group>"; };
		F96D3E8408F272A6004A47F5 /* PrintDbl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = PrintDbl.3; sourceTree = "<group>"; };
		F96D3E8508F272A6004A47F5 /* proc.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = proc.n; sourceTree = "<group>"; };
		F96D3E8608F272A6004A47F5 /* puts.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = puts.n; sourceTree = "<group>"; };
		F96D3E8708F272A6004A47F5 /* pwd.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pwd.n; sourceTree = "<group>"; };
		F96D3E8808F272A6004A47F5 /* re_syntax.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = re_syntax.n; sourceTree = "<group>"; };
		F96D3E8908F272A6004A47F5 /* read.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = read.n; sourceTree = "<group>"; };
		F96D3E8A08F272A6004A47F5 /* RecEvalObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RecEvalObj.3; sourceTree = "<group>"; };
		F96D3E8B08F272A6004A47F5 /* RecordEval.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RecordEval.3; sourceTree = "<group>"; };
		F96D3E8C08F272A6004A47F5 /* RegConfig.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RegConfig.3; sourceTree = "<group>"; };
		F96D3E8D08F272A6004A47F5 /* RegExp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RegExp.3; sourceTree = "<group>"; };
		F96D3E8E08F272A6004A47F5 /* regexp.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = regexp.n; sourceTree = "<group>"; };
		F96D3E8F08F272A6004A47F5 /* registry.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = registry.n; sourceTree = "<group>"; };
		F96D3E9008F272A6004A47F5 /* regsub.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = regsub.n; sourceTree = "<group>"; };
		F96D3E9108F272A6004A47F5 /* rename.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = rename.n; sourceTree = "<group>"; };
		F96D3E9208F272A6004A47F5 /* return.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = return.n; sourceTree = "<group>"; };
		F96D3E9308F272A6004A47F5 /* safe.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = safe.n; sourceTree = "<group>"; };
		F96D3E9408F272A6004A47F5 /* SaveInterpState.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SaveInterpState.3; sourceTree = "<group>"; };
		F96D3E9508F272A6004A47F5 /* scan.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = scan.n; sourceTree = "<group>"; };
		F96D3E9608F272A6004A47F5 /* seek.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = seek.n; sourceTree = "<group>"; };
		F96D3E9708F272A6004A47F5 /* set.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = set.n; sourceTree = "<group>"; };
		F96D3E9808F272A6004A47F5 /* SetChanErr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetChanErr.3; sourceTree = "<group>"; };
		F96D3E9908F272A6004A47F5 /* SetErrno.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetErrno.3; sourceTree = "<group>"; };
		F96D3E9A08F272A6004A47F5 /* SetRecLmt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetRecLmt.3; sourceTree = "<group>"; };
		F96D3E9B08F272A7004A47F5 /* SetResult.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetResult.3; sourceTree = "<group>"; };
		F96D3E9C08F272A7004A47F5 /* SetVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetVar.3; sourceTree = "<group>"; };
		F96D3E9D08F272A7004A47F5 /* Signal.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Signal.3; sourceTree = "<group>"; };
		F96D3E9E08F272A7004A47F5 /* Sleep.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Sleep.3; sourceTree = "<group>"; };
		F96D3E9F08F272A7004A47F5 /* socket.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = socket.n; sourceTree = "<group>"; };
		F96D3EA008F272A7004A47F5 /* source.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = source.n; sourceTree = "<group>"; };
		F96D3EA108F272A7004A47F5 /* SourceRCFile.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SourceRCFile.3; sourceTree = "<group>"; };
		F96D3EA208F272A7004A47F5 /* split.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = split.n; sourceTree = "<group>"; };
		F96D3EA308F272A7004A47F5 /* SplitList.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitList.3; sourceTree = "<group>"; };
		F96D3EA408F272A7004A47F5 /* SplitPath.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitPath.3; sourceTree = "<group>"; };
		F96D3EA508F272A7004A47F5 /* StaticLibrary.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StaticLibrary.3; sourceTree = "<group>"; };
		F96D3EA608F272A7004A47F5 /* StdChannels.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StdChannels.3; sourceTree = "<group>"; };
		F96D3EA708F272A7004A47F5 /* string.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = string.n; sourceTree = "<group>"; };
		F96D3EA808F272A7004A47F5 /* StringObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StringObj.3; sourceTree = "<group>"; };
		F96D3EA908F272A7004A47F5 /* StrMatch.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StrMatch.3; sourceTree = "<group>"; };
		F96D3EAA08F272A7004A47F5 /* subst.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = subst.n; sourceTree = "<group>"; };
		F96D3EAB08F272A7004A47F5 /* SubstObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SubstObj.3; sourceTree = "<group>"; };
		F96D3EAC08F272A7004A47F5 /* switch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = switch.n; sourceTree = "<group>"; };
		F96D3EAD08F272A7004A47F5 /* Tcl.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tcl.n; sourceTree = "<group>"; };
		F96D3EAE08F272A7004A47F5 /* Tcl_Main.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tcl_Main.3; sourceTree = "<group>"; };
		F96D3EAF08F272A7004A47F5 /* TCL_MEM_DEBUG.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TCL_MEM_DEBUG.3; sourceTree = "<group>"; };
		F96D3EB008F272A7004A47F5 /* tclsh.1 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tclsh.1; sourceTree = "<group>"; };
		F96D3EB108F272A7004A47F5 /* tcltest.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tcltest.n; sourceTree = "<group>"; };
		F96D3EB208F272A7004A47F5 /* tclvars.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tclvars.n; sourceTree = "<group>"; };
		F96D3EB308F272A7004A47F5 /* tell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tell.n; sourceTree = "<group>"; };
		F96D3EB408F272A7004A47F5 /* Thread.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Thread.3; sourceTree = "<group>"; };
		F96D3EB508F272A7004A47F5 /* time.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = time.n; sourceTree = "<group>"; };
		F96D3EB608F272A7004A47F5 /* tm.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tm.n; sourceTree = "<group>"; };
		F96D3EB708F272A7004A47F5 /* ToUpper.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ToUpper.3; sourceTree = "<group>"; };
		F96D3EB808F272A7004A47F5 /* trace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = trace.n; sourceTree = "<group>"; };
		F96D3EB908F272A7004A47F5 /* TraceCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TraceCmd.3; sourceTree = "<group>"; };
		F96D3EBA08F272A7004A47F5 /* TraceVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TraceVar.3; sourceTree = "<group>"; };
		F96D3EBB08F272A7004A47F5 /* Translate.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Translate.3; sourceTree = "<group>"; };
		F96D3EBC08F272A7004A47F5 /* UniCharIsAlpha.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = UniCharIsAlpha.3; sourceTree = "<group>"; };
		F96D3EBD08F272A7004A47F5 /* unknown.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unknown.n; sourceTree = "<group>"; };
		F96D3EBE08F272A7004A47F5 /* unload.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unload.n; sourceTree = "<group>"; };
		F96D3EBF08F272A7004A47F5 /* unset.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unset.n; sourceTree = "<group>"; };
		F96D3EC008F272A7004A47F5 /* update.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = update.n; sourceTree = "<group>"; };
		F96D3EC108F272A7004A47F5 /* uplevel.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = uplevel.n; sourceTree = "<group>"; };
		F96D3EC208F272A7004A47F5 /* UpVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = UpVar.3; sourceTree = "<group>"; };
		F96D3EC308F272A7004A47F5 /* upvar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = upvar.n; sourceTree = "<group>"; };
		F96D3EC408F272A7004A47F5 /* Utf.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Utf.3; sourceTree = "<group>"; };
		F96D3EC508F272A7004A47F5 /* variable.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = variable.n; sourceTree = "<group>"; };
		F96D3EC608F272A7004A47F5 /* vwait.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = vwait.n; sourceTree = "<group>"; };
		F96D3EC708F272A7004A47F5 /* while.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = while.n; sourceTree = "<group>"; };
		F96D3EC808F272A7004A47F5 /* WrongNumArgs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = WrongNumArgs.3; sourceTree = "<group>"; };
		F96D3ECA08F272A7004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D3ECB08F272A7004A47F5 /* regc_color.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_color.c; sourceTree = "<group>"; };
		F96D3ECC08F272A7004A47F5 /* regc_cvec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_cvec.c; sourceTree = "<group>"; };
		F96D3ECD08F272A7004A47F5 /* regc_lex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_lex.c; sourceTree = "<group>"; };
		F96D3ECE08F272A7004A47F5 /* regc_locale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_locale.c; sourceTree = "<group>"; };
		F96D3ECF08F272A7004A47F5 /* regc_nfa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_nfa.c; sourceTree = "<group>"; };
		F96D3ED008F272A7004A47F5 /* regcomp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regcomp.c; sourceTree = "<group>"; };
		F96D3ED108F272A7004A47F5 /* regcustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regcustom.h; sourceTree = "<group>"; };
		F96D3ED208F272A7004A47F5 /* rege_dfa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rege_dfa.c; sourceTree = "<group>"; };
		F96D3ED308F272A7004A47F5 /* regerror.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regerror.c; sourceTree = "<group>"; };
		F96D3ED408F272A7004A47F5 /* regerrs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regerrs.h; sourceTree = "<group>"; };
		F96D3ED508F272A7004A47F5 /* regex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regex.h; sourceTree = "<group>"; };
		F96D3ED608F272A7004A47F5 /* regexec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regexec.c; sourceTree = "<group>"; };
		F96D3ED708F272A7004A47F5 /* regfree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regfree.c; sourceTree = "<group>"; };
		F96D3ED808F272A7004A47F5 /* regfronts.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regfronts.c; sourceTree = "<group>"; };
		F96D3ED908F272A7004A47F5 /* regguts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regguts.h; sourceTree = "<group>"; };
		F96D3EDA08F272A7004A47F5 /* tcl.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcl.decls; sourceTree = "<group>"; };
		F96D3EDB08F272A7004A47F5 /* tcl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tcl.h; sourceTree = "<group>"; };
		F96D3EDC08F272A7004A47F5 /* tclAlloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAlloc.c; sourceTree = "<group>"; };
		F96D3EDD08F272A7004A47F5 /* tclAsync.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAsync.c; sourceTree = "<group>"; };
		F96D3EDE08F272A7004A47F5 /* tclBasic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclBasic.c; sourceTree = "<group>"; };
		F96D3EDF08F272A7004A47F5 /* tclBinary.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclBinary.c; sourceTree = "<group>"; };
		F96D3EE008F272A7004A47F5 /* tclCkalloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCkalloc.c; sourceTree = "<group>"; };
		F96D3EE108F272A7004A47F5 /* tclClock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclClock.c; sourceTree = "<group>"; };
		F96D3EE208F272A7004A47F5 /* tclCmdAH.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdAH.c; sourceTree = "<group>"; };
		F96D3EE308F272A7004A47F5 /* tclCmdIL.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdIL.c; sourceTree = "<group>"; };
		F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdMZ.c; sourceTree = "<group>"; };
		F96D3EE508F272A7004A47F5 /* tclCompCmds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompCmds.c; sourceTree = "<group>"; };
		F96D3EE608F272A7004A47F5 /* tclCompExpr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompExpr.c; sourceTree = "<group>"; };
		F96D3EE708F272A7004A47F5 /* tclCompile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompile.c; sourceTree = "<group>"; };
		F96D3EE808F272A7004A47F5 /* tclCompile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclCompile.h; sourceTree = "<group>"; };
		F96D3EE908F272A7004A47F5 /* tclConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclConfig.c; sourceTree = "<group>"; };
		F96D3EEA08F272A7004A47F5 /* tclDate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclDate.c; sourceTree = "<group>"; };
		F96D3EEB08F272A7004A47F5 /* tclDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclDecls.h; sourceTree = "<group>"; };
		F96D3EEC08F272A7004A47F5 /* tclDictObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclDictObj.c; sourceTree = "<group>"; };
		F96D3EED08F272A7004A47F5 /* tclEncoding.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEncoding.c; sourceTree = "<group>"; };
		F96D3EEE08F272A7004A47F5 /* tclEnv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEnv.c; sourceTree = "<group>"; };
		F96D3EEF08F272A7004A47F5 /* tclEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEvent.c; sourceTree = "<group>"; };
		F96D3EF008F272A7004A47F5 /* tclExecute.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclExecute.c; sourceTree = "<group>"; };
		F96D3EF108F272A7004A47F5 /* tclFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclFCmd.c; sourceTree = "<group>"; };
		F96D3EF208F272A7004A47F5 /* tclFileName.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclFileName.c; sourceTree = "<group>"; };
		F96D3EF308F272A7004A47F5 /* tclFileSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclFileSystem.h; sourceTree = "<group>"; };
		F96D3EF408F272A7004A47F5 /* tclGet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclGet.c; sourceTree = "<group>"; };
		F96D3EF508F272A7004A47F5 /* tclGetDate.y */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.yacc; path = tclGetDate.y; sourceTree = "<group>"; };
		F96D3EF608F272A7004A47F5 /* tclHash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclHash.c; sourceTree = "<group>"; };
		F96D3EF708F272A7004A47F5 /* tclHistory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclHistory.c; sourceTree = "<group>"; };
		F96D3EF808F272A7004A47F5 /* tclIndexObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIndexObj.c; sourceTree = "<group>"; };
		F96D3EF908F272A7004A47F5 /* tclInt.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclInt.decls; sourceTree = "<group>"; };
		F96D3EFA08F272A7004A47F5 /* tclInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclInt.h; sourceTree = "<group>"; };
		F96D3EFB08F272A7004A47F5 /* tclIntDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIntDecls.h; sourceTree = "<group>"; };
		F96D3EFC08F272A7004A47F5 /* tclInterp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclInterp.c; sourceTree = "<group>"; };
		F96D3EFD08F272A7004A47F5 /* tclIntPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIntPlatDecls.h; sourceTree = "<group>"; };
		F96D3EFE08F272A7004A47F5 /* tclIO.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIO.c; sourceTree = "<group>"; };
		F96D3EFF08F272A7004A47F5 /* tclIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIO.h; sourceTree = "<group>"; };
		F96D3F0008F272A7004A47F5 /* tclIOCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOCmd.c; sourceTree = "<group>"; };
		F96D3F0108F272A7004A47F5 /* tclIOGT.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOGT.c; sourceTree = "<group>"; };
		F96D3F0208F272A7004A47F5 /* tclIORChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIORChan.c; sourceTree = "<group>"; };
		F96D3F0308F272A7004A47F5 /* tclIOSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOSock.c; sourceTree = "<group>"; };
		F96D3F0408F272A7004A47F5 /* tclIOUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOUtil.c; sourceTree = "<group>"; };
		F96D3F0508F272A7004A47F5 /* tclLink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLink.c; sourceTree = "<group>"; };
		F96D3F0608F272A7004A47F5 /* tclListObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclListObj.c; sourceTree = "<group>"; };
		F96D3F0708F272A7004A47F5 /* tclLiteral.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLiteral.c; sourceTree = "<group>"; };
		F96D3F0808F272A7004A47F5 /* tclLoad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoad.c; sourceTree = "<group>"; };
		F96D3F0908F272A7004A47F5 /* tclLoadNone.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadNone.c; sourceTree = "<group>"; };
		F96D3F0A08F272A7004A47F5 /* tclMain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMain.c; sourceTree = "<group>"; };
		F96D3F0B08F272A7004A47F5 /* tclNamesp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclNamesp.c; sourceTree = "<group>"; };
		F96D3F0C08F272A7004A47F5 /* tclNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclNotify.c; sourceTree = "<group>"; };
		F96D3F0D08F272A7004A47F5 /* tclObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclObj.c; sourceTree = "<group>"; };
		F96D3F0E08F272A7004A47F5 /* tclPanic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPanic.c; sourceTree = "<group>"; };
		F96D3F0F08F272A7004A47F5 /* tclParse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclParse.c; sourceTree = "<group>"; };
		F96D3F1108F272A7004A47F5 /* tclPathObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPathObj.c; sourceTree = "<group>"; };
		F96D3F1208F272A7004A47F5 /* tclPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPipe.c; sourceTree = "<group>"; };
		F96D3F1308F272A7004A47F5 /* tclPkg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPkg.c; sourceTree = "<group>"; };
		F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPkgConfig.c; sourceTree = "<group>"; };
		F96D3F1508F272A7004A47F5 /* tclPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclPlatDecls.h; sourceTree = "<group>"; };
		F96D3F1608F272A7004A47F5 /* tclPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclPort.h; sourceTree = "<group>"; };
		F96D3F1708F272A7004A47F5 /* tclPosixStr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPosixStr.c; sourceTree = "<group>"; };
		F96D3F1808F272A7004A47F5 /* tclPreserve.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPreserve.c; sourceTree = "<group>"; };
		F96D3F1908F272A7004A47F5 /* tclProc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclProc.c; sourceTree = "<group>"; };
		F96D3F1A08F272A7004A47F5 /* tclRegexp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclRegexp.c; sourceTree = "<group>"; };
		F96D3F1B08F272A7004A47F5 /* tclRegexp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclRegexp.h; sourceTree = "<group>"; };
		F96D3F1C08F272A7004A47F5 /* tclResolve.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclResolve.c; sourceTree = "<group>"; };
		F96D3F1D08F272A7004A47F5 /* tclResult.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclResult.c; sourceTree = "<group>"; };
		F96D3F1E08F272A7004A47F5 /* tclScan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclScan.c; sourceTree = "<group>"; };
		F96D3F1F08F272A7004A47F5 /* tclStringObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStringObj.c; sourceTree = "<group>"; };
		F96D3F2408F272A7004A47F5 /* tclStrToD.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStrToD.c; sourceTree = "<group>"; };
		F96D3F2508F272A7004A47F5 /* tclStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStubInit.c; sourceTree = "<group>"; };
		F96D3F2608F272A7004A47F5 /* tclStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStubLib.c; sourceTree = "<group>"; };
		F96D3F2708F272A7004A47F5 /* tclTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTest.c; sourceTree = "<group>"; };
		F96D3F2808F272A7004A47F5 /* tclTestObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTestObj.c; sourceTree = "<group>"; };
		F96D3F2908F272A7004A47F5 /* tclTestProcBodyObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTestProcBodyObj.c; sourceTree = "<group>"; };
		F96D3F2A08F272A7004A47F5 /* tclThread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThread.c; sourceTree = "<group>"; };
		F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadAlloc.c; sourceTree = "<group>"; };
		F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadJoin.c; sourceTree = "<group>"; };
		F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadStorage.c; sourceTree = "<group>"; };
		F96D3F2E08F272A7004A47F5 /* tclThreadTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadTest.c; sourceTree = "<group>"; };
		F96D3F2F08F272A7004A47F5 /* tclTimer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTimer.c; sourceTree = "<group>"; };
		F96D3F3008F272A7004A47F5 /* tclTomMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclTomMath.h; sourceTree = "<group>"; };
		F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTomMathInterface.c; sourceTree = "<group>"; };
		F96D3F3208F272A7004A47F5 /* tclTrace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTrace.c; sourceTree = "<group>"; };
		F96D3F3308F272A7004A47F5 /* tclUniData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUniData.c; sourceTree = "<group>"; };
		F96D3F3408F272A7004A47F5 /* tclUtf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUtf.c; sourceTree = "<group>"; };
		F96D3F3508F272A7004A47F5 /* tclUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUtil.c; sourceTree = "<group>"; };
		F96D3F3608F272A7004A47F5 /* tclVar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclVar.c; sourceTree = "<group>"; };
		F96D3F3908F272A8004A47F5 /* auto.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = auto.tcl; sourceTree = "<group>"; };
		F96D3F3A08F272A8004A47F5 /* clock.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clock.tcl; sourceTree = "<group>"; };
		F96D3F3C08F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D3F8C08F272A8004A47F5 /* history.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = history.tcl; sourceTree = "<group>"; };
		F96D3F8E08F272A8004A47F5 /* http.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.tcl; sourceTree = "<group>"; };
		F96D3F8F08F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D3F9108F272A8004A47F5 /* http.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.tcl; sourceTree = "<group>"; };
		F96D3F9208F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D3F9308F272A8004A47F5 /* init.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = init.tcl; sourceTree = "<group>"; };
		F96D3F9508F272A8004A47F5 /* msgcat.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgcat.tcl; sourceTree = "<group>"; };
		F96D3F9608F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D401808F272AA004A47F5 /* optparse.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = optparse.tcl; sourceTree = "<group>"; };
		F96D401908F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D401A08F272AA004A47F5 /* package.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = package.tcl; sourceTree = "<group>"; };
		F96D401B08F272AA004A47F5 /* parray.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parray.tcl; sourceTree = "<group>"; };
		F96D401D08F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D401E08F272AA004A47F5 /* safe.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safe.tcl; sourceTree = "<group>"; };
		F96D401F08F272AA004A47F5 /* tclIndex */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclIndex; sourceTree = "<group>"; };
		F96D402108F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F96D402208F272AA004A47F5 /* tcltest.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcltest.tcl; sourceTree = "<group>"; };
		F96D402308F272AA004A47F5 /* tm.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tm.tcl; sourceTree = "<group>"; };
		F96D425B08F272B2004A47F5 /* word.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = word.tcl; sourceTree = "<group>"; };
		F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_mul_digs.c; sourceTree = "<group>"; };
		F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_sqr.c; sourceTree = "<group>"; };
		F96D426908F272B3004A47F5 /* bn_mp_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_add.c; sourceTree = "<group>"; };
		F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_add_d.c; sourceTree = "<group>"; };
		F96D426C08F272B3004A47F5 /* bn_mp_and.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_and.c; sourceTree = "<group>"; };
		F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clamp.c; sourceTree = "<group>"; };
		F96D426E08F272B3004A47F5 /* bn_mp_clear.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clear.c; sourceTree = "<group>"; };
		F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clear_multi.c; sourceTree = "<group>"; };
		F96D427008F272B3004A47F5 /* bn_mp_cmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp.c; sourceTree = "<group>"; };
		F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp_d.c; sourceTree = "<group>"; };
		F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp_mag.c; sourceTree = "<group>"; };
		F96D427408F272B3004A47F5 /* bn_mp_copy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_copy.c; sourceTree = "<group>"; };
		F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_count_bits.c; sourceTree = "<group>"; };
		F96D427608F272B3004A47F5 /* bn_mp_div.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div.c; sourceTree = "<group>"; };
		F96D427708F272B3004A47F5 /* bn_mp_div_2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_2.c; sourceTree = "<group>"; };
		F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_2d.c; sourceTree = "<group>"; };
		F96D427908F272B3004A47F5 /* bn_s_mp_div_3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_div_3.c; sourceTree = "<group>"; };
		F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_d.c; sourceTree = "<group>"; };
		F96D427E08F272B3004A47F5 /* bn_mp_exch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exch.c; sourceTree = "<group>"; };
		F96D427F08F272B3004A47F5 /* bn_mp_expt_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_expt_n.c; sourceTree = "<group>"; };
		F96D427F08F272B3004A47F5 /* bn_mp_expt_d_ex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_expt_d_ex.c; sourceTree = "<group>"; };
		F96D428708F272B3004A47F5 /* bn_mp_grow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_grow.c; sourceTree = "<group>"; };
		F96D428808F272B3004A47F5 /* bn_mp_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init.c; sourceTree = "<group>"; };
		F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_copy.c; sourceTree = "<group>"; };
		F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_multi.c; sourceTree = "<group>"; };
		F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_set.c; sourceTree = "<group>"; };
		F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_size.c; sourceTree = "<group>"; };
		F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_karatsuba_mul.c; sourceTree = "<group>"; };
		F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_karatsuba_sqr.c; sourceTree = "<group>"; };
		F96D429508F272B3004A47F5 /* bn_mp_lshd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_lshd.c; sourceTree = "<group>"; };
		F96D429608F272B3004A47F5 /* bn_mp_mod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod.c; sourceTree = "<group>"; };
		F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod_2d.c; sourceTree = "<group>"; };
		F96D429C08F272B3004A47F5 /* bn_mp_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul.c; sourceTree = "<group>"; };
		F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_2.c; sourceTree = "<group>"; };
		F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_2d.c; sourceTree = "<group>"; };
		F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_d.c; sourceTree = "<group>"; };
		F96D42A208F272B3004A47F5 /* bn_mp_neg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_neg.c; sourceTree = "<group>"; };
		F96D42A308F272B3004A47F5 /* bn_mp_or.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_or.c; sourceTree = "<group>"; };
		F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_radix_size.c; sourceTree = "<group>"; };
		F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_radix_smap.c; sourceTree = "<group>"; };
		F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_read_radix.c; sourceTree = "<group>"; };
		F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_rshd.c; sourceTree = "<group>"; };
		F96D42BA08F272B3004A47F5 /* bn_mp_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_set.c; sourceTree = "<group>"; };
		F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_shrink.c; sourceTree = "<group>"; };
		F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqr.c; sourceTree = "<group>"; };
		F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqrt.c; sourceTree = "<group>"; };
		F96D42C108F272B3004A47F5 /* bn_mp_sub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sub.c; sourceTree = "<group>"; };
		F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sub_d.c; sourceTree = "<group>"; };
		F96D42C608F272B3004A47F5 /* bn_mp_to_ubin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_ubin.c; sourceTree = "<group>"; };
		F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toom_mul.c; sourceTree = "<group>"; };
		F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toom_sqr.c; sourceTree = "<group>"; };
		F96D42CB08F272B3004A47F5 /* bn_mp_to_radix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_radix.c; sourceTree = "<group>"; };
		F96D42CC08F272B3004A47F5 /* bn_mp_ubin_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_ubin_size.c; sourceTree = "<group>"; };
		F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_xor.c; sourceTree = "<group>"; };
		F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_zero.c; sourceTree = "<group>"; };
		F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_add.c; sourceTree = "<group>"; };
		F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_mul_digs.c; sourceTree = "<group>"; };
		F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_sqr.c; sourceTree = "<group>"; };
		F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_sub.c; sourceTree = "<group>"; };
		F96D432908F272B4004A47F5 /* tommath_class.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath_class.h; sourceTree = "<group>"; };
		F96D432A08F272B4004A47F5 /* tommath_superclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath_superclass.h; sourceTree = "<group>"; };
		F96D432B08F272B4004A47F5 /* license.terms */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = license.terms; sourceTree = "<group>"; };
		F96D432E08F272B5004A47F5 /* configure.ac */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure.ac; sourceTree = "<group>"; };
		F96D432F08F272B5004A47F5 /* GNUmakefile */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = GNUmakefile; sourceTree = "<group>"; };
		F96D433108F272B5004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D433208F272B5004A47F5 /* Tcl-Info.plist.in */ = {isa = PBXFileReference; explicitFileType = text.plist; fileEncoding = 4; path = "Tcl-Info.plist.in"; sourceTree = "<group>"; };
		F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXBundle.c; sourceTree = "<group>"; };
		F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXFCmd.c; sourceTree = "<group>"; };
		F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXNotify.c; sourceTree = "<group>"; };
		F96D434308F272B5004A47F5 /* README */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = README; sourceTree = "<group>"; };
		F96D434508F272B5004A47F5 /* all.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = all.tcl; sourceTree = "<group>"; };
		F96D434608F272B5004A47F5 /* append.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = append.test; sourceTree = "<group>"; };
		F96D434708F272B5004A47F5 /* appendComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = appendComp.test; sourceTree = "<group>"; };
		F96D434808F272B5004A47F5 /* assocd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = assocd.test; sourceTree = "<group>"; };
		F96D434908F272B5004A47F5 /* async.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = async.test; sourceTree = "<group>"; };
		F96D434A08F272B5004A47F5 /* autoMkindex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = autoMkindex.test; sourceTree = "<group>"; };
		F96D434B08F272B5004A47F5 /* basic.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = basic.test; sourceTree = "<group>"; };
		F96D434C08F272B5004A47F5 /* binary.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = binary.test; sourceTree = "<group>"; };
		F96D434D08F272B5004A47F5 /* case.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = case.test; sourceTree = "<group>"; };
		F96D434E08F272B5004A47F5 /* chan.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = chan.test; sourceTree = "<group>"; };
		F96D434F08F272B5004A47F5 /* clock.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clock.test; sourceTree = "<group>"; };
		F96D435008F272B5004A47F5 /* cmdAH.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdAH.test; sourceTree = "<group>"; };
		F96D435108F272B5004A47F5 /* cmdIL.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdIL.test; sourceTree = "<group>"; };
		F96D435208F272B5004A47F5 /* cmdInfo.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdInfo.test; sourceTree = "<group>"; };
		F96D435308F272B5004A47F5 /* cmdMZ.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdMZ.test; sourceTree = "<group>"; };
		F96D435408F272B5004A47F5 /* compExpr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "compExpr-old.test"; sourceTree = "<group>"; };
		F96D435508F272B5004A47F5 /* compExpr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = compExpr.test; sourceTree = "<group>"; };
		F96D435608F272B5004A47F5 /* compile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = compile.test; sourceTree = "<group>"; };
		F96D435708F272B5004A47F5 /* concat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = concat.test; sourceTree = "<group>"; };
		F96D435808F272B5004A47F5 /* config.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = config.test; sourceTree = "<group>"; };
		F96D435908F272B5004A47F5 /* dcall.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dcall.test; sourceTree = "<group>"; };
		F96D435A08F272B5004A47F5 /* dict.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dict.test; sourceTree = "<group>"; };
		F96D435C08F272B5004A47F5 /* dstring.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dstring.test; sourceTree = "<group>"; };
		F96D435E08F272B5004A47F5 /* encoding.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = encoding.test; sourceTree = "<group>"; };
		F96D435F08F272B5004A47F5 /* env.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = env.test; sourceTree = "<group>"; };
		F96D436008F272B5004A47F5 /* error.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = error.test; sourceTree = "<group>"; };
		F96D436108F272B5004A47F5 /* eval.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = eval.test; sourceTree = "<group>"; };
		F96D436208F272B5004A47F5 /* event.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = event.test; sourceTree = "<group>"; };
		F96D436308F272B5004A47F5 /* exec.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = exec.test; sourceTree = "<group>"; };
		F96D436408F272B5004A47F5 /* execute.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = execute.test; sourceTree = "<group>"; };
		F96D436508F272B5004A47F5 /* expr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "expr-old.test"; sourceTree = "<group>"; };
		F96D436608F272B5004A47F5 /* expr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = expr.test; sourceTree = "<group>"; };
		F96D436708F272B6004A47F5 /* fCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fCmd.test; sourceTree = "<group>"; };
		F96D436808F272B6004A47F5 /* fileName.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fileName.test; sourceTree = "<group>"; };
		F96D436908F272B6004A47F5 /* fileSystem.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fileSystem.test; sourceTree = "<group>"; };
		F96D436A08F272B6004A47F5 /* for-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "for-old.test"; sourceTree = "<group>"; };
		F96D436B08F272B6004A47F5 /* for.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = for.test; sourceTree = "<group>"; };
		F96D436C08F272B6004A47F5 /* foreach.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = foreach.test; sourceTree = "<group>"; };
		F96D436D08F272B6004A47F5 /* format.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = format.test; sourceTree = "<group>"; };
		F96D436E08F272B6004A47F5 /* get.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = get.test; sourceTree = "<group>"; };
		F96D436F08F272B6004A47F5 /* history.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = history.test; sourceTree = "<group>"; };
		F96D437008F272B6004A47F5 /* http.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.test; sourceTree = "<group>"; };
		F96D437108F272B6004A47F5 /* httpd */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = httpd; sourceTree = "<group>"; };
		F96D437208F272B6004A47F5 /* httpold.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = httpold.test; sourceTree = "<group>"; };
		F96D437308F272B6004A47F5 /* if-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "if-old.test"; sourceTree = "<group>"; };
		F96D437408F272B6004A47F5 /* if.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = if.test; sourceTree = "<group>"; };
		F96D437508F272B6004A47F5 /* incr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "incr-old.test"; sourceTree = "<group>"; };
		F96D437608F272B6004A47F5 /* incr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = incr.test; sourceTree = "<group>"; };
		F96D437708F272B6004A47F5 /* indexObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = indexObj.test; sourceTree = "<group>"; };
		F96D437808F272B6004A47F5 /* info.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = info.test; sourceTree = "<group>"; };
		F96D437908F272B6004A47F5 /* init.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = init.test; sourceTree = "<group>"; };
		F96D437A08F272B6004A47F5 /* interp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = interp.test; sourceTree = "<group>"; };
		F96D437B08F272B6004A47F5 /* io.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = io.test; sourceTree = "<group>"; };
		F96D437C08F272B6004A47F5 /* ioCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ioCmd.test; sourceTree = "<group>"; };
		F96D437D08F272B6004A47F5 /* iogt.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = iogt.test; sourceTree = "<group>"; };
		F96D437F08F272B6004A47F5 /* join.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = join.test; sourceTree = "<group>"; };
		F96D438008F272B6004A47F5 /* lindex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lindex.test; sourceTree = "<group>"; };
		F96D438108F272B6004A47F5 /* link.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = link.test; sourceTree = "<group>"; };
		F96D438208F272B6004A47F5 /* linsert.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = linsert.test; sourceTree = "<group>"; };
		F96D438308F272B6004A47F5 /* list.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = list.test; sourceTree = "<group>"; };
		F96D438408F272B6004A47F5 /* listObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = listObj.test; sourceTree = "<group>"; };
		F96D438508F272B6004A47F5 /* llength.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = llength.test; sourceTree = "<group>"; };
		F96D438608F272B6004A47F5 /* load.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = load.test; sourceTree = "<group>"; };
		F96D438708F272B6004A47F5 /* lrange.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lrange.test; sourceTree = "<group>"; };
		F96D438808F272B6004A47F5 /* lrepeat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lrepeat.test; sourceTree = "<group>"; };
		F96D438908F272B6004A47F5 /* lreplace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lreplace.test; sourceTree = "<group>"; };
		F96D438A08F272B6004A47F5 /* lsearch.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lsearch.test; sourceTree = "<group>"; };
		F96D438B08F272B6004A47F5 /* lset.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lset.test; sourceTree = "<group>"; };
		F96D438C08F272B6004A47F5 /* lsetComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lsetComp.test; sourceTree = "<group>"; };
		F96D438D08F272B6004A47F5 /* macOSXFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = macOSXFCmd.test; sourceTree = "<group>"; };
		F96D438E08F272B6004A47F5 /* main.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = main.test; sourceTree = "<group>"; };
		F96D438F08F272B6004A47F5 /* misc.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = misc.test; sourceTree = "<group>"; };
		F96D439008F272B6004A47F5 /* msgcat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgcat.test; sourceTree = "<group>"; };
		F96D439108F272B6004A47F5 /* namespace-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "namespace-old.test"; sourceTree = "<group>"; };
		F96D439208F272B7004A47F5 /* namespace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = namespace.test; sourceTree = "<group>"; };
		F96D439308F272B7004A47F5 /* notify.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = notify.test; sourceTree = "<group>"; };
		F96D439408F272B7004A47F5 /* obj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = obj.test; sourceTree = "<group>"; };
		F96D439508F272B7004A47F5 /* opt.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = opt.test; sourceTree = "<group>"; };
		F96D439608F272B7004A47F5 /* package.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = package.test; sourceTree = "<group>"; };
		F96D439708F272B7004A47F5 /* parse.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parse.test; sourceTree = "<group>"; };
		F96D439808F272B7004A47F5 /* parseExpr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parseExpr.test; sourceTree = "<group>"; };
		F96D439908F272B7004A47F5 /* parseOld.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parseOld.test; sourceTree = "<group>"; };
		F96D439A08F272B7004A47F5 /* pid.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pid.test; sourceTree = "<group>"; };
		F96D439B08F272B7004A47F5 /* pkg.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkg.test; sourceTree = "<group>"; };
		F96D439C08F272B7004A47F5 /* pkgMkIndex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgMkIndex.test; sourceTree = "<group>"; };
		F96D439D08F272B7004A47F5 /* platform.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = platform.test; sourceTree = "<group>"; };
		F96D439E08F272B7004A47F5 /* proc-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "proc-old.test"; sourceTree = "<group>"; };
		F96D439F08F272B7004A47F5 /* proc.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = proc.test; sourceTree = "<group>"; };
		F96D43A008F272B7004A47F5 /* pwd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pwd.test; sourceTree = "<group>"; };
		F96D43A108F272B7004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D43A208F272B7004A47F5 /* reg.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = reg.test; sourceTree = "<group>"; };
		F96D43A308F272B7004A47F5 /* regexp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexp.test; sourceTree = "<group>"; };
		F96D43A408F272B7004A47F5 /* regexpComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexpComp.test; sourceTree = "<group>"; };
		F96D43A508F272B7004A47F5 /* registry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = registry.test; sourceTree = "<group>"; };
		F96D43A608F272B7004A47F5 /* remote.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = remote.tcl; sourceTree = "<group>"; };
		F96D43A708F272B7004A47F5 /* rename.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = rename.test; sourceTree = "<group>"; };
		F96D43A808F272B7004A47F5 /* result.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = result.test; sourceTree = "<group>"; };
		F96D43A908F272B7004A47F5 /* safe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safe.test; sourceTree = "<group>"; };
		F96D43AA08F272B7004A47F5 /* scan.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scan.test; sourceTree = "<group>"; };
		F96D43AB08F272B7004A47F5 /* security.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = security.test; sourceTree = "<group>"; };
		F96D43AC08F272B7004A47F5 /* set-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "set-old.test"; sourceTree = "<group>"; };
		F96D43AD08F272B7004A47F5 /* set.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = set.test; sourceTree = "<group>"; };
		F96D43AE08F272B7004A47F5 /* socket.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = socket.test; sourceTree = "<group>"; };
		F96D43AF08F272B7004A47F5 /* source.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = source.test; sourceTree = "<group>"; };
		F96D43B008F272B7004A47F5 /* split.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = split.test; sourceTree = "<group>"; };
		F96D43B108F272B7004A47F5 /* stack.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stack.test; sourceTree = "<group>"; };
		F96D43B208F272B7004A47F5 /* string.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = string.test; sourceTree = "<group>"; };
		F96D43B308F272B7004A47F5 /* stringComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stringComp.test; sourceTree = "<group>"; };
		F96D43B408F272B7004A47F5 /* stringObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stringObj.test; sourceTree = "<group>"; };
		F96D43B508F272B7004A47F5 /* subst.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = subst.test; sourceTree = "<group>"; };
		F96D43B608F272B7004A47F5 /* switch.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = switch.test; sourceTree = "<group>"; };
		F96D43B708F272B7004A47F5 /* tcltest.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcltest.test; sourceTree = "<group>"; };
		F96D43B808F272B7004A47F5 /* thread.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = thread.test; sourceTree = "<group>"; };
		F96D43B908F272B7004A47F5 /* timer.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = timer.test; sourceTree = "<group>"; };
		F96D43BA08F272B7004A47F5 /* tm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tm.test; sourceTree = "<group>"; };
		F96D43BB08F272B7004A47F5 /* trace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = trace.test; sourceTree = "<group>"; };
		F96D43BC08F272B7004A47F5 /* unixFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixFCmd.test; sourceTree = "<group>"; };
		F96D43BD08F272B7004A47F5 /* unixFile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixFile.test; sourceTree = "<group>"; };
		F96D43BE08F272B7004A47F5 /* unixInit.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixInit.test; sourceTree = "<group>"; };
		F96D43BF08F272B7004A47F5 /* unixNotfy.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixNotfy.test; sourceTree = "<group>"; };
		F96D43C008F272B7004A47F5 /* unknown.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unknown.test; sourceTree = "<group>"; };
		F96D43C108F272B7004A47F5 /* unload.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unload.test; sourceTree = "<group>"; };
		F96D43C208F272B7004A47F5 /* uplevel.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uplevel.test; sourceTree = "<group>"; };
		F96D43C308F272B7004A47F5 /* upvar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = upvar.test; sourceTree = "<group>"; };
		F96D43C408F272B7004A47F5 /* utf.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = utf.test; sourceTree = "<group>"; };
		F96D43C508F272B7004A47F5 /* util.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = util.test; sourceTree = "<group>"; };
		F96D43C608F272B7004A47F5 /* var.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = var.test; sourceTree = "<group>"; };
		F96D43C708F272B7004A47F5 /* while-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "while-old.test"; sourceTree = "<group>"; };
		F96D43C808F272B7004A47F5 /* while.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = while.test; sourceTree = "<group>"; };
		F96D43C908F272B7004A47F5 /* winConsole.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winConsole.test; sourceTree = "<group>"; };
		F96D43CA08F272B7004A47F5 /* winDde.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winDde.test; sourceTree = "<group>"; };
		F96D43CB08F272B7004A47F5 /* winFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winFCmd.test; sourceTree = "<group>"; };
		F96D43CC08F272B7004A47F5 /* winFile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winFile.test; sourceTree = "<group>"; };
		F96D43CD08F272B7004A47F5 /* winNotify.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winNotify.test; sourceTree = "<group>"; };
		F96D43CE08F272B7004A47F5 /* winPipe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winPipe.test; sourceTree = "<group>"; };
		F96D43CF08F272B7004A47F5 /* winTime.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winTime.test; sourceTree = "<group>"; };
		F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = checkLibraryDoc.tcl; sourceTree = "<group>"; };
		F96D43D208F272B8004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F96D43D308F272B8004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
		F96D442508F272B8004A47F5 /* genStubs.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = genStubs.tcl; sourceTree = "<group>"; };
		F96D442708F272B8004A47F5 /* index.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = index.tcl; sourceTree = "<group>"; };
		F96D442808F272B8004A47F5 /* installData.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = installData.tcl; sourceTree = "<group>"; };
		F96D442908F272B8004A47F5 /* loadICU.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = loadICU.tcl; sourceTree = "<group>"; };
		F96D442A08F272B8004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D442B08F272B8004A47F5 /* makeTestCases.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = makeTestCases.tcl; sourceTree = "<group>"; };
		F96D443208F272B8004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D443308F272B8004A47F5 /* regexpTestLib.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexpTestLib.tcl; sourceTree = "<group>"; };
		F96D443908F272B9004A47F5 /* tcltk-man2html.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "tcltk-man2html.tcl"; sourceTree = "<group>"; };
		F96D443A08F272B9004A47F5 /* tclZIC.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclZIC.tcl; sourceTree = "<group>"; };
		F96D443B08F272B9004A47F5 /* uniClass.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniClass.tcl; sourceTree = "<group>"; };
		F96D443C08F272B9004A47F5 /* uniParse.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniParse.tcl; sourceTree = "<group>"; };
		F96D444008F272B9004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
		F96D444108F272B9004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F96D444208F272B9004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
		F96D444408F272B9004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D444508F272B9004A47F5 /* pkga.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkga.c; sourceTree = "<group>"; };
		F96D444608F272B9004A47F5 /* pkgb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgb.c; sourceTree = "<group>"; };
		F96D444708F272B9004A47F5 /* pkgc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgc.c; sourceTree = "<group>"; };
		F96D444808F272B9004A47F5 /* pkgd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgd.c; sourceTree = "<group>"; };
		F96D444908F272B9004A47F5 /* pkge.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkge.c; sourceTree = "<group>"; };
		F96D444B08F272B9004A47F5 /* pkgua.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgua.c; sourceTree = "<group>"; };
		F96D444C08F272B9004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D444D08F272B9004A47F5 /* install-sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "install-sh"; sourceTree = "<group>"; };
		F96D444E08F272B9004A47F5 /* installManPage */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = installManPage; sourceTree = "<group>"; };
		F96D444F08F272B9004A47F5 /* ldAix */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = ldAix; sourceTree = "<group>"; };
		F96D445008F272B9004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D445208F272B9004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D445308F272B9004A47F5 /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
		F96D445408F272B9004A47F5 /* tcl.spec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.spec; sourceTree = "<group>"; };
		F96D445508F272B9004A47F5 /* tclAppInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAppInit.c; sourceTree = "<group>"; };
		F96D445608F272B9004A47F5 /* tclConfig.h.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = tclConfig.h.in; sourceTree = "<group>"; };
		F96D445708F272B9004A47F5 /* tclConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tclConfig.sh.in; sourceTree = "<group>"; };
		F96D445808F272B9004A47F5 /* tclLoadAix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadAix.c; sourceTree = "<group>"; };
		F96D445908F272B9004A47F5 /* tclLoadDl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadDl.c; sourceTree = "<group>"; };
		F96D445B08F272B9004A47F5 /* tclLoadDyld.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadDyld.c; sourceTree = "<group>"; };
		F96D445C08F272B9004A47F5 /* tclLoadNext.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadNext.c; sourceTree = "<group>"; };
		F96D445D08F272B9004A47F5 /* tclLoadOSF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadOSF.c; sourceTree = "<group>"; };
		F96D445E08F272B9004A47F5 /* tclLoadShl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadShl.c; sourceTree = "<group>"; };
		F96D445F08F272B9004A47F5 /* tclUnixChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixChan.c; sourceTree = "<group>"; };
		F96D446008F272B9004A47F5 /* tclUnixEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixEvent.c; sourceTree = "<group>"; };
		F96D446108F272B9004A47F5 /* tclUnixFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixFCmd.c; sourceTree = "<group>"; };
		F96D446208F272B9004A47F5 /* tclUnixFile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixFile.c; sourceTree = "<group>"; };
		F96D446308F272B9004A47F5 /* tclUnixInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixInit.c; sourceTree = "<group>"; };
		F96D446408F272B9004A47F5 /* tclUnixNotfy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixNotfy.c; sourceTree = "<group>"; };
		F96D446508F272B9004A47F5 /* tclUnixPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixPipe.c; sourceTree = "<group>"; };
		F96D446608F272B9004A47F5 /* tclUnixPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclUnixPort.h; sourceTree = "<group>"; };
		F96D446708F272B9004A47F5 /* tclUnixSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixSock.c; sourceTree = "<group>"; };
		F96D446808F272B9004A47F5 /* tclUnixTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixTest.c; sourceTree = "<group>"; };
		F96D446908F272B9004A47F5 /* tclUnixThrd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixThrd.c; sourceTree = "<group>"; };
		F96D446B08F272B9004A47F5 /* tclUnixTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixTime.c; sourceTree = "<group>"; };
		F96D446C08F272B9004A47F5 /* tclXtNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtNotify.c; sourceTree = "<group>"; };
		F96D446D08F272B9004A47F5 /* tclXtTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtTest.c; sourceTree = "<group>"; };
		F96D447008F272BA004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
		F96D447108F272BA004A47F5 /* buildall.vc.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = buildall.vc.bat; sourceTree = "<group>"; };
		F96D447208F272BA004A47F5 /* cat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cat.c; sourceTree = "<group>"; };
		F96D447308F272BA004A47F5 /* coffbase.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = coffbase.txt; sourceTree = "<group>"; };
		F96D447408F272BA004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
		F96D447508F272BA004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = "<group>"; };
		F96D447708F272BA004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
		F96D447808F272BA004A47F5 /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = "<group>"; };
		F96D447908F272BA004A47F5 /* nmakehlp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nmakehlp.c; sourceTree = "<group>"; };
		F96D447A08F272BA004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
		F96D447C08F272BA004A47F5 /* rules.vc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rules.vc; sourceTree = "<group>"; };
		F96D447D08F272BA004A47F5 /* stub16.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stub16.c; sourceTree = "<group>"; };
		F96D447E08F272BA004A47F5 /* tcl.dsp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.dsp; sourceTree = "<group>"; };
		F96D447F08F272BA004A47F5 /* tcl.dsw */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.dsw; sourceTree = "<group>"; };
		F96D448108F272BA004A47F5 /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
		F96D448208F272BA004A47F5 /* tcl.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.rc; sourceTree = "<group>"; };
		F96D448308F272BA004A47F5 /* tclAppInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAppInit.c; sourceTree = "<group>"; };
		F96D448408F272BA004A47F5 /* tclConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tclConfig.sh.in; sourceTree = "<group>"; };
		F96D448608F272BA004A47F5 /* tclsh.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tclsh.rc; sourceTree = "<group>"; };
		F96D448708F272BA004A47F5 /* tclWin32Dll.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWin32Dll.c; sourceTree = "<group>"; };
		F96D448808F272BA004A47F5 /* tclWinChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinChan.c; sourceTree = "<group>"; };
		F96D448908F272BA004A47F5 /* tclWinConsole.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinConsole.c; sourceTree = "<group>"; };
		F96D448A08F272BA004A47F5 /* tclWinDde.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinDde.c; sourceTree = "<group>"; };
		F96D448B08F272BA004A47F5 /* tclWinError.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinError.c; sourceTree = "<group>"; };
		F96D448C08F272BA004A47F5 /* tclWinFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinFCmd.c; sourceTree = "<group>"; };
		F96D448D08F272BA004A47F5 /* tclWinFile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinFile.c; sourceTree = "<group>"; };
		F96D448E08F272BA004A47F5 /* tclWinInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinInit.c; sourceTree = "<group>"; };
		F96D448F08F272BA004A47F5 /* tclWinInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinInt.h; sourceTree = "<group>"; };
		F96D449008F272BA004A47F5 /* tclWinLoad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinLoad.c; sourceTree = "<group>"; };
		F96D449108F272BA004A47F5 /* tclWinNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinNotify.c; sourceTree = "<group>"; };
		F96D449208F272BA004A47F5 /* tclWinPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinPipe.c; sourceTree = "<group>"; };
		F96D449308F272BA004A47F5 /* tclWinPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinPort.h; sourceTree = "<group>"; };
		F96D449408F272BA004A47F5 /* tclWinReg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinReg.c; sourceTree = "<group>"; };
		F96D449508F272BA004A47F5 /* tclWinSerial.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinSerial.c; sourceTree = "<group>"; };
		F96D449608F272BA004A47F5 /* tclWinSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinSock.c; sourceTree = "<group>"; };
		F96D449708F272BA004A47F5 /* tclWinTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinTest.c; sourceTree = "<group>"; };
		F96D449808F272BA004A47F5 /* tclWinThrd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinThrd.c; sourceTree = "<group>"; };
		F96D449A08F272BA004A47F5 /* tclWinTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinTime.c; sourceTree = "<group>"; };
		F974D56C0FBE7D6300BF728B /* http11.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http11.test; sourceTree = "<group>"; };
		F974D56D0FBE7D6300BF728B /* httpd11.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = httpd11.tcl; sourceTree = "<group>"; };
		F974D5720FBE7DC600BF728B /* coroutine.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = coroutine.n; sourceTree = "<group>"; };
		F974D5760FBE7E1900BF728B /* tailcall.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tailcall.n; sourceTree = "<group>"; };
		F974D5770FBE7E6100BF728B /* coroutine.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = coroutine.test; sourceTree = "<group>"; };
		F974D5780FBE7E6100BF728B /* tailcall.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tailcall.test; sourceTree = "<group>"; };
		F974D5790FBE7E9C00BF728B /* tcl.pc.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.pc.in; sourceTree = "<group>"; };
		F97AE7F10B65C1E900310EA2 /* Tcl-Common.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Tcl-Common.xcconfig"; sourceTree = "<group>"; };
		F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Tcl-Release.xcconfig"; sourceTree = "<group>"; };
		F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Tcl-Debug.xcconfig"; sourceTree = "<group>"; };
		F9903CAF094FAADA004613E9 /* tclTomMath.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclTomMath.decls; sourceTree = "<group>"; };
		F9903CB0094FAADA004613E9 /* tclTomMathDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclTomMathDecls.h; sourceTree = "<group>"; };
		F99D61180EF5573A00BBFE01 /* TclZlib.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TclZlib.3; sourceTree = "<group>"; };
		F9A3084B08F2D4CE00BAE1AB /* tclsh */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = tclsh; sourceTree = BUILT_PRODUCTS_DIR; };
		F9A3084E08F2D4F400BAE1AB /* Tcl.framework */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.framework; path = Tcl.framework; sourceTree = BUILT_PRODUCTS_DIR; };
		F9A493240CEBF38300B78AE2 /* chanio.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = chanio.test; sourceTree = "<group>"; };
		F9ECB1120B26521500A28025 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
		F9ECB1130B26521500A28025 /* platform.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = platform.tcl; sourceTree = "<group>"; };
		F9ECB1140B26521500A28025 /* shell.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = shell.tcl; sourceTree = "<group>"; };
		F9ECB1CA0B2652D300A28025 /* apply.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = apply.test; sourceTree = "<group>"; };
		F9ECB1CB0B26534C00A28025 /* mathop.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = mathop.test; sourceTree = "<group>"; };
		F9ECB1E10B26543C00A28025 /* platform_shell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = platform_shell.n; sourceTree = "<group>"; };
		F9ECB1E20B26543C00A28025 /* platform.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = platform.n; sourceTree = "<group>"; };
		F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = tclDTrace.d; sourceTree = "<group>"; };
		F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixCompat.c; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
		8DD76FAD0486AB0100D96B5E /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				F966C07508F2820D005CB29B /* CoreFoundation.framework in Frameworks */,
				F96437E70EF0D652003F468E /* libz.dylib in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
		08FB7794FE84155DC02AAC07 /* Tcl */ = {
			isa = PBXGroup;
			children = (
				F96D3DF608F27169004A47F5 /* Tcl Sources */,
				F966C06F08F281DC005CB29B /* Frameworks */,
				1AB674ADFE9D54B511CA2CBB /* Products */,
			);
			comments = "Copyright (c) 2004-2009 Daniel A. Steffen <das@users.sourceforge.net>\nCopyright 2008-2009, Apple Inc.\n\nSee the file \"license.terms\" for information on usage and redistribution of\nthis file, and for a DISCLAIMER OF ALL WARRANTIES.\n\n";
			name = Tcl;
			path = .;
			sourceTree = SOURCE_ROOT;
		};
		1AB674ADFE9D54B511CA2CBB /* Products */ = {
			isa = PBXGroup;
			children = (
				F9A3084B08F2D4CE00BAE1AB /* tclsh */,
				8DD76FB20486AB0100D96B5E /* tcltest */,
				F9A3084E08F2D4F400BAE1AB /* Tcl.framework */,
			);
			includeInIndex = 0;
			name = Products;
			sourceTree = "<group>";
		};
		F9183E690EFC81560030B814 /* pkgs */ = {
			isa = PBXGroup;
			children = (
				F9183E6A0EFC81560030B814 /* README */,
				F946FB8B0FBE3AED00CD6495 /* itcl */,
				F9183E8F0EFC817B0030B814 /* tdbc */,
			);
			path = pkgs;
			sourceTree = "<group>";
		};
		F966C06F08F281DC005CB29B /* Frameworks */ = {
			isa = PBXGroup;
			children = (
				F966C07408F2820D005CB29B /* CoreFoundation.framework */,
				F96437E60EF0D652003F468E /* libz.dylib */,
			);
			name = Frameworks;
			sourceTree = "<group>";
		};
		F96D3DF608F27169004A47F5 /* Tcl Sources */ = {
			isa = PBXGroup;
			children = (
				F96D3EC908F272A7004A47F5 /* generic */,
				F96D432C08F272B4004A47F5 /* macosx */,
				F96D443E08F272B9004A47F5 /* unix */,
				F96D425C08F272B2004A47F5 /* libtommath */,
				F96D446E08F272B9004A47F5 /* win */,
				F96D3F3808F272A7004A47F5 /* library */,
				F96D434408F272B5004A47F5 /* tests */,
				F96D3DFC08F272A4004A47F5 /* doc */,
				F96D43D008F272B8004A47F5 /* tools */,
				F9183E690EFC81560030B814 /* pkgs */,
				F96D3DFB08F272A4004A47F5 /* changes.md */,
				F96D434308F272B5004A47F5 /* README.md */,
				F96D432B08F272B4004A47F5 /* license.terms */,
			);
			name = "Tcl Sources";
			sourceTree = TCL_SRCROOT;
		};
		F96D3DFC08F272A4004A47F5 /* doc */ = {
			isa = PBXGroup;
			children = (
				F96D3DFD08F272A4004A47F5 /* Access.3 */,
				F96D3DFE08F272A4004A47F5 /* AddErrInfo.3 */,
				F96D3DFF08F272A4004A47F5 /* after.n */,
				F96D3E0008F272A4004A47F5 /* Alloc.3 */,
				F96D3E0108F272A4004A47F5 /* AllowExc.3 */,
				F96D3E0208F272A4004A47F5 /* append.n */,
				F96D3E0308F272A4004A47F5 /* AppInit.3 */,
				F96D3E0408F272A5004A47F5 /* array.n */,
				F96D3E0508F272A5004A47F5 /* AssocData.3 */,
				F96D3E0608F272A5004A47F5 /* Async.3 */,
				F96D3E0708F272A5004A47F5 /* BackgdErr.3 */,
				F96D3E0808F272A5004A47F5 /* Backslash.3 */,
				F96D3E0908F272A5004A47F5 /* bgerror.n */,
				F96D3E0A08F272A5004A47F5 /* binary.n */,
				F96D3E0B08F272A5004A47F5 /* BoolObj.3 */,
				F96D3E0C08F272A5004A47F5 /* break.n */,
				F96D3E0D08F272A5004A47F5 /* ByteArrObj.3 */,
				F96D3E0E08F272A5004A47F5 /* CallDel.3 */,
				F96D3E1008F272A5004A47F5 /* catch.n */,
				F96D3E1108F272A5004A47F5 /* cd.n */,
				F96D3E1208F272A5004A47F5 /* chan.n */,
				F96D3E1308F272A5004A47F5 /* ChnlStack.3 */,
				F93599CF0DF1F87F00E04F67 /* Class.3 */,
				F93599D00DF1F89E00E04F67 /* class.n */,
				F96D3E1408F272A5004A47F5 /* clock.n */,
				F96D3E1508F272A5004A47F5 /* close.n */,
				F96D3E1608F272A5004A47F5 /* CmdCmplt.3 */,
				F96D3E1708F272A5004A47F5 /* Concat.3 */,
				F96D3E1808F272A5004A47F5 /* concat.n */,
				F96D3E1908F272A5004A47F5 /* continue.n */,
				F93599D20DF1F8DF00E04F67 /* copy.n */,
				F974D5720FBE7DC600BF728B /* coroutine.n */,
				F96D3E1A08F272A5004A47F5 /* CrtChannel.3 */,
				F96D3E1B08F272A5004A47F5 /* CrtChnlHdlr.3 */,
				F96D3E1C08F272A5004A47F5 /* CrtCloseHdlr.3 */,
				F96D3E1D08F272A5004A47F5 /* CrtCommand.3 */,
				F96D3E1E08F272A5004A47F5 /* CrtFileHdlr.3 */,
				F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */,
				F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */,
				F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */,
				F96D3E2208F272A5004A47F5 /* CrtAlias.3 */,
				F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */,
				F96D3E2408F272A5004A47F5 /* CrtTrace.3 */,
				F96D3E2508F272A5004A47F5 /* dde.n */,
				F93599D30DF1F8F500E04F67 /* define.n */,
				F96D3E2608F272A5004A47F5 /* DetachPids.3 */,
				F96D3E2708F272A5004A47F5 /* dict.n */,
				F96D3E2808F272A5004A47F5 /* DictObj.3 */,
				F96D3E2908F272A5004A47F5 /* DoOneEvent.3 */,
				F96D3E2A08F272A5004A47F5 /* DoubleObj.3 */,
				F96D3E2B08F272A5004A47F5 /* DoWhenIdle.3 */,
				F96D3E2C08F272A5004A47F5 /* DString.3 */,
				F96D3E2D08F272A5004A47F5 /* DumpActiveMemory.3 */,
				F96D3E2E08F272A5004A47F5 /* Encoding.3 */,
				F96D3E2F08F272A5004A47F5 /* encoding.n */,
				F96D3E3008F272A5004A47F5 /* Ensemble.3 */,
				F96D3E3108F272A5004A47F5 /* Environment.3 */,
				F96D3E3208F272A5004A47F5 /* eof.n */,
				F96D3E3308F272A5004A47F5 /* error.n */,
				F96D3E3408F272A5004A47F5 /* Eval.3 */,
				F96D3E3508F272A5004A47F5 /* eval.n */,
				F96D3E3608F272A5004A47F5 /* exec.n */,
				F96D3E3708F272A5004A47F5 /* Exit.3 */,
				F96D3E3808F272A5004A47F5 /* exit.n */,
				F96D3E3908F272A5004A47F5 /* expr.n */,
				F96D3E3A08F272A5004A47F5 /* ExprLong.3 */,
				F96D3E3B08F272A5004A47F5 /* ExprLongObj.3 */,
				F96D3E3C08F272A5004A47F5 /* fblocked.n */,
				F96D3E3D08F272A5004A47F5 /* fconfigure.n */,
				F96D3E3E08F272A5004A47F5 /* fcopy.n */,
				F96D3E3F08F272A5004A47F5 /* file.n */,
				F96D3E4008F272A5004A47F5 /* fileevent.n */,
				F96D3E4108F272A5004A47F5 /* filename.n */,
				F96D3E4208F272A5004A47F5 /* FileSystem.3 */,
				F96D3E4308F272A5004A47F5 /* FindExec.3 */,
				F96D3E4408F272A5004A47F5 /* flush.n */,
				F96D3E4508F272A5004A47F5 /* for.n */,
				F96D3E4608F272A5004A47F5 /* foreach.n */,
				F96D3E4708F272A5004A47F5 /* format.n */,
				F96D3E4808F272A5004A47F5 /* GetCwd.3 */,
				F96D3E4908F272A5004A47F5 /* GetHostName.3 */,
				F96D3E4A08F272A5004A47F5 /* GetIndex.3 */,
				F96D3E4B08F272A5004A47F5 /* GetInt.3 */,
				F96D3E4C08F272A5004A47F5 /* GetOpnFl.3 */,
				F96D3E4D08F272A5004A47F5 /* gets.n */,
				F96D3E4E08F272A5004A47F5 /* GetStdChan.3 */,
				F96D3E4F08F272A5004A47F5 /* GetTime.3 */,
				F96D3E5008F272A5004A47F5 /* GetVersion.3 */,
				F96D3E5108F272A5004A47F5 /* glob.n */,
				F96D3E5208F272A6004A47F5 /* global.n */,
				F96D3E5308F272A6004A47F5 /* Hash.3 */,
				F96D3E5408F272A6004A47F5 /* history.n */,
				F96D3E5508F272A6004A47F5 /* http.n */,
				F96D3E5608F272A6004A47F5 /* if.n */,
				F96D3E5708F272A6004A47F5 /* incr.n */,
				F96D3E5808F272A6004A47F5 /* info.n */,
				F96D3E5908F272A6004A47F5 /* Init.3 */,
				F96D3E5A08F272A6004A47F5 /* InitStubs.3 */,
				F96D3E5B08F272A6004A47F5 /* Interp.3 */,
				F96D3E5C08F272A6004A47F5 /* interp.n */,
				F96D3E5D08F272A6004A47F5 /* IntObj.3 */,
				F96D3E5E08F272A6004A47F5 /* join.n */,
				F96D3E5F08F272A6004A47F5 /* lappend.n */,
				F96D3E6008F272A6004A47F5 /* lassign.n */,
				F96D3E6108F272A6004A47F5 /* library.n */,
				F96D3E6208F272A6004A47F5 /* Limit.3 */,
				F96D3E6308F272A6004A47F5 /* lindex.n */,
				F96D3E6408F272A6004A47F5 /* LinkVar.3 */,
				F96D3E6508F272A6004A47F5 /* linsert.n */,
				F96D3E6608F272A6004A47F5 /* list.n */,
				F96D3E6708F272A6004A47F5 /* ListObj.3 */,
				F96D3E6808F272A6004A47F5 /* llength.n */,
				F96D3E6908F272A6004A47F5 /* load.n */,
				F96D3E6A08F272A6004A47F5 /* lrange.n */,
				F96D3E6B08F272A6004A47F5 /* lrepeat.n */,
				F96D3E6C08F272A6004A47F5 /* lreplace.n */,
				F96D3E6D08F272A6004A47F5 /* lsearch.n */,
				F96D3E6E08F272A6004A47F5 /* lset.n */,
				F96D3E6F08F272A6004A47F5 /* lsort.n */,
				F96D3E7008F272A6004A47F5 /* man.macros */,
				F96D3E7108F272A6004A47F5 /* mathfunc.n */,
				F96D3E7208F272A6004A47F5 /* memory.n */,
				F93599D40DF1F91900E04F67 /* Method.3 */,
				F96D3E7308F272A6004A47F5 /* msgcat.n */,
				F93599D50DF1F93700E04F67 /* my.n */,
				F96D3E7408F272A6004A47F5 /* Namespace.3 */,
				F96D3E7508F272A6004A47F5 /* namespace.n */,
				F93599D60DF1F95000E04F67 /* next.n */,
				F96D3E7608F272A6004A47F5 /* Notifier.3 */,
				F96D3E7708F272A6004A47F5 /* Object.3 */,
				F93599D70DF1F96800E04F67 /* object.n */,
				F96D3E7808F272A6004A47F5 /* ObjectType.3 */,
				F96D3E7908F272A6004A47F5 /* open.n */,
				F96D3E7A08F272A6004A47F5 /* OpenFileChnl.3 */,
				F96D3E7B08F272A6004A47F5 /* OpenTcp.3 */,
				F96D3E7C08F272A6004A47F5 /* package.n */,
				F96D3E7D08F272A6004A47F5 /* packagens.n */,
				F96D3E7E08F272A6004A47F5 /* Panic.3 */,
				F96D3E7F08F272A6004A47F5 /* ParseCmd.3 */,
				F96D3E8008F272A6004A47F5 /* pid.n */,
				F96D3E8108F272A6004A47F5 /* pkgMkIndex.n */,
				F96D3E8208F272A6004A47F5 /* PkgRequire.3 */,
				F9ECB1E10B26543C00A28025 /* platform_shell.n */,
				F9ECB1E20B26543C00A28025 /* platform.n */,
				F96D3E8308F272A6004A47F5 /* Preserve.3 */,
				F96D3E8408F272A6004A47F5 /* PrintDbl.3 */,
				F96D3E8508F272A6004A47F5 /* proc.n */,
				F96D3E8608F272A6004A47F5 /* puts.n */,
				F96D3E8708F272A6004A47F5 /* pwd.n */,
				F96D3E8808F272A6004A47F5 /* re_syntax.n */,
				F96D3E8908F272A6004A47F5 /* read.n */,
				F96D3E8A08F272A6004A47F5 /* RecEvalObj.3 */,
				F96D3E8B08F272A6004A47F5 /* RecordEval.3 */,
				F96D3E8C08F272A6004A47F5 /* RegConfig.3 */,
				F96D3E8D08F272A6004A47F5 /* RegExp.3 */,
				F96D3E8E08F272A6004A47F5 /* regexp.n */,
				F96D3E8F08F272A6004A47F5 /* registry.n */,
				F96D3E9008F272A6004A47F5 /* regsub.n */,
				F96D3E9108F272A6004A47F5 /* rename.n */,
				F96D3E9208F272A6004A47F5 /* return.n */,
				F96D3E9308F272A6004A47F5 /* safe.n */,
				F96D3E9408F272A6004A47F5 /* SaveInterpState.3 */,
				F96D3E9508F272A6004A47F5 /* scan.n */,
				F96D3E9608F272A6004A47F5 /* seek.n */,
				F93599D80DF1F98300E04F67 /* self.n */,
				F96D3E9708F272A6004A47F5 /* set.n */,
				F96D3E9808F272A6004A47F5 /* SetChanErr.3 */,
				F96D3E9908F272A6004A47F5 /* SetErrno.3 */,
				F96D3E9A08F272A6004A47F5 /* SetRecLmt.3 */,
				F96D3E9B08F272A7004A47F5 /* SetResult.3 */,
				F96D3E9C08F272A7004A47F5 /* SetVar.3 */,
				F96D3E9D08F272A7004A47F5 /* Signal.3 */,
				F96D3E9E08F272A7004A47F5 /* Sleep.3 */,
				F96D3E9F08F272A7004A47F5 /* socket.n */,
				F96D3EA008F272A7004A47F5 /* source.n */,
				F96D3EA108F272A7004A47F5 /* SourceRCFile.3 */,
				F96D3EA208F272A7004A47F5 /* split.n */,
				F96D3EA308F272A7004A47F5 /* SplitList.3 */,
				F96D3EA408F272A7004A47F5 /* SplitPath.3 */,
				F96D3EA508F272A7004A47F5 /* StaticLibrary.3 */,
				F96D3EA608F272A7004A47F5 /* StdChannels.3 */,
				F96D3EA708F272A7004A47F5 /* string.n */,
				F96D3EA808F272A7004A47F5 /* StringObj.3 */,
				F96D3EA908F272A7004A47F5 /* StrMatch.3 */,
				F96D3EAA08F272A7004A47F5 /* subst.n */,
				F96D3EAB08F272A7004A47F5 /* SubstObj.3 */,
				F96D3EAC08F272A7004A47F5 /* switch.n */,
				F974D5760FBE7E1900BF728B /* tailcall.n */,
				F96D3EAD08F272A7004A47F5 /* Tcl.n */,
				F99D61180EF5573A00BBFE01 /* TclZlib.3 */,
				F96D3EAE08F272A7004A47F5 /* Tcl_Main.3 */,
				F96D3EAF08F272A7004A47F5 /* TCL_MEM_DEBUG.3 */,
				F96D3EB008F272A7004A47F5 /* tclsh.1 */,
				F96D3EB108F272A7004A47F5 /* tcltest.n */,
				F96D3EB208F272A7004A47F5 /* tclvars.n */,
				F96D3EB308F272A7004A47F5 /* tell.n */,
				F96D3EB408F272A7004A47F5 /* Thread.3 */,
				F9183E640EFC80CD0030B814 /* throw.n */,
				F96D3EB508F272A7004A47F5 /* time.n */,
				F96D3EB608F272A7004A47F5 /* tm.n */,
				F96D3EB708F272A7004A47F5 /* ToUpper.3 */,
				F96D3EB808F272A7004A47F5 /* trace.n */,
				F96D3EB908F272A7004A47F5 /* TraceCmd.3 */,
				F96D3EBA08F272A7004A47F5 /* TraceVar.3 */,
				F96D3EBB08F272A7004A47F5 /* Translate.3 */,
				F9183E650EFC80D70030B814 /* try.n */,
				F96D3EBC08F272A7004A47F5 /* UniCharIsAlpha.3 */,
				F96D3EBD08F272A7004A47F5 /* unknown.n */,
				F96D3EBE08F272A7004A47F5 /* unload.n */,
				F96D3EBF08F272A7004A47F5 /* unset.n */,
				F96D3EC008F272A7004A47F5 /* update.n */,
				F96D3EC108F272A7004A47F5 /* uplevel.n */,
				F96D3EC208F272A7004A47F5 /* UpVar.3 */,
				F96D3EC308F272A7004A47F5 /* upvar.n */,
				F96D3EC408F272A7004A47F5 /* Utf.3 */,
				F96D3EC508F272A7004A47F5 /* variable.n */,
				F96D3EC608F272A7004A47F5 /* vwait.n */,
				F96D3EC708F272A7004A47F5 /* while.n */,
				F96D3EC808F272A7004A47F5 /* WrongNumArgs.3 */,
				F915432D0EF201EE0032D1E8 /* zlib.n */,
			);
			path = doc;
			sourceTree = "<group>";
		};
		F96D3EC908F272A7004A47F5 /* generic */ = {
			isa = PBXGroup;
			children = (
				F96D3ECA08F272A7004A47F5 /* README */,
				F96D3ECB08F272A7004A47F5 /* regc_color.c */,
				F96D3ECC08F272A7004A47F5 /* regc_cvec.c */,
				F96D3ECD08F272A7004A47F5 /* regc_lex.c */,
				F96D3ECE08F272A7004A47F5 /* regc_locale.c */,
				F96D3ECF08F272A7004A47F5 /* regc_nfa.c */,
				F96D3ED008F272A7004A47F5 /* regcomp.c */,
				F96D3ED108F272A7004A47F5 /* regcustom.h */,
				F96D3ED208F272A7004A47F5 /* rege_dfa.c */,
				F96D3ED308F272A7004A47F5 /* regerror.c */,
				F96D3ED408F272A7004A47F5 /* regerrs.h */,
				F96D3ED508F272A7004A47F5 /* regex.h */,
				F96D3ED608F272A7004A47F5 /* regexec.c */,
				F96D3ED708F272A7004A47F5 /* regfree.c */,
				F96D3ED808F272A7004A47F5 /* regfronts.c */,
				F96D3ED908F272A7004A47F5 /* regguts.h */,
				F96D3EDA08F272A7004A47F5 /* tcl.decls */,
				F96D3EDB08F272A7004A47F5 /* tcl.h */,
				F96D3EDC08F272A7004A47F5 /* tclAlloc.c */,
				F96D3EDD08F272A7004A47F5 /* tclAsync.c */,
				F96D3EDE08F272A7004A47F5 /* tclBasic.c */,
				F96D3EDF08F272A7004A47F5 /* tclBinary.c */,
				F96D3EE008F272A7004A47F5 /* tclCkalloc.c */,
				F96D3EE108F272A7004A47F5 /* tclClock.c */,
				F96D3EE208F272A7004A47F5 /* tclCmdAH.c */,
				F96D3EE308F272A7004A47F5 /* tclCmdIL.c */,
				F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */,
				F96D3EE508F272A7004A47F5 /* tclCompCmds.c */,
				F96D3EE608F272A7004A47F5 /* tclCompExpr.c */,
				F96D3EE708F272A7004A47F5 /* tclCompile.c */,
				F96D3EE808F272A7004A47F5 /* tclCompile.h */,
				F96D3EE908F272A7004A47F5 /* tclConfig.c */,
				F96D3EEA08F272A7004A47F5 /* tclDate.c */,
				F96D3EEB08F272A7004A47F5 /* tclDecls.h */,
				F96D3EEC08F272A7004A47F5 /* tclDictObj.c */,
				F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */,
				F96D3EED08F272A7004A47F5 /* tclEncoding.c */,
				F96D3EEE08F272A7004A47F5 /* tclEnv.c */,
				F96D3EEF08F272A7004A47F5 /* tclEvent.c */,
				F96D3EF008F272A7004A47F5 /* tclExecute.c */,
				F96D3EF108F272A7004A47F5 /* tclFCmd.c */,
				F96D3EF208F272A7004A47F5 /* tclFileName.c */,
				F96D3EF308F272A7004A47F5 /* tclFileSystem.h */,
				F96D3EF408F272A7004A47F5 /* tclGet.c */,
				F96D3EF508F272A7004A47F5 /* tclGetDate.y */,
				F96D3EF608F272A7004A47F5 /* tclHash.c */,
				F96D3EF708F272A7004A47F5 /* tclHistory.c */,
				F96D3EF808F272A7004A47F5 /* tclIndexObj.c */,
				F96D3EF908F272A7004A47F5 /* tclInt.decls */,
				F96D3EFA08F272A7004A47F5 /* tclInt.h */,
				F96D3EFB08F272A7004A47F5 /* tclIntDecls.h */,
				F96D3EFC08F272A7004A47F5 /* tclInterp.c */,
				F96D3EFD08F272A7004A47F5 /* tclIntPlatDecls.h */,
				F96D3EFE08F272A7004A47F5 /* tclIO.c */,
				F96D3EFF08F272A7004A47F5 /* tclIO.h */,
				F96D3F0008F272A7004A47F5 /* tclIOCmd.c */,
				F96D3F0108F272A7004A47F5 /* tclIOGT.c */,
				F96D3F0208F272A7004A47F5 /* tclIORChan.c */,
				F95D77E90DFD820D00A8BF6F /* tclIORTrans.c */,
				F96D3F0308F272A7004A47F5 /* tclIOSock.c */,
				F96D3F0408F272A7004A47F5 /* tclIOUtil.c */,
				F96D3F0508F272A7004A47F5 /* tclLink.c */,
				F96D3F0608F272A7004A47F5 /* tclListObj.c */,
				F96D3F0708F272A7004A47F5 /* tclLiteral.c */,
				F96D3F0808F272A7004A47F5 /* tclLoad.c */,
				F96D3F0908F272A7004A47F5 /* tclLoadNone.c */,
				F96D3F0A08F272A7004A47F5 /* tclMain.c */,
				F96D3F0B08F272A7004A47F5 /* tclNamesp.c */,
				F96D3F0C08F272A7004A47F5 /* tclNotify.c */,
				F96D3F0D08F272A7004A47F5 /* tclObj.c */,
				F93599B20DF1F75400E04F67 /* tclOO.c */,
				F93599B40DF1F75900E04F67 /* tclOO.decls */,
				F93599B50DF1F75D00E04F67 /* tclOO.h */,
				F93599B60DF1F76100E04F67 /* tclOOBasic.c */,
				F93599B80DF1F76600E04F67 /* tclOOCall.c */,
				F93599BA0DF1F76A00E04F67 /* tclOODecls.h */,
				F93599BB0DF1F77000E04F67 /* tclOODefineCmds.c */,
				F93599BD0DF1F77400E04F67 /* tclOOInfo.c */,
				F93599BF0DF1F77900E04F67 /* tclOOInt.h */,
				F93599C00DF1F77D00E04F67 /* tclOOIntDecls.h */,
				F93599C10DF1F78300E04F67 /* tclOOMethod.c */,
				F93599C30DF1F78800E04F67 /* tclOOStubInit.c */,
				F93599C50DF1F78D00E04F67 /* tclOOStubLib.c */,
				F96D3F0E08F272A7004A47F5 /* tclPanic.c */,
				F96D3F0F08F272A7004A47F5 /* tclParse.c */,
				F96D3F1108F272A7004A47F5 /* tclPathObj.c */,
				F96D3F1208F272A7004A47F5 /* tclPipe.c */,
				F96D3F1308F272A7004A47F5 /* tclPkg.c */,
				F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */,
				F96D3F1508F272A7004A47F5 /* tclPlatDecls.h */,
				F96D3F1608F272A7004A47F5 /* tclPort.h */,
				F96D3F1708F272A7004A47F5 /* tclPosixStr.c */,
				F96D3F1808F272A7004A47F5 /* tclPreserve.c */,
				F96D3F1908F272A7004A47F5 /* tclProc.c */,
				F96D3F1A08F272A7004A47F5 /* tclRegexp.c */,
				F96D3F1B08F272A7004A47F5 /* tclRegexp.h */,
				F96D3F1C08F272A7004A47F5 /* tclResolve.c */,
				F96D3F1D08F272A7004A47F5 /* tclResult.c */,
				F96D3F1E08F272A7004A47F5 /* tclScan.c */,
				F96D3F1F08F272A7004A47F5 /* tclStringObj.c */,
				F96D3F2408F272A7004A47F5 /* tclStrToD.c */,
				F96D3F2508F272A7004A47F5 /* tclStubInit.c */,
				F96D3F2608F272A7004A47F5 /* tclStubLib.c */,
				F96D3F2708F272A7004A47F5 /* tclTest.c */,
				F96D3F2808F272A7004A47F5 /* tclTestObj.c */,
				F96D3F2908F272A7004A47F5 /* tclTestProcBodyObj.c */,
				F96D3F2A08F272A7004A47F5 /* tclThread.c */,
				F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */,
				F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */,
				F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */,
				F96D3F2E08F272A7004A47F5 /* tclThreadTest.c */,
				F96D3F2F08F272A7004A47F5 /* tclTimer.c */,
				F9903CAF094FAADA004613E9 /* tclTomMath.decls */,
				F96D3F3008F272A7004A47F5 /* tclTomMath.h */,
				F9903CB0094FAADA004613E9 /* tclTomMathDecls.h */,
				F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */,
				F96D3F3208F272A7004A47F5 /* tclTrace.c */,
				F96D3F3308F272A7004A47F5 /* tclUniData.c */,
				F96D3F3408F272A7004A47F5 /* tclUtf.c */,
				F96D3F3508F272A7004A47F5 /* tclUtil.c */,
				F96D3F3608F272A7004A47F5 /* tclVar.c */,
				F96437C90EF0D4B2003F468E /* tclZlib.c */,
			);
			path = generic;
			sourceTree = "<group>";
		};
		F96D3F3808F272A7004A47F5 /* library */ = {
			isa = PBXGroup;
			children = (
				F96D3F3908F272A8004A47F5 /* auto.tcl */,
				F96D3F3A08F272A8004A47F5 /* clock.tcl */,
				F96D3F3B08F272A8004A47F5 /* dde */,
				F96D3F8C08F272A8004A47F5 /* history.tcl */,
				F96D3F8D08F272A8004A47F5 /* http */,
				F96D3F9308F272A8004A47F5 /* init.tcl */,
				F96D3F9408F272A8004A47F5 /* msgcat */,
				F96D401708F272AA004A47F5 /* opt */,
				F96D401A08F272AA004A47F5 /* package.tcl */,
				F96D401B08F272AA004A47F5 /* parray.tcl */,
				F9ECB1110B26521500A28025 /* platform */,
				F96D401C08F272AA004A47F5 /* reg */,
				F96D401E08F272AA004A47F5 /* safe.tcl */,
				F96D401F08F272AA004A47F5 /* tclIndex */,
				F96D402008F272AA004A47F5 /* tcltest */,
				F96D402308F272AA004A47F5 /* tm.tcl */,
				F96D425B08F272B2004A47F5 /* word.tcl */,
			);
			path = library;
			sourceTree = "<group>";
		};
		F96D3F3B08F272A8004A47F5 /* dde */ = {
			isa = PBXGroup;
			children = (
				F96D3F3C08F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = dde;
			sourceTree = "<group>";
		};
		F96D3F8D08F272A8004A47F5 /* http */ = {
			isa = PBXGroup;
			children = (
				F96D3F8E08F272A8004A47F5 /* http.tcl */,
				F96D3F8F08F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = http;
			sourceTree = "<group>";
		};
		F96D3F9408F272A8004A47F5 /* msgcat */ = {
			isa = PBXGroup;
			children = (
				F96D3F9508F272A8004A47F5 /* msgcat.tcl */,
				F96D3F9608F272A8004A47F5 /* pkgIndex.tcl */,
			);
			path = msgcat;
			sourceTree = "<group>";
		};
		F96D401708F272AA004A47F5 /* opt */ = {
			isa = PBXGroup;
			children = (
				F96D401808F272AA004A47F5 /* optparse.tcl */,
				F96D401908F272AA004A47F5 /* pkgIndex.tcl */,
			);
			path = opt;
			sourceTree = "<group>";
		};
		F96D401C08F272AA004A47F5 /* reg */ = {
			isa = PBXGroup;
			children = (
				F96D401D08F272AA004A47F5 /* pkgIndex.tcl */,
			);
			path = reg;
			sourceTree = "<group>";
		};
		F96D402008F272AA004A47F5 /* tcltest */ = {
			isa = PBXGroup;
			children = (
				F96D402108F272AA004A47F5 /* pkgIndex.tcl */,
				F96D402208F272AA004A47F5 /* tcltest.tcl */,
			);
			path = tcltest;
			sourceTree = "<group>";
		};
		F96D425C08F272B2004A47F5 /* libtommath */ = {
			isa = PBXGroup;
			children = (
				F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */,
				F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */,
				F96D426908F272B3004A47F5 /* bn_mp_add.c */,
				F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */,
				F96D426C08F272B3004A47F5 /* bn_mp_and.c */,
				F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */,
				F96D426E08F272B3004A47F5 /* bn_mp_clear.c */,
				F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */,
				F96D427008F272B3004A47F5 /* bn_mp_cmp.c */,
				F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */,
				F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */,
				F96D427408F272B3004A47F5 /* bn_mp_copy.c */,
				F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */,
				F96D427608F272B3004A47F5 /* bn_mp_div.c */,
				F96D427708F272B3004A47F5 /* bn_mp_div_2.c */,
				F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */,
				F96D427908F272B3004A47F5 /* bn_s_mp_div_3.c */,
				F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */,
				F96D427E08F272B3004A47F5 /* bn_mp_exch.c */,
				F96D427F08F272B3004A47F5 /* bn_mp_expt_n.c */,
				F96D427F08F272B3004A47F5 /* bn_mp_expt_d_ex.c */,
				F96D428708F272B3004A47F5 /* bn_mp_grow.c */,
				F96D428808F272B3004A47F5 /* bn_mp_init.c */,
				F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */,
				F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */,
				F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */,
				F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */,
				F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */,
				F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */,
				F96D429508F272B3004A47F5 /* bn_mp_lshd.c */,
				F96D429608F272B3004A47F5 /* bn_mp_mod.c */,
				F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */,
				F96D429C08F272B3004A47F5 /* bn_mp_mul.c */,
				F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */,
				F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */,
				F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */,
				F96D42A208F272B3004A47F5 /* bn_mp_neg.c */,
				F96D42A308F272B3004A47F5 /* bn_mp_or.c */,
				F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */,
				F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */,
				F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */,
				F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */,
				F96D42BA08F272B3004A47F5 /* bn_mp_set.c */,
				F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */,
				F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */,
				F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */,
				F96D42C108F272B3004A47F5 /* bn_mp_sub.c */,
				F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */,
				F96D42C608F272B3004A47F5 /* bn_mp_to_ubin.c */,
				F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */,
				F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */,
				F96D42CB08F272B3004A47F5 /* bn_mp_to_radix.c */,
				F96D42CC08F272B3004A47F5 /* bn_mp_ubin_size.c */,
				F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */,
				F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */,
				F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */,
				F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */,
				F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */,
				F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */,
				F96D432908F272B4004A47F5 /* tommath_class.h */,
				F96D432A08F272B4004A47F5 /* tommath_superclass.h */,
			);
			path = libtommath;
			sourceTree = "<group>";
		};
		F96D432C08F272B4004A47F5 /* macosx */ = {
			isa = PBXGroup;
			children = (
				F96D432E08F272B5004A47F5 /* configure.ac */,
				F96D432F08F272B5004A47F5 /* GNUmakefile */,
				F96D433108F272B5004A47F5 /* README */,
				F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */,
				F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */,
				F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */,
				F96D433208F272B5004A47F5 /* Tcl-Info.plist.in */,
				F91E62260C1AE686006C9D96 /* Tclsh-Info.plist.in */,
				F97AE7F10B65C1E900310EA2 /* Tcl-Common.xcconfig */,
				F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */,
				F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */,
			);
			path = macosx;
			sourceTree = "<group>";
		};
		F96D434408F272B5004A47F5 /* tests */ = {
			isa = PBXGroup;
			children = (
				F96D434508F272B5004A47F5 /* all.tcl */,
				F96D434608F272B5004A47F5 /* append.test */,
				F96D434708F272B5004A47F5 /* appendComp.test */,
				F9ECB1CA0B2652D300A28025 /* apply.test */,
				F96D434808F272B5004A47F5 /* assocd.test */,
				F96D434908F272B5004A47F5 /* async.test */,
				F96D434A08F272B5004A47F5 /* autoMkindex.test */,
				F96D434B08F272B5004A47F5 /* basic.test */,
				F96D434C08F272B5004A47F5 /* binary.test */,
				F96D434D08F272B5004A47F5 /* case.test */,
				F96D434E08F272B5004A47F5 /* chan.test */,
				F9A493240CEBF38300B78AE2 /* chanio.test */,
				F96D434F08F272B5004A47F5 /* clock.test */,
				F96D435008F272B5004A47F5 /* cmdAH.test */,
				F96D435108F272B5004A47F5 /* cmdIL.test */,
				F96D435208F272B5004A47F5 /* cmdInfo.test */,
				F96D435308F272B5004A47F5 /* cmdMZ.test */,
				F96D435408F272B5004A47F5 /* compExpr-old.test */,
				F96D435508F272B5004A47F5 /* compExpr.test */,
				F96D435608F272B5004A47F5 /* compile.test */,
				F96D435708F272B5004A47F5 /* concat.test */,
				F96D435808F272B5004A47F5 /* config.test */,
				F974D5770FBE7E6100BF728B /* coroutine.test */,
				F96D435908F272B5004A47F5 /* dcall.test */,
				F96D435A08F272B5004A47F5 /* dict.test */,
				F96D435C08F272B5004A47F5 /* dstring.test */,
				F96D435E08F272B5004A47F5 /* encoding.test */,
				F96D435F08F272B5004A47F5 /* env.test */,
				F96D436008F272B5004A47F5 /* error.test */,
				F96D436108F272B5004A47F5 /* eval.test */,
				F96D436208F272B5004A47F5 /* event.test */,
				F96D436308F272B5004A47F5 /* exec.test */,
				F96D436408F272B5004A47F5 /* execute.test */,
				F96D436508F272B5004A47F5 /* expr-old.test */,
				F96D436608F272B5004A47F5 /* expr.test */,
				F96D436708F272B6004A47F5 /* fCmd.test */,
				F96D436808F272B6004A47F5 /* fileName.test */,
				F96D436908F272B6004A47F5 /* fileSystem.test */,
				F96D436A08F272B6004A47F5 /* for-old.test */,
				F96D436B08F272B6004A47F5 /* for.test */,
				F96D436C08F272B6004A47F5 /* foreach.test */,
				F96D436D08F272B6004A47F5 /* format.test */,
				F96D436E08F272B6004A47F5 /* get.test */,
				F96D436F08F272B6004A47F5 /* history.test */,
				F96D437008F272B6004A47F5 /* http.test */,
				F974D56C0FBE7D6300BF728B /* http11.test */,
				F96D437108F272B6004A47F5 /* httpd */,
				F974D56D0FBE7D6300BF728B /* httpd11.tcl */,
				F96D437208F272B6004A47F5 /* httpold.test */,
				F96D437308F272B6004A47F5 /* if-old.test */,
				F96D437408F272B6004A47F5 /* if.test */,
				F96D437508F272B6004A47F5 /* incr-old.test */,
				F96D437608F272B6004A47F5 /* incr.test */,
				F96D437708F272B6004A47F5 /* indexObj.test */,
				F96D437808F272B6004A47F5 /* info.test */,
				F96D437908F272B6004A47F5 /* init.test */,
				F96D437A08F272B6004A47F5 /* interp.test */,
				F96D437B08F272B6004A47F5 /* io.test */,
				F96D437C08F272B6004A47F5 /* ioCmd.test */,
				F96D437D08F272B6004A47F5 /* iogt.test */,
				F96D437F08F272B6004A47F5 /* join.test */,
				F96D438008F272B6004A47F5 /* lindex.test */,
				F96D438108F272B6004A47F5 /* link.test */,
				F96D438208F272B6004A47F5 /* linsert.test */,
				F96D438308F272B6004A47F5 /* list.test */,
				F96D438408F272B6004A47F5 /* listObj.test */,
				F96D438508F272B6004A47F5 /* llength.test */,
				F96D438608F272B6004A47F5 /* load.test */,
				F96D438708F272B6004A47F5 /* lrange.test */,
				F96D438808F272B6004A47F5 /* lrepeat.test */,
				F96D438908F272B6004A47F5 /* lreplace.test */,
				F96D438A08F272B6004A47F5 /* lsearch.test */,
				F96D438B08F272B6004A47F5 /* lset.test */,
				F96D438C08F272B6004A47F5 /* lsetComp.test */,
				F96D438D08F272B6004A47F5 /* macOSXFCmd.test */,
				F95FAFF90B34F1130072E431 /* macOSXLoad.test */,
				F96D438E08F272B6004A47F5 /* main.test */,
				F9ECB1CB0B26534C00A28025 /* mathop.test */,
				F96D438F08F272B6004A47F5 /* misc.test */,
				F96D439008F272B6004A47F5 /* msgcat.test */,
				F96D439108F272B6004A47F5 /* namespace-old.test */,
				F96D439208F272B7004A47F5 /* namespace.test */,
				F96D439308F272B7004A47F5 /* notify.test */,
				F91DC23C0E44C51B002CB8D1 /* nre.test */,
				F96D439408F272B7004A47F5 /* obj.test */,
				F93599C80DF1F81900E04F67 /* oo.test */,
				F96D439508F272B7004A47F5 /* opt.test */,
				F96D439608F272B7004A47F5 /* package.test */,
				F96D439708F272B7004A47F5 /* parse.test */,
				F96D439808F272B7004A47F5 /* parseExpr.test */,
				F96D439908F272B7004A47F5 /* parseOld.test */,
				F96D439A08F272B7004A47F5 /* pid.test */,
				F96D439B08F272B7004A47F5 /* pkg.test */,
				F96D439C08F272B7004A47F5 /* pkgMkIndex.test */,
				F96D439D08F272B7004A47F5 /* platform.test */,
				F96D439E08F272B7004A47F5 /* proc-old.test */,
				F96D439F08F272B7004A47F5 /* proc.test */,
				F96D43A008F272B7004A47F5 /* pwd.test */,
				F96D43A108F272B7004A47F5 /* README */,
				F96D43A208F272B7004A47F5 /* reg.test */,
				F96D43A308F272B7004A47F5 /* regexp.test */,
				F96D43A408F272B7004A47F5 /* regexpComp.test */,
				F96D43A508F272B7004A47F5 /* registry.test */,
				F96D43A608F272B7004A47F5 /* remote.tcl */,
				F96D43A708F272B7004A47F5 /* rename.test */,
				F96D43A808F272B7004A47F5 /* result.test */,
				F96D43A908F272B7004A47F5 /* safe.test */,
				F96D43AA08F272B7004A47F5 /* scan.test */,
				F96D43AB08F272B7004A47F5 /* security.test */,
				F96D43AC08F272B7004A47F5 /* set-old.test */,
				F96D43AD08F272B7004A47F5 /* set.test */,
				F96D43AE08F272B7004A47F5 /* socket.test */,
				F96D43AF08F272B7004A47F5 /* source.test */,
				F96D43B008F272B7004A47F5 /* split.test */,
				F96D43B108F272B7004A47F5 /* stack.test */,
				F96D43B208F272B7004A47F5 /* string.test */,
				F96D43B308F272B7004A47F5 /* stringComp.test */,
				F96D43B408F272B7004A47F5 /* stringObj.test */,
				F96D43B508F272B7004A47F5 /* subst.test */,
				F96D43B608F272B7004A47F5 /* switch.test */,
				F974D5780FBE7E6100BF728B /* tailcall.test */,
				F96D43B708F272B7004A47F5 /* tcltest.test */,
				F96D43B808F272B7004A47F5 /* thread.test */,
				F96D43B908F272B7004A47F5 /* timer.test */,
				F96D43BA08F272B7004A47F5 /* tm.test */,
				F96D43BB08F272B7004A47F5 /* trace.test */,
				F96D43BC08F272B7004A47F5 /* unixFCmd.test */,
				F96D43BD08F272B7004A47F5 /* unixFile.test */,
				F96D43BE08F272B7004A47F5 /* unixInit.test */,
				F96D43BF08F272B7004A47F5 /* unixNotfy.test */,
				F96D43C008F272B7004A47F5 /* unknown.test */,
				F96D43C108F272B7004A47F5 /* unload.test */,
				F96D43C208F272B7004A47F5 /* uplevel.test */,
				F96D43C308F272B7004A47F5 /* upvar.test */,
				F96D43C408F272B7004A47F5 /* utf.test */,
				F96D43C508F272B7004A47F5 /* util.test */,
				F96D43C608F272B7004A47F5 /* var.test */,
				F96D43C708F272B7004A47F5 /* while-old.test */,
				F96D43C808F272B7004A47F5 /* while.test */,
				F96D43C908F272B7004A47F5 /* winConsole.test */,
				F96D43CA08F272B7004A47F5 /* winDde.test */,
				F96D43CB08F272B7004A47F5 /* winFCmd.test */,
				F96D43CC08F272B7004A47F5 /* winFile.test */,
				F96D43CD08F272B7004A47F5 /* winNotify.test */,
				F96D43CE08F272B7004A47F5 /* winPipe.test */,
				F96D43CF08F272B7004A47F5 /* winTime.test */,
				F915432A0EF201CF0032D1E8 /* zlib.test */,
			);
			path = tests;
			sourceTree = "<group>";
		};
		F96D43D008F272B8004A47F5 /* tools */ = {
			isa = PBXGroup;
			children = (
				F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */,
				F96D442508F272B8004A47F5 /* genStubs.tcl */,
				F96D442708F272B8004A47F5 /* index.tcl */,
				F96D442808F272B8004A47F5 /* installData.tcl */,
				F96D442908F272B8004A47F5 /* loadICU.tcl */,
				F96D442B08F272B8004A47F5 /* makeTestCases.tcl */,
				F96D443208F272B8004A47F5 /* README */,
				F96D443308F272B8004A47F5 /* regexpTestLib.tcl */,
				F96D443908F272B9004A47F5 /* tcltk-man2html.tcl */,
				F96D443A08F272B9004A47F5 /* tclZIC.tcl */,
				F92D7F100DE777240033A13A /* tsdPerf.tcl */,
				F96D443B08F272B9004A47F5 /* uniClass.tcl */,
				F96D443C08F272B9004A47F5 /* uniParse.tcl */,
			);
			path = tools;
			sourceTree = "<group>";
		};
		F96D443E08F272B9004A47F5 /* unix */ = {
			isa = PBXGroup;
			children = (
				F96D444008F272B9004A47F5 /* aclocal.m4 */,
				F96D444108F272B9004A47F5 /* configure */,
				F96D444208F272B9004A47F5 /* configure.ac */,
				F96D444308F272B9004A47F5 /* dltest */,
				F96D444D08F272B9004A47F5 /* install-sh */,
				F96D444E08F272B9004A47F5 /* installManPage */,
				F96D444F08F272B9004A47F5 /* ldAix */,
				F96D445008F272B9004A47F5 /* Makefile.in */,
				F96D445208F272B9004A47F5 /* README */,
				F96D445308F272B9004A47F5 /* tcl.m4 */,
				F974D5790FBE7E9C00BF728B /* tcl.pc.in */,
				F96D445408F272B9004A47F5 /* tcl.spec */,
				F96D445508F272B9004A47F5 /* tclAppInit.c */,
				F96D445608F272B9004A47F5 /* tclConfig.h.in */,
				F96D445708F272B9004A47F5 /* tclConfig.sh.in */,
				F96D445808F272B9004A47F5 /* tclLoadAix.c */,
				F96D445908F272B9004A47F5 /* tclLoadDl.c */,
				F96D445B08F272B9004A47F5 /* tclLoadDyld.c */,
				F96D445C08F272B9004A47F5 /* tclLoadNext.c */,
				F96D445D08F272B9004A47F5 /* tclLoadOSF.c */,
				F96D445E08F272B9004A47F5 /* tclLoadShl.c */,
				F96D445F08F272B9004A47F5 /* tclUnixChan.c */,
				F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */,
				F96D446008F272B9004A47F5 /* tclUnixEvent.c */,
				F96D446108F272B9004A47F5 /* tclUnixFCmd.c */,
				F96D446208F272B9004A47F5 /* tclUnixFile.c */,
				F96D446308F272B9004A47F5 /* tclUnixInit.c */,
				F96D446408F272B9004A47F5 /* tclUnixNotfy.c */,
				F96D446508F272B9004A47F5 /* tclUnixPipe.c */,
				F96D446608F272B9004A47F5 /* tclUnixPort.h */,
				F96D446708F272B9004A47F5 /* tclUnixSock.c */,
				F96D446808F272B9004A47F5 /* tclUnixTest.c */,
				F96D446908F272B9004A47F5 /* tclUnixThrd.c */,
				F96D446B08F272B9004A47F5 /* tclUnixTime.c */,
				F96D446C08F272B9004A47F5 /* tclXtNotify.c */,
				F96D446D08F272B9004A47F5 /* tclXtTest.c */,
			);
			path = unix;
			sourceTree = "<group>";
		};
		F96D444308F272B9004A47F5 /* dltest */ = {
			isa = PBXGroup;
			children = (
				F96D444408F272B9004A47F5 /* Makefile.in */,
				F96D444508F272B9004A47F5 /* pkga.c */,
				F96D444608F272B9004A47F5 /* pkgb.c */,
				F96D444708F272B9004A47F5 /* pkgc.c */,
				F96D444808F272B9004A47F5 /* pkgd.c */,
				F96D444908F272B9004A47F5 /* pkge.c */,
				F96D444B08F272B9004A47F5 /* pkgua.c */,
				F96D444C08F272B9004A47F5 /* README */,
			);
			path = dltest;
			sourceTree = "<group>";
		};
		F96D446E08F272B9004A47F5 /* win */ = {
			isa = PBXGroup;
			children = (
				F96D447008F272BA004A47F5 /* aclocal.m4 */,
				F96D447108F272BA004A47F5 /* buildall.vc.bat */,
				F96D447208F272BA004A47F5 /* cat.c */,
				F96D447308F272BA004A47F5 /* coffbase.txt */,
				F96D447408F272BA004A47F5 /* configure */,
				F96D447508F272BA004A47F5 /* configure.ac */,
				F96D447708F272BA004A47F5 /* Makefile.in */,
				F96D447808F272BA004A47F5 /* makefile.vc */,
				F96D447908F272BA004A47F5 /* nmakehlp.c */,
				F96D447A08F272BA004A47F5 /* README */,
				F96D447C08F272BA004A47F5 /* rules.vc */,
				F96D447D08F272BA004A47F5 /* stub16.c */,
				F96D447E08F272BA004A47F5 /* tcl.dsp */,
				F96D447F08F272BA004A47F5 /* tcl.dsw */,
				F96D448108F272BA004A47F5 /* tcl.m4 */,
				F96D448208F272BA004A47F5 /* tcl.rc */,
				F96D448308F272BA004A47F5 /* tclAppInit.c */,
				F96D448408F272BA004A47F5 /* tclConfig.sh.in */,
				F96D448608F272BA004A47F5 /* tclsh.rc */,
				F96D448708F272BA004A47F5 /* tclWin32Dll.c */,
				F96D448808F272BA004A47F5 /* tclWinChan.c */,
				F96D448908F272BA004A47F5 /* tclWinConsole.c */,
				F96D448A08F272BA004A47F5 /* tclWinDde.c */,
				F96D448B08F272BA004A47F5 /* tclWinError.c */,
				F96D448C08F272BA004A47F5 /* tclWinFCmd.c */,
				F96D448D08F272BA004A47F5 /* tclWinFile.c */,
				F96D448E08F272BA004A47F5 /* tclWinInit.c */,
				F96D448F08F272BA004A47F5 /* tclWinInt.h */,
				F96D449008F272BA004A47F5 /* tclWinLoad.c */,
				F96D449108F272BA004A47F5 /* tclWinNotify.c */,
				F96D449208F272BA004A47F5 /* tclWinPipe.c */,
				F96D449308F272BA004A47F5 /* tclWinPort.h */,
				F96D449408F272BA004A47F5 /* tclWinReg.c */,
				F96D449508F272BA004A47F5 /* tclWinSerial.c */,
				F96D449608F272BA004A47F5 /* tclWinSock.c */,
				F96D449708F272BA004A47F5 /* tclWinTest.c */,
				F96D449808F272BA004A47F5 /* tclWinThrd.c */,
				F96D449A08F272BA004A47F5 /* tclWinTime.c */,
			);
			path = win;
			sourceTree = "<group>";
		};
		F9ECB1110B26521500A28025 /* platform */ = {
			isa = PBXGroup;
			children = (
				F9ECB1120B26521500A28025 /* pkgIndex.tcl */,
				F9ECB1130B26521500A28025 /* platform.tcl */,
				F9ECB1140B26521500A28025 /* shell.tcl */,
			);
			path = platform;
			sourceTree = "<group>";
		};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
		8DD76FA90486AB0100D96B5E /* tcltest */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = F95CC8B009158F3100EA5ACE /* Build configuration list for PBXNativeTarget "tcltest" */;
			buildPhases = (
				F9A5C5F508F651A2008AE941 /* Configure Tcl */,
				8DD76FAB0486AB0100D96B5E /* Sources */,
				8DD76FAD0486AB0100D96B5E /* Frameworks */,
				F95FA74C0B32CE190072E431 /* Build dltest */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = tcltest;
			productInstallPath = "$(BINDIR)";
			productName = tcltest;
			productReference = 8DD76FB20486AB0100D96B5E /* tcltest */;
			productType = "com.apple.product-type.tool";
		};
		F97258A50A86873C00096C78 /* tests */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = F97258A80A86873D00096C78 /* Build configuration list for PBXNativeTarget "tests" */;
			buildPhases = (
				F97258A40A86873C00096C78 /* Run Testsuite */,
			);
			buildRules = (
			);
			dependencies = (
				F97258D30A868C6F00096C78 /* PBXTargetDependency */,
			);
			name = tests;
			productName = tests;
			productType = "com.apple.product-type.bundle";
		};
		F9E61D16090A3E94002B3151 /* Tcl */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = F95CC8AB09158F3100EA5ACE /* Build configuration list for PBXNativeTarget "Tcl" */;
			buildPhases = (
				F97AF02F0B665DA900310EA2 /* Build Tcl */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = Tcl;
			productName = tclsh;
			productReference = F9A3084B08F2D4CE00BAE1AB /* tclsh */;
			productType = "com.apple.product-type.tool";
		};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
		08FB7793FE84155DC02AAC07 /* Project object */ = {
			isa = PBXProject;
			attributes = {
				BuildIndependentTargetsInParallel = YES;
			};
			buildConfigurationList = F95CC8B509158F3100EA5ACE /* Build configuration list for PBXProject "Tcl" */;
			compatibilityVersion = "Xcode 3.2";
			hasScannedForEncodings = 1;
			mainGroup = 08FB7794FE84155DC02AAC07 /* Tcl */;
			projectDirPath = "";
			projectRoot = ..;
			targets = (
				F9E61D16090A3E94002B3151 /* Tcl */,
				8DD76FA90486AB0100D96B5E /* tcltest */,
				F97258A50A86873C00096C78 /* tests */,
			);
		};
/* End PBXProject section */

/* Begin PBXShellScriptBuildPhase section */
		F95FA74C0B32CE190072E431 /* Build dltest */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(DERIVED_FILE_DIR)/tcl/tclConfig.sh",
				"$(TCL_SRCROOT)/generic/tclStubLib.c",
				"$(TCL_SRCROOT)/unix/dltest/pkga.c",
				"$(TCL_SRCROOT)/unix/dltest/pkgb.c",
				"$(TCL_SRCROOT)/unix/dltest/pkgc.c",
				"$(TCL_SRCROOT)/unix/dltest/pkgd.c",
				"$(TCL_SRCROOT)/unix/dltest/pkge.c",
				"$(TCL_SRCROOT)/unix/dltest/pkgua.c",
			);
			name = "Build dltest";
			outputPaths = (
				"$(DERIVED_FILE_DIR)/tcl/dltest.marker",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "## dltest build script phase\n\nrm -f \"${DERIVED_FILE_DIR}/tcl/dltest.marker\"\nmake -C \"${DERIVED_FILE_DIR}/tcl\" dltest.marker\nln -fsh \"${DERIVED_FILE_DIR}/tcl/dltest\" \"${CONFIGURATION_BUILD_DIR}\"\n";
			showEnvVarsInLog = 0;
		};
		F97258A40A86873C00096C78 /* Run Testsuite */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
			);
			name = "Run Testsuite";
			outputPaths = (
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "if [ \"${ACTION:-build}\" == \"build\" ]; then\nif [ -z \"${HOME}\" ]; then export HOME=\"$(echo ~)\"; fi\ncd \"${TARGET_TEMP_DIR}\"; rm -rf \"${DERIVED_FILE_DIR}\"; mkdir -p \"${DERIVED_FILE_DIR}\"\nprintf '%s%s%s%s%s' '\npackage require tcltest 2.5\nnamespace import tcltest::*\nconfigure -testdir [file normalize {' \"${TCL_SRCROOT}\" '/tests}]\nconfigure -tmpdir [file normalize {' \"${DERIVED_FILE_DIR}\" '}]\nconfigure -verbose [concat [configure -verbose] line]\nrunAllTests\n' | \"${TEST_RIG}\"; TEST_RIG_RESULT=$?\n[ ${TEST_RIG_RESULT} -ne 0 ] && echo \"tcltest:0: error: tcltest exited abnormally with code ${TEST_RIG_RESULT}.\"\nexit ${TEST_RIG_RESULT}\nfi";
			showEnvVarsInLog = 0;
		};
		F97AF02F0B665DA900310EA2 /* Build Tcl */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"${TARGET_TEMP_DIR}/.none",
			);
			name = "Build Tcl";
			outputPaths = (
				"${TARGET_BUILD_DIR}/${EXECUTABLE_NAME}",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "if [ -e \"${TARGET_BUILD_DIR}/tclsh\" ]; then\n    mv -f \"${TARGET_BUILD_DIR}/tclsh\" \"${TARGET_BUILD_DIR}/tclsh${VERSION}\"\nfi\nexport CC=$(xcrun -find ${GCC} || echo ${GCC}); export LD=${CC}\ngnumake -C \"${TCL_SRCROOT}/macosx\" -j \"$(sysctl -n hw.activecpu)\" \"$(echo \"${ACTION}\" | sed -e s/build// -e s/clean/distclean/ -e s/..\\*/\\&-/)${MAKE_TARGET}\" CFLAGS_WARNING=\"${WARNING_CFLAGS}\" CFLAGS_OPTIMIZE=\"-O${GCC_OPTIMIZATION_LEVEL}\" SYMROOT=\"${BUILT_PRODUCTS_DIR}\" OBJ_DIR=\"${OBJECT_FILE_DIR}\" INSTALL_ROOT=\"${DSTROOT}\" PREFIX=\"${PREFIX}\" BINDIR=\"${BINDIR}\" LIBDIR=\"${FRAMEWORK_INSTALL_PATH}\" MANDIR=\"${MANDIR}\" EXTRA_CONFIGURE_ARGS=\"${CONFIGURE_ARGS}\" ${EXTRA_MAKE_FLAGS}\nresult=$?\nif [ -e \"${TARGET_BUILD_DIR}/tclsh${VERSION}\" ]; then\n    mv -f \"${TARGET_BUILD_DIR}/tclsh${VERSION}\" \"${TARGET_BUILD_DIR}/tclsh\"\nfi\nif [ -e \"${BUILT_PRODUCTS_DIR}/tcltest\" ]; then\n\trm -f \"${BUILT_PRODUCTS_DIR}/tcltest\"\nfi\necho \"Done\"\nrm -f \"${SCRIPT_INPUT_FILE_0}\"\nexit ${result}\n";
			showEnvVarsInLog = 0;
		};
		F9A5C5F508F651A2008AE941 /* Configure Tcl */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TCL_SRCROOT)/macosx/configure.ac",
				"$(TCL_SRCROOT)/unix/configure.ac",
				"$(TCL_SRCROOT)/unix/tcl.m4",
				"$(TCL_SRCROOT)/unix/aclocal.m4",
				"$(TCL_SRCROOT)/unix/tclConfig.sh.in",
				"$(TCL_SRCROOT)/unix/Makefile.in",
				"$(TCL_SRCROOT)/unix/dltest/Makefile.in",
			);
			name = "Configure Tcl";
			outputPaths = (
				"$(DERIVED_FILE_DIR)/tcl/tclConfig.sh",
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/bash;
			shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tcl/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tcl\"\n    CC=$(xcrun -find ${GCC} || echo ${GCC})\n    \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi\n";
			showEnvVarsInLog = 0;
		};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
		8DD76FAB0486AB0100D96B5E /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				F96D456F08F272BB004A47F5 /* regcomp.c in Sources */,
				F96D457208F272BB004A47F5 /* regerror.c in Sources */,
				F96D457508F272BB004A47F5 /* regexec.c in Sources */,
				F96D457608F272BB004A47F5 /* regfree.c in Sources */,
				F96D457B08F272BB004A47F5 /* tclAlloc.c in Sources */,
				F96D457C08F272BB004A47F5 /* tclAsync.c in Sources */,
				F96D457D08F272BB004A47F5 /* tclBasic.c in Sources */,
				F96D457E08F272BC004A47F5 /* tclBinary.c in Sources */,
				F96D457F08F272BC004A47F5 /* tclCkalloc.c in Sources */,
				F96D458008F272BC004A47F5 /* tclClock.c in Sources */,
				F96D458108F272BC004A47F5 /* tclCmdAH.c in Sources */,
				F96D458208F272BC004A47F5 /* tclCmdIL.c in Sources */,
				F96D458308F272BC004A47F5 /* tclCmdMZ.c in Sources */,
				F96D458408F272BC004A47F5 /* tclCompCmds.c in Sources */,
				F96D458508F272BC004A47F5 /* tclCompExpr.c in Sources */,
				F96D458608F272BC004A47F5 /* tclCompile.c in Sources */,
				F96D458808F272BC004A47F5 /* tclConfig.c in Sources */,
				F96D458908F272BC004A47F5 /* tclDate.c in Sources */,
				F96D458B08F272BC004A47F5 /* tclDictObj.c in Sources */,
				F96D458C08F272BC004A47F5 /* tclEncoding.c in Sources */,
				F96D458D08F272BC004A47F5 /* tclEnv.c in Sources */,
				F96D458E08F272BC004A47F5 /* tclEvent.c in Sources */,
				F96D458F08F272BC004A47F5 /* tclExecute.c in Sources */,
				F96D459008F272BC004A47F5 /* tclFCmd.c in Sources */,
				F96D459108F272BC004A47F5 /* tclFileName.c in Sources */,
				F96D459308F272BC004A47F5 /* tclGet.c in Sources */,
				F96D459508F272BC004A47F5 /* tclHash.c in Sources */,
				F96D459608F272BC004A47F5 /* tclHistory.c in Sources */,
				F96D459708F272BC004A47F5 /* tclIndexObj.c in Sources */,
				F96D459B08F272BC004A47F5 /* tclInterp.c in Sources */,
				F96D459D08F272BC004A47F5 /* tclIO.c in Sources */,
				F96D459F08F272BC004A47F5 /* tclIOCmd.c in Sources */,
				F96D45A008F272BC004A47F5 /* tclIOGT.c in Sources */,
				F96D45A108F272BC004A47F5 /* tclIORChan.c in Sources */,
				F95D77EA0DFD820D00A8BF6F /* tclIORTrans.c in Sources */,
				F96D45A208F272BC004A47F5 /* tclIOSock.c in Sources */,
				F96D45A308F272BC004A47F5 /* tclIOUtil.c in Sources */,
				F96D45A408F272BC004A47F5 /* tclLink.c in Sources */,
				F96D45A508F272BC004A47F5 /* tclListObj.c in Sources */,
				F96D45A608F272BC004A47F5 /* tclLiteral.c in Sources */,
				F96D45A708F272BC004A47F5 /* tclLoad.c in Sources */,
				F96D45A908F272BC004A47F5 /* tclMain.c in Sources */,
				F96D45AA08F272BC004A47F5 /* tclNamesp.c in Sources */,
				F96D45AB08F272BC004A47F5 /* tclNotify.c in Sources */,
				F96D45AC08F272BC004A47F5 /* tclObj.c in Sources */,
				F93599B30DF1F75400E04F67 /* tclOO.c in Sources */,
				F93599B70DF1F76100E04F67 /* tclOOBasic.c in Sources */,
				F93599B90DF1F76600E04F67 /* tclOOCall.c in Sources */,
				F93599BC0DF1F77000E04F67 /* tclOODefineCmds.c in Sources */,
				F93599BE0DF1F77400E04F67 /* tclOOInfo.c in Sources */,
				F93599C20DF1F78300E04F67 /* tclOOMethod.c in Sources */,
				F93599C40DF1F78800E04F67 /* tclOOStubInit.c in Sources */,
				F93599C60DF1F78D00E04F67 /* tclOOStubLib.c in Sources */,
				F96D45AD08F272BC004A47F5 /* tclPanic.c in Sources */,
				F96D45AE08F272BC004A47F5 /* tclParse.c in Sources */,
				F96D45B008F272BC004A47F5 /* tclPathObj.c in Sources */,
				F96D45B108F272BC004A47F5 /* tclPipe.c in Sources */,
				F96D45B208F272BC004A47F5 /* tclPkg.c in Sources */,
				F96D45B308F272BC004A47F5 /* tclPkgConfig.c in Sources */,
				F96D45B608F272BC004A47F5 /* tclPosixStr.c in Sources */,
				F96D45B708F272BC004A47F5 /* tclPreserve.c in Sources */,
				F96D45B808F272BC004A47F5 /* tclProc.c in Sources */,
				F96D45B908F272BC004A47F5 /* tclRegexp.c in Sources */,
				F96D45BB08F272BC004A47F5 /* tclResolve.c in Sources */,
				F96D45BC08F272BC004A47F5 /* tclResult.c in Sources */,
				F96D45BD08F272BC004A47F5 /* tclScan.c in Sources */,
				F96D45BE08F272BC004A47F5 /* tclStringObj.c in Sources */,
				F96D45C308F272BC004A47F5 /* tclStrToD.c in Sources */,
				F96D45C408F272BC004A47F5 /* tclStubInit.c in Sources */,
				F96D45C508F272BC004A47F5 /* tclStubLib.c in Sources */,
				F96D45C608F272BC004A47F5 /* tclTest.c in Sources */,
				F96D45C708F272BC004A47F5 /* tclTestObj.c in Sources */,
				F96D45C808F272BC004A47F5 /* tclTestProcBodyObj.c in Sources */,
				F96D45C908F272BC004A47F5 /* tclThread.c in Sources */,
				F96D45CA08F272BC004A47F5 /* tclThreadAlloc.c in Sources */,
				F96D45CB08F272BC004A47F5 /* tclThreadJoin.c in Sources */,
				F96D45CC08F272BC004A47F5 /* tclThreadStorage.c in Sources */,
				F96D45CD08F272BC004A47F5 /* tclThreadTest.c in Sources */,
				F96D45CE08F272BC004A47F5 /* tclTimer.c in Sources */,
				F96D45D008F272BC004A47F5 /* tclTomMathInterface.c in Sources */,
				F96D45D108F272BC004A47F5 /* tclTrace.c in Sources */,
				F96D45D308F272BC004A47F5 /* tclUtf.c in Sources */,
				F96D45D408F272BC004A47F5 /* tclUtil.c in Sources */,
				F96D45D508F272BC004A47F5 /* tclVar.c in Sources */,
				F96437CA0EF0D4B2003F468E /* tclZlib.c in Sources */,
				F96D48E208F272C3004A47F5 /* bn_fast_s_mp_mul_digs.c in Sources */,
				F96D48E408F272C3004A47F5 /* bn_fast_s_mp_sqr.c in Sources */,
				F96D48E708F272C3004A47F5 /* bn_mp_add.c in Sources */,
				F96D48E808F272C3004A47F5 /* bn_mp_add_d.c in Sources */,
				F9E61D2B090A48A4002B3151 /* bn_mp_and.c in Sources */,
				F96D48EB08F272C3004A47F5 /* bn_mp_clamp.c in Sources */,
				F96D48EC08F272C3004A47F5 /* bn_mp_clear.c in Sources */,
				F96D48ED08F272C3004A47F5 /* bn_mp_clear_multi.c in Sources */,
				F96D48EE08F272C3004A47F5 /* bn_mp_cmp.c in Sources */,
				F9E61D28090A481F002B3151 /* bn_mp_cmp_d.c in Sources */,
				F96D48F008F272C3004A47F5 /* bn_mp_cmp_mag.c in Sources */,
				F96D48F208F272C3004A47F5 /* bn_mp_cnt_lsb.c in Sources */,
				F96D48F208F272C3004A47F5 /* bn_mp_copy.c in Sources */,
				F96D48F308F272C3004A47F5 /* bn_mp_count_bits.c in Sources */,
				F96D48F408F272C3004A47F5 /* bn_mp_div.c in Sources */,
				F96D48F508F272C3004A47F5 /* bn_mp_div_2.c in Sources */,
				F96D48F608F272C3004A47F5 /* bn_mp_div_2d.c in Sources */,
				F96D48F708F272C3004A47F5 /* bn_s_mp_div_3.c in Sources */,
				F96D48F808F272C3004A47F5 /* bn_mp_div_d.c in Sources */,
				F96D48FC08F272C3004A47F5 /* bn_mp_exch.c in Sources */,
				F9E61D2C090A48AC002B3151 /* bn_mp_expt_n.c in Sources */,
				F9E61D2C090A48AC002B3151 /* bn_mp_expt_d_ex.c in Sources */,
				F96D490508F272C3004A47F5 /* bn_mp_grow.c in Sources */,
				F96D490608F272C3004A47F5 /* bn_mp_init.c in Sources */,
				F96D490708F272C3004A47F5 /* bn_mp_init_copy.c in Sources */,
				F96D490808F272C3004A47F5 /* bn_mp_init_multi.c in Sources */,
				F96D490908F272C3004A47F5 /* bn_mp_init_set.c in Sources */,
				F96D490B08F272C3004A47F5 /* bn_mp_init_size.c in Sources */,
				F96D491008F272C3004A47F5 /* bn_mp_karatsuba_mul.c in Sources */,
				F96D491108F272C3004A47F5 /* bn_mp_karatsuba_sqr.c in Sources */,
				F96D491308F272C3004A47F5 /* bn_mp_lshd.c in Sources */,
				F96D491408F272C3004A47F5 /* bn_mp_mod.c in Sources */,
				F96D491508F272C3004A47F5 /* bn_mp_mod_2d.c in Sources */,
				F96D491A08F272C3004A47F5 /* bn_mp_mul.c in Sources */,
				F96D491B08F272C3004A47F5 /* bn_mp_mul_2.c in Sources */,
				F96D491C08F272C3004A47F5 /* bn_mp_mul_2d.c in Sources */,
				F96D491D08F272C3004A47F5 /* bn_mp_mul_d.c in Sources */,
				F9E61D29090A486C002B3151 /* bn_mp_neg.c in Sources */,
				F9E61D2E090A48BF002B3151 /* bn_mp_or.c in Sources */,
				F96D492908F272C3004A47F5 /* bn_mp_radix_size.c in Sources */,
				F96D492A08F272C3004A47F5 /* bn_mp_radix_smap.c in Sources */,
				F96D492C08F272C3004A47F5 /* bn_mp_read_radix.c in Sources */,
				F96D493708F272C3004A47F5 /* bn_mp_rshd.c in Sources */,
				F96D493808F272C3004A47F5 /* bn_mp_set.c in Sources */,
				F9E61D2F090A48C7002B3151 /* bn_mp_shrink.c in Sources */,
				F96D493C08F272C3004A47F5 /* bn_mp_sqr.c in Sources */,
				F9E61D2A090A4891002B3151 /* bn_mp_sqrt.c in Sources */,
				F96D493F08F272C3004A47F5 /* bn_mp_sub.c in Sources */,
				F96D494008F272C3004A47F5 /* bn_mp_sub_d.c in Sources */,
				F9E61D31090A48F9002B3151 /* bn_mp_to_ubin.c in Sources */,
				F96D494608F272C3004A47F5 /* bn_mp_toom_mul.c in Sources */,
				F96D494708F272C3004A47F5 /* bn_mp_toom_sqr.c in Sources */,
				F96D494908F272C3004A47F5 /* bn_mp_to_radix.c in Sources */,
				F9E61D32090A48FA002B3151 /* bn_mp_ubin_size.c in Sources */,
				F9E61D2D090A48BB002B3151 /* bn_mp_xor.c in Sources */,
				F96D494C08F272C3004A47F5 /* bn_mp_zero.c in Sources */,
				F96D494F08F272C3004A47F5 /* bn_s_mp_add.c in Sources */,
				F96D495108F272C3004A47F5 /* bn_s_mp_mul_digs.c in Sources */,
				F96D495308F272C3004A47F5 /* bn_s_mp_sqr.c in Sources */,
				F96D495408F272C3004A47F5 /* bn_s_mp_sub.c in Sources */,
				F96D49A908F272C4004A47F5 /* tclMacOSXBundle.c in Sources */,
				F96D49AD08F272C4004A47F5 /* tclMacOSXFCmd.c in Sources */,
				F96D49AE08F272C4004A47F5 /* tclMacOSXNotify.c in Sources */,
				F90509300913A72400327603 /* tclAppInit.c in Sources */,
				F96D4AC608F272C9004A47F5 /* tclLoadDyld.c in Sources */,
				F96D4ACA08F272C9004A47F5 /* tclUnixChan.c in Sources */,
				F9FC77B80AB29E9100B7077D /* tclUnixCompat.c in Sources */,
				F96D4ACB08F272C9004A47F5 /* tclUnixEvent.c in Sources */,
				F96D4ACC08F272C9004A47F5 /* tclUnixFCmd.c in Sources */,
				F96D4ACD08F272C9004A47F5 /* tclUnixFile.c in Sources */,
				F96D4ACE08F272C9004A47F5 /* tclUnixInit.c in Sources */,
				F96D4ACF08F272C9004A47F5 /* tclUnixNotfy.c in Sources */,
				F96D4AD008F272C9004A47F5 /* tclUnixPipe.c in Sources */,
				F96D4AD208F272CA004A47F5 /* tclUnixSock.c in Sources */,
				F96D4AD308F272CA004A47F5 /* tclUnixTest.c in Sources */,
				F96D4AD408F272CA004A47F5 /* tclUnixThrd.c in Sources */,
				F96D4AD608F272CA004A47F5 /* tclUnixTime.c in Sources */,
				F9F4415E0C8BAE6F00BCCD67 /* tclDTrace.d in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXSourcesBuildPhase section */

/* Begin PBXTargetDependency section */
		F97258D30A868C6F00096C78 /* PBXTargetDependency */ = {
			isa = PBXTargetDependency;
			target = 8DD76FA90486AB0100D96B5E /* tcltest */;
			targetProxy = F97258D20A868C6F00096C78 /* PBXContainerItemProxy */;
		};
/* End PBXTargetDependency section */

/* Begin XCBuildConfiguration section */
		F91BCC4F093152310042A6BF /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tclsh;
				SKIP_INSTALL = NO;
			};
			name = ReleaseUniversal;
		};
		F91BCC50093152310042A6BF /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tcltest;
			};
			name = ReleaseUniversal;
		};
		F91BCC51093152310042A6BF /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
				CFLAGS = "-arch x86_64 -arch arm64 $(CFLAGS)";
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				PREBINDING = NO;
			};
			name = ReleaseUniversal;
		};
		F93084370BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tclsh;
				SKIP_INSTALL = NO;
			};
			name = DebugMemCompile;
		};
		F93084380BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tcltest;
			};
			name = DebugMemCompile;
		};
		F93084390BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CODE_SIGN_IDENTITY = "";
				PRODUCT_NAME = tests;
				TCLTEST_OPTIONS = "";
				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
			};
			name = DebugMemCompile;
		};
		F930843A0BB93D2800CD0B9E /* DebugMemCompile */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-symbols=all";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugMemCompile;
		};
		F9359B250DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_GENERATE_TEST_COVERAGE_FILES = YES;
				GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				OTHER_LDFLAGS = (
					"$(OTHER_LDFLAGS)",
					"-lgcov",
				);
				PREBINDING = NO;
			};
			name = DebugGCov;
		};
		F9359B260DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tclsh;
				SKIP_INSTALL = NO;
			};
			name = DebugGCov;
		};
		F9359B270DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tcltest;
			};
			name = DebugGCov;
		};
		F9359B280DF212DA00E04F67 /* DebugGCov */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CODE_SIGN_IDENTITY = "";
				PRODUCT_NAME = tests;
				TCLTEST_OPTIONS = "";
				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
			};
			name = DebugGCov;
		};
		F95CC8AC09158F3100EA5ACE /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tclsh;
				SKIP_INSTALL = NO;
			};
			name = Debug;
		};
		F95CC8AD09158F3100EA5ACE /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tclsh;
				SKIP_INSTALL = NO;
			};
			name = Release;
		};
		F95CC8AE09158F3100EA5ACE /* DebugNoFixAndContinue */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tclsh;
				SKIP_INSTALL = NO;
			};
			name = DebugNoFixAndContinue;
		};
		F95CC8B109158F3100EA5ACE /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				PRODUCT_NAME = tcltest;
			};
			name = Debug;
		};
		F95CC8B209158F3100EA5ACE /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tcltest;
			};
			name = Release;
		};
		F95CC8B309158F3100EA5ACE /* DebugNoFixAndContinue */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tcltest;
			};
			name = DebugNoFixAndContinue;
		};
		F95CC8B609158F3100EA5ACE /* Debug */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = Debug;
		};
		F95CC8B709158F3100EA5ACE /* Release */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = Release;
		};
		F95CC8B809158F3100EA5ACE /* DebugNoFixAndContinue */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugNoFixAndContinue;
		};
		F97258A90A86873D00096C78 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CODE_SIGN_IDENTITY = "";
				PRODUCT_NAME = tests;
				TCLTEST_OPTIONS = "";
				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
			};
			name = Debug;
		};
		F97258AA0A86873D00096C78 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CODE_SIGN_IDENTITY = "";
				PRODUCT_NAME = tests;
				TCLTEST_OPTIONS = "";
				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
			};
			name = Release;
		};
		F97258AB0A86873D00096C78 /* DebugNoFixAndContinue */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CODE_SIGN_IDENTITY = "";
				PRODUCT_NAME = tests;
				TCLTEST_OPTIONS = "";
				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
			};
			name = DebugNoFixAndContinue;
		};
		F97258AC0A86873D00096C78 /* ReleaseUniversal */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CODE_SIGN_IDENTITY = "";
				PRODUCT_NAME = tests;
				TCLTEST_OPTIONS = "";
				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
			};
			name = ReleaseUniversal;
		};
		F987512F0DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-corefoundation";
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = DebugNoCF;
		};
		F98751300DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tclsh;
				SKIP_INSTALL = NO;
			};
			name = DebugNoCF;
		};
		F98751310DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tcltest;
			};
			name = DebugNoCF;
		};
		F98751320DE7B57E00B1C9EC /* DebugNoCF */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CODE_SIGN_IDENTITY = "";
				PRODUCT_NAME = tests;
				TCLTEST_OPTIONS = "";
				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
			};
			name = DebugNoCF;
		};
		F9988AB10D814C6500B6B03B /* Debug gcc40 */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_VERSION = 4.0;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = "Debug gcc40";
		};
		F9988AB20D814C6500B6B03B /* Debug gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tclsh;
				SKIP_INSTALL = NO;
			};
			name = "Debug gcc40";
		};
		F9988AB30D814C6500B6B03B /* Debug gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				PRODUCT_NAME = tcltest;
			};
			name = "Debug gcc40";
		};
		F9988AB40D814C6500B6B03B /* Debug gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CODE_SIGN_IDENTITY = "";
				PRODUCT_NAME = tests;
				TCLTEST_OPTIONS = "";
				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
			};
			name = "Debug gcc40";
		};
		F9988AB50D814C7500B6B03B /* Debug llvm-gcc */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC = "llvm-gcc";
				GCC_VERSION = com.apple.compilers.llvmgcc42;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = "Debug llvm-gcc";
		};
		F9988AB60D814C7500B6B03B /* Debug llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tclsh;
				SKIP_INSTALL = NO;
			};
			name = "Debug llvm-gcc";
		};
		F9988AB70D814C7500B6B03B /* Debug llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				PRODUCT_NAME = tcltest;
			};
			name = "Debug llvm-gcc";
		};
		F9988AB80D814C7500B6B03B /* Debug llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CODE_SIGN_IDENTITY = "";
				PRODUCT_NAME = tests;
				TCLTEST_OPTIONS = "";
				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
			};
			name = "Debug llvm-gcc";
		};
		F9988BB10D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
				CFLAGS = "-arch x86_64 -arch arm64 $(CFLAGS)";
				GCC_VERSION = 4.0;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				PREBINDING = NO;
			};
			name = "ReleaseUniversal gcc40";
		};
		F9988BB20D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tclsh;
				SKIP_INSTALL = NO;
			};
			name = "ReleaseUniversal gcc40";
		};
		F9988BB30D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tcltest;
			};
			name = "ReleaseUniversal gcc40";
		};
		F9988BB40D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CODE_SIGN_IDENTITY = "";
				PRODUCT_NAME = tests;
				TCLTEST_OPTIONS = "";
				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
			};
			name = "ReleaseUniversal gcc40";
		};
		F9988BB50D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
				CFLAGS = "-arch x86_64 -arch arm64 $(CFLAGS)";
				DEBUG_INFORMATION_FORMAT = dwarf;
				GCC = "llvm-gcc";
				GCC_OPTIMIZATION_LEVEL = 4;
				GCC_VERSION = com.apple.compilers.llvmgcc42;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				PREBINDING = NO;
			};
			name = "ReleaseUniversal llvm-gcc";
		};
		F9988BB60D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tclsh;
				SKIP_INSTALL = NO;
			};
			name = "ReleaseUniversal llvm-gcc";
		};
		F9988BB70D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tcltest;
			};
			name = "ReleaseUniversal llvm-gcc";
		};
		F9988BB80D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CODE_SIGN_IDENTITY = "";
				PRODUCT_NAME = tests;
				TCLTEST_OPTIONS = "";
				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
			};
			name = "ReleaseUniversal llvm-gcc";
		};
		F99EE73C0BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tclsh;
				SKIP_INSTALL = NO;
			};
			name = DebugLeaks;
		};
		F99EE73E0BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tcltest;
			};
			name = DebugLeaks;
		};
		F99EE7400BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CODE_SIGN_IDENTITY = "";
				PRODUCT_NAME = tests;
				TCLTEST_OPTIONS = "";
				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
			};
			name = DebugLeaks;
		};
		F99EE7420BE835310060D4AF /* DebugLeaks */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC_PREPROCESSOR_DEFINITIONS = (
					PURIFY,
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
				RUN_CLANG_STATIC_ANALYZER = YES;
			};
			name = DebugLeaks;
		};
		F9A9D1EF0FC77787002A2BE3 /* Debug clang */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
					"$(NATIVE_ARCH_32_BIT)",
				);
				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
				GCC = clang;
				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				ONLY_ACTIVE_ARCH = YES;
				PREBINDING = NO;
			};
			name = "Debug clang";
		};
		F9A9D1F00FC77787002A2BE3 /* Debug clang */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tclsh;
				SKIP_INSTALL = NO;
			};
			name = "Debug clang";
		};
		F9A9D1F10FC77787002A2BE3 /* Debug clang */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"__private_extern__=extern",
					"$(GCC_PREPROCESSOR_DEFINITIONS)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				PRODUCT_NAME = tcltest;
			};
			name = "Debug clang";
		};
		F9A9D1F20FC77787002A2BE3 /* Debug clang */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CODE_SIGN_IDENTITY = "";
				PRODUCT_NAME = tests;
				TCLTEST_OPTIONS = "";
				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
			};
			name = "Debug clang";
		};
		F9A9D1F30FC77799002A2BE3 /* ReleaseUniversal clang */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */;
			buildSettings = {
				ARCHS = (
					"$(NATIVE_ARCH_64_BIT)",
				);
				CFLAGS = "-arch x86_64 -arch arm64 $(CFLAGS)";
				DEBUG_INFORMATION_FORMAT = dwarf;
				GCC = clang;
				GCC_OPTIMIZATION_LEVEL = 4;
				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
				MACOSX_DEPLOYMENT_TARGET = 10.6;
				PREBINDING = NO;
			};
			name = "ReleaseUniversal clang";
		};
		F9A9D1F40FC77799002A2BE3 /* ReleaseUniversal clang */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tclsh;
				SKIP_INSTALL = NO;
			};
			name = "ReleaseUniversal clang";
		};
		F9A9D1F50FC77799002A2BE3 /* ReleaseUniversal clang */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tcltest;
			};
			name = "ReleaseUniversal clang";
		};
		F9A9D1F60FC77799002A2BE3 /* ReleaseUniversal clang */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CODE_SIGN_IDENTITY = "";
				PRODUCT_NAME = tests;
				TCLTEST_OPTIONS = "";
				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
			};
			name = "ReleaseUniversal clang";
		};
		F9EEED960C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tclsh;
				SKIP_INSTALL = NO;
			};
			name = ReleaseUniversal10.5SDK;
		};
		F9EEED970C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				PRODUCT_NAME = tcltest;
			};
			name = ReleaseUniversal10.5SDK;
		};
		F9EEED980C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CODE_SIGN_IDENTITY = "";
				PRODUCT_NAME = tests;
				TCLTEST_OPTIONS = "";
				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
			};
			name = ReleaseUniversal10.5SDK;
		};
		F9EEED990C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */;
			buildSettings = {
				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
				CFLAGS = "-arch x86_64 -arch arm64 $(CFLAGS)";
				CPPFLAGS = "-isysroot $(SDKROOT) $(CPPFLAGS)";
				MACOSX_DEPLOYMENT_TARGET = 10.5;
				PREBINDING = NO;
				SDKROOT = macosx10.5;
			};
			name = ReleaseUniversal10.5SDK;
		};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
		F95CC8AB09158F3100EA5ACE /* Build configuration list for PBXNativeTarget "Tcl" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F95CC8AC09158F3100EA5ACE /* Debug */,
				F9A9D1F00FC77787002A2BE3 /* Debug clang */,
				F9988AB60D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB20D814C6500B6B03B /* Debug gcc40 */,
				F95CC8AE09158F3100EA5ACE /* DebugNoFixAndContinue */,
				F98751300DE7B57E00B1C9EC /* DebugNoCF */,
				F93084370BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE73C0BE835310060D4AF /* DebugLeaks */,
				F9359B260DF212DA00E04F67 /* DebugGCov */,
				F95CC8AD09158F3100EA5ACE /* Release */,
				F91BCC4F093152310042A6BF /* ReleaseUniversal */,
				F9A9D1F40FC77799002A2BE3 /* ReleaseUniversal clang */,
				F9988BB60D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB20D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED960C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F95CC8B009158F3100EA5ACE /* Build configuration list for PBXNativeTarget "tcltest" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F95CC8B109158F3100EA5ACE /* Debug */,
				F9A9D1F10FC77787002A2BE3 /* Debug clang */,
				F9988AB70D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB30D814C6500B6B03B /* Debug gcc40 */,
				F95CC8B309158F3100EA5ACE /* DebugNoFixAndContinue */,
				F98751310DE7B57E00B1C9EC /* DebugNoCF */,
				F93084380BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE73E0BE835310060D4AF /* DebugLeaks */,
				F9359B270DF212DA00E04F67 /* DebugGCov */,
				F95CC8B209158F3100EA5ACE /* Release */,
				F91BCC50093152310042A6BF /* ReleaseUniversal */,
				F9A9D1F50FC77799002A2BE3 /* ReleaseUniversal clang */,
				F9988BB70D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB30D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED970C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F95CC8B509158F3100EA5ACE /* Build configuration list for PBXProject "Tcl" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F95CC8B609158F3100EA5ACE /* Debug */,
				F9A9D1EF0FC77787002A2BE3 /* Debug clang */,
				F9988AB50D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB10D814C6500B6B03B /* Debug gcc40 */,
				F95CC8B809158F3100EA5ACE /* DebugNoFixAndContinue */,
				F987512F0DE7B57E00B1C9EC /* DebugNoCF */,
				F930843A0BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE7420BE835310060D4AF /* DebugLeaks */,
				F9359B250DF212DA00E04F67 /* DebugGCov */,
				F95CC8B709158F3100EA5ACE /* Release */,
				F91BCC51093152310042A6BF /* ReleaseUniversal */,
				F9A9D1F30FC77799002A2BE3 /* ReleaseUniversal clang */,
				F9988BB50D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB10D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED990C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
		F97258A80A86873D00096C78 /* Build configuration list for PBXNativeTarget "tests" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				F97258A90A86873D00096C78 /* Debug */,
				F9A9D1F20FC77787002A2BE3 /* Debug clang */,
				F9988AB80D814C7500B6B03B /* Debug llvm-gcc */,
				F9988AB40D814C6500B6B03B /* Debug gcc40 */,
				F97258AB0A86873D00096C78 /* DebugNoFixAndContinue */,
				F98751320DE7B57E00B1C9EC /* DebugNoCF */,
				F93084390BB93D2800CD0B9E /* DebugMemCompile */,
				F99EE7400BE835310060D4AF /* DebugLeaks */,
				F9359B280DF212DA00E04F67 /* DebugGCov */,
				F97258AA0A86873D00096C78 /* Release */,
				F97258AC0A86873D00096C78 /* ReleaseUniversal */,
				F9A9D1F60FC77799002A2BE3 /* ReleaseUniversal clang */,
				F9988BB80D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
				F9988BB40D81586D00B6B03B /* ReleaseUniversal gcc40 */,
				F9EEED980C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Debug;
		};
/* End XCConfigurationList section */
	};
	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to tests-perf/comparePerf.tcl.
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371

    set runtimes [dict create]

    set path [file normalize $testrun_path]
    set fd [open $path]
    array set header {}
    while {[gets $fd line] >= 0} {
        set line [regsub -all {\s+} [string trim $line] " "]
        switch -glob -- $line {
            "#*" {
                # Skip comments
            }
            "R *" -
            "L *" -
            "D *" -
            "V *" -
            "T *" -
            "E *" {
                set marker [lindex $line 0]
                if {[info exists header($marker)]} {
                    warn "Ignoring $marker record (duplicate): \"$line\""
                }
                set header($marker) [string range $line 2 end]
            }
            "P *" {
                if {[scan $line "P %f %n" runtime id_start] == 2} {
                    set id [string range $line $id_start end]
                    if {[dict exists $runtimes $id]} {
                        warn "Ignoring duplicate test id \"$id\""
                    } else {
                        dict set runtimes $id $runtime
                    }
                } else {
                    warn "Invalid test result line format: \"$line\""
                }
            }
            default {
                puts stderr "Warning: ignoring unrecognized line \"$line\""
            }
        }
    }
    close $fd

    set result [dict create Input $path Runtimes $runtimes]
    foreach {c k} {
        L Label
        V Version
        E Executable
        D Description
    } {
        if {[info exists header($c)]} {
            dict set result $k $header($c)
        }
    }

    return $result
}

proc perf::compare::burp {test_sets} {
    variable Options

    # Print the key for each test run
    set header "           "
    set separator "           "
    foreach test_set $test_sets {
        set test_set_key "\[[incr test_set_num]\]"
        if {! $Options(--no-header)} {
            print "$test_set_key"
            foreach k {Label Executable Version Input Description} {
                if {[dict exists $test_set $k]} {
                    print "$k: [dict get $test_set $k]"
                }
            }
        }
        append header $test_set_key $separator
        set separator "                 "; # Expand because later columns have ratio
    }
    set header [string trimright $header]

    if {! $Options(--no-header)} {
        print ""
        if {$Options(--ratio) eq "rate"} {
            set ratio_description "ratio of baseline to the measurement (higher is faster)."
        } else {
            set ratio_description "ratio of measurement to the baseline (lower is faster)."
        }
        print "The first column \[1\] is the baseline measurement."
        print "Subsequent columns are pairs of the additional measurement and "
        print $ratio_description
        print ""
    }

    # Print the actual test run data

    print $header
    set test_sets [lassign $test_sets base_set]
    set fmt {%#10.5f}
    set fmt_ratio {%-6.2f}
    foreach {id base_runtime} [dict get $base_set Runtimes] {
        if {[info exists Options(--regexp)]} {
            if {![regexp $Options(--regexp) $id]} {
                continue
            }
        }
        if {$Options(--print-test-number)} {
            set line "[format %-4s [incr counter].]"
        } else {
            set line ""
        }
        append line [format $fmt $base_runtime]
        foreach test_set $test_sets {
            if {[dict exists $test_set Runtimes $id]} {
                set runtime [dict get $test_set Runtimes $id]
                if {$Options(--ratio) eq "time"} {
                    if {$base_runtime != 0} {
                        set ratio [format $fmt_ratio [expr {$runtime/$base_runtime}]]
                    } else {
                        if {$runtime == 0} {
                            set ratio "NaN   "
                        } else {
                            set ratio "Inf   "
                        }
                    }
                } else {
                    if {$runtime != 0} {
                        set ratio [format $fmt_ratio [expr {$base_runtime/$runtime}]]
                    } else {
                        if {$base_runtime == 0} {
                            set ratio "NaN   "
                        } else {
                            set ratio "Inf   "
                        }
                    }
                }
                append line "|" [format $fmt $runtime] "|" $ratio
            } else {
                append line [string repeat { } 11]
            }
        }
        append line "|" $id
        print $line
    }
}

proc perf::compare::chew {test_sets} {
    variable Options

    # Combine test sets that have the same label, averaging the values
    set unlabeled_sets {}
    array set labeled_sets {}

    foreach test_set $test_sets {
        # If there is no label, treat as independent set
        if {![dict exists $test_set Label]} {
            lappend unlabeled_sets $test_set
        } else {
            lappend labeled_sets([dict get $test_set Label]) $test_set
        }
    }

    foreach label [array names labeled_sets] {
        set combined_set [lindex $labeled_sets($label) 0]
        set runtimes [dict get $combined_set Runtimes]
        foreach test_set [lrange $labeled_sets($label) 1 end] {
            dict for {id timing} [dict get $test_set Runtimes] {
                dict lappend runtimes $id $timing
            }
        }
        dict for {id timings} $runtimes {
            set total [tcl::mathop::+ {*}$timings]
            dict set runtimes $id [expr {$total/[llength $timings]}]
        }
        dict set combined_set Runtimes $runtimes
        set labeled_sets($label) $combined_set
    }

    # Choose the "base" test set
    if {![info exists Options(--base)]} {
        set first_set [lindex $test_sets 0]
        if {[dict exists $first_set Label]} {
            # Use label of first as the base
            set Options(--base) [dict get $first_set Label]
        }
    }

    if {[info exists Options(--base)] && $Options(--base) ne ""} {
        lappend combined_sets $labeled_sets($Options(--base));# Will error if no such
        unset labeled_sets($Options(--base))
    } else {
        lappend combined_sets [lindex $unlabeled_sets 0]
        set unlabeled_sets [lrange $unlabeled_sets 1 end]
    }
    foreach label [array names labeled_sets] {
        lappend combined_sets $labeled_sets($label)
    }
    lappend combined_sets {*}$unlabeled_sets

    return $combined_sets
}

proc perf::compare::setup {argv} {
    variable Options

    array set Options {
        --ratio rate
        --combine 0
        --print-test-number 0
        --no-header 0
    }
    while {[llength $argv]} {
        set argv [lassign $argv arg]
        switch -glob -- $arg {
            -r -
            --regexp {
                if {[llength $argv] == 0} {
                    error "Missing value for option $arg"
                }
                set argv [lassign $argv val]
                set Options(--regexp) $val
            }
            --ratio {
                if {[llength $argv] == 0} {
                    error "Missing value for option $arg"
                }
                set argv [lassign $argv val]
                if {$val ni {time rate}} {
                    error "Value for option $arg must be either \"time\" or \"rate\""
                }
                set Options(--ratio) $val
            }
            --print-test-number -
            --combine -
            --no-header {
                set Options($arg) 1
            }
            --base {
                if {[llength $argv] == 0} {
                    error "Missing value for option $arg"
                }
                set argv [lassign $argv val]
                set Options($arg) $val
            }
            -- {
                # Remaining will be passed back to the caller
                break
            }
            --* {
                error "Unknown option $arg"
            }
            -* {
                error "Unknown option -[lindex $arg 0]"
            }
            default {
                # Remaining will be passed back to the caller
                set argv [linsert $argv 0 $arg]
                break;
            }
        }
    }

    set paths {}
    foreach path $argv {
        set path [file join $path]; # Convert from native else glob fails
        if {[file isfile $path]} {
            lappend paths $path
            continue
        }
        if {[file isfile $path.perf]} {
            lappend paths $path.perf
            continue
        }
        lappend paths {*}[glob -nocomplain $path]
    }
    return $paths
}
proc perf::compare::main {} {
    variable Options

    set paths [setup $::argv]
    if {[llength $paths] == 0} {
        error "No test data files specified."
    }
    set test_data [list ]
    set seen [dict create]
    foreach path $paths {
        if {![dict exists $seen $path]} {
            lappend test_data [slurp $path]
            dict set seen $path ""
        }
    }

    if {$Options(--combine)} {
        set test_data [chew $test_data]
    }

    burp $test_data
}

perf::compare::main







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|





|
|
|
|

|
|
|












|
|
|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|









|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|











|
|
|
|
|
|



|
|
|
|
|
|
|
|
|
|
|
|
|




|
|
|
|
|



|
|

|
|


|










|
|
|
|


|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|








|




|
|
|
|



|






73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371

    set runtimes [dict create]

    set path [file normalize $testrun_path]
    set fd [open $path]
    array set header {}
    while {[gets $fd line] >= 0} {
	set line [regsub -all {\s+} [string trim $line] " "]
	switch -glob -- $line {
	    "#*" {
		# Skip comments
	    }
	    "R *" -
	    "L *" -
	    "D *" -
	    "V *" -
	    "T *" -
	    "E *" {
		set marker [lindex $line 0]
		if {[info exists header($marker)]} {
		    warn "Ignoring $marker record (duplicate): \"$line\""
		}
		set header($marker) [string range $line 2 end]
	    }
	    "P *" {
		if {[scan $line "P %f %n" runtime id_start] == 2} {
		    set id [string range $line $id_start end]
		    if {[dict exists $runtimes $id]} {
			warn "Ignoring duplicate test id \"$id\""
		    } else {
			dict set runtimes $id $runtime
		    }
		} else {
		    warn "Invalid test result line format: \"$line\""
		}
	    }
	    default {
		puts stderr "Warning: ignoring unrecognized line \"$line\""
	    }
	}
    }
    close $fd

    set result [dict create Input $path Runtimes $runtimes]
    foreach {c k} {
	L Label
	V Version
	E Executable
	D Description
    } {
	if {[info exists header($c)]} {
	    dict set result $k $header($c)
	}
    }

    return $result
}

proc perf::compare::burp {test_sets} {
    variable Options

    # Print the key for each test run
    set header "           "
    set separator "           "
    foreach test_set $test_sets {
	set test_set_key "\[[incr test_set_num]\]"
	if {! $Options(--no-header)} {
	    print "$test_set_key"
	    foreach k {Label Executable Version Input Description} {
		if {[dict exists $test_set $k]} {
		    print "$k: [dict get $test_set $k]"
		}
	    }
	}
	append header $test_set_key $separator
	set separator "                 "; # Expand because later columns have ratio
    }
    set header [string trimright $header]

    if {! $Options(--no-header)} {
	print ""
	if {$Options(--ratio) eq "rate"} {
	    set ratio_description "ratio of baseline to the measurement (higher is faster)."
	} else {
	    set ratio_description "ratio of measurement to the baseline (lower is faster)."
	}
	print "The first column \[1\] is the baseline measurement."
	print "Subsequent columns are pairs of the additional measurement and "
	print $ratio_description
	print ""
    }

    # Print the actual test run data

    print $header
    set test_sets [lassign $test_sets base_set]
    set fmt {%#10.5f}
    set fmt_ratio {%-6.2f}
    foreach {id base_runtime} [dict get $base_set Runtimes] {
	if {[info exists Options(--regexp)]} {
	    if {![regexp $Options(--regexp) $id]} {
		continue
	    }
	}
	if {$Options(--print-test-number)} {
	    set line "[format %-4s [incr counter].]"
	} else {
	    set line ""
	}
	append line [format $fmt $base_runtime]
	foreach test_set $test_sets {
	    if {[dict exists $test_set Runtimes $id]} {
		set runtime [dict get $test_set Runtimes $id]
		if {$Options(--ratio) eq "time"} {
		    if {$base_runtime != 0} {
			set ratio [format $fmt_ratio [expr {$runtime/$base_runtime}]]
		    } else {
			if {$runtime == 0} {
			    set ratio "NaN   "
			} else {
			    set ratio "Inf   "
			}
		    }
		} else {
		    if {$runtime != 0} {
			set ratio [format $fmt_ratio [expr {$base_runtime/$runtime}]]
		    } else {
			if {$base_runtime == 0} {
			    set ratio "NaN   "
			} else {
			    set ratio "Inf   "
			}
		    }
		}
		append line "|" [format $fmt $runtime] "|" $ratio
	    } else {
		append line [string repeat { } 11]
	    }
	}
	append line "|" $id
	print $line
    }
}

proc perf::compare::chew {test_sets} {
    variable Options

    # Combine test sets that have the same label, averaging the values
    set unlabeled_sets {}
    array set labeled_sets {}

    foreach test_set $test_sets {
	# If there is no label, treat as independent set
	if {![dict exists $test_set Label]} {
	    lappend unlabeled_sets $test_set
	} else {
	    lappend labeled_sets([dict get $test_set Label]) $test_set
	}
    }

    foreach label [array names labeled_sets] {
	set combined_set [lindex $labeled_sets($label) 0]
	set runtimes [dict get $combined_set Runtimes]
	foreach test_set [lrange $labeled_sets($label) 1 end] {
	    dict for {id timing} [dict get $test_set Runtimes] {
		dict lappend runtimes $id $timing
	    }
	}
	dict for {id timings} $runtimes {
	    set total [tcl::mathop::+ {*}$timings]
	    dict set runtimes $id [expr {$total/[llength $timings]}]
	}
	dict set combined_set Runtimes $runtimes
	set labeled_sets($label) $combined_set
    }

    # Choose the "base" test set
    if {![info exists Options(--base)]} {
	set first_set [lindex $test_sets 0]
	if {[dict exists $first_set Label]} {
	    # Use label of first as the base
	    set Options(--base) [dict get $first_set Label]
	}
    }

    if {[info exists Options(--base)] && $Options(--base) ne ""} {
	lappend combined_sets $labeled_sets($Options(--base));# Will error if no such
	unset labeled_sets($Options(--base))
    } else {
	lappend combined_sets [lindex $unlabeled_sets 0]
	set unlabeled_sets [lrange $unlabeled_sets 1 end]
    }
    foreach label [array names labeled_sets] {
	lappend combined_sets $labeled_sets($label)
    }
    lappend combined_sets {*}$unlabeled_sets

    return $combined_sets
}

proc perf::compare::setup {argv} {
    variable Options

    array set Options {
	--ratio rate
	--combine 0
	--print-test-number 0
	--no-header 0
    }
    while {[llength $argv]} {
	set argv [lassign $argv arg]
	switch -glob -- $arg {
	    -r -
	    --regexp {
		if {[llength $argv] == 0} {
		    error "Missing value for option $arg"
		}
		set argv [lassign $argv val]
		set Options(--regexp) $val
	    }
	    --ratio {
		if {[llength $argv] == 0} {
		    error "Missing value for option $arg"
		}
		set argv [lassign $argv val]
		if {$val ni {time rate}} {
		    error "Value for option $arg must be either \"time\" or \"rate\""
		}
		set Options(--ratio) $val
	    }
	    --print-test-number -
	    --combine -
	    --no-header {
		set Options($arg) 1
	    }
	    --base {
		if {[llength $argv] == 0} {
		    error "Missing value for option $arg"
		}
		set argv [lassign $argv val]
		set Options($arg) $val
	    }
	    -- {
		# Remaining will be passed back to the caller
		break
	    }
	    --* {
		error "Unknown option $arg"
	    }
	    -* {
		error "Unknown option -[lindex $arg 0]"
	    }
	    default {
		# Remaining will be passed back to the caller
		set argv [linsert $argv 0 $arg]
		break;
	    }
	}
    }

    set paths {}
    foreach path $argv {
	set path [file join $path]; # Convert from native else glob fails
	if {[file isfile $path]} {
	    lappend paths $path
	    continue
	}
	if {[file isfile $path.perf]} {
	    lappend paths $path.perf
	    continue
	}
	lappend paths {*}[glob -nocomplain $path]
    }
    return $paths
}
proc perf::compare::main {} {
    variable Options

    set paths [setup $::argv]
    if {[llength $paths] == 0} {
	error "No test data files specified."
    }
    set test_data [list ]
    set seen [dict create]
    foreach path $paths {
	if {![dict exists $seen $path]} {
	    lappend test_data [slurp $path]
	    dict set seen $path ""
	}
    }

    if {$Options(--combine)} {
	set test_data [chew $test_data]
    }

    burp $test_data
}

perf::compare::main
Changes to tests-perf/listPerf.tcl.
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295

    variable RunTimes
    set RunTimes(command) 0.0
    set RunTimes(total) 0.0

    variable Options
    array set Options {
        --print-comments   0
        --print-iterations 0
    }

    # Procs used for calibrating overhead
    proc proc2args {a b} {}
    proc proc3args {a b c} {}

    proc print {s} {
        puts $s
    }
    proc print_usage {} {
        puts stderr "Usage: [file tail [info nameofexecutable]] $::argv0 \[options\] \[command ...\]"
        puts stderr "\t--description DESC\tHuman readable description of test run"
        puts stderr "\t--label LABEL\tA label used to identify test environment"
        puts stderr "\t--print-comments\tPrint comment for each test"
        puts stderr "\t--print-iterations\tPrint number of iterations run for each test"
    }

    proc setup {argv} {
        variable Options
        variable Lengths

        while {[llength $argv]} {
            set argv [lassign $argv arg]
            switch -glob -- $arg {
                --print-comments -
                --print-iterations {
                    set Options($arg) 1
                }
                --label -
                --description {
                    if {[llength $argv] == 0} {
                        error "Missing value for option $arg"
                    }
                    set argv [lassign $argv val]
                    set Options($arg) $val
                }
                --lengths {
                    if {[llength $argv] == 0} {
                        error "Missing value for option $arg"
                    }
                    set argv [lassign $argv val]
                    set Lengths $val
                }
                -- {
                    # Remaining will be passed back to the caller
                    break
                }
                --* {
                    puts stderr "Unknown option $arg"
                    print_usage
                    exit 1
                }
                default {
                    # Remaining will be passed back to the caller
                    set argv [linsert $argv 0 $arg]
                    break;
                }
            }
        }

        return $argv
    }
    proc format_timings {us iters} {
        variable Options
        if {!$Options(--print-iterations)} {
            return "[format {%#10.4f} $us]"
        }
        return "[format {%#10.4f} $us] [format {%8d} $iters]"
    }
    proc measure {id script args} {
        variable NullOverhead
        variable RunTimes
        variable Options

        set opts(-overhead) ""
        set opts(-runs) 5
        while {[llength $args]} {
            set args [lassign $args opt]
            if {[llength $args] == 0} {
                error "No argument supplied for $opt option. Test: $id"
            }
            set args [lassign $args val]
            switch $opt {
                -setup -
                -cleanup -
                -overhead -
                -time -
                -runs -
                -reps {
                    set opts($opt) $val
                }
                default {
                    error "Unknown option $opt. Test: $id"
                }
            }
        }

        set timerate_args {}
        if {[info exists opts(-time)]} {
            lappend timerate_args $opts(-time)
        }
        if {[info exists opts(-reps)]} {
            if {[info exists opts(-time)]} {
                set timerate_args [list $opts(-time) $opts(-reps)]
            } else {
                # Force the default for first time option
                set timerate_args [list 1000 $opts(-reps)]
            }
        } elseif {[info exists opts(-time)]} {
            set timerate_args [list $opts(-time)]
        }
        if {[info exists opts(-setup)]} {
            uplevel 1 $opts(-setup)
        }
        # Cache the empty overhead to prevent unnecessary delays. Note if you modify
        # to cache other scripts, the cache key must be AFTER substituting the
        # overhead script in the caller's context.
        if {$opts(-overhead) eq ""} {
            if {![info exists NullOverhead]} {
                set NullOverhead [lindex [timerate {}] 0]
            }
            set overhead_us $NullOverhead
        } else {
            # The overhead measurements might use setup so we need to setup
            # first and then cleanup in preparation for setting up again for
            # the script to be measured
            if {[info exists opts(-setup)]} {
                uplevel 1 $opts(-setup)
            }
            set overhead_us [lindex [uplevel 1 [list timerate $opts(-overhead)]] 0]
            if {[info exists opts(-cleanup)]} {
                uplevel 1 $opts(-cleanup)
            }
        }
        set timings {}
        for {set i 0} {$i < $opts(-runs)} {incr i} {
            if {[info exists opts(-setup)]} {
                uplevel 1 $opts(-setup)
            }
            lappend timings [uplevel 1 [list timerate -overhead $overhead_us $script {*}$timerate_args]]
            if {[info exists opts(-cleanup)]} {
                uplevel 1 $opts(-cleanup)
            }
        }
        set timings [lsort -real -index 0 $timings]
        if {$opts(-runs) > 15} {
            set ignore [expr {$opts(-runs)/8}]
        } elseif {$opts(-runs) >= 5} {
            set ignore 2
        } else {
            set ignore 0
        }
        # Ignore highest and lowest
        set timings [lrange $timings 0 end-$ignore]
        # Average it out
        set us 0
        set iters 0
        foreach timing $timings {
            set us [expr {$us + [lindex $timing 0]}]
            set iters [expr {$iters + [lindex $timing 2]}]
        }
        set us [expr {$us/[llength $timings]}]
        set iters [expr {$iters/[llength $timings]}]

        set RunTimes(command) [expr {$RunTimes(command) + $us}]
        print "P [format_timings $us $iters] $id"
    }
    proc comment {args} {
        variable Options
        if {$Options(--print-comments)} {
            print "# [join $args { }]"
        }
    }
    proc spanned_list {len} {
        # Note - for small len, this will not create a spanned list
        set delta [expr {$len/8}]
        return [lrange [lrepeat [expr {$len+(2*$delta)}] a] $delta [expr {$delta+$len-1}]]
    }
    proc print_separator {command} {
        comment [string repeat = 80]
        comment Command: $command
    }

    oo::class create ListPerf {
        constructor {args} {
            my variable Opts
            # Note default Opts can be overridden in construct as well as in measure
            set Opts [dict merge {
                -setup {
                    set L [lrepeat $len a]
                    set Lspan [perf::list::spanned_list $len]
                } -cleanup {
                    unset -nocomplain L
                    unset -nocomplain Lspan
                    unset -nocomplain L2
                }
            } $args]
        }
        method measure {comment script locals args} {
            my variable Opts
            dict with locals {}
            ::perf::list::measure $comment $script {*}[dict merge $Opts $args]
        }
        method option {opt val} {
            my variable Opts
            dict set Opts $opt $val
        }
        method option_unset {opt} {
            my variable Opts
            unset -nocomplain Opts($opt)
        }
    }

    proc linsert_describe {share_mode len at num iters} {
        return "linsert L\[$len\] $share_mode $num elems $iters times at $at"
    }
    proc linsert_perf {} {
        variable Lengths

        print_separator linsert

        ListPerf create perf -overhead {set L {}} -time 1000

        # Note: Const indices take different path through bytecode than variable
        # indices hence separate cases below


        # Var case
        foreach share_mode {shared unshared} {
            set idx 0
            if {$share_mode eq "shared"} {
                comment == Insert into empty lists
                comment Insert one element into empty list
                measure [linsert_describe shared 0 "0 (var)" 1 1] {linsert $L $idx ""} -setup {set idx 0; set L {}}
            } else {
                comment == Insert into empty lists
                comment Insert one element into empty list
                measure [linsert_describe unshared 0 "0 (var)" 1 1] {linsert {} $idx ""} -setup {set idx 0}
            }
            foreach idx_str [list 0 1 mid end-1 end] {
                foreach len $Lengths {
                    if {$idx_str eq "mid"} {
                        set idx [expr {$len/2}]
                    } else {
                        set idx $idx_str
                    }
                    # perf option -reps $reps
                    set reps 1000
                    if {$share_mode eq "shared"} {
                        comment Insert once to shared list with variable index
                        perf measure [linsert_describe shared $len "$idx (var)" 1 1] \
                            {linsert $L $idx x} [list len $len idx $idx] -overhead {} -reps 100000

                        comment Insert multiple times to shared list with variable index
                        perf measure [linsert_describe shared $len "$idx (var)" 1 $reps] {
                            set L [linsert $L $idx X]
                        } [list len $len idx $idx] -reps $reps

                        comment Insert multiple items multiple times to shared list with variable index
                        perf measure [linsert_describe shared $len "$idx (var)" 5 $reps] {
                            set L [linsert $L $idx X X X X X]
                        } [list len $len idx $idx] -reps $reps
                    } else {
                        # NOTE : the Insert once case is left out for unshared lists
                        # because it requires re-init on every iteration resulting
                        # in a lot of measurement noise
                        comment Insert multiple times to unshared list with variable index
                        perf measure [linsert_describe unshared $len "$idx (var)" 1 $reps] {
                            set L [linsert $L[set L {}] $idx X]
                        } [list len $len idx $idx] -reps $reps
                        comment Insert multiple items multiple times to unshared list with variable index
                        perf measure [linsert_describe unshared $len "$idx (var)" 5 $reps] {
                            set L [linsert $L[set L {}] $idx X X X X X]
                        } [list len $len idx $idx] -reps $reps
                    }
                }
            }
        }

        # Const index
        foreach share_mode {shared unshared} {
            if {$share_mode eq "shared"} {
                comment == Insert into empty lists
                comment Insert one element into empty list
                measure [linsert_describe shared 0 "0 (const)" 1 1] {linsert $L 0 ""} -setup {set L {}}
            } else {
                comment == Insert into empty lists
                comment Insert one element into empty list
                measure [linsert_describe unshared 0 "0 (const)" 1 1] {linsert {} 0 ""}
            }
            foreach idx_str [list 0 1 mid end end-1] {
                foreach len $Lengths {
                    # Note end, end-1 explicitly calculated as otherwise they
                    # are not treated as const
                    if {$idx_str eq "mid"} {
                        set idx [expr {$len/2}]
                    } elseif {$idx_str eq "end"} {
                        set idx [expr {$len-1}]
                    } elseif {$idx_str eq "end-1"} {
                        set idx [expr {$len-2}]
                    } else {
                        set idx $idx_str
                    }
                    #perf option -reps $reps
                    set reps 100
                    if {$share_mode eq "shared"} {
                        comment Insert once to shared list with const index
                        perf measure [linsert_describe shared $len "$idx (const)" 1 1] \
                            "linsert \$L $idx x" [list len $len] -overhead {} -reps 10000

                        comment Insert multiple times to shared list with const index
                        perf measure [linsert_describe shared $len "$idx (const)" 1 $reps] \
                            "set L \[linsert \$L $idx X\]" [list len $len] -reps $reps

                        comment Insert multiple items multiple times to shared list with const index
                        perf measure [linsert_describe shared $len "$idx (const)" 5 $reps] \
                            "set L \[linsert \$L $idx X X X X X\]" [list len $len] -reps $reps
                    } else {
                        comment Insert multiple times to unshared list with const index
                        perf measure [linsert_describe unshared $len "$idx (const)" 1 $reps] \
                            "set L \[linsert \$L\[set L {}\] $idx X]" [list len $len] -reps $reps

                        comment Insert multiple items multiple times to unshared list with const index
                        perf measure [linsert_describe unshared $len "$idx (const)" 5 $reps] \
                            "set L \[linsert \$L\[set L {}\] $idx X X X X X]" [list len $len] -reps $reps
                    }
                }
            }
        }

        # Note: no span tests because the inserts above will themselves create
        # spanned lists

        perf destroy
    }

    proc list_describe {len text} {
        return "list L\[$len\] $text"
    }
    proc list_perf {} {
        variable Lengths

        print_separator list

        ListPerf create perf
        foreach len $Lengths {
            set s [join [lrepeat $len x]]
            comment Create a list from a string
            perf measure [list_describe $len "from a string"] {list $s} [list s $s len $len]
        }
        foreach len $Lengths {
            comment Create a list from expansion - single list (special optimal case)
            perf measure [list_describe $len "from a {*}list"] {list {*}$L} [list len $len]
            comment Create a list from two lists - real test of expansion speed
            perf measure [list_describe $len "from a {*}list {*}list"] {list {*}$L {*}$L} [list len [expr {$len/2}]]
        }

        perf destroy
    }

    proc lappend_describe {share_mode len num iters} {
        return "lappend L\[$len\] $share_mode $num elems $iters times"
    }
    proc lappend_perf {} {
        variable Lengths

        print_separator lappend

        ListPerf create perf -setup {set L [lrepeat [expr {$len/4}] x]}

        # Shared
        foreach len $Lengths {
            comment Append to a shared list variable multiple times
            perf measure [lappend_describe shared [expr {$len/2}] 1 $len] {
                set L2 $L; # Make shared
                lappend L x
            } [list len $len] -reps $len -overhead {set L2 $L}
        }

        # Unshared
        foreach len $Lengths {
            comment Append to a unshared list variable multiple times
            perf measure [lappend_describe unshared [expr {$len/2}] 1 $len] {
                lappend L x
            } [list len $len] -reps $len
        }

        # Span
        foreach len $Lengths {
            comment Append to a unshared-span list variable multiple times
            perf measure [lappend_describe unshared-span [expr {$len/2}] 1 $len] {
                lappend Lspan x
            } [list len $len] -reps $len
        }

        perf destroy
    }

    proc lpop_describe {share_mode len at reps} {
        return "lpop L\[$len\] $share_mode at $at $reps times"
    }
    proc lpop_perf {} {
        variable Lengths

        print_separator lpop

        ListPerf create perf

        # Shared
        perf option -overhead {set L2 $L}
        foreach len $Lengths {
            set reps [expr {($len >= 1000 ? ($len/2) : $len) - 2}]
            foreach idx {0 1 end-1 end}  {
                comment Pop element at position $idx from a shared list variable
                perf measure [lpop_describe shared $len $idx $reps] {
                    set L2 $L
                    lpop L $idx
                } [list len $len idx $idx] -reps $reps
            }
        }

        # Unshared
        perf option -overhead {}
        foreach len $Lengths {
            set reps [expr {($len >= 1000 ? ($len/2) : $len) - 2}]
            foreach idx {0 1 end-1 end}  {
                comment Pop element at position $idx from an unshared list variable
                perf measure [lpop_describe unshared $len $idx $reps] {
                    lpop L $idx
                } [list len $len idx $idx] -reps $reps
            }
        }

        perf destroy

        # Nested
        ListPerf create perf -setup {
            set L [lrepeat $len [list a b]]
        }

        # Shared, nested index
        perf option -overhead {set L2 $L; set L L2}
        foreach len $Lengths {
            set reps [expr {($len >= 1000 ? ($len/2) : $len) - 2}]
            foreach idx {0 1 end-1 end}  {
                perf measure [lpop_describe shared $len "{$idx 0}" $reps] {
                    set L2 $L
                    lpop L $idx 0
                    set L $L2
                } [list len $len idx $idx] -reps $reps
            }
        }

        # TODO - Nested Unshared
        # Not sure how to measure performance. When unshared there is no copy
        # so deleting a nested index repeatedly is not feasible

        perf destroy
    }

    proc lassign_describe {share_mode len num reps} {
        return "lassign L\[$len\] $share_mode $num elems $reps times"
    }
    proc lassign_perf {} {
        variable Lengths

        print_separator lassign

        ListPerf create perf

        foreach share_mode {shared unshared} {
            foreach len $Lengths {
                if {$share_mode eq "shared"} {
                    set reps 1000
                    comment Reflexive lassign - shared
                    perf measure [lassign_describe shared $len 1 $reps] {
                        set L2 $L
                        set L2 [lassign $L2 v]
                    } [list len $len] -overhead {set L2 $L} -reps $reps

                    comment Reflexive lassign - shared, multiple
                    perf measure [lassign_describe shared $len 5 $reps] {
                        set L2 $L
                        set L2 [lassign $L2 a b c d e]
                    } [list len $len] -overhead {set L2 $L} -reps $reps
                } else {
                    set reps [expr {($len >= 1000 ? ($len/2) : $len) - 2}]
                    comment Reflexive lassign - unshared
                    perf measure [lassign_describe unshared $len 1 $reps] {
                        set L [lassign $L v]
                    } [list len $len] -reps $reps
                }
            }
        }
        perf destroy
    }

    proc lrepeat_describe {len num} {
        return "lrepeat L\[$len\] $num elems at a time"
    }
    proc lrepeat_perf {} {
        variable Lengths

        print_separator lrepeat

        ListPerf create perf -reps 100000
        foreach len $Lengths {
            comment Generate a list from a single repeated element
            perf measure [lrepeat_describe $len 1] {
                lrepeat $len a
            } [list len $len]

            comment Generate a list from multiple repeated elements
            perf measure [lrepeat_describe $len 5] {
                lrepeat $len a b c d e
            } [list len $len]
        }

        perf destroy
    }

    proc lreverse_describe {share_mode len} {
        return "lreverse L\[$len\] $share_mode"
    }
    proc lreverse_perf {} {
        variable Lengths

        print_separator lreverse

        ListPerf create perf -reps 10000

        foreach share_mode {shared unshared} {
            foreach len $Lengths {
                if {$share_mode eq "shared"} {
                    comment Reverse a shared list
                    perf measure [lreverse_describe shared $len] {
                        lreverse $L
                    } [list len $len]

                    if {$len > 100} {
                        comment Reverse a shared-span list
                        perf measure [lreverse_describe shared-span $len] {
                            lreverse $Lspan
                        } [list len $len]
                    }
                } else {
                    comment Reverse a unshared list
                    perf measure [lreverse_describe unshared $len] {
                        set L [lreverse $L[set L {}]]
                    } [list len $len] -overhead {set L $L; set L {}}

                    if {$len >= 100} {
                        comment Reverse a unshared-span list
                        perf measure [lreverse_describe unshared-span $len] {
                            set Lspan [lreverse $Lspan[set Lspan {}]]
                        } [list len $len] -overhead {set Lspan $Lspan; set Lspan {}}
                    }
                }
            }
        }

        perf destroy
    }

    proc llength_describe {share_mode len} {
        return "llength L\[$len\] $share_mode"
    }
    proc llength_perf {} {
        variable Lengths

        print_separator llength

        ListPerf create perf -reps 100000

        foreach len $Lengths {
            comment Length of a list
            perf measure [llength_describe shared $len] {
                llength $L
            } [list len $len]

            if {$len >= 100} {
                comment Length of a span list
                perf measure [llength_describe shared-span $len] {
                    llength $Lspan
                } [list len $len]
            }
        }

        perf destroy
    }

    proc lindex_describe {share_mode len at} {
        return "lindex L\[$len\] $share_mode at $at"
    }
    proc lindex_perf {} {
        variable Lengths

        print_separator lindex

        ListPerf create perf -reps 100000

        foreach len $Lengths {
            comment Index into a list
            set idx [expr {$len/2}]
            perf measure [lindex_describe shared $len $idx] {
                lindex $L $idx
            } [list len $len idx $idx]

            if {$len >= 100} {
                comment Index into a span list
                perf measure [lindex_describe shared-span $len $idx] {
                    lindex $Lspan $idx
                } [list len $len idx $idx]
            }
        }

        perf destroy
    }

    proc lrange_describe {share_mode len range} {
        return "lrange L\[$len\] $share_mode range $range"
    }

    proc lrange_perf {} {
        variable Lengths

        print_separator lrange

        ListPerf create perf -time 1000 -reps 100000

        foreach share_mode {shared unshared} {
            foreach len $Lengths {
                set eighth [expr {$len/8}]
                set ranges [list \
                                [list 0 0]  [list 0 end-1] \
                                [list $eighth [expr {3*$eighth}]] \
                                [list $eighth [expr {7*$eighth}]] \
                                [list 1 end] [list end-1 end] \
                               ]
                foreach range $ranges {
                    comment Range $range in $share_mode list of length $len
                    if {$share_mode eq "shared"} {
                        perf measure [lrange_describe shared $len $range] \
                            "lrange \$L $range" [list len $len range $range]
                    } else {
                        perf measure [lrange_describe unshared $len $range] \
                            "lrange \[lrepeat \$len\ a] $range" \
                            [list len $len range $range] -overhead {lrepeat $len a}
                    }
                }

                if {$len >= 100} {
                    foreach range $ranges {
                        comment Range $range in ${share_mode}-span list of length $len
                        if {$share_mode eq "shared"} {
                            perf measure [lrange_describe shared-span $len $range] \
                                "lrange \$Lspan {*}$range" [list len $len range $range]
                        } else {
                            perf measure [lrange_describe unshared-span $len $range] \
                                "lrange \[perf::list::spanned_list \$len\] $range" \
                                [list len $len range $range] -overhead {perf::list::spanned_list $len}
                        }
                    }
                }
            }
        }

        perf destroy
    }

    proc lset_describe {share_mode len at} {
        return "lset L\[$len\] $share_mode at $at"
    }
    proc lset_perf {} {
        variable Lengths

        print_separator lset

        ListPerf create perf -reps 10000

        # Shared
        foreach share_mode {shared unshared} {
            foreach len $Lengths {
                foreach idx {0 1 end-1 end end+1}  {
                    comment lset at position $idx in a $share_mode list variable
                    if {$share_mode eq "shared"} {
                        perf measure [lset_describe shared $len $idx] {
                            set L2 $L
                            lset L $idx X
                        } [list len $len idx $idx] -overhead {set L2 $L}
                    } else {
                        perf measure [lset_describe unshared $len $idx] {
                            lset L $idx X
                        } [list len $len idx $idx]
                    }
                }
            }
        }

        perf destroy

        # Nested
        ListPerf create perf -setup {
            set L [lrepeat $len [list a b]]
        }

        foreach share_mode {shared unshared} {
            foreach len $Lengths {
                foreach idx {0 1 end-1 end}  {
                    comment lset at position $idx in a $share_mode list variable
                    if {$share_mode eq "shared"} {
                        perf measure [lset_describe shared $len "{$idx 0}"] {
                            set L2 $L
                            lset L $idx 0 X
                        } [list len $len idx $idx] -overhead {set L2 $L}
                    } else {
                        perf measure [lset_describe unshared $len "{$idx 0}"] {
                            lset L $idx 0 {X Y}
                        } [list len $len idx $idx]
                    }
                }
            }
        }

        perf destroy
    }

    proc lremove_describe {share_mode len at nremoved} {
        return "lremove L\[$len\] $share_mode $nremoved elements at $at"
    }
    proc lremove_perf {} {
        variable Lengths

        print_separator lremove

        ListPerf create perf -reps 10000

        foreach share_mode {shared unshared} {
            foreach len $Lengths {
                foreach idx [list 0 1 [expr {$len/2}] end-1 end] {
                    if {$share_mode eq "shared"} {
                        comment Remove one element from shared list
                        perf measure [lremove_describe shared $len $idx 1] \
                            {lremove $L $idx} [list len $len idx $idx]

                    } else {
                        comment Remove one element from unshared list
                        set reps [expr {$len >= 1000 ? ($len/8) : ($len-2)}]
                        perf measure [lremove_describe unshared $len $idx 1] \
                            {set L [lremove $L[set L {}] $idx]} [list len $len idx $idx] \
                            -overhead {set L $L; set L {}} -reps $reps
                    }
                }
                if {$share_mode eq "shared"} {
                    comment Remove multiple elements from shared list
                    perf measure [lremove_describe shared $len [list 0 1 [expr {$len/2}] end-1 end] 5] {
                        lremove $L 0 1 [expr {$len/2}] end-1 end
                    } [list len $len]
                }
            }
            # Span
            foreach len $Lengths {
                foreach idx [list 0 1 [expr {$len/2}] end-1 end] {
                    if {$share_mode eq "shared"} {
                        comment Remove one element from shared-span list
                        perf measure [lremove_describe shared-span $len $idx 1] \
                            {lremove $Lspan $idx} [list len $len idx $idx]
                    } else {
                        comment Remove one element from unshared-span list
                        set reps [expr {$len >= 1000 ? ($len/8) : ($len-2)}]
                        perf measure [lremove_describe unshared-span $len $idx 1] \
                            {set Lspan [lremove $Lspan[set Lspan {}] $idx]} [list len $len idx $idx] \
                            -overhead {set Lspan $Lspan; set Lspan {}} -reps $reps
                    }
                }
                if {$share_mode eq "shared"} {
                    comment Remove multiple elements from shared-span list
                    perf measure [lremove_describe shared-span $len [list 0 1 [expr {$len/2}] end-1 end] 5] {
                        lremove $Lspan 0 1 [expr {$len/2}] end-1 end
                    } [list len $len]
                }
            }
        }

        perf destroy
    }

    proc lreplace_describe {share_mode len first last ninsert {times 1}} {
        if {$last < $first} {
            return "lreplace L\[$len\] $share_mode 0 ($first:$last) elems at $first with $ninsert elems $times times."
        }
        return "lreplace L\[$len\] $share_mode $first:$last with $ninsert elems $times times."
    }
    proc lreplace_perf {} {
        variable Lengths

        print_separator lreplace

        set default_reps 10000
        ListPerf create perf -reps $default_reps

        foreach share_mode {shared unshared} {
            # Insert only
            foreach len $Lengths {
                set reps [expr {$len <= 100 ? ($len-2) : ($len/8)}]
                foreach first [list 0 1 [expr {$len/2}] end-1 end] {
                    if {$share_mode eq "shared"} {
                        comment Insert one to shared list
                        perf measure [lreplace_describe shared $len $first -1 1] {
                            lreplace $L $first -1 x
                        } [list len $len first $first]

                        comment Insert multiple to shared list
                        perf measure [lreplace_describe shared $len $first -1 10] {
                            lreplace $L $first -1 X X X X X X X X X X
                        } [list len $len first $first]

                        comment Insert one to shared list repeatedly
                        perf measure [lreplace_describe shared $len $first -1 1 $reps] {
                            set L [lreplace $L $first -1 x]
                        } [list len $len first $first] -reps $reps

                        comment Insert multiple to shared list repeatedly
                        perf measure [lreplace_describe shared $len $first -1 10 $reps] {
                            set L [lreplace $L $first -1 X X X X X X X X X X]
                        } [list len $len first $first] -reps $reps

                    } else {
                        comment Insert one to unshared list
                        perf measure [lreplace_describe unshared $len $first -1 1] {
                            set L [lreplace $L[set L {}] $first -1 x]
                        } [list len $len first $first] -overhead {
                            set L $L; set L {}
                        } -reps $reps

                        comment Insert multiple to unshared list
                        perf measure [lreplace_describe unshared $len $first -1 10] {
                            set L [lreplace $L[set L {}] $first -1 X X X X X X X X X X]
                        } [list len $len first $first] -overhead {
                            set L $L; set L {}
                        } -reps $reps
                    }
                }
            }

            # Delete only
            foreach len $Lengths {
                set reps [expr {$len <= 100 ? ($len-2) : ($len/8)}]
                foreach first [list 0 1 [expr {$len/2}] end-1 end] {
                    if {$share_mode eq "shared"} {
                        comment Delete one from shared list
                        perf measure [lreplace_describe shared $len $first $first 0] {
                            lreplace $L $first $first
                        } [list len $len first $first]
                    } else {
                        comment Delete one from unshared list
                        perf measure [lreplace_describe unshared $len $first $first 0] {
                            set L [lreplace $L[set L {}] $first $first x]
                        } [list len $len first $first] -overhead {
                            set L $L; set L {}
                        } -reps $reps
                    }
                }
            }

            # Insert + delete
            foreach len $Lengths {
                set reps [expr {$len <= 100 ? ($len-2) : ($len/8)}]
                foreach range [list {0 1} {1 2} {end-2 end-1} {end-1 end}] {
                    lassign $range first last
                    if {$share_mode eq "shared"} {
                        comment Insertions more than deletions from shared list
                        perf measure [lreplace_describe shared $len $first $last 3] {
                            lreplace $L $first $last X Y Z
                        } [list len $len first $first last $last]

                        comment Insertions same as deletions from shared list
                        perf measure [lreplace_describe shared $len $first $last 2] {
                            lreplace $L $first $last X Y
                        } [list len $len first $first last $last]

                        comment Insertions fewer than deletions from shared list
                        perf measure [lreplace_describe shared $len $first $last 1] {
                            lreplace $L $first $last X
                        } [list len $len first $first last $last]
                    } else {
                        comment Insertions more than deletions from unshared list
                        perf measure [lreplace_describe unshared $len $first $last 3] {
                            set L [lreplace $L[set L {}] $first $last X Y Z]
                        } [list len $len first $first last $last] -overhead {
                            set L $L; set L {}
                        } -reps $reps

                        comment Insertions same as deletions from unshared list
                        perf measure [lreplace_describe unshared $len $first $last 2] {
                            set L [lreplace $L[set L {}] $first $last X Y ]
                        } [list len $len first $first last $last] -overhead {
                            set L $L; set L {}
                        } -reps $reps

                        comment Insertions fewer than deletions from unshared list
                        perf measure [lreplace_describe unshared $len $first $last 1] {
                            set L [lreplace $L[set L {}] $first $last X]
                        } [list len $len first $first last $last] -overhead {
                            set L $L; set L {}
                        } -reps $reps
                    }
                }
            }
            # Spanned Insert + delete
            foreach len $Lengths {
                set reps [expr {$len <= 100 ? ($len-2) : ($len/8)}]
                foreach range [list {0 1} {1 2} {end-2 end-1} {end-1 end}] {
                    lassign $range first last
                    if {$share_mode eq "shared"} {
                        comment Insertions more than deletions from shared-span list
                        perf measure [lreplace_describe shared-span $len $first $last 3] {
                            lreplace $Lspan $first $last X Y Z
                        } [list len $len first $first last $last]

                        comment Insertions same as deletions from shared-span list
                        perf measure [lreplace_describe shared-span $len $first $last 2] {
                            lreplace $Lspan $first $last X Y
                        } [list len $len first $first last $last]

                        comment Insertions fewer than deletions from shared-span list
                        perf measure [lreplace_describe shared-span $len $first $last 1] {
                            lreplace $Lspan $first $last X
                        } [list len $len first $first last $last]
                    } else {
                        comment Insertions more than deletions from unshared-span list
                        perf measure [lreplace_describe unshared-span $len $first $last 3] {
                            set Lspan [lreplace $Lspan[set Lspan {}] $first $last X Y Z]
                        } [list len $len first $first last $last] -overhead {
                            set Lspan $Lspan; set Lspan {}
                        } -reps $reps

                        comment Insertions same as deletions from unshared-span list
                        perf measure [lreplace_describe unshared-span $len $first $last 2] {
                            set Lspan [lreplace $Lspan[set Lspan {}] $first $last X Y ]
                        } [list len $len first $first last $last] -overhead {
                            set Lspan $Lspan; set Lspan {}
                        } -reps $reps

                        comment Insertions fewer than deletions from unshared-span list
                        perf measure [lreplace_describe unshared-span $len $first $last 1] {
                            set Lspan [lreplace $Lspan[set Lspan {}] $first $last X]
                        } [list len $len first $first last $last] -overhead {
                            set Lspan $Lspan; set Lspan {}
                        } -reps $reps
                    }
                }
            }
        }

        perf destroy
    }

    proc split_describe {len} {
        return "split L\[$len\]"
    }
    proc split_perf {} {
        variable Lengths
        print_separator split

        ListPerf create perf -setup {set S [string repeat "x " $len]}
        foreach len $Lengths {
            comment Split a string
            perf measure [split_describe $len] {
                split $S " "
            } [list len $len]
        }
    }

    proc join_describe {share_mode len} {
        return "join L\[$len\] $share_mode"
    }
    proc join_perf {} {
        variable Lengths

        print_separator join

        ListPerf create perf -reps 10000
        foreach len $Lengths {
            comment Join a list
            perf measure [join_describe shared $len] {
                join $L
            } [list len $len]
        }
        foreach len $Lengths {
            comment Join a spanned list
            perf measure [join_describe shared-span $len] {
                join $Lspan
            } [list len $len]
        }
        perf destroy
    }

    proc lsearch_describe {share_mode len} {
        return "lsearch L\[$len\] $share_mode"
    }
    proc lsearch_perf {} {
        variable Lengths

        print_separator lsearch

        ListPerf create perf -reps 100000
        foreach len $Lengths {
            comment Search a list
            perf measure [lsearch_describe shared $len] {
                lsearch $L needle
            } [list len $len]
        }
        foreach len $Lengths {
            comment Search a spanned list
            perf measure [lsearch_describe shared-span $len] {
                lsearch $Lspan needle
            } [list len $len]
        }
        perf destroy
    }

    proc foreach_describe {share_mode len} {
        return "foreach L\[$len\] $share_mode"
    }
    proc foreach_perf {} {
        variable Lengths

        print_separator foreach

        ListPerf create perf -reps 10000
        foreach len $Lengths {
            comment Iterate through a list
            perf measure [foreach_describe shared $len] {
                foreach e $L {}
            } [list len $len]
        }
        foreach len $Lengths {
            comment Iterate a spanned list
            perf measure [foreach_describe shared-span $len] {
                foreach e $Lspan {}
            } [list len $len]
        }
        perf destroy
    }

    proc lmap_describe {share_mode len} {
        return "lmap L\[$len\] $share_mode"
    }
    proc lmap_perf {} {
        variable Lengths

        print_separator lmap

        ListPerf create perf -reps 10000
        foreach len $Lengths {
            comment Iterate through a list
            perf measure [lmap_describe shared $len] {
                lmap e $L {}
            } [list len $len]
        }
        foreach len $Lengths {
            comment Iterate a spanned list
            perf measure [lmap_describe shared-span $len] {
                lmap e $Lspan {}
            } [list len $len]
        }
        perf destroy
    }

    proc get_sort_sample {{spanned 0}} {
        variable perfScript
        variable sortSampleText

        if {![info exists sortSampleText]} {
            set fd [open $perfScript]
            set sortSampleText [split [read $fd] ""]
            close $fd
        }
        set sortSampleText [string range $sortSampleText 0 9999]

        # NOTE: do NOT cache list result in a variable as we need it unshared
        if {$spanned} {
            return [lrange [split $sortSampleText ""] 1 end-1]
        } else {
            return [split $sortSampleText ""]
        }
    }
    proc lsort_describe {share_mode len} {
        return "lsort L\[$len] $share_mode"
    }
    proc lsort_perf {} {
        print_separator lsort

        ListPerf create perf -setup {}

        comment Sort a shared list
        perf measure [lsort_describe shared [llength [perf::list::get_sort_sample]]] {
            lsort $L
        } {} -setup {set L [perf::list::get_sort_sample]}

        comment Sort a shared-span list
        perf measure [lsort_describe shared-span [llength [perf::list::get_sort_sample 1]]] {
            lsort $L
        } {} -setup {set L [perf::list::get_sort_sample 1]}

        comment Sort an unshared list
        perf measure [lsort_describe unshared [llength [perf::list::get_sort_sample]]] {
            lsort [perf::list::get_sort_sample]
        } {} -overhead {perf::list::get_sort_sample}

        comment Sort an unshared-span list
        perf measure [lsort_describe unshared-span [llength [perf::list::get_sort_sample 1]]] {
            lsort [perf::list::get_sort_sample 1]
        } {} -overhead {perf::list::get_sort_sample 1}

        perf destroy
    }

    proc concat_describe {canonicality len elemlen} {
        return "concat L\[$len\] $canonicality with elements of length $elemlen"
    }
    proc concat_perf {} {
        variable Lengths

        print_separator concat

        ListPerf create perf -reps 100000

        foreach len $Lengths {
            foreach elemlen {1 100} {
                comment Pure lists (no string representation)
                perf measure [concat_describe "pure lists" $len $elemlen] {
                    concat $L $L
                } [list len $len elemlen $elemlen] -setup {
                    set L [lrepeat $len [string repeat a $elemlen]]
                }

                comment Canonical lists (with string representation)
                perf measure [concat_describe "canonical lists" $len $elemlen] {
                    concat $L $L
                } [list len $len elemlen $elemlen] -setup {
                    set L [lrepeat $len [string repeat a $elemlen]]
                    append x x $L; # Generate string while keeping internal rep list
                    unset x
                }

                comment Non-canonical lists
                perf measure [concat_describe "non-canonical lists" $len $elemlen] {
                    concat $L $L
                } [list len $len elemlen $elemlen] -setup {
                    set L [string repeat "[string repeat a $elemlen] " $len]
                    llength $L
                }
            }
        }

        # Span version
        foreach len $Lengths {
            foreach elemlen {1 100} {
                comment Pure span lists (no string representation)
                perf measure [concat_describe "pure spanned lists" $len $elemlen] {
                    concat $L $L
                } [list len $len elemlen $elemlen] -setup {
                    set L [lrange [lrepeat [expr {$len+2}] [string repeat a $elemlen]] 1 end-1]
                }

                comment Canonical span lists (with string representation)
                perf measure [concat_describe "canonical spanned lists" $len $elemlen] {
                    concat $L $L
                } [list len $len elemlen $elemlen] -setup {
                    set L [lrange [lrepeat [expr {$len+2}] [string repeat a $elemlen]] 1 end-1]
                    append x x $L; # Generate string while keeping internal rep list
                    unset x
                }
            }
        }

        perf destroy
    }

    proc test {} {
        variable RunTimes
        variable Options

        set selections [perf::list::setup $::argv]
        if {[llength $selections] == 0} {
            set commands [info commands ::perf::list::*_perf]
        } else {
            set commands [lmap sel $selections {
                if {$sel eq "help"} {
                    print_usage
                    exit 0
                }
                set cmd ::perf::list::${sel}_perf
                if {$cmd ni [info commands ::perf::list::*_perf]} {
                    puts stderr "Error: command $sel is not known or supported. Skipping."
                    continue
                }
                set cmd
            }]
        }
        comment Setting up
        timerate -calibrate {}
        if {[info exists Options(--label)]} {
            print "L $Options(--label)"
        }
        print "V [info patchlevel]"
        print "E [info nameofexecutable]"
        if {[info exists Options(--description)]} {
            print "D $Options(--description)"
        }
        set twapi_keys {-privatebytes -workingset -workingsetpeak}
        if {[info commands ::twapi::get_process_memory_info] ne ""} {
            set twapi_vm_pre [::twapi::get_process_memory_info]
        }
        foreach cmd [lsort -dictionary $commands] {
            set RunTimes(command) 0.0
            $cmd
            set RunTimes(total) [expr {$RunTimes(total)+$RunTimes(command)}]
            print "P [format_timings $RunTimes(command) 1] [string range $cmd 14 end-5] total run time"
        }
        # Print total runtime in same format as timerate output
        print "P [format_timings $RunTimes(total) 1] Total run time"

        if {[info exists twapi_vm_pre]} {
            set twapi_vm_post [::twapi::get_process_memory_info]
            set MB 1048576.0
            foreach key $twapi_keys {
                set pre [expr {[dict get $twapi_vm_pre $key]/$MB}]
                set post [expr {[dict get $twapi_vm_post $key]/$MB}]
                print "P [format_timings $pre 1] Memory (MB) $key pre-test"
                print "P [format_timings $post 1] Memory (MB) $key post-test"
                print "P [format_timings [expr {$post-$pre}] 1] Memory (MB) delta $key"
            }
        }
        if {[info commands memory] ne ""} {
            foreach line [split [memory info] \n] {
                if {$line eq ""} continue
                set line [split $line]
                set val [expr {[lindex $line end]/1000.0}]
                set line [string trim [join [lrange $line 0 end-1]]]
                print "P [format_timings $val 1] memdbg $line (in thousands)"
            }
            print "# Allocations not freed on exit written to the lost-memory.tmp file."
            print "# These will have to be manually compared."
            # env TCL_FINALIZE_ON_EXIT must be set to 1 for this.
            # DO NOT SET HERE - set ::env(TCL_FINALIZE_ON_EXIT) 1
            # Must be set in environment before starting tclsh else bogus results
            if {[info exists Options(--label)]} {
                set dump_file list-memory-$Options(--label).memdmp
            } else {
                set dump_file list-memory-[pid].memdmp
            }
            memory onexit $dump_file
        }
    }
}


if {[info exists ::argv0] && [file tail $::argv0] eq [file tail [info script]]} {
    ::perf::list::test
}







|
|







|


|
|
|
|
|



|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|


|
|
|
|
|


|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|


|
|
|
|


|
|
|


|
|



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|



|


|

|

|

|
|


|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|

|
|
|
|
|
|
|

|
|
|
|
|
|
|

|
|

|



|


|

|

|
|
|
|
|
|
|
|
|
|
|
|

|



|


|

|

|

|
|
|
|
|
|
|
|

|
|
|
|
|
|
|

|
|
|
|
|
|
|

|



|


|

|

|

|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|

|

|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|

|
|
|

|



|


|

|

|

|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|



|


|

|

|
|
|
|
|
|

|
|
|
|
|

|



|


|

|

|

|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|

|



|


|

|

|

|
|
|
|
|

|
|
|
|
|
|
|

|



|


|

|

|

|
|
|
|
|
|

|
|
|
|
|
|
|

|



|



|

|

|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|



|


|

|

|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|

|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|



|


|

|

|

|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|



|
|
|
|


|

|

|
|

|
|
|
|
|
|
|
|
|
|

|
|
|
|

|
|
|
|

|
|
|
|

|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|

|
|
|
|

|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|

|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|

|



|


|
|

|
|
|
|
|
|
|



|


|

|

|
|
|
|
|
|
|
|
|
|
|
|
|
|



|


|

|

|
|
|
|
|
|
|
|
|
|
|
|
|
|



|


|

|

|
|
|
|
|
|
|
|
|
|
|
|
|
|



|


|

|

|
|
|
|
|
|
|
|
|
|
|
|
|
|



|
|

|
|
|
|
|
|

|
|
|
|
|
|


|


|

|

|
|
|
|

|
|
|
|

|
|
|
|

|
|
|
|

|



|


|

|

|

|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|

|



|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295

    variable RunTimes
    set RunTimes(command) 0.0
    set RunTimes(total) 0.0

    variable Options
    array set Options {
	--print-comments   0
	--print-iterations 0
    }

    # Procs used for calibrating overhead
    proc proc2args {a b} {}
    proc proc3args {a b c} {}

    proc print {s} {
	puts $s
    }
    proc print_usage {} {
	puts stderr "Usage: [file tail [info nameofexecutable]] $::argv0 \[options\] \[command ...\]"
	puts stderr "\t--description DESC\tHuman readable description of test run"
	puts stderr "\t--label LABEL\tA label used to identify test environment"
	puts stderr "\t--print-comments\tPrint comment for each test"
	puts stderr "\t--print-iterations\tPrint number of iterations run for each test"
    }

    proc setup {argv} {
	variable Options
	variable Lengths

	while {[llength $argv]} {
	    set argv [lassign $argv arg]
	    switch -glob -- $arg {
		--print-comments -
		--print-iterations {
		    set Options($arg) 1
		}
		--label -
		--description {
		    if {[llength $argv] == 0} {
			error "Missing value for option $arg"
		    }
		    set argv [lassign $argv val]
		    set Options($arg) $val
		}
		--lengths {
		    if {[llength $argv] == 0} {
			error "Missing value for option $arg"
		    }
		    set argv [lassign $argv val]
		    set Lengths $val
		}
		-- {
		    # Remaining will be passed back to the caller
		    break
		}
		--* {
		    puts stderr "Unknown option $arg"
		    print_usage
		    exit 1
		}
		default {
		    # Remaining will be passed back to the caller
		    set argv [linsert $argv 0 $arg]
		    break;
		}
	    }
	}

	return $argv
    }
    proc format_timings {us iters} {
	variable Options
	if {!$Options(--print-iterations)} {
	    return "[format {%#10.4f} $us]"
	}
	return "[format {%#10.4f} $us] [format {%8d} $iters]"
    }
    proc measure {id script args} {
	variable NullOverhead
	variable RunTimes
	variable Options

	set opts(-overhead) ""
	set opts(-runs) 5
	while {[llength $args]} {
	    set args [lassign $args opt]
	    if {[llength $args] == 0} {
		error "No argument supplied for $opt option. Test: $id"
	    }
	    set args [lassign $args val]
	    switch $opt {
		-setup -
		-cleanup -
		-overhead -
		-time -
		-runs -
		-reps {
		    set opts($opt) $val
		}
		default {
		    error "Unknown option $opt. Test: $id"
		}
	    }
	}

	set timerate_args {}
	if {[info exists opts(-time)]} {
	    lappend timerate_args $opts(-time)
	}
	if {[info exists opts(-reps)]} {
	    if {[info exists opts(-time)]} {
		set timerate_args [list $opts(-time) $opts(-reps)]
	    } else {
		# Force the default for first time option
		set timerate_args [list 1000 $opts(-reps)]
	    }
	} elseif {[info exists opts(-time)]} {
	    set timerate_args [list $opts(-time)]
	}
	if {[info exists opts(-setup)]} {
	    uplevel 1 $opts(-setup)
	}
	# Cache the empty overhead to prevent unnecessary delays. Note if you modify
	# to cache other scripts, the cache key must be AFTER substituting the
	# overhead script in the caller's context.
	if {$opts(-overhead) eq ""} {
	    if {![info exists NullOverhead]} {
		set NullOverhead [lindex [timerate {}] 0]
	    }
	    set overhead_us $NullOverhead
	} else {
	    # The overhead measurements might use setup so we need to setup
	    # first and then cleanup in preparation for setting up again for
	    # the script to be measured
	    if {[info exists opts(-setup)]} {
		uplevel 1 $opts(-setup)
	    }
	    set overhead_us [lindex [uplevel 1 [list timerate $opts(-overhead)]] 0]
	    if {[info exists opts(-cleanup)]} {
		uplevel 1 $opts(-cleanup)
	    }
	}
	set timings {}
	for {set i 0} {$i < $opts(-runs)} {incr i} {
	    if {[info exists opts(-setup)]} {
		uplevel 1 $opts(-setup)
	    }
	    lappend timings [uplevel 1 [list timerate -overhead $overhead_us $script {*}$timerate_args]]
	    if {[info exists opts(-cleanup)]} {
		uplevel 1 $opts(-cleanup)
	    }
	}
	set timings [lsort -real -index 0 $timings]
	if {$opts(-runs) > 15} {
	    set ignore [expr {$opts(-runs)/8}]
	} elseif {$opts(-runs) >= 5} {
	    set ignore 2
	} else {
	    set ignore 0
	}
	# Ignore highest and lowest
	set timings [lrange $timings 0 end-$ignore]
	# Average it out
	set us 0
	set iters 0
	foreach timing $timings {
	    set us [expr {$us + [lindex $timing 0]}]
	    set iters [expr {$iters + [lindex $timing 2]}]
	}
	set us [expr {$us/[llength $timings]}]
	set iters [expr {$iters/[llength $timings]}]

	set RunTimes(command) [expr {$RunTimes(command) + $us}]
	print "P [format_timings $us $iters] $id"
    }
    proc comment {args} {
	variable Options
	if {$Options(--print-comments)} {
	    print "# [join $args { }]"
	}
    }
    proc spanned_list {len} {
	# Note - for small len, this will not create a spanned list
	set delta [expr {$len/8}]
	return [lrange [lrepeat [expr {$len+(2*$delta)}] a] $delta [expr {$delta+$len-1}]]
    }
    proc print_separator {command} {
	comment [string repeat = 80]
	comment Command: $command
    }

    oo::class create ListPerf {
	constructor {args} {
	    my variable Opts
	    # Note default Opts can be overridden in construct as well as in measure
	    set Opts [dict merge {
		-setup {
		    set L [lrepeat $len a]
		    set Lspan [perf::list::spanned_list $len]
		} -cleanup {
		    unset -nocomplain L
		    unset -nocomplain Lspan
		    unset -nocomplain L2
		}
	    } $args]
	}
	method measure {comment script locals args} {
	    my variable Opts
	    dict with locals {}
	    ::perf::list::measure $comment $script {*}[dict merge $Opts $args]
	}
	method option {opt val} {
	    my variable Opts
	    dict set Opts $opt $val
	}
	method option_unset {opt} {
	    my variable Opts
	    unset -nocomplain Opts($opt)
	}
    }

    proc linsert_describe {share_mode len at num iters} {
	return "linsert L\[$len\] $share_mode $num elems $iters times at $at"
    }
    proc linsert_perf {} {
	variable Lengths

	print_separator linsert

	ListPerf create perf -overhead {set L {}} -time 1000

	# Note: Const indices take different path through bytecode than variable
	# indices hence separate cases below


	# Var case
	foreach share_mode {shared unshared} {
	    set idx 0
	    if {$share_mode eq "shared"} {
		comment == Insert into empty lists
		comment Insert one element into empty list
		measure [linsert_describe shared 0 "0 (var)" 1 1] {linsert $L $idx ""} -setup {set idx 0; set L {}}
	    } else {
		comment == Insert into empty lists
		comment Insert one element into empty list
		measure [linsert_describe unshared 0 "0 (var)" 1 1] {linsert {} $idx ""} -setup {set idx 0}
	    }
	    foreach idx_str [list 0 1 mid end-1 end] {
		foreach len $Lengths {
		    if {$idx_str eq "mid"} {
			set idx [expr {$len/2}]
		    } else {
			set idx $idx_str
		    }
		    # perf option -reps $reps
		    set reps 1000
		    if {$share_mode eq "shared"} {
			comment Insert once to shared list with variable index
			perf measure [linsert_describe shared $len "$idx (var)" 1 1] \
			    {linsert $L $idx x} [list len $len idx $idx] -overhead {} -reps 100000

			comment Insert multiple times to shared list with variable index
			perf measure [linsert_describe shared $len "$idx (var)" 1 $reps] {
			    set L [linsert $L $idx X]
			} [list len $len idx $idx] -reps $reps

			comment Insert multiple items multiple times to shared list with variable index
			perf measure [linsert_describe shared $len "$idx (var)" 5 $reps] {
			    set L [linsert $L $idx X X X X X]
			} [list len $len idx $idx] -reps $reps
		    } else {
			# NOTE : the Insert once case is left out for unshared lists
			# because it requires re-init on every iteration resulting
			# in a lot of measurement noise
			comment Insert multiple times to unshared list with variable index
			perf measure [linsert_describe unshared $len "$idx (var)" 1 $reps] {
			    set L [linsert $L[set L {}] $idx X]
			} [list len $len idx $idx] -reps $reps
			comment Insert multiple items multiple times to unshared list with variable index
			perf measure [linsert_describe unshared $len "$idx (var)" 5 $reps] {
			    set L [linsert $L[set L {}] $idx X X X X X]
			} [list len $len idx $idx] -reps $reps
		    }
		}
	    }
	}

	# Const index
	foreach share_mode {shared unshared} {
	    if {$share_mode eq "shared"} {
		comment == Insert into empty lists
		comment Insert one element into empty list
		measure [linsert_describe shared 0 "0 (const)" 1 1] {linsert $L 0 ""} -setup {set L {}}
	    } else {
		comment == Insert into empty lists
		comment Insert one element into empty list
		measure [linsert_describe unshared 0 "0 (const)" 1 1] {linsert {} 0 ""}
	    }
	    foreach idx_str [list 0 1 mid end end-1] {
		foreach len $Lengths {
		    # Note end, end-1 explicitly calculated as otherwise they
		    # are not treated as const
		    if {$idx_str eq "mid"} {
			set idx [expr {$len/2}]
		    } elseif {$idx_str eq "end"} {
			set idx [expr {$len-1}]
		    } elseif {$idx_str eq "end-1"} {
			set idx [expr {$len-2}]
		    } else {
			set idx $idx_str
		    }
		    #perf option -reps $reps
		    set reps 100
		    if {$share_mode eq "shared"} {
			comment Insert once to shared list with const index
			perf measure [linsert_describe shared $len "$idx (const)" 1 1] \
			    "linsert \$L $idx x" [list len $len] -overhead {} -reps 10000

			comment Insert multiple times to shared list with const index
			perf measure [linsert_describe shared $len "$idx (const)" 1 $reps] \
			    "set L \[linsert \$L $idx X\]" [list len $len] -reps $reps

			comment Insert multiple items multiple times to shared list with const index
			perf measure [linsert_describe shared $len "$idx (const)" 5 $reps] \
			    "set L \[linsert \$L $idx X X X X X\]" [list len $len] -reps $reps
		    } else {
			comment Insert multiple times to unshared list with const index
			perf measure [linsert_describe unshared $len "$idx (const)" 1 $reps] \
			    "set L \[linsert \$L\[set L {}\] $idx X]" [list len $len] -reps $reps

			comment Insert multiple items multiple times to unshared list with const index
			perf measure [linsert_describe unshared $len "$idx (const)" 5 $reps] \
			    "set L \[linsert \$L\[set L {}\] $idx X X X X X]" [list len $len] -reps $reps
		    }
		}
	    }
	}

	# Note: no span tests because the inserts above will themselves create
	# spanned lists

	perf destroy
    }

    proc list_describe {len text} {
	return "list L\[$len\] $text"
    }
    proc list_perf {} {
	variable Lengths

	print_separator list

	ListPerf create perf
	foreach len $Lengths {
	    set s [join [lrepeat $len x]]
	    comment Create a list from a string
	    perf measure [list_describe $len "from a string"] {list $s} [list s $s len $len]
	}
	foreach len $Lengths {
	    comment Create a list from expansion - single list (special optimal case)
	    perf measure [list_describe $len "from a {*}list"] {list {*}$L} [list len $len]
	    comment Create a list from two lists - real test of expansion speed
	    perf measure [list_describe $len "from a {*}list {*}list"] {list {*}$L {*}$L} [list len [expr {$len/2}]]
	}

	perf destroy
    }

    proc lappend_describe {share_mode len num iters} {
	return "lappend L\[$len\] $share_mode $num elems $iters times"
    }
    proc lappend_perf {} {
	variable Lengths

	print_separator lappend

	ListPerf create perf -setup {set L [lrepeat [expr {$len/4}] x]}

	# Shared
	foreach len $Lengths {
	    comment Append to a shared list variable multiple times
	    perf measure [lappend_describe shared [expr {$len/2}] 1 $len] {
		set L2 $L; # Make shared
		lappend L x
	    } [list len $len] -reps $len -overhead {set L2 $L}
	}

	# Unshared
	foreach len $Lengths {
	    comment Append to a unshared list variable multiple times
	    perf measure [lappend_describe unshared [expr {$len/2}] 1 $len] {
		lappend L x
	    } [list len $len] -reps $len
	}

	# Span
	foreach len $Lengths {
	    comment Append to a unshared-span list variable multiple times
	    perf measure [lappend_describe unshared-span [expr {$len/2}] 1 $len] {
		lappend Lspan x
	    } [list len $len] -reps $len
	}

	perf destroy
    }

    proc lpop_describe {share_mode len at reps} {
	return "lpop L\[$len\] $share_mode at $at $reps times"
    }
    proc lpop_perf {} {
	variable Lengths

	print_separator lpop

	ListPerf create perf

	# Shared
	perf option -overhead {set L2 $L}
	foreach len $Lengths {
	    set reps [expr {($len >= 1000 ? ($len/2) : $len) - 2}]
	    foreach idx {0 1 end-1 end}  {
		comment Pop element at position $idx from a shared list variable
		perf measure [lpop_describe shared $len $idx $reps] {
		    set L2 $L
		    lpop L $idx
		} [list len $len idx $idx] -reps $reps
	    }
	}

	# Unshared
	perf option -overhead {}
	foreach len $Lengths {
	    set reps [expr {($len >= 1000 ? ($len/2) : $len) - 2}]
	    foreach idx {0 1 end-1 end}  {
		comment Pop element at position $idx from an unshared list variable
		perf measure [lpop_describe unshared $len $idx $reps] {
		    lpop L $idx
		} [list len $len idx $idx] -reps $reps
	    }
	}

	perf destroy

	# Nested
	ListPerf create perf -setup {
	    set L [lrepeat $len [list a b]]
	}

	# Shared, nested index
	perf option -overhead {set L2 $L; set L L2}
	foreach len $Lengths {
	    set reps [expr {($len >= 1000 ? ($len/2) : $len) - 2}]
	    foreach idx {0 1 end-1 end}  {
		perf measure [lpop_describe shared $len "{$idx 0}" $reps] {
		    set L2 $L
		    lpop L $idx 0
		    set L $L2
		} [list len $len idx $idx] -reps $reps
	    }
	}

	# TODO - Nested Unshared
	# Not sure how to measure performance. When unshared there is no copy
	# so deleting a nested index repeatedly is not feasible

	perf destroy
    }

    proc lassign_describe {share_mode len num reps} {
	return "lassign L\[$len\] $share_mode $num elems $reps times"
    }
    proc lassign_perf {} {
	variable Lengths

	print_separator lassign

	ListPerf create perf

	foreach share_mode {shared unshared} {
	    foreach len $Lengths {
		if {$share_mode eq "shared"} {
		    set reps 1000
		    comment Reflexive lassign - shared
		    perf measure [lassign_describe shared $len 1 $reps] {
			set L2 $L
			set L2 [lassign $L2 v]
		    } [list len $len] -overhead {set L2 $L} -reps $reps

		    comment Reflexive lassign - shared, multiple
		    perf measure [lassign_describe shared $len 5 $reps] {
			set L2 $L
			set L2 [lassign $L2 a b c d e]
		    } [list len $len] -overhead {set L2 $L} -reps $reps
		} else {
		    set reps [expr {($len >= 1000 ? ($len/2) : $len) - 2}]
		    comment Reflexive lassign - unshared
		    perf measure [lassign_describe unshared $len 1 $reps] {
			set L [lassign $L v]
		    } [list len $len] -reps $reps
		}
	    }
	}
	perf destroy
    }

    proc lrepeat_describe {len num} {
	return "lrepeat L\[$len\] $num elems at a time"
    }
    proc lrepeat_perf {} {
	variable Lengths

	print_separator lrepeat

	ListPerf create perf -reps 100000
	foreach len $Lengths {
	    comment Generate a list from a single repeated element
	    perf measure [lrepeat_describe $len 1] {
		lrepeat $len a
	    } [list len $len]

	    comment Generate a list from multiple repeated elements
	    perf measure [lrepeat_describe $len 5] {
		lrepeat $len a b c d e
	    } [list len $len]
	}

	perf destroy
    }

    proc lreverse_describe {share_mode len} {
	return "lreverse L\[$len\] $share_mode"
    }
    proc lreverse_perf {} {
	variable Lengths

	print_separator lreverse

	ListPerf create perf -reps 10000

	foreach share_mode {shared unshared} {
	    foreach len $Lengths {
		if {$share_mode eq "shared"} {
		    comment Reverse a shared list
		    perf measure [lreverse_describe shared $len] {
			lreverse $L
		    } [list len $len]

		    if {$len > 100} {
			comment Reverse a shared-span list
			perf measure [lreverse_describe shared-span $len] {
			    lreverse $Lspan
			} [list len $len]
		    }
		} else {
		    comment Reverse a unshared list
		    perf measure [lreverse_describe unshared $len] {
			set L [lreverse $L[set L {}]]
		    } [list len $len] -overhead {set L $L; set L {}}

		    if {$len >= 100} {
			comment Reverse a unshared-span list
			perf measure [lreverse_describe unshared-span $len] {
			    set Lspan [lreverse $Lspan[set Lspan {}]]
			} [list len $len] -overhead {set Lspan $Lspan; set Lspan {}}
		    }
		}
	    }
	}

	perf destroy
    }

    proc llength_describe {share_mode len} {
	return "llength L\[$len\] $share_mode"
    }
    proc llength_perf {} {
	variable Lengths

	print_separator llength

	ListPerf create perf -reps 100000

	foreach len $Lengths {
	    comment Length of a list
	    perf measure [llength_describe shared $len] {
		llength $L
	    } [list len $len]

	    if {$len >= 100} {
		comment Length of a span list
		perf measure [llength_describe shared-span $len] {
		    llength $Lspan
		} [list len $len]
	    }
	}

	perf destroy
    }

    proc lindex_describe {share_mode len at} {
	return "lindex L\[$len\] $share_mode at $at"
    }
    proc lindex_perf {} {
	variable Lengths

	print_separator lindex

	ListPerf create perf -reps 100000

	foreach len $Lengths {
	    comment Index into a list
	    set idx [expr {$len/2}]
	    perf measure [lindex_describe shared $len $idx] {
		lindex $L $idx
	    } [list len $len idx $idx]

	    if {$len >= 100} {
		comment Index into a span list
		perf measure [lindex_describe shared-span $len $idx] {
		    lindex $Lspan $idx
		} [list len $len idx $idx]
	    }
	}

	perf destroy
    }

    proc lrange_describe {share_mode len range} {
	return "lrange L\[$len\] $share_mode range $range"
    }

    proc lrange_perf {} {
	variable Lengths

	print_separator lrange

	ListPerf create perf -time 1000 -reps 100000

	foreach share_mode {shared unshared} {
	    foreach len $Lengths {
		set eighth [expr {$len/8}]
		set ranges [list \
				[list 0 0]  [list 0 end-1] \
				[list $eighth [expr {3*$eighth}]] \
				[list $eighth [expr {7*$eighth}]] \
				[list 1 end] [list end-1 end] \
			       ]
		foreach range $ranges {
		    comment Range $range in $share_mode list of length $len
		    if {$share_mode eq "shared"} {
			perf measure [lrange_describe shared $len $range] \
			    "lrange \$L $range" [list len $len range $range]
		    } else {
			perf measure [lrange_describe unshared $len $range] \
			    "lrange \[lrepeat \$len\ a] $range" \
			    [list len $len range $range] -overhead {lrepeat $len a}
		    }
		}

		if {$len >= 100} {
		    foreach range $ranges {
			comment Range $range in ${share_mode}-span list of length $len
			if {$share_mode eq "shared"} {
			    perf measure [lrange_describe shared-span $len $range] \
				"lrange \$Lspan {*}$range" [list len $len range $range]
			} else {
			    perf measure [lrange_describe unshared-span $len $range] \
				"lrange \[perf::list::spanned_list \$len\] $range" \
				[list len $len range $range] -overhead {perf::list::spanned_list $len}
			}
		    }
		}
	    }
	}

	perf destroy
    }

    proc lset_describe {share_mode len at} {
	return "lset L\[$len\] $share_mode at $at"
    }
    proc lset_perf {} {
	variable Lengths

	print_separator lset

	ListPerf create perf -reps 10000

	# Shared
	foreach share_mode {shared unshared} {
	    foreach len $Lengths {
		foreach idx {0 1 end-1 end end+1}  {
		    comment lset at position $idx in a $share_mode list variable
		    if {$share_mode eq "shared"} {
			perf measure [lset_describe shared $len $idx] {
			    set L2 $L
			    lset L $idx X
			} [list len $len idx $idx] -overhead {set L2 $L}
		    } else {
			perf measure [lset_describe unshared $len $idx] {
			    lset L $idx X
			} [list len $len idx $idx]
		    }
		}
	    }
	}

	perf destroy

	# Nested
	ListPerf create perf -setup {
	    set L [lrepeat $len [list a b]]
	}

	foreach share_mode {shared unshared} {
	    foreach len $Lengths {
		foreach idx {0 1 end-1 end}  {
		    comment lset at position $idx in a $share_mode list variable
		    if {$share_mode eq "shared"} {
			perf measure [lset_describe shared $len "{$idx 0}"] {
			    set L2 $L
			    lset L $idx 0 X
			} [list len $len idx $idx] -overhead {set L2 $L}
		    } else {
			perf measure [lset_describe unshared $len "{$idx 0}"] {
			    lset L $idx 0 {X Y}
			} [list len $len idx $idx]
		    }
		}
	    }
	}

	perf destroy
    }

    proc lremove_describe {share_mode len at nremoved} {
	return "lremove L\[$len\] $share_mode $nremoved elements at $at"
    }
    proc lremove_perf {} {
	variable Lengths

	print_separator lremove

	ListPerf create perf -reps 10000

	foreach share_mode {shared unshared} {
	    foreach len $Lengths {
		foreach idx [list 0 1 [expr {$len/2}] end-1 end] {
		    if {$share_mode eq "shared"} {
			comment Remove one element from shared list
			perf measure [lremove_describe shared $len $idx 1] \
			    {lremove $L $idx} [list len $len idx $idx]

		    } else {
			comment Remove one element from unshared list
			set reps [expr {$len >= 1000 ? ($len/8) : ($len-2)}]
			perf measure [lremove_describe unshared $len $idx 1] \
			    {set L [lremove $L[set L {}] $idx]} [list len $len idx $idx] \
			    -overhead {set L $L; set L {}} -reps $reps
		    }
		}
		if {$share_mode eq "shared"} {
		    comment Remove multiple elements from shared list
		    perf measure [lremove_describe shared $len [list 0 1 [expr {$len/2}] end-1 end] 5] {
			lremove $L 0 1 [expr {$len/2}] end-1 end
		    } [list len $len]
		}
	    }
	    # Span
	    foreach len $Lengths {
		foreach idx [list 0 1 [expr {$len/2}] end-1 end] {
		    if {$share_mode eq "shared"} {
			comment Remove one element from shared-span list
			perf measure [lremove_describe shared-span $len $idx 1] \
			    {lremove $Lspan $idx} [list len $len idx $idx]
		    } else {
			comment Remove one element from unshared-span list
			set reps [expr {$len >= 1000 ? ($len/8) : ($len-2)}]
			perf measure [lremove_describe unshared-span $len $idx 1] \
			    {set Lspan [lremove $Lspan[set Lspan {}] $idx]} [list len $len idx $idx] \
			    -overhead {set Lspan $Lspan; set Lspan {}} -reps $reps
		    }
		}
		if {$share_mode eq "shared"} {
		    comment Remove multiple elements from shared-span list
		    perf measure [lremove_describe shared-span $len [list 0 1 [expr {$len/2}] end-1 end] 5] {
			lremove $Lspan 0 1 [expr {$len/2}] end-1 end
		    } [list len $len]
		}
	    }
	}

	perf destroy
    }

    proc lreplace_describe {share_mode len first last ninsert {times 1}} {
	if {$last < $first} {
	    return "lreplace L\[$len\] $share_mode 0 ($first:$last) elems at $first with $ninsert elems $times times."
	}
	return "lreplace L\[$len\] $share_mode $first:$last with $ninsert elems $times times."
    }
    proc lreplace_perf {} {
	variable Lengths

	print_separator lreplace

	set default_reps 10000
	ListPerf create perf -reps $default_reps

	foreach share_mode {shared unshared} {
	    # Insert only
	    foreach len $Lengths {
		set reps [expr {$len <= 100 ? ($len-2) : ($len/8)}]
		foreach first [list 0 1 [expr {$len/2}] end-1 end] {
		    if {$share_mode eq "shared"} {
			comment Insert one to shared list
			perf measure [lreplace_describe shared $len $first -1 1] {
			    lreplace $L $first -1 x
			} [list len $len first $first]

			comment Insert multiple to shared list
			perf measure [lreplace_describe shared $len $first -1 10] {
			    lreplace $L $first -1 X X X X X X X X X X
			} [list len $len first $first]

			comment Insert one to shared list repeatedly
			perf measure [lreplace_describe shared $len $first -1 1 $reps] {
			    set L [lreplace $L $first -1 x]
			} [list len $len first $first] -reps $reps

			comment Insert multiple to shared list repeatedly
			perf measure [lreplace_describe shared $len $first -1 10 $reps] {
			    set L [lreplace $L $first -1 X X X X X X X X X X]
			} [list len $len first $first] -reps $reps

		    } else {
			comment Insert one to unshared list
			perf measure [lreplace_describe unshared $len $first -1 1] {
			    set L [lreplace $L[set L {}] $first -1 x]
			} [list len $len first $first] -overhead {
			    set L $L; set L {}
			} -reps $reps

			comment Insert multiple to unshared list
			perf measure [lreplace_describe unshared $len $first -1 10] {
			    set L [lreplace $L[set L {}] $first -1 X X X X X X X X X X]
			} [list len $len first $first] -overhead {
			    set L $L; set L {}
			} -reps $reps
		    }
		}
	    }

	    # Delete only
	    foreach len $Lengths {
		set reps [expr {$len <= 100 ? ($len-2) : ($len/8)}]
		foreach first [list 0 1 [expr {$len/2}] end-1 end] {
		    if {$share_mode eq "shared"} {
			comment Delete one from shared list
			perf measure [lreplace_describe shared $len $first $first 0] {
			    lreplace $L $first $first
			} [list len $len first $first]
		    } else {
			comment Delete one from unshared list
			perf measure [lreplace_describe unshared $len $first $first 0] {
			    set L [lreplace $L[set L {}] $first $first x]
			} [list len $len first $first] -overhead {
			    set L $L; set L {}
			} -reps $reps
		    }
		}
	    }

	    # Insert + delete
	    foreach len $Lengths {
		set reps [expr {$len <= 100 ? ($len-2) : ($len/8)}]
		foreach range [list {0 1} {1 2} {end-2 end-1} {end-1 end}] {
		    lassign $range first last
		    if {$share_mode eq "shared"} {
			comment Insertions more than deletions from shared list
			perf measure [lreplace_describe shared $len $first $last 3] {
			    lreplace $L $first $last X Y Z
			} [list len $len first $first last $last]

			comment Insertions same as deletions from shared list
			perf measure [lreplace_describe shared $len $first $last 2] {
			    lreplace $L $first $last X Y
			} [list len $len first $first last $last]

			comment Insertions fewer than deletions from shared list
			perf measure [lreplace_describe shared $len $first $last 1] {
			    lreplace $L $first $last X
			} [list len $len first $first last $last]
		    } else {
			comment Insertions more than deletions from unshared list
			perf measure [lreplace_describe unshared $len $first $last 3] {
			    set L [lreplace $L[set L {}] $first $last X Y Z]
			} [list len $len first $first last $last] -overhead {
			    set L $L; set L {}
			} -reps $reps

			comment Insertions same as deletions from unshared list
			perf measure [lreplace_describe unshared $len $first $last 2] {
			    set L [lreplace $L[set L {}] $first $last X Y ]
			} [list len $len first $first last $last] -overhead {
			    set L $L; set L {}
			} -reps $reps

			comment Insertions fewer than deletions from unshared list
			perf measure [lreplace_describe unshared $len $first $last 1] {
			    set L [lreplace $L[set L {}] $first $last X]
			} [list len $len first $first last $last] -overhead {
			    set L $L; set L {}
			} -reps $reps
		    }
		}
	    }
	    # Spanned Insert + delete
	    foreach len $Lengths {
		set reps [expr {$len <= 100 ? ($len-2) : ($len/8)}]
		foreach range [list {0 1} {1 2} {end-2 end-1} {end-1 end}] {
		    lassign $range first last
		    if {$share_mode eq "shared"} {
			comment Insertions more than deletions from shared-span list
			perf measure [lreplace_describe shared-span $len $first $last 3] {
			    lreplace $Lspan $first $last X Y Z
			} [list len $len first $first last $last]

			comment Insertions same as deletions from shared-span list
			perf measure [lreplace_describe shared-span $len $first $last 2] {
			    lreplace $Lspan $first $last X Y
			} [list len $len first $first last $last]

			comment Insertions fewer than deletions from shared-span list
			perf measure [lreplace_describe shared-span $len $first $last 1] {
			    lreplace $Lspan $first $last X
			} [list len $len first $first last $last]
		    } else {
			comment Insertions more than deletions from unshared-span list
			perf measure [lreplace_describe unshared-span $len $first $last 3] {
			    set Lspan [lreplace $Lspan[set Lspan {}] $first $last X Y Z]
			} [list len $len first $first last $last] -overhead {
			    set Lspan $Lspan; set Lspan {}
			} -reps $reps

			comment Insertions same as deletions from unshared-span list
			perf measure [lreplace_describe unshared-span $len $first $last 2] {
			    set Lspan [lreplace $Lspan[set Lspan {}] $first $last X Y ]
			} [list len $len first $first last $last] -overhead {
			    set Lspan $Lspan; set Lspan {}
			} -reps $reps

			comment Insertions fewer than deletions from unshared-span list
			perf measure [lreplace_describe unshared-span $len $first $last 1] {
			    set Lspan [lreplace $Lspan[set Lspan {}] $first $last X]
			} [list len $len first $first last $last] -overhead {
			    set Lspan $Lspan; set Lspan {}
			} -reps $reps
		    }
		}
	    }
	}

	perf destroy
    }

    proc split_describe {len} {
	return "split L\[$len\]"
    }
    proc split_perf {} {
	variable Lengths
	print_separator split

	ListPerf create perf -setup {set S [string repeat "x " $len]}
	foreach len $Lengths {
	    comment Split a string
	    perf measure [split_describe $len] {
		split $S " "
	    } [list len $len]
	}
    }

    proc join_describe {share_mode len} {
	return "join L\[$len\] $share_mode"
    }
    proc join_perf {} {
	variable Lengths

	print_separator join

	ListPerf create perf -reps 10000
	foreach len $Lengths {
	    comment Join a list
	    perf measure [join_describe shared $len] {
		join $L
	    } [list len $len]
	}
	foreach len $Lengths {
	    comment Join a spanned list
	    perf measure [join_describe shared-span $len] {
		join $Lspan
	    } [list len $len]
	}
	perf destroy
    }

    proc lsearch_describe {share_mode len} {
	return "lsearch L\[$len\] $share_mode"
    }
    proc lsearch_perf {} {
	variable Lengths

	print_separator lsearch

	ListPerf create perf -reps 100000
	foreach len $Lengths {
	    comment Search a list
	    perf measure [lsearch_describe shared $len] {
		lsearch $L needle
	    } [list len $len]
	}
	foreach len $Lengths {
	    comment Search a spanned list
	    perf measure [lsearch_describe shared-span $len] {
		lsearch $Lspan needle
	    } [list len $len]
	}
	perf destroy
    }

    proc foreach_describe {share_mode len} {
	return "foreach L\[$len\] $share_mode"
    }
    proc foreach_perf {} {
	variable Lengths

	print_separator foreach

	ListPerf create perf -reps 10000
	foreach len $Lengths {
	    comment Iterate through a list
	    perf measure [foreach_describe shared $len] {
		foreach e $L {}
	    } [list len $len]
	}
	foreach len $Lengths {
	    comment Iterate a spanned list
	    perf measure [foreach_describe shared-span $len] {
		foreach e $Lspan {}
	    } [list len $len]
	}
	perf destroy
    }

    proc lmap_describe {share_mode len} {
	return "lmap L\[$len\] $share_mode"
    }
    proc lmap_perf {} {
	variable Lengths

	print_separator lmap

	ListPerf create perf -reps 10000
	foreach len $Lengths {
	    comment Iterate through a list
	    perf measure [lmap_describe shared $len] {
		lmap e $L {}
	    } [list len $len]
	}
	foreach len $Lengths {
	    comment Iterate a spanned list
	    perf measure [lmap_describe shared-span $len] {
		lmap e $Lspan {}
	    } [list len $len]
	}
	perf destroy
    }

    proc get_sort_sample {{spanned 0}} {
	variable perfScript
	variable sortSampleText

	if {![info exists sortSampleText]} {
	    set fd [open $perfScript]
	    set sortSampleText [split [read $fd] ""]
	    close $fd
	}
	set sortSampleText [string range $sortSampleText 0 9999]

	# NOTE: do NOT cache list result in a variable as we need it unshared
	if {$spanned} {
	    return [lrange [split $sortSampleText ""] 1 end-1]
	} else {
	    return [split $sortSampleText ""]
	}
    }
    proc lsort_describe {share_mode len} {
	return "lsort L\[$len] $share_mode"
    }
    proc lsort_perf {} {
	print_separator lsort

	ListPerf create perf -setup {}

	comment Sort a shared list
	perf measure [lsort_describe shared [llength [perf::list::get_sort_sample]]] {
	    lsort $L
	} {} -setup {set L [perf::list::get_sort_sample]}

	comment Sort a shared-span list
	perf measure [lsort_describe shared-span [llength [perf::list::get_sort_sample 1]]] {
	    lsort $L
	} {} -setup {set L [perf::list::get_sort_sample 1]}

	comment Sort an unshared list
	perf measure [lsort_describe unshared [llength [perf::list::get_sort_sample]]] {
	    lsort [perf::list::get_sort_sample]
	} {} -overhead {perf::list::get_sort_sample}

	comment Sort an unshared-span list
	perf measure [lsort_describe unshared-span [llength [perf::list::get_sort_sample 1]]] {
	    lsort [perf::list::get_sort_sample 1]
	} {} -overhead {perf::list::get_sort_sample 1}

	perf destroy
    }

    proc concat_describe {canonicality len elemlen} {
	return "concat L\[$len\] $canonicality with elements of length $elemlen"
    }
    proc concat_perf {} {
	variable Lengths

	print_separator concat

	ListPerf create perf -reps 100000

	foreach len $Lengths {
	    foreach elemlen {1 100} {
		comment Pure lists (no string representation)
		perf measure [concat_describe "pure lists" $len $elemlen] {
		    concat $L $L
		} [list len $len elemlen $elemlen] -setup {
		    set L [lrepeat $len [string repeat a $elemlen]]
		}

		comment Canonical lists (with string representation)
		perf measure [concat_describe "canonical lists" $len $elemlen] {
		    concat $L $L
		} [list len $len elemlen $elemlen] -setup {
		    set L [lrepeat $len [string repeat a $elemlen]]
		    append x x $L; # Generate string while keeping internal rep list
		    unset x
		}

		comment Non-canonical lists
		perf measure [concat_describe "non-canonical lists" $len $elemlen] {
		    concat $L $L
		} [list len $len elemlen $elemlen] -setup {
		    set L [string repeat "[string repeat a $elemlen] " $len]
		    llength $L
		}
	    }
	}

	# Span version
	foreach len $Lengths {
	    foreach elemlen {1 100} {
		comment Pure span lists (no string representation)
		perf measure [concat_describe "pure spanned lists" $len $elemlen] {
		    concat $L $L
		} [list len $len elemlen $elemlen] -setup {
		    set L [lrange [lrepeat [expr {$len+2}] [string repeat a $elemlen]] 1 end-1]
		}

		comment Canonical span lists (with string representation)
		perf measure [concat_describe "canonical spanned lists" $len $elemlen] {
		    concat $L $L
		} [list len $len elemlen $elemlen] -setup {
		    set L [lrange [lrepeat [expr {$len+2}] [string repeat a $elemlen]] 1 end-1]
		    append x x $L; # Generate string while keeping internal rep list
		    unset x
		}
	    }
	}

	perf destroy
    }

    proc test {} {
	variable RunTimes
	variable Options

	set selections [perf::list::setup $::argv]
	if {[llength $selections] == 0} {
	    set commands [info commands ::perf::list::*_perf]
	} else {
	    set commands [lmap sel $selections {
		if {$sel eq "help"} {
		    print_usage
		    exit 0
		}
		set cmd ::perf::list::${sel}_perf
		if {$cmd ni [info commands ::perf::list::*_perf]} {
		    puts stderr "Error: command $sel is not known or supported. Skipping."
		    continue
		}
		set cmd
	    }]
	}
	comment Setting up
	timerate -calibrate {}
	if {[info exists Options(--label)]} {
	    print "L $Options(--label)"
	}
	print "V [info patchlevel]"
	print "E [info nameofexecutable]"
	if {[info exists Options(--description)]} {
	    print "D $Options(--description)"
	}
	set twapi_keys {-privatebytes -workingset -workingsetpeak}
	if {[info commands ::twapi::get_process_memory_info] ne ""} {
	    set twapi_vm_pre [::twapi::get_process_memory_info]
	}
	foreach cmd [lsort -dictionary $commands] {
	    set RunTimes(command) 0.0
	    $cmd
	    set RunTimes(total) [expr {$RunTimes(total)+$RunTimes(command)}]
	    print "P [format_timings $RunTimes(command) 1] [string range $cmd 14 end-5] total run time"
	}
	# Print total runtime in same format as timerate output
	print "P [format_timings $RunTimes(total) 1] Total run time"

	if {[info exists twapi_vm_pre]} {
	    set twapi_vm_post [::twapi::get_process_memory_info]
	    set MB 1048576.0
	    foreach key $twapi_keys {
		set pre [expr {[dict get $twapi_vm_pre $key]/$MB}]
		set post [expr {[dict get $twapi_vm_post $key]/$MB}]
		print "P [format_timings $pre 1] Memory (MB) $key pre-test"
		print "P [format_timings $post 1] Memory (MB) $key post-test"
		print "P [format_timings [expr {$post-$pre}] 1] Memory (MB) delta $key"
	    }
	}
	if {[info commands memory] ne ""} {
	    foreach line [split [memory info] \n] {
		if {$line eq ""} continue
		set line [split $line]
		set val [expr {[lindex $line end]/1000.0}]
		set line [string trim [join [lrange $line 0 end-1]]]
		print "P [format_timings $val 1] memdbg $line (in thousands)"
	    }
	    print "# Allocations not freed on exit written to the lost-memory.tmp file."
	    print "# These will have to be manually compared."
	    # env TCL_FINALIZE_ON_EXIT must be set to 1 for this.
	    # DO NOT SET HERE - set ::env(TCL_FINALIZE_ON_EXIT) 1
	    # Must be set in environment before starting tclsh else bogus results
	    if {[info exists Options(--label)]} {
		set dump_file list-memory-$Options(--label).memdmp
	    } else {
		set dump_file list-memory-[pid].memdmp
	    }
	    memory onexit $dump_file
	}
    }
}


if {[info exists ::argv0] && [file tail $::argv0] eq [file tail [info script]]} {
    ::perf::list::test
}
Changes to tests-perf/test-performance.tcl.
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
      break
    }
    if {[string is boolean -strict $_($o)]} {
      set _($o) [expr {! $_($o)}]
      set args [lrange $args 1 end]
    } else {
      if {[llength $args] <= 2} {
        return -code error "value expected for option $o"
      }
      set _($o) [lindex $args 1]
      set args [lrange $args 2 end]
    }
  }
  unset -nocomplain o
  if {[llength $args] < 2 || [llength $args] > 3} {







|







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
      break
    }
    if {[string is boolean -strict $_($o)]} {
      set _($o) [expr {! $_($o)}]
      set args [lrange $args 1 end]
    } else {
      if {[llength $args] <= 2} {
	return -code error "value expected for option $o"
      }
      set _($o) [lindex $args 1]
      set args [lrange $args 2 end]
    }
  }
  unset -nocomplain o
  if {[llength $args] < 2 || [llength $args] > 3} {
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
  # process measurement:
  foreach _(c) [_test_get_commands $lst] {
    {*}$_(outcmd) "% [regsub -all {\n[ \t]*} $_(c) {; }]"
    if {[regexp {^\s*\#} $_(c)]} continue
    if {[regexp {^\s*(?:setup|cleanup)\s+} $_(c)]} {
      set _(c) [lindex $_(c) 1]
      if {$_(-uplevel)} {
        set _(c) [list uplevel 1 $_(c)]
      }
      {*}$_(outcmd) [if 1 $_(c)]
      continue
    }
    if {$_(-uplevel)} {
      set _(c) [list uplevel 1 $_(c)]
    }
    set _(ittime) $_(reptime)
    # if output result (and not once):
    if {!$_(-no-result)} {
      set _(r) [if 1 $_(c)]
      if {$_(-convert-result) ne ""} { set _(r) [if 1 $_(-convert-result)] }
      {*}$_(outcmd) $_(r)
      if {[llength $_(ittime)] > 1} { # decrement max-count
        lset _(ittime) 1 [expr {[lindex $_(ittime) 1] - 1}]
      }
    }
    {*}$_(outcmd) [set _(m) [timerate $_(c) {*}$_(ittime)]]
    lappend _(itm) $_(m)
    {*}$_(outcmd) ""
  }
  if {$_(-from-run)} {
    _test_out_total
  }
}

}; # end of namespace ::tclTestPerf







|














|












165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
  # process measurement:
  foreach _(c) [_test_get_commands $lst] {
    {*}$_(outcmd) "% [regsub -all {\n[ \t]*} $_(c) {; }]"
    if {[regexp {^\s*\#} $_(c)]} continue
    if {[regexp {^\s*(?:setup|cleanup)\s+} $_(c)]} {
      set _(c) [lindex $_(c) 1]
      if {$_(-uplevel)} {
	set _(c) [list uplevel 1 $_(c)]
      }
      {*}$_(outcmd) [if 1 $_(c)]
      continue
    }
    if {$_(-uplevel)} {
      set _(c) [list uplevel 1 $_(c)]
    }
    set _(ittime) $_(reptime)
    # if output result (and not once):
    if {!$_(-no-result)} {
      set _(r) [if 1 $_(c)]
      if {$_(-convert-result) ne ""} { set _(r) [if 1 $_(-convert-result)] }
      {*}$_(outcmd) $_(r)
      if {[llength $_(ittime)] > 1} { # decrement max-count
	lset _(ittime) 1 [expr {[lindex $_(ittime) 1] - 1}]
      }
    }
    {*}$_(outcmd) [set _(m) [timerate $_(c) {*}$_(ittime)]]
    lappend _(itm) $_(m)
    {*}$_(outcmd) ""
  }
  if {$_(-from-run)} {
    _test_out_total
  }
}

}; # end of namespace ::tclTestPerf
Changes to tests/aaa_exit.test.
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

if {"::tcltest" ni [namespace children]} {
    package require tcltest 2.5
    namespace import -force ::tcltest::*
}

test exit-1.1 {normal, quick exit} {
     set f [open "|[interpreter] << \"exec [interpreter] << {set ::env(TCL_FINALIZE_ON_EXIT) 0;exit}\"" r]
     set aft [after 1000 {set done "Quick exit hangs !!!"}]
     fileevent $f readable {after cancel $aft;set done OK}
     vwait done
     if {$done != "OK"} {
     	fconfigure $f -blocking 0
	close $f
     } else {
	if {[catch {close $f} err]} {
	    set done "Quick exit misbehaves: $err"
	}
     }
     set done
} OK

test exit-1.2 {full-finalized exit} {
     set f [open "|[interpreter] << \"exec [interpreter] << {set ::env(TCL_FINALIZE_ON_EXIT) 1;exit}\"" r]
     set aft [after 1000 {set done "Full-finalized exit hangs !!!"}]
     fileevent $f readable {after cancel $aft;set done OK}
     vwait done
     if {$done != "OK"} {
     	fconfigure $f -blocking 0
	close $f
     } else {
	if {[catch {close $f} err]} {
	    set done "Full-finalized exit misbehaves: $err"
	}
     }
     set done
} OK


# cleanup
::tcltest::cleanupTests
return







|
|
|
|
|
|

|



|
|



|
|
|
|
|
|

|



|
|






13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

if {"::tcltest" ni [namespace children]} {
    package require tcltest 2.5
    namespace import -force ::tcltest::*
}

test exit-1.1 {normal, quick exit} {
    set f [open "|[interpreter] << \"exec [interpreter] << {set ::env(TCL_FINALIZE_ON_EXIT) 0;exit}\"" r]
    set aft [after 1000 {set done "Quick exit hangs !!!"}]
    fileevent $f readable {after cancel $aft;set done OK}
    vwait done
    if {$done != "OK"} {
	fconfigure $f -blocking 0
	close $f
    } else {
	if {[catch {close $f} err]} {
	    set done "Quick exit misbehaves: $err"
	}
    }
    set done
} OK

test exit-1.2 {full-finalized exit} {
    set f [open "|[interpreter] << \"exec [interpreter] << {set ::env(TCL_FINALIZE_ON_EXIT) 1;exit}\"" r]
    set aft [after 1000 {set done "Full-finalized exit hangs !!!"}]
    fileevent $f readable {after cancel $aft;set done OK}
    vwait done
    if {$done != "OK"} {
	fconfigure $f -blocking 0
	close $f
    } else {
	if {[catch {close $f} err]} {
	    set done "Full-finalized exit misbehaves: $err"
	}
    }
    set done
} OK


# cleanup
::tcltest::cleanupTests
return
Changes to tests/assemble.test.
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
	eval [list assemble {push hello}]
    }
    -result hello
}
test assemble-6.4 {push4} {
    -body {
	proc x {} "
            [fillTables]
            assemble {push hello}
        "
	x
    }
    -cleanup {
	rename x {}
    }
    -result hello
}







|
|
|







277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
	eval [list assemble {push hello}]
    }
    -result hello
}
test assemble-6.4 {push4} {
    -body {
	proc x {} "
	    [fillTables]
	    assemble {push hello}
	"
	x
    }
    -cleanup {
	rename x {}
    }
    -result hello
}
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
    -result able
    -cleanup {rename x {}}
}
test assemble-8.7 {load4} {
    -body {
	proc x {a} "
	    [fillTables]
            set b \$a
            assemble {load b}
        "
	x able
    }
    -result able
    -cleanup {rename x {}}
}
test assemble-8.8 {loadArray1} {
    -body {







|
|
|







862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
    -result able
    -cleanup {rename x {}}
}
test assemble-8.7 {load4} {
    -body {
	proc x {a} "
	    [fillTables]
	    set b \$a
	    assemble {load b}
	"
	x able
    }
    -result able
    -cleanup {rename x {}}
}
test assemble-8.8 {loadArray1} {
    -body {
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
    }
    -result charlie
    -cleanup {rename x {}}
}
test assemble-8.9 {loadArray4} {
    -body "
	proc x {} {
            [fillTables]
	    set able(baker) charlie
	    assemble {
		push baker
		loadArray able
	    }
	}
	x







|







887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
    }
    -result charlie
    -cleanup {rename x {}}
}
test assemble-8.9 {loadArray4} {
    -body "
	proc x {} {
	    [fillTables]
	    set able(baker) charlie
	    assemble {
		push baker
		loadArray able
	    }
	}
	x
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
    }
    -result {hello, world}
    -cleanup {rename x {}}
}
test assemble-8.11 {append4} {
    -body {
	proc x {} "
            [fillTables]
	    set y {hello, }
	    assemble {
		push world; append y
	    }
	"
	x
    }







|







915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
    }
    -result {hello, world}
    -cleanup {rename x {}}
}
test assemble-8.11 {append4} {
    -body {
	proc x {} "
	    [fillTables]
	    set y {hello, }
	    assemble {
		push world; append y
	    }
	"
	x
    }
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
    }
    -result {hello, world}
    -cleanup {rename x {}}
}
test assemble-8.13 {appendArray4} {
    -body {
	proc x {} "
            [fillTables]
	    set y(z) {hello, }
	    assemble {
		push z; push world; appendArray y
	    }
	"
	x
    }







|







942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
    }
    -result {hello, world}
    -cleanup {rename x {}}
}
test assemble-8.13 {appendArray4} {
    -body {
	proc x {} "
	    [fillTables]
	    set y(z) {hello, }
	    assemble {
		push z; push world; appendArray y
	    }
	"
	x
    }
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
    }
    -result {hello, world}
    -cleanup {rename x {}}
}
test assemble-8.15 {lappend4} {
    -body {
	proc x {} "
            [fillTables]
	    set y {hello,}
	    assemble {
		push world; lappend y
	    }
	"
	x
    }







|







969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
    }
    -result {hello, world}
    -cleanup {rename x {}}
}
test assemble-8.15 {lappend4} {
    -body {
	proc x {} "
	    [fillTables]
	    set y {hello,}
	    assemble {
		push world; lappend y
	    }
	"
	x
    }
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
    }
    -result {hello, world}
    -cleanup {rename x {}}
}
test assemble-8.17 {lappendArray4} {
    -body {
	proc x {} "
            [fillTables]
	    set y(z) {hello,}
	    assemble {
		push z; push world; lappendArray y
	    }
	"
	x
    }







|







996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
    }
    -result {hello, world}
    -cleanup {rename x {}}
}
test assemble-8.17 {lappendArray4} {
    -body {
	proc x {} "
	    [fillTables]
	    set y(z) {hello,}
	    assemble {
		push z; push world; lappendArray y
	    }
	"
	x
    }
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
    }
    -result {test}
    -cleanup {rename x {}}
}
test assemble-8.19 {store4} {
    -body {
	proc x {} "
            [fillTables]
	    assemble {
		push test; store y
	    }
            set y
	"
	x
    }
    -result test
    -cleanup {rename x {}}
}
test assemble-8.20 {storeArray1} {







|



|







1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
    }
    -result {test}
    -cleanup {rename x {}}
}
test assemble-8.19 {store4} {
    -body {
	proc x {} "
	    [fillTables]
	    assemble {
		push test; store y
	    }
	    set y
	"
	x
    }
    -result test
    -cleanup {rename x {}}
}
test assemble-8.20 {storeArray1} {
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
    }
    -result test
    -cleanup {rename x {}}
}
test assemble-8.21 {storeArray4} {
    -body {
	proc x {} "
            [fillTables]
	    assemble {
		push z; push test; storeArray y
	    }
	"
	x
    }
    -result test







|







1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
    }
    -result test
    -cleanup {rename x {}}
}
test assemble-8.21 {storeArray4} {
    -body {
	proc x {} "
	    [fillTables]
	    assemble {
		push z; push test; storeArray y
	    }
	"
	x
    }
    -result test
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
    -result 8
    -cleanup {rename x {}}
}
test assemble-12.6 {incr, stupid stack restriction} {
    -body {
	proc x {} "
	    [fillTables]
            set y 5
            assemble {push 3; incr y}
        "
	list [catch {x} result] $result $errorCode
    }
    -result {1 {operand does not fit in one byte} {TCL ASSEM 1BYTE}}
    -cleanup {unset result; rename x {}}
}

# assemble-13 -- ASSEM_LVT1_SINT1 - incrImm and incrArrayImm







|
|
|







1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
    -result 8
    -cleanup {rename x {}}
}
test assemble-12.6 {incr, stupid stack restriction} {
    -body {
	proc x {} "
	    [fillTables]
	    set y 5
	    assemble {push 3; incr y}
	"
	list [catch {x} result] $result $errorCode
    }
    -result {1 {operand does not fit in one byte} {TCL ASSEM 1BYTE}}
    -cleanup {unset result; rename x {}}
}

# assemble-13 -- ASSEM_LVT1_SINT1 - incrImm and incrArrayImm
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
    -result 8
    -cleanup {rename x {}}
}
test assemble-13.9 {incrImm, stupid stack restriction} {
    -body {
	proc x {} "
	    [fillTables]
            set y 5
            assemble {incrImm y 3}
        "
	list [catch {x} result] $result $errorCode
    }
    -result {1 {operand does not fit in one byte} {TCL ASSEM 1BYTE}}
    -cleanup {unset result; rename x {}}
}

# assemble-14 -- ASSEM_SINT1 (incrArrayStkImm and incrStkImm)







|
|
|







1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
    -result 8
    -cleanup {rename x {}}
}
test assemble-13.9 {incrImm, stupid stack restriction} {
    -body {
	proc x {} "
	    [fillTables]
	    set y 5
	    assemble {incrImm y 3}
	"
	list [catch {x} result] $result $errorCode
    }
    -result {1 {operand does not fit in one byte} {TCL ASSEM 1BYTE}}
    -cleanup {unset result; rename x {}}
}

# assemble-14 -- ASSEM_SINT1 (incrArrayStkImm and incrStkImm)
Changes to tests/autoMkindex.test.
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
    proc pub_one {args} {return "one: $args"}
    proc pub_two {args} {return "two: $args"}
}
proc buried::within {args} {return "within: $args"}

namespace eval buried {
    namespace eval under {
        proc neath {args} {return "neath: $args"}
    }
    namespace eval ::buried {
        proc relative {args} {return "relative: $args"}
        proc ::top {args} {return "top: $args"}
        proc ::buried::explicit {args} {return "explicit: $args"}
    }
}

# With proper hooks, we should be able to support other commands that create
# procedures

proc buried::myproc {name body args} {







|


|
|
|







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
    proc pub_one {args} {return "one: $args"}
    proc pub_two {args} {return "two: $args"}
}
proc buried::within {args} {return "within: $args"}

namespace eval buried {
    namespace eval under {
	proc neath {args} {return "neath: $args"}
    }
    namespace eval ::buried {
	proc relative {args} {return "relative: $args"}
	proc ::top {args} {return "top: $args"}
	proc ::buried::explicit {args} {return "explicit: $args"}
    }
}

# With proper hooks, we should be able to support other commands that create
# procedures

proc buried::myproc {name body args} {
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
} {1}
set element "{source -encoding utf-8 [file join . autoMkindex.tcl]}"
test autoMkindex-1.3 {examine tclIndex} -setup {
    file delete tclIndex
} -body {
    auto_mkindex . autoMkindex.tcl
    namespace eval tcl_autoMkindex_tmp {
        set dir "."
        variable auto_index
        source tclIndex
        set ::result ""
        foreach elem [lsort [array names auto_index]] {
            lappend ::result [list $elem $auto_index($elem)]
        }
    }
    return $result
} -cleanup {
    namespace delete tcl_autoMkindex_tmp
} -result "{::buried::explicit $element} {::buried::inside $element} {{::buried::my proc} $element} {::buried::mycmd1 $element} {::buried::mycmd4 $element} {::buried::myproc $element} {::buried::pub_one $element} {::buried::pub_two $element} {::buried::relative $element} {::buried::under::neath $element} {::buried::within $element} {::parent::child::test $element} {indented $element} {normal $element} {top $element}"

test autoMkindex-2.1 {commands on the autoload path can be imported} -setup {
    file delete tclIndex
    interp create child
} -body {
    auto_mkindex . autoMkindex.tcl
    child eval {
        namespace eval blt {}
        set auto_path [linsert $auto_path 0 .]
        set info [list [catch {namespace import buried::*} result] $result]
        foreach name [lsort [info commands pub_*]] {
            lappend info $name [namespace origin $name]
        }
        return $info
    }
} -cleanup {
    interp delete child
} -result "0 {} pub_one ::buried::pub_one pub_two ::buried::pub_two"

# Test auto_mkindex hooks








|
|
|
|
|
|
|












|
|
|
|
|
|
|







127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
} {1}
set element "{source -encoding utf-8 [file join . autoMkindex.tcl]}"
test autoMkindex-1.3 {examine tclIndex} -setup {
    file delete tclIndex
} -body {
    auto_mkindex . autoMkindex.tcl
    namespace eval tcl_autoMkindex_tmp {
	set dir "."
	variable auto_index
	source tclIndex
	set ::result ""
	foreach elem [lsort [array names auto_index]] {
	    lappend ::result [list $elem $auto_index($elem)]
	}
    }
    return $result
} -cleanup {
    namespace delete tcl_autoMkindex_tmp
} -result "{::buried::explicit $element} {::buried::inside $element} {{::buried::my proc} $element} {::buried::mycmd1 $element} {::buried::mycmd4 $element} {::buried::myproc $element} {::buried::pub_one $element} {::buried::pub_two $element} {::buried::relative $element} {::buried::under::neath $element} {::buried::within $element} {::parent::child::test $element} {indented $element} {normal $element} {top $element}"

test autoMkindex-2.1 {commands on the autoload path can be imported} -setup {
    file delete tclIndex
    interp create child
} -body {
    auto_mkindex . autoMkindex.tcl
    child eval {
	namespace eval blt {}
	set auto_path [linsert $auto_path 0 .]
	set info [list [catch {namespace import buried::*} result] $result]
	foreach name [lsort [info commands pub_*]] {
	    lappend info $name [namespace origin $name]
	}
	return $info
    }
} -cleanup {
    interp delete child
} -result "0 {} pub_one ::buried::pub_one pub_two ::buried::pub_two"

# Test auto_mkindex hooks

190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
	variable index
	variable scriptFile
	append index [list set auto_index([fullname $name])] \
		" \[list source -encoding utf-8 \[file join \$dir [list $scriptFile]\]\]\n"
    }
    auto_mkindex . autoMkindex.tcl
    namespace eval tcl_autoMkindex_tmp {
        set dir "."
        variable auto_index
        source tclIndex
        set ::result ""
        foreach elem [lsort [array names auto_index]] {
            lappend ::result [list $elem $auto_index($elem)]
        }
	return $::result
    }
} -cleanup {
    namespace delete tcl_autoMkindex_tmp
    # Reset initCommands to avoid trashing other tests
    AutoMkindexTestReset
} -result "{::buried::explicit $element} {::buried::inside $element} {{::buried::my proc} $element} {::buried::mycmd1 $element} {::buried::mycmd2 $element} {::buried::mycmd4 $element} {::buried::myproc $element} {::buried::pub_one $element} {::buried::pub_two $element} {::buried::relative $element} {::buried::under::neath $element} {::buried::within $element} {::parent::child::test $element} {indented $element} {mycmd3 $element} {normal $element} {top $element}"
test autoMkindex-3.3 {auto_mkindex_parser::command} -setup {
    file delete tclIndex
} -constraints {knownBug} -body {
    auto_mkindex_parser::command {buried::my proc} {name args} {
	variable index
	variable scriptFile
	puts "my proc $name"
	append index [list set auto_index([fullname $name])] \
		" \[list source -encoding utf-8 \[file join \$dir [list $scriptFile]\]\]\n"
    }
    auto_mkindex . autoMkindex.tcl
    namespace eval tcl_autoMkindex_tmp {
        set dir "."
        variable auto_index
        source tclIndex
        set ::result ""
        foreach elem [lsort [array names auto_index]] {
            lappend ::result [list $elem $auto_index($elem)]
        }
    }
    list [lsearch -inline $::result *mycmd4*] \
	[lsearch -inline $::result *mycmd5*] \
	[lsearch -inline $::result *mycmd6*]
} -cleanup {
    namespace delete tcl_autoMkindex_tmp
    # Reset initCommands to avoid trashing other tests







|
|
|
|
|
|
|



















|
|
|
|
|
|
|







190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
	variable index
	variable scriptFile
	append index [list set auto_index([fullname $name])] \
		" \[list source -encoding utf-8 \[file join \$dir [list $scriptFile]\]\]\n"
    }
    auto_mkindex . autoMkindex.tcl
    namespace eval tcl_autoMkindex_tmp {
	set dir "."
	variable auto_index
	source tclIndex
	set ::result ""
	foreach elem [lsort [array names auto_index]] {
	    lappend ::result [list $elem $auto_index($elem)]
	}
	return $::result
    }
} -cleanup {
    namespace delete tcl_autoMkindex_tmp
    # Reset initCommands to avoid trashing other tests
    AutoMkindexTestReset
} -result "{::buried::explicit $element} {::buried::inside $element} {{::buried::my proc} $element} {::buried::mycmd1 $element} {::buried::mycmd2 $element} {::buried::mycmd4 $element} {::buried::myproc $element} {::buried::pub_one $element} {::buried::pub_two $element} {::buried::relative $element} {::buried::under::neath $element} {::buried::within $element} {::parent::child::test $element} {indented $element} {mycmd3 $element} {normal $element} {top $element}"
test autoMkindex-3.3 {auto_mkindex_parser::command} -setup {
    file delete tclIndex
} -constraints {knownBug} -body {
    auto_mkindex_parser::command {buried::my proc} {name args} {
	variable index
	variable scriptFile
	puts "my proc $name"
	append index [list set auto_index([fullname $name])] \
		" \[list source -encoding utf-8 \[file join \$dir [list $scriptFile]\]\]\n"
    }
    auto_mkindex . autoMkindex.tcl
    namespace eval tcl_autoMkindex_tmp {
	set dir "."
	variable auto_index
	source tclIndex
	set ::result ""
	foreach elem [lsort [array names auto_index]] {
	    lappend ::result [list $elem $auto_index($elem)]
	}
    }
    list [lsearch -inline $::result *mycmd4*] \
	[lsearch -inline $::result *mycmd5*] \
	[lsearch -inline $::result *mycmd6*]
} -cleanup {
    namespace delete tcl_autoMkindex_tmp
    # Reset initCommands to avoid trashing other tests
Changes to tests/basic.test.
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
catch {rename cmd ""}
unset -nocomplain x

test basic-1.1 {Tcl_CreateInterp, creates interp's global namespace} {
    catch {interp delete test_interp}
    interp create test_interp
    interp eval test_interp {
        namespace eval test_ns_basic {
            proc p {} {
                return [namespace current]
            }
        }
    }
    list [interp eval test_interp {test_ns_basic::p}] \
         [interp delete test_interp]
} {::test_ns_basic {}}

test basic-2.1 {TclHideUnsafeCommands} {emptyTest} {
} {}

test basic-3.1 {Tcl_CallWhenDeleted: see dcall.test} {emptyTest} {
} {}







|
|
|
|
|


|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
catch {rename cmd ""}
unset -nocomplain x

test basic-1.1 {Tcl_CreateInterp, creates interp's global namespace} {
    catch {interp delete test_interp}
    interp create test_interp
    interp eval test_interp {
	namespace eval test_ns_basic {
	    proc p {} {
		return [namespace current]
	    }
	}
    }
    list [interp eval test_interp {test_ns_basic::p}] \
	 [interp delete test_interp]
} {::test_ns_basic {}}

test basic-2.1 {TclHideUnsafeCommands} {emptyTest} {
} {}

test basic-3.1 {Tcl_CallWhenDeleted: see dcall.test} {emptyTest} {
} {}
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
test basic-9.1 {Tcl_DeleteInterp: see interp.test} {emptyTest} {
} {}

test basic-10.1 {DeleteInterpProc, destroys interp's global namespace} {
    catch {interp delete test_interp}
    interp create test_interp
    interp eval test_interp {
        namespace eval test_ns_basic {
            namespace export p
            proc p {} {
                return [namespace current]
            }
        }
        namespace eval test_ns_2 {
            namespace import ::test_ns_basic::p
            variable v 27
            proc q {} {
                variable v
                return "[p] $v"
            }
        }
    }
    list [interp eval test_interp {test_ns_2::q}] \
         [interp eval test_interp {namespace delete ::}] \
         [catch {interp eval test_interp {set a 123}} msg] $msg \
         [interp delete test_interp]
} {{::test_ns_basic 27} {} 1 {invalid command name "set"} {}}

test basic-11.1 {HiddenCmdsDeleteProc, invalidate cached refs to deleted hidden cmd} {
    catch {interp delete test_interp}
    interp create test_interp
    interp eval test_interp {
        proc p {} {
            return 27
        }
    }
    interp alias {} localP test_interp p
    list [interp eval test_interp {p}] \
         [localP] \
         [test_interp hide p] \
         [catch {localP} msg] $msg \
         [interp delete test_interp] \
         [catch {localP} msg] $msg
} {27 27 {} 1 {invalid command name "p"} {} 1 {invalid command name "localP"}}

# NB: More tests about hide/expose are found in interp.test

test basic-12.1 {Tcl_HideCommand, names of hidden cmds can't have namespace qualifiers} {
    catch {interp delete test_interp}
    interp create test_interp
    interp eval test_interp {
        namespace eval test_ns_basic {
            proc p {} {
                return [namespace current]
            }
        }
    }
    list [catch {test_interp hide test_ns_basic::p x} msg] $msg \
	 [catch {test_interp hide x test_ns_basic::p} msg1] $msg1 \
         [interp delete test_interp]
} {1 {can only hide global namespace commands (use rename then hide)} 1 {cannot use namespace qualifiers in hidden command token (rename)} {}}

test basic-12.2 {Tcl_HideCommand, a hidden cmd remembers its containing namespace} {
    catch {namespace delete test_ns_basic}
    catch {rename cmd ""}
    proc cmd {} {   ;# note that this is global
        return [namespace current]
    }
    namespace eval test_ns_basic {
        proc hideCmd {} {
            interp hide {} cmd
        }
        proc exposeCmd {} {
            interp expose {} cmd
        }
        proc callCmd {} {
            cmd
        }
    }
    list [test_ns_basic::callCmd] \
         [test_ns_basic::hideCmd] \
         [catch {cmd} msg] $msg \
         [test_ns_basic::exposeCmd] \
         [test_ns_basic::callCmd] \
         [namespace delete test_ns_basic]
} {:: {} 1 {invalid command name "cmd"} {} :: {}}

test basic-13.1 {Tcl_ExposeCommand, a command stays in the global namespace and cannot go to another namespace} {
    catch {namespace delete test_ns_basic}
    catch {rename cmd ""}
    proc cmd {} {   ;# note that this is global
        return [namespace current]
    }
    namespace eval test_ns_basic {
        proc hideCmd {} {
            interp hide {} cmd
        }
        proc exposeCmdFailing {} {
            interp expose {} cmd ::test_ns_basic::newCmd
        }
        proc exposeCmdWorkAround {} {
            interp expose {} cmd;
	    rename cmd ::test_ns_basic::newCmd;
        }
        proc callCmd {} {
            cmd
        }
    }
    list [test_ns_basic::callCmd] \
         [test_ns_basic::hideCmd] \
         [catch {test_ns_basic::exposeCmdFailing} msg] $msg \
         [test_ns_basic::exposeCmdWorkAround] \
         [test_ns_basic::newCmd] \
         [namespace delete test_ns_basic]
} {:: {} 1 {cannot expose to a namespace (use expose to toplevel, then rename)} {} ::test_ns_basic {}}
test basic-13.2 {Tcl_ExposeCommand, invalidate cached refs to cmd now being exposed} {
    catch {rename p ""}
    catch {rename cmd ""}
    proc p {} {
        cmd
    }
    proc cmd {} {
        return 42
    }
    list [p] \
         [interp hide {} cmd] \
         [proc cmd {} {return Hello}] \
         [cmd] \
         [rename cmd ""] \
         [interp expose {} cmd] \
         [p]
} {42 {} {} Hello {} {} 42}

test basic-14.1 {Tcl_CreateCommand, new cmd goes into a namespace specified in its name, if any} {testcreatecommand} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    list [testcreatecommand create] \
	 [test_ns_basic::createdcommand] \
	 [testcreatecommand delete]
} {{} {CreatedCommandProc in ::test_ns_basic} {}}
test basic-14.2 {Tcl_CreateCommand, namespace code ignore single ":"s in middle or end of names} {testcreatecommand} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {rename value:at: ""}
    list [testcreatecommand create2] \
	 [value:at:] \
	 [testcreatecommand delete2]
} {{} {CreatedCommandProc2 in ::} {}}

test basic-15.1 {Tcl_CreateObjCommand, new cmd goes into a namespace specified in its name, if any} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_basic {}
    proc test_ns_basic::cmd {} {  ;# proc requires that ns already exist
        return [namespace current]
    }
    list [test_ns_basic::cmd] \
         [namespace delete test_ns_basic]
} {::test_ns_basic {}}
test basic-15.2 {Tcl_CreateObjCommand, Bug 0e4d88b650} -setup {
    proc deleter {ns args} {
        namespace delete $ns
    }
    namespace eval n {
        proc p {} {}
    }
    trace add command n::p delete [list [namespace which deleter] [namespace current]::n]
} -body {
    proc n::p {} {}
} -cleanup {
    namespace delete n
    rename deleter {}
}


test basic-16.1 {InvokeStringCommand} {emptyTest} {
} {}

test basic-17.1 {InvokeObjCommand} {emptyTest} {
} {}

test basic-18.1 {TclRenameCommand, name of existing cmd can have namespace qualifiers} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {rename cmd ""}
    namespace eval test_ns_basic {
        proc p {} {
            return "p in [namespace current]"
        }
    }
    list [test_ns_basic::p] \
         [rename test_ns_basic::p test_ns_basic::q] \
         [test_ns_basic::q]
} {{p in ::test_ns_basic} {} {p in ::test_ns_basic}}
test basic-18.2 {TclRenameCommand, existing cmd must be found} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    list [catch {rename test_ns_basic::p test_ns_basic::q} msg] $msg
} {1 {can't rename "test_ns_basic::p": command doesn't exist}}
test basic-18.3 {TclRenameCommand, delete cmd if new name is empty} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_basic {
        proc p {} {
            return "p in [namespace current]"
        }
    }
    list [info commands test_ns_basic::*] \
         [rename test_ns_basic::p ""] \
         [info commands test_ns_basic::*]
} {::test_ns_basic::p {} {}}
test basic-18.4 {TclRenameCommand, bad new name} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_basic {
        proc p {} {
            return "p in [namespace current]"
        }
    }
    rename test_ns_basic::p :::george::martha
} {}
test basic-18.5 {TclRenameCommand, new name must not already exist} -setup {
    if {![llength [info commands :::george::martha]]} {
        catch {namespace delete {*}[namespace children :: test_ns_*]}
        namespace eval test_ns_basic {
            proc p {} {
                return "p in [namespace current]"
            }
        }
        rename test_ns_basic::p :::george::martha
    }
} -body {
    namespace eval test_ns_basic {
        proc q {} {
            return 42
        }
    }
    list [catch {rename test_ns_basic::q :::george::martha} msg] $msg
} -result {1 {can't rename to ":::george::martha": command already exists}}
test basic-18.6 {TclRenameCommand, check for command shadowing by newly renamed cmd} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {rename p ""}
    catch {rename q ""}
    proc p {} {
        return "p in [namespace current]"
    }
    proc q {} {
        return "q in [namespace current]"
    }
    namespace eval test_ns_basic {
        proc callP {} {
            p
        }
    }
    list [test_ns_basic::callP] \
         [rename q test_ns_basic::p] \
         [test_ns_basic::callP]
} {{p in ::} {} {q in ::test_ns_basic}}

test basic-19.1 {Tcl_SetCommandInfo} {emptyTest} {
} {}

test basic-20.1 {Tcl_GetCommandInfo, names for commands created inside namespaces} {testcmdtoken} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {rename p ""}
    catch {rename q ""}
    unset -nocomplain x
    set x [namespace eval test_ns_basic::test_ns_basic2 {
        # the following creates a cmd in the global namespace
        testcmdtoken create p
    }]
    list [testcmdtoken name $x] \
         [rename ::p q] \
         [testcmdtoken name $x]
} {{p ::p} {} {q ::q}}
test basic-20.2 {Tcl_GetCommandInfo, names for commands created outside namespaces} {testcmdtoken} {
    catch {rename q ""}
    set x [testcmdtoken create test_ns_basic::test_ns_basic2::p]
    list [testcmdtoken name $x] \
         [rename test_ns_basic::test_ns_basic2::p q] \
         [testcmdtoken name $x]
} {{p ::test_ns_basic::test_ns_basic2::p} {} {q ::q}}
test basic-20.3 {Tcl_GetCommandInfo, #-quoting} testcmdtoken {
    catch {rename \# ""}
    set x [testcmdtoken create \#]
    return [testcmdtoken name $x]
} {{#} ::#}

test basic-21.1 {Tcl_GetCommandName} {emptyTest} {
} {}

test basic-22.1 {Tcl_GetCommandFullName} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_basic1 {
        namespace export cmd*
        proc cmd1 {} {}
        proc cmd2 {} {}
    }
    namespace eval test_ns_basic2 {
        namespace export *
        namespace import ::test_ns_basic1::*
        proc p {} {}
    }
    namespace eval test_ns_basic3 {
        namespace import ::test_ns_basic2::*
        proc q {} {}
        list [namespace which -command foreach] \
             [namespace which -command q] \
             [namespace which -command p] \
             [namespace which -command cmd1] \
             [namespace which -command ::test_ns_basic2::cmd2]
    }
} {::foreach ::test_ns_basic3::q ::test_ns_basic3::p ::test_ns_basic3::cmd1 ::test_ns_basic2::cmd2}

test basic-23.1 {Tcl_DeleteCommand} {emptyTest} {
} {}

test basic-24.1 {Tcl_DeleteCommandFromToken, invalidate all compiled code if cmd has compile proc} {
    catch {interp delete test_interp}
    unset -nocomplain x
    interp create test_interp
    interp eval test_interp {
        proc useSet {} {
            return [set a 123]
        }
    }
    set x [interp eval test_interp {useSet}]
    interp eval test_interp {
        rename set ""
        proc set {args} {
            return "set called with $args"
        }
    }
    list $x \
         [interp eval test_interp {useSet}] \
         [interp delete test_interp]
} {123 {set called with a 123} {}}
test basic-24.2 {Tcl_DeleteCommandFromToken, deleting commands changes command epoch} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {rename p ""}
    proc p {} {
        return "global p"
    }
    namespace eval test_ns_basic {
        proc p {} {
            return "namespace p"
        }
        proc callP {} {
            p
        }
    }
    list [test_ns_basic::callP] \
         [rename test_ns_basic::p ""] \
         [test_ns_basic::callP]
} {{namespace p} {} {global p}}
test basic-24.3 {Tcl_DeleteCommandFromToken, delete imported cmds that refer to a deleted cmd} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {rename p ""}
    namespace eval test_ns_basic {
        namespace export p
        proc p {} {return 42}
    }
    namespace eval test_ns_basic2 {
        namespace import ::test_ns_basic::*
        proc callP {} {
            p
        }
    }
    list [test_ns_basic2::callP] \
         [info commands test_ns_basic2::*] \
         [rename test_ns_basic::p ""] \
         [catch {test_ns_basic2::callP} msg] $msg \
         [info commands test_ns_basic2::*]
} {42 {::test_ns_basic2::callP ::test_ns_basic2::p} {} 1 {invalid command name "p"} ::test_ns_basic2::callP}

test basic-25.1 {TclCleanupCommand} {emptyTest} {
} {}

test basic-26.1 {Tcl_EvalObj: preserve object while evaling it} -setup {
    proc myHandler {msg options} {







|
|
|
|
|
|
|
|
|
|
|
|
|
|


|
|
|






|
|
|



|
|
|
|
|








|
|
|
|
|



|






|


|
|
|
|
|
|
|
|
|


|
|
|
|
|






|


|
|
|
|
|
|
|
|

|
|
|
|


|
|
|
|
|





|


|


|
|
|
|
|
|




















|


|



|


|




















|
|
|


|
|








|
|
|


|
|




|
|
|





|
|
|
|
|
|
|



|
|
|








|


|


|
|
|


|
|











|
|


|
|





|
|













|
|
|


|
|
|


|
|
|
|
|
|
|











|
|
|



|
|
|
|


|
|





|


|
|
|
|
|
|


|
|





|
|


|
|
|
|


|
|
|
|







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
test basic-9.1 {Tcl_DeleteInterp: see interp.test} {emptyTest} {
} {}

test basic-10.1 {DeleteInterpProc, destroys interp's global namespace} {
    catch {interp delete test_interp}
    interp create test_interp
    interp eval test_interp {
	namespace eval test_ns_basic {
	    namespace export p
	    proc p {} {
		return [namespace current]
	    }
	}
	namespace eval test_ns_2 {
	    namespace import ::test_ns_basic::p
	    variable v 27
	    proc q {} {
		variable v
		return "[p] $v"
	    }
	}
    }
    list [interp eval test_interp {test_ns_2::q}] \
	 [interp eval test_interp {namespace delete ::}] \
	 [catch {interp eval test_interp {set a 123}} msg] $msg \
	 [interp delete test_interp]
} {{::test_ns_basic 27} {} 1 {invalid command name "set"} {}}

test basic-11.1 {HiddenCmdsDeleteProc, invalidate cached refs to deleted hidden cmd} {
    catch {interp delete test_interp}
    interp create test_interp
    interp eval test_interp {
	proc p {} {
	    return 27
	}
    }
    interp alias {} localP test_interp p
    list [interp eval test_interp {p}] \
	 [localP] \
	 [test_interp hide p] \
	 [catch {localP} msg] $msg \
	 [interp delete test_interp] \
	 [catch {localP} msg] $msg
} {27 27 {} 1 {invalid command name "p"} {} 1 {invalid command name "localP"}}

# NB: More tests about hide/expose are found in interp.test

test basic-12.1 {Tcl_HideCommand, names of hidden cmds can't have namespace qualifiers} {
    catch {interp delete test_interp}
    interp create test_interp
    interp eval test_interp {
	namespace eval test_ns_basic {
	    proc p {} {
		return [namespace current]
	    }
	}
    }
    list [catch {test_interp hide test_ns_basic::p x} msg] $msg \
	 [catch {test_interp hide x test_ns_basic::p} msg1] $msg1 \
	 [interp delete test_interp]
} {1 {can only hide global namespace commands (use rename then hide)} 1 {cannot use namespace qualifiers in hidden command token (rename)} {}}

test basic-12.2 {Tcl_HideCommand, a hidden cmd remembers its containing namespace} {
    catch {namespace delete test_ns_basic}
    catch {rename cmd ""}
    proc cmd {} {   ;# note that this is global
	return [namespace current]
    }
    namespace eval test_ns_basic {
	proc hideCmd {} {
	    interp hide {} cmd
	}
	proc exposeCmd {} {
	    interp expose {} cmd
	}
	proc callCmd {} {
	    cmd
	}
    }
    list [test_ns_basic::callCmd] \
	 [test_ns_basic::hideCmd] \
	 [catch {cmd} msg] $msg \
	 [test_ns_basic::exposeCmd] \
	 [test_ns_basic::callCmd] \
	 [namespace delete test_ns_basic]
} {:: {} 1 {invalid command name "cmd"} {} :: {}}

test basic-13.1 {Tcl_ExposeCommand, a command stays in the global namespace and cannot go to another namespace} {
    catch {namespace delete test_ns_basic}
    catch {rename cmd ""}
    proc cmd {} {   ;# note that this is global
	return [namespace current]
    }
    namespace eval test_ns_basic {
	proc hideCmd {} {
	    interp hide {} cmd
	}
	proc exposeCmdFailing {} {
	    interp expose {} cmd ::test_ns_basic::newCmd
	}
	proc exposeCmdWorkAround {} {
	    interp expose {} cmd;
	    rename cmd ::test_ns_basic::newCmd;
	}
	proc callCmd {} {
	    cmd
	}
    }
    list [test_ns_basic::callCmd] \
	 [test_ns_basic::hideCmd] \
	 [catch {test_ns_basic::exposeCmdFailing} msg] $msg \
	 [test_ns_basic::exposeCmdWorkAround] \
	 [test_ns_basic::newCmd] \
	 [namespace delete test_ns_basic]
} {:: {} 1 {cannot expose to a namespace (use expose to toplevel, then rename)} {} ::test_ns_basic {}}
test basic-13.2 {Tcl_ExposeCommand, invalidate cached refs to cmd now being exposed} {
    catch {rename p ""}
    catch {rename cmd ""}
    proc p {} {
	cmd
    }
    proc cmd {} {
	return 42
    }
    list [p] \
	 [interp hide {} cmd] \
	 [proc cmd {} {return Hello}] \
	 [cmd] \
	 [rename cmd ""] \
	 [interp expose {} cmd] \
	 [p]
} {42 {} {} Hello {} {} 42}

test basic-14.1 {Tcl_CreateCommand, new cmd goes into a namespace specified in its name, if any} {testcreatecommand} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    list [testcreatecommand create] \
	 [test_ns_basic::createdcommand] \
	 [testcreatecommand delete]
} {{} {CreatedCommandProc in ::test_ns_basic} {}}
test basic-14.2 {Tcl_CreateCommand, namespace code ignore single ":"s in middle or end of names} {testcreatecommand} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {rename value:at: ""}
    list [testcreatecommand create2] \
	 [value:at:] \
	 [testcreatecommand delete2]
} {{} {CreatedCommandProc2 in ::} {}}

test basic-15.1 {Tcl_CreateObjCommand, new cmd goes into a namespace specified in its name, if any} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_basic {}
    proc test_ns_basic::cmd {} {  ;# proc requires that ns already exist
	return [namespace current]
    }
    list [test_ns_basic::cmd] \
	 [namespace delete test_ns_basic]
} {::test_ns_basic {}}
test basic-15.2 {Tcl_CreateObjCommand, Bug 0e4d88b650} -setup {
    proc deleter {ns args} {
	namespace delete $ns
    }
    namespace eval n {
	proc p {} {}
    }
    trace add command n::p delete [list [namespace which deleter] [namespace current]::n]
} -body {
    proc n::p {} {}
} -cleanup {
    namespace delete n
    rename deleter {}
}


test basic-16.1 {InvokeStringCommand} {emptyTest} {
} {}

test basic-17.1 {InvokeObjCommand} {emptyTest} {
} {}

test basic-18.1 {TclRenameCommand, name of existing cmd can have namespace qualifiers} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {rename cmd ""}
    namespace eval test_ns_basic {
	proc p {} {
	    return "p in [namespace current]"
	}
    }
    list [test_ns_basic::p] \
	 [rename test_ns_basic::p test_ns_basic::q] \
	 [test_ns_basic::q]
} {{p in ::test_ns_basic} {} {p in ::test_ns_basic}}
test basic-18.2 {TclRenameCommand, existing cmd must be found} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    list [catch {rename test_ns_basic::p test_ns_basic::q} msg] $msg
} {1 {can't rename "test_ns_basic::p": command doesn't exist}}
test basic-18.3 {TclRenameCommand, delete cmd if new name is empty} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_basic {
	proc p {} {
	    return "p in [namespace current]"
	}
    }
    list [info commands test_ns_basic::*] \
	 [rename test_ns_basic::p ""] \
	 [info commands test_ns_basic::*]
} {::test_ns_basic::p {} {}}
test basic-18.4 {TclRenameCommand, bad new name} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_basic {
	proc p {} {
	    return "p in [namespace current]"
	}
    }
    rename test_ns_basic::p :::george::martha
} {}
test basic-18.5 {TclRenameCommand, new name must not already exist} -setup {
    if {![llength [info commands :::george::martha]]} {
	catch {namespace delete {*}[namespace children :: test_ns_*]}
	namespace eval test_ns_basic {
	    proc p {} {
		return "p in [namespace current]"
	    }
	}
	rename test_ns_basic::p :::george::martha
    }
} -body {
    namespace eval test_ns_basic {
	proc q {} {
	    return 42
	}
    }
    list [catch {rename test_ns_basic::q :::george::martha} msg] $msg
} -result {1 {can't rename to ":::george::martha": command already exists}}
test basic-18.6 {TclRenameCommand, check for command shadowing by newly renamed cmd} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {rename p ""}
    catch {rename q ""}
    proc p {} {
	return "p in [namespace current]"
    }
    proc q {} {
	return "q in [namespace current]"
    }
    namespace eval test_ns_basic {
	proc callP {} {
	    p
	}
    }
    list [test_ns_basic::callP] \
	 [rename q test_ns_basic::p] \
	 [test_ns_basic::callP]
} {{p in ::} {} {q in ::test_ns_basic}}

test basic-19.1 {Tcl_SetCommandInfo} {emptyTest} {
} {}

test basic-20.1 {Tcl_GetCommandInfo, names for commands created inside namespaces} {testcmdtoken} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {rename p ""}
    catch {rename q ""}
    unset -nocomplain x
    set x [namespace eval test_ns_basic::test_ns_basic2 {
	# the following creates a cmd in the global namespace
	testcmdtoken create p
    }]
    list [testcmdtoken name $x] \
	 [rename ::p q] \
	 [testcmdtoken name $x]
} {{p ::p} {} {q ::q}}
test basic-20.2 {Tcl_GetCommandInfo, names for commands created outside namespaces} {testcmdtoken} {
    catch {rename q ""}
    set x [testcmdtoken create test_ns_basic::test_ns_basic2::p]
    list [testcmdtoken name $x] \
	 [rename test_ns_basic::test_ns_basic2::p q] \
	 [testcmdtoken name $x]
} {{p ::test_ns_basic::test_ns_basic2::p} {} {q ::q}}
test basic-20.3 {Tcl_GetCommandInfo, #-quoting} testcmdtoken {
    catch {rename \# ""}
    set x [testcmdtoken create \#]
    return [testcmdtoken name $x]
} {{#} ::#}

test basic-21.1 {Tcl_GetCommandName} {emptyTest} {
} {}

test basic-22.1 {Tcl_GetCommandFullName} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_basic1 {
	namespace export cmd*
	proc cmd1 {} {}
	proc cmd2 {} {}
    }
    namespace eval test_ns_basic2 {
	namespace export *
	namespace import ::test_ns_basic1::*
	proc p {} {}
    }
    namespace eval test_ns_basic3 {
	namespace import ::test_ns_basic2::*
	proc q {} {}
	list [namespace which -command foreach] \
	     [namespace which -command q] \
	     [namespace which -command p] \
	     [namespace which -command cmd1] \
	     [namespace which -command ::test_ns_basic2::cmd2]
    }
} {::foreach ::test_ns_basic3::q ::test_ns_basic3::p ::test_ns_basic3::cmd1 ::test_ns_basic2::cmd2}

test basic-23.1 {Tcl_DeleteCommand} {emptyTest} {
} {}

test basic-24.1 {Tcl_DeleteCommandFromToken, invalidate all compiled code if cmd has compile proc} {
    catch {interp delete test_interp}
    unset -nocomplain x
    interp create test_interp
    interp eval test_interp {
	proc useSet {} {
	    return [set a 123]
	}
    }
    set x [interp eval test_interp {useSet}]
    interp eval test_interp {
	rename set ""
	proc set {args} {
	    return "set called with $args"
	}
    }
    list $x \
	 [interp eval test_interp {useSet}] \
	 [interp delete test_interp]
} {123 {set called with a 123} {}}
test basic-24.2 {Tcl_DeleteCommandFromToken, deleting commands changes command epoch} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {rename p ""}
    proc p {} {
	return "global p"
    }
    namespace eval test_ns_basic {
	proc p {} {
	    return "namespace p"
	}
	proc callP {} {
	    p
	}
    }
    list [test_ns_basic::callP] \
	 [rename test_ns_basic::p ""] \
	 [test_ns_basic::callP]
} {{namespace p} {} {global p}}
test basic-24.3 {Tcl_DeleteCommandFromToken, delete imported cmds that refer to a deleted cmd} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {rename p ""}
    namespace eval test_ns_basic {
	namespace export p
	proc p {} {return 42}
    }
    namespace eval test_ns_basic2 {
	namespace import ::test_ns_basic::*
	proc callP {} {
	    p
	}
    }
    list [test_ns_basic2::callP] \
	 [info commands test_ns_basic2::*] \
	 [rename test_ns_basic::p ""] \
	 [catch {test_ns_basic2::callP} msg] $msg \
	 [info commands test_ns_basic2::*]
} {42 {::test_ns_basic2::callP ::test_ns_basic2::p} {} 1 {invalid command name "p"} ::test_ns_basic2::callP}

test basic-25.1 {TclCleanupCommand} {emptyTest} {
} {}

test basic-26.1 {Tcl_EvalObj: preserve object while evaling it} -setup {
    proc myHandler {msg options} {
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
} {}

test basic-36.1 {Tcl_EvalObjv, lookup of "unknown" command} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {interp delete test_interp}
    interp create test_interp
    interp eval test_interp {
        proc unknown {args} {
            return "global unknown"
        }
        namespace eval test_ns_basic {
            proc unknown {args} {
                return "namespace unknown"
            }
        }
    }
    list [interp alias test_interp newAlias test_interp doesntExist] \
         [catch {interp eval test_interp {newAlias}} msg] $msg \
         [interp delete test_interp]
} {newAlias 0 {global unknown} {}}

test basic-37.1 {Tcl_ExprString: see expr.test} {emptyTest} {
} {}

test basic-38.1 {Tcl_ExprObj} {emptyTest} {
} {}







|
|
|
|
|
|
|
|


|
|







529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
} {}

test basic-36.1 {Tcl_EvalObjv, lookup of "unknown" command} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {interp delete test_interp}
    interp create test_interp
    interp eval test_interp {
	proc unknown {args} {
	    return "global unknown"
	}
	namespace eval test_ns_basic {
	    proc unknown {args} {
		return "namespace unknown"
	    }
	}
    }
    list [interp alias test_interp newAlias test_interp doesntExist] \
	 [catch {interp eval test_interp {newAlias}} msg] $msg \
	 [interp delete test_interp]
} {newAlias 0 {global unknown} {}}

test basic-37.1 {Tcl_ExprString: see expr.test} {emptyTest} {
} {}

test basic-38.1 {Tcl_ExprObj} {emptyTest} {
} {}
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
			3   {*}$::l1

		# Comment again
	}
} {1 2 3 a {b b} c d}

test basic-48.2.$noComp {no expansion} $constraints {
        run {list $::l1 $::l2 [l3]}
} {{a {b b} c d} {e f {g g} h} {i j k {l l}}}

test basic-48.3.$noComp {expansion} $constraints {
        run {list {*}$::l1 $::l2 {*}[l3]}
} {a {b b} c d {e f {g g} h} i j k {l l}}

test basic-48.4.$noComp {expansion: really long cmd} $constraints {
        set cmd [list list]
        for {set t 0} {$t < 500} {incr t} {
            lappend cmd {{*}$::l1}
        }
        llength [run [join $cmd]]
} 2000

test basic-48.5.$noComp {expansion: error detection} -setup {
	set l "a {a b}x y"
} -constraints $constraints -body {
	run {list $::l1 {*}$l}
} -cleanup {
	unset l
} -returnCodes 1 -result {list element in braces followed by "x" instead of space}

test basic-48.6.$noComp {expansion: odd usage} $constraints {
        run {list {*}$::l1$::l2}
} {a {b b} c de f {g g} h}

test basic-48.7.$noComp {expansion: odd usage} -constraints $constraints -body {
        run {list {*}[l3]$::l1}
} -returnCodes 1 -result {list element in braces followed by "a" instead of space}

test basic-48.8.$noComp {expansion: odd usage} $constraints {
        run {list {*}hej$::l1}
} {heja {b b} c d}

test basic-48.9.$noComp {expansion: Not all {*} should trigger} $constraints {
	run {list {*}$::l1 \{*\}$::l2 "{*}$::l1" {{*} i j k}}
} {a {b b} c d {{*}e f {g g} h} {{*}a {b b} c d} {{*} i j k}}

test basic-48.10.$noComp {expansion: expansion of command word} -setup {
	set cmd [list string range jultomte]
} -constraints $constraints -body {
	run {{*}$cmd 2 6}
} -cleanup {
	unset cmd
} -result ltomt

test basic-48.11.$noComp {expansion: expansion into nothing} -setup {
        set cmd {}
        set bar {}
} -constraints $constraints -body {
        run {{*}$cmd {*}$bar}
} -cleanup {
	unset cmd bar
} -result {}

test basic-48.12.$noComp {expansion: odd usage} $constraints {
	run {list {*}$::l1 {*}"hej hopp" {*}$::l2}
} {a {b b} c d hej hopp e f {g g} h}

test basic-48.13.$noComp {expansion: odd usage} $constraints {
	run {list {*}$::l1 {*}{hej hopp} {*}$::l2}
} {a {b b} c d hej hopp e f {g g} h}

test basic-48.14.$noComp {expansion: hash command} -setup {
        catch {rename \# ""}
        set cmd "#"
    } -constraints $constraints -body {
           run { {*}$cmd apa bepa }
    } -cleanup {
	unset cmd
} -returnCodes 1 -result {invalid command name "#"}

test basic-48.15.$noComp {expansion: complex words} -setup {
            set a(x) [list a {b c} d e]
            set b x
            set c [list {f\ g h\ i j k} x y]
            set d {0\ 1 2 3}
    } -constraints $constraints -body {
            run { lappend d {*}$a($b) {*}[lindex $c 0] }
    } -cleanup {
	unset a b c d
} -result {{0 1} 2 3 a {b c} d e {f g} {h i} j k}

testConstraint memory [llength [info commands memory]]
test basic-48.16.$noComp {expansion: testing for leaks} -setup {
        proc getbytes {} {
            set lines [split [memory info] "\n"]
            lindex [lindex $lines 3] 3
        }
        # This test is made to stress the allocation, reallocation and
        # object reference management in Tcl_EvalEx.
        proc stress {} {
            set a x
            # Create free objects that should disappear
            set l [list 1$a 2$a 3$a 4$a 5$a 6$a 7$a]
            # A short number of words and a short result (8)
            set l [run {list {*}$l $a$a}]
            # A short number of words and a longer result (27)
            set l [run {list {*}$l $a$a {*}$l $a$a {*}$l $a$a}]
            # A short number of words and a longer result, with an error
            # This is to stress the cleanup in the error case
            if {![catch {run {_moo_ {*}$l $a$a {*}$l $a$a {*}$l}}]} {
                error "An error was expected in the previous statement"
            }
            # Many words
            set l [run {list {*}$l $a$a {*}$l $a$a \
                                 {*}$l $a$a {*}$l $a$a \
                                 {*}$l $a$a {*}$l $a$a \
                                 {*}$l $a$a {*}$l $a$a \
                                 {*}$l $a$a {*}$l $a$a \
                                 {*}$l $a$a {*}$l $a$a \
                                 {*}$l $a$a {*}$l $a$a \
                                 {*}$l $a$a {*}$l $a$a \
                                 {*}$l $a$a {*}$l $a$a \
                                 {*}$l $a$a}]

            if {[llength $l] != 19*28} {
                error "Bad Length: [llength $l] should be [expr {19*28}]"
            }
        }
    } -constraints [linsert $constraints 0 memory] -body {
        set end [getbytes]
        for {set i 0} {$i < 5} {incr i} {
            stress
            set tmp $end
            set end [getbytes]
        }
        set leak [expr {$end - $tmp}]
    } -cleanup {
	unset end i tmp
	rename getbytes {}
	rename stress {}
} -result 0

test basic-48.17.$noComp {expansion: object safety} -constraints $constraints -body {
            set third [expr {1.0/3.0}]
            set l [list $third $third]
            set x [run {list $third {*}$l $third}]
            set res [list]
            foreach t $x {
                lappend res [expr {$t * 3.0}]
            }
            set res
    } -cleanup {
        unset res t l x third
} -result {1.0 1.0 1.0 1.0}

test basic-48.18.$noComp {expansion: list semantics} -constraints $constraints -body {
        set badcmd {
            list a b
            set apa 10
        }
        set apa 0
        list [llength [run { {*}$badcmd }]] $apa
    } -cleanup {
	unset apa badcmd
} -result {5 0}

test basic-48.19.$noComp {expansion: error checking order} -body {
        set badlist "a {}x y"
        set a 0
        set b 0
        catch {run {list [incr a] {*}$badlist [incr b]}}
        list $a $b
    } -constraints $constraints -cleanup {
	unset badlist a b
} -result {1 0}

test basic-48.20.$noComp {expansion: odd case with word boundaries} $constraints {
    run {list {*}$::l1 {*}"hej hopp" {*}$::l2}
} {a {b b} c d hej hopp e f {g g} h}

test basic-48.21.$noComp {expansion: odd case with word boundaries} $constraints {
    run {list {*}$::l1 {*}{hej hopp} {*}$::l2}
} {a {b b} c d hej hopp e f {g g} h}

test basic-48.22.$noComp {expansion: odd case with word boundaries} -body {
    run {list {*}$::l1 {*}"hej hopp {*}$::l2}
} -constraints $constraints -returnCodes error -result {missing "}

test basic-48.23.$noComp {expansion: handle return codes} -constraints $constraints -body {
        set res {}
        for {set t 0} {$t < 10} {incr t} {
            run { {*}break }
        }
        lappend res $t

        for {set t 0} {$t < 10} {incr t} {
            run { {*}continue }
            set t 20
        }
        lappend res $t

        lappend res [catch { run { {*}{error Hejsan} } } err]
        lappend res $err
    } -cleanup {
	unset res t
} -result {0 10 1 Hejsan}

test basic-48.24.$noComp {expansion: empty not canonical list, regression test, bug [cc1e91552c]} -constraints $constraints -setup {
    unset -nocomplain a
} -body {







|



|



|
|
|
|
|











|



|



|















|
|

|













|
|

|





|
|
|
|

|






|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|

|
|
|
|
|
|
|







|
|
|
|
|
|
|
|

|



|
|
|
|
|
|





|
|
|
|
|

















|
|
|
|
|

|
|
|
|
|

|
|







756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
			3   {*}$::l1

		# Comment again
	}
} {1 2 3 a {b b} c d}

test basic-48.2.$noComp {no expansion} $constraints {
	run {list $::l1 $::l2 [l3]}
} {{a {b b} c d} {e f {g g} h} {i j k {l l}}}

test basic-48.3.$noComp {expansion} $constraints {
	run {list {*}$::l1 $::l2 {*}[l3]}
} {a {b b} c d {e f {g g} h} i j k {l l}}

test basic-48.4.$noComp {expansion: really long cmd} $constraints {
	set cmd [list list]
	for {set t 0} {$t < 500} {incr t} {
	    lappend cmd {{*}$::l1}
	}
	llength [run [join $cmd]]
} 2000

test basic-48.5.$noComp {expansion: error detection} -setup {
	set l "a {a b}x y"
} -constraints $constraints -body {
	run {list $::l1 {*}$l}
} -cleanup {
	unset l
} -returnCodes 1 -result {list element in braces followed by "x" instead of space}

test basic-48.6.$noComp {expansion: odd usage} $constraints {
	run {list {*}$::l1$::l2}
} {a {b b} c de f {g g} h}

test basic-48.7.$noComp {expansion: odd usage} -constraints $constraints -body {
	run {list {*}[l3]$::l1}
} -returnCodes 1 -result {list element in braces followed by "a" instead of space}

test basic-48.8.$noComp {expansion: odd usage} $constraints {
	run {list {*}hej$::l1}
} {heja {b b} c d}

test basic-48.9.$noComp {expansion: Not all {*} should trigger} $constraints {
	run {list {*}$::l1 \{*\}$::l2 "{*}$::l1" {{*} i j k}}
} {a {b b} c d {{*}e f {g g} h} {{*}a {b b} c d} {{*} i j k}}

test basic-48.10.$noComp {expansion: expansion of command word} -setup {
	set cmd [list string range jultomte]
} -constraints $constraints -body {
	run {{*}$cmd 2 6}
} -cleanup {
	unset cmd
} -result ltomt

test basic-48.11.$noComp {expansion: expansion into nothing} -setup {
	set cmd {}
	set bar {}
} -constraints $constraints -body {
	run {{*}$cmd {*}$bar}
} -cleanup {
	unset cmd bar
} -result {}

test basic-48.12.$noComp {expansion: odd usage} $constraints {
	run {list {*}$::l1 {*}"hej hopp" {*}$::l2}
} {a {b b} c d hej hopp e f {g g} h}

test basic-48.13.$noComp {expansion: odd usage} $constraints {
	run {list {*}$::l1 {*}{hej hopp} {*}$::l2}
} {a {b b} c d hej hopp e f {g g} h}

test basic-48.14.$noComp {expansion: hash command} -setup {
	catch {rename \# ""}
	set cmd "#"
    } -constraints $constraints -body {
	   run { {*}$cmd apa bepa }
    } -cleanup {
	unset cmd
} -returnCodes 1 -result {invalid command name "#"}

test basic-48.15.$noComp {expansion: complex words} -setup {
	    set a(x) [list a {b c} d e]
	    set b x
	    set c [list {f\ g h\ i j k} x y]
	    set d {0\ 1 2 3}
    } -constraints $constraints -body {
	    run { lappend d {*}$a($b) {*}[lindex $c 0] }
    } -cleanup {
	unset a b c d
} -result {{0 1} 2 3 a {b c} d e {f g} {h i} j k}

testConstraint memory [llength [info commands memory]]
test basic-48.16.$noComp {expansion: testing for leaks} -setup {
	proc getbytes {} {
	    set lines [split [memory info] "\n"]
	    lindex [lindex $lines 3] 3
	}
	# This test is made to stress the allocation, reallocation and
	# object reference management in Tcl_EvalEx.
	proc stress {} {
	    set a x
	    # Create free objects that should disappear
	    set l [list 1$a 2$a 3$a 4$a 5$a 6$a 7$a]
	    # A short number of words and a short result (8)
	    set l [run {list {*}$l $a$a}]
	    # A short number of words and a longer result (27)
	    set l [run {list {*}$l $a$a {*}$l $a$a {*}$l $a$a}]
	    # A short number of words and a longer result, with an error
	    # This is to stress the cleanup in the error case
	    if {![catch {run {_moo_ {*}$l $a$a {*}$l $a$a {*}$l}}]} {
		error "An error was expected in the previous statement"
	    }
	    # Many words
	    set l [run {list {*}$l $a$a {*}$l $a$a \
				 {*}$l $a$a {*}$l $a$a \
				 {*}$l $a$a {*}$l $a$a \
				 {*}$l $a$a {*}$l $a$a \
				 {*}$l $a$a {*}$l $a$a \
				 {*}$l $a$a {*}$l $a$a \
				 {*}$l $a$a {*}$l $a$a \
				 {*}$l $a$a {*}$l $a$a \
				 {*}$l $a$a {*}$l $a$a \
				 {*}$l $a$a}]

	    if {[llength $l] != 19*28} {
		error "Bad Length: [llength $l] should be [expr {19*28}]"
	    }
	}
    } -constraints [linsert $constraints 0 memory] -body {
	set end [getbytes]
	for {set i 0} {$i < 5} {incr i} {
	    stress
	    set tmp $end
	    set end [getbytes]
	}
	set leak [expr {$end - $tmp}]
    } -cleanup {
	unset end i tmp
	rename getbytes {}
	rename stress {}
} -result 0

test basic-48.17.$noComp {expansion: object safety} -constraints $constraints -body {
	    set third [expr {1.0/3.0}]
	    set l [list $third $third]
	    set x [run {list $third {*}$l $third}]
	    set res [list]
	    foreach t $x {
		lappend res [expr {$t * 3.0}]
	    }
	    set res
    } -cleanup {
	unset res t l x third
} -result {1.0 1.0 1.0 1.0}

test basic-48.18.$noComp {expansion: list semantics} -constraints $constraints -body {
	set badcmd {
	    list a b
	    set apa 10
	}
	set apa 0
	list [llength [run { {*}$badcmd }]] $apa
    } -cleanup {
	unset apa badcmd
} -result {5 0}

test basic-48.19.$noComp {expansion: error checking order} -body {
	set badlist "a {}x y"
	set a 0
	set b 0
	catch {run {list [incr a] {*}$badlist [incr b]}}
	list $a $b
    } -constraints $constraints -cleanup {
	unset badlist a b
} -result {1 0}

test basic-48.20.$noComp {expansion: odd case with word boundaries} $constraints {
    run {list {*}$::l1 {*}"hej hopp" {*}$::l2}
} {a {b b} c d hej hopp e f {g g} h}

test basic-48.21.$noComp {expansion: odd case with word boundaries} $constraints {
    run {list {*}$::l1 {*}{hej hopp} {*}$::l2}
} {a {b b} c d hej hopp e f {g g} h}

test basic-48.22.$noComp {expansion: odd case with word boundaries} -body {
    run {list {*}$::l1 {*}"hej hopp {*}$::l2}
} -constraints $constraints -returnCodes error -result {missing "}

test basic-48.23.$noComp {expansion: handle return codes} -constraints $constraints -body {
	set res {}
	for {set t 0} {$t < 10} {incr t} {
	    run { {*}break }
	}
	lappend res $t

	for {set t 0} {$t < 10} {incr t} {
	    run { {*}continue }
	    set t 20
	}
	lappend res $t

	lappend res [catch { run { {*}{error Hejsan} } } err]
	lappend res $err
    } -cleanup {
	unset res t
} -result {0 10 1 Hejsan}

test basic-48.24.$noComp {expansion: empty not canonical list, regression test, bug [cc1e91552c]} -constraints $constraints -setup {
    unset -nocomplain a
} -body {
Changes to tests/bigdata.test.
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# only be used when operands are not modified and when combining tests
# does not consume too much additional memory.

# Wrapper to generate compiled and uncompiled cases for a test. If $args does
# not contain a -body key, $comment is treated as the test body
proc bigtest {id comment result args} {
    if {[dict exists $args -body]} {
        set body [dict get $args -body]
        dict unset args -body
    } else {
        set body $comment
    }
    dict lappend args -constraints bigdata

    uplevel 1 [list test $id.uncompiled "$comment (uncompiled)" \
                   -body [list testevalex $body] \
                   -result $result \
                   {*}$args]

    uplevel 1 [list test $id.compiled-script "$comment (compiled script)" \
                   -body [list try $body] \
                   -result $result \
                   {*}$args]

    return

    # TODO - is this proc compilation required separately from the compile-script above?
    dict append args -setup \n[list proc testxproc {} $body]
    dict append args -cleanup "\nrename testxproc {}"
    uplevel 1 [list test $id.compiled-proc "$comment (compiled proc)" \
                   -body {testxproc} \
                   -result $result \
                   {*}$args]
}

# Like bigtest except that both compiled and uncompiled are combined into one
# test using the same inout argument. This saves time but for obvious reasons
# should only be used when the input argument is not modified.
proc bigtestRO {id comment result args} {
    if {[dict exists $args -body]} {
        set body [dict get $args -body]
        dict unset args -body
    } else {
        set body $comment
    }
    dict lappend args -constraints bigdata

    set wrapper ""
    set body "{$body}"
    append wrapper "set uncompiled_result \[testevalex $body]" \n
    append wrapper "set compiled_result \[try $body]" \n
    append wrapper {list $uncompiled_result $compiled_result}
    uplevel 1 [list test $id.uncompiled,compiled {$comment} \
                   -body $wrapper \
                   -result [list $result $result] \
                   {*}$args]
    return
}

interp alias {} bigClean {} unset -nocomplain s s1 s2 bin bin1 bin2 l l1 l2

interp alias {} bigString {} testbigdata string
interp alias {} bigBinary {} testbigdata bytearray
interp alias {} bigList {} testbigdata list
proc bigPatLen {} {
    proc bigPatLen {} "return [string length [testbigdata string]]"
    bigPatLen
}

# Returns list of expected elements at the indices specified
proc bigStringIndices {indices} {
    set pat [testbigdata string]
    set patlen [string length $pat]
    lmap idx $indices {
        string index $pat [expr {$idx%$patlen}]
    }
}

# Returns the largest multiple of the pattern length that is less than $limit
proc bigPatlenMultiple {limit} {
    set patlen [bigPatLen]
    return [expr {($limit/$patlen)*$patlen}]







|
|

|




|
|
|


|
|
|







|
|
|







|
|

|









|
|
|


















|







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# only be used when operands are not modified and when combining tests
# does not consume too much additional memory.

# Wrapper to generate compiled and uncompiled cases for a test. If $args does
# not contain a -body key, $comment is treated as the test body
proc bigtest {id comment result args} {
    if {[dict exists $args -body]} {
	set body [dict get $args -body]
	dict unset args -body
    } else {
	set body $comment
    }
    dict lappend args -constraints bigdata

    uplevel 1 [list test $id.uncompiled "$comment (uncompiled)" \
		   -body [list testevalex $body] \
		   -result $result \
		   {*}$args]

    uplevel 1 [list test $id.compiled-script "$comment (compiled script)" \
		   -body [list try $body] \
		   -result $result \
		   {*}$args]

    return

    # TODO - is this proc compilation required separately from the compile-script above?
    dict append args -setup \n[list proc testxproc {} $body]
    dict append args -cleanup "\nrename testxproc {}"
    uplevel 1 [list test $id.compiled-proc "$comment (compiled proc)" \
		   -body {testxproc} \
		   -result $result \
		   {*}$args]
}

# Like bigtest except that both compiled and uncompiled are combined into one
# test using the same inout argument. This saves time but for obvious reasons
# should only be used when the input argument is not modified.
proc bigtestRO {id comment result args} {
    if {[dict exists $args -body]} {
	set body [dict get $args -body]
	dict unset args -body
    } else {
	set body $comment
    }
    dict lappend args -constraints bigdata

    set wrapper ""
    set body "{$body}"
    append wrapper "set uncompiled_result \[testevalex $body]" \n
    append wrapper "set compiled_result \[try $body]" \n
    append wrapper {list $uncompiled_result $compiled_result}
    uplevel 1 [list test $id.uncompiled,compiled {$comment} \
		   -body $wrapper \
		   -result [list $result $result] \
		   {*}$args]
    return
}

interp alias {} bigClean {} unset -nocomplain s s1 s2 bin bin1 bin2 l l1 l2

interp alias {} bigString {} testbigdata string
interp alias {} bigBinary {} testbigdata bytearray
interp alias {} bigList {} testbigdata list
proc bigPatLen {} {
    proc bigPatLen {} "return [string length [testbigdata string]]"
    bigPatLen
}

# Returns list of expected elements at the indices specified
proc bigStringIndices {indices} {
    set pat [testbigdata string]
    set patlen [string length $pat]
    lmap idx $indices {
	string index $pat [expr {$idx%$patlen}]
    }
}

# Returns the largest multiple of the pattern length that is less than $limit
proc bigPatlenMultiple {limit} {
    set patlen [bigPatLen]
    return [expr {($limit/$patlen)*$patlen}]
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
    bigClean
} -constraints panic-in-EnterCmdStartData

#
# string cat
bigtest string-cat-bigdata-1 "string cat large small result > INT_MAX" 1 -body {
    string equal \
        [string cat [bigString $::bigLengths(patlenmultiple)] [bigString]] \
        [bigString [expr {[bigPatLen]+$::bigLengths(patlenmultiple)}]]
}
bigtest string-cat-bigdata-2 "string cat small large result > INT_MAX" 1 -body {
    string equal \
        [string cat [bigString] [bigString $::bigLengths(patlenmultiple)]] \
        [bigString [expr {[bigPatLen]+$::bigLengths(patlenmultiple)}]]
}
bigtest string-cat-bigdata-3 "string cat result > UINT_MAX" 1 -body {
    set s [bigString $::bigLengths(patlenmultiple)]
    string equal \
        [string cat $s [bigString] $s] \
        [bigString [expr {[bigPatLen]+2*$::bigLengths(patlenmultiple)}]]
}

#
# string compare/equal
bigtestRO string-equal/compare-bigdata-1 "string compare/equal equal strings" {0 1} -body {
    list [string compare $s1 $s2] [string equal $s1 $s2]
} -setup {







|
|



|
|




|
|







141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
    bigClean
} -constraints panic-in-EnterCmdStartData

#
# string cat
bigtest string-cat-bigdata-1 "string cat large small result > INT_MAX" 1 -body {
    string equal \
	[string cat [bigString $::bigLengths(patlenmultiple)] [bigString]] \
	[bigString [expr {[bigPatLen]+$::bigLengths(patlenmultiple)}]]
}
bigtest string-cat-bigdata-2 "string cat small large result > INT_MAX" 1 -body {
    string equal \
	[string cat [bigString] [bigString $::bigLengths(patlenmultiple)]] \
	[bigString [expr {[bigPatLen]+$::bigLengths(patlenmultiple)}]]
}
bigtest string-cat-bigdata-3 "string cat result > UINT_MAX" 1 -body {
    set s [bigString $::bigLengths(patlenmultiple)]
    string equal \
	[string cat $s [bigString] $s] \
	[bigString [expr {[bigPatLen]+2*$::bigLengths(patlenmultiple)}]]
}

#
# string compare/equal
bigtestRO string-equal/compare-bigdata-1 "string compare/equal equal strings" {0 1} -body {
    list [string compare $s1 $s2] [string equal $s1 $s2]
} -setup {
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
    bigClean
}

#
# string first
bigtestRO string-first-bigdata-1 "string first > INT_MAX" {2147483648 -1 2147483650 1} -body {
    list \
        [string first X $s] \
        [string first Y $s] \
        [string first 0 $s 0x80000000] \
        [string first 1 $s end-0x80000010]
} -setup {
    set s [bigString 0x8000000a 0x80000000]
} -cleanup {
    bigClean
}

bigtestRO string-first-bigdata-2 "string first > UINT_MAX" {4294967296 -1 4294967300 1} -body {
    list \
        [string first X $s] \
        [string first Y $s] \
        [string first 0 $s 0x100000000] \
        [string first 1 $s end-0x100000010]
} -setup {
    set s [bigString 0x10000000a 0x100000000]
} -cleanup {
    bigClean
}

bigtestRO string-first-bigdata-3 "string first - long needle" 10 -body {
    string first $needle $s
} -setup {
    set s [bigString 0x10000000a 0]
    set needle [bigString 0x100000000]
} -cleanup {
   bigClean needle
}

#
# string index
bigtestRO string-index-bigdata-1 "string index" {6 7 5 {} 5 4 {} 9 {}} -body {
    list \
        [string index $s 0x100000000] \
        [string index $s 0x100000000+1] \
        [string index $s 0x100000000-1] \
        [string index $s 0x10000000a] \
        [string index $s end] \
        [string index $s end-1] \
        [string index $s end+1] \
        [string index $s end-0x100000000] \
        [string index $s end-0x10000000a]
} -setup {
    set s [bigString 0x10000000a]
} -cleanup {
    bigClean
}

#







|
|
|
|








|
|
|
|



















|
|
|
|
|
|
|
|
|







186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
    bigClean
}

#
# string first
bigtestRO string-first-bigdata-1 "string first > INT_MAX" {2147483648 -1 2147483650 1} -body {
    list \
	[string first X $s] \
	[string first Y $s] \
	[string first 0 $s 0x80000000] \
	[string first 1 $s end-0x80000010]
} -setup {
    set s [bigString 0x8000000a 0x80000000]
} -cleanup {
    bigClean
}

bigtestRO string-first-bigdata-2 "string first > UINT_MAX" {4294967296 -1 4294967300 1} -body {
    list \
	[string first X $s] \
	[string first Y $s] \
	[string first 0 $s 0x100000000] \
	[string first 1 $s end-0x100000010]
} -setup {
    set s [bigString 0x10000000a 0x100000000]
} -cleanup {
    bigClean
}

bigtestRO string-first-bigdata-3 "string first - long needle" 10 -body {
    string first $needle $s
} -setup {
    set s [bigString 0x10000000a 0]
    set needle [bigString 0x100000000]
} -cleanup {
   bigClean needle
}

#
# string index
bigtestRO string-index-bigdata-1 "string index" {6 7 5 {} 5 4 {} 9 {}} -body {
    list \
	[string index $s 0x100000000] \
	[string index $s 0x100000000+1] \
	[string index $s 0x100000000-1] \
	[string index $s 0x10000000a] \
	[string index $s end] \
	[string index $s end-1] \
	[string index $s end+1] \
	[string index $s end-0x100000000] \
	[string index $s end-0x10000000a]
} -setup {
    set s [bigString 0x10000000a]
} -cleanup {
    bigClean
}

#
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
}

#
# string last
bigtestRO string-last-bigdata-1 "string last > INT_MAX" {2 -1 2147483640 11} -body {
    set s [bigString 0x80000010 2]
    list \
        [string last X $s] \
        [string last Y $s] \
        [string last 0 $s 0x80000000] \
        [string last 1 $s end-0x80000000]
} -setup {
    set s [bigString 0x80000010 2]
} -cleanup {
    bigClean
}
bigtestRO string-last-bigdata-2 "string last > UINT_MAX" {4294967320 -1 4294967290 1} -body {
    list \
        [string last 0 $s] \
        [string last Y $s] \
        [string last 0 $s 0x100000000] \
        [string last 1 $s end-0x100000010]
} -setup {
    set s [bigString 0x10000001a 2]
} -cleanup {
    bigClean
}
bigtestRO string-last-bigdata-3 "string last - long needle" 0 -body {
    string last $needle $s







|
|
|
|







|
|
|
|







264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
}

#
# string last
bigtestRO string-last-bigdata-1 "string last > INT_MAX" {2 -1 2147483640 11} -body {
    set s [bigString 0x80000010 2]
    list \
	[string last X $s] \
	[string last Y $s] \
	[string last 0 $s 0x80000000] \
	[string last 1 $s end-0x80000000]
} -setup {
    set s [bigString 0x80000010 2]
} -cleanup {
    bigClean
}
bigtestRO string-last-bigdata-2 "string last > UINT_MAX" {4294967320 -1 4294967290 1} -body {
    list \
	[string last 0 $s] \
	[string last Y $s] \
	[string last 0 $s 0x100000000] \
	[string last 1 $s end-0x100000010]
} -setup {
    set s [bigString 0x10000001a 2]
} -cleanup {
    bigClean
}
bigtestRO string-last-bigdata-3 "string last - long needle" 0 -body {
    string last $needle $s
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
# string map
bigtestRO string-map-bigdata-1 {string map} {5 0 0 5} -body {
    # Unset explicitly before setting to save memory as bigtestRO runs the
    # script below twice.
    unset -nocomplain s2
    set s2 [string map {0 5 5 0} $s]
    list \
        [string index $s2 0] \
        [string index $s2 5] \
        [string index $s2 end] \
        [string index $s2 end-5]
} -setup {
    set s [bigString 0x100000000]
} -cleanup {
    bigClean
} -constraints bug-takesTooLong

#
# string match
bigtestRO string-match-bigdata-1 {string match} {1 0 1} -body {
    list \
        [string match 0*5 $s] \
        [string match 0*4 $s] \
        [string match $s $s]
} -setup {
    set s [bigString 0x100000000]
} -cleanup {
    bigClean
}

#
# string range
bigtestRO string-range-bigdata-1 "string range" {6 7 5 {} 5 4 {} 9 {}} -body {
    list \
        [string range $s 0x100000000 0x100000000] \
        [string range $s 0x100000000+1 0x100000000+1] \
        [string range $s 0x100000000-1 0x100000000-1] \
        [string range $s 0x10000000a 0x10000000a] \
        [string range $s end end] \
        [string range $s end-1 end-1] \
        [string range $s end+1 end+1] \
        [string range $s end-0x100000000 end-0x100000000] \
        [string range $s end-0x10000000a end-0x10000000a]
} -setup {
    set s [bigString 0x10000000a]
} -cleanup {
    bigClean
}
bigtestRO string-range-bigdata-2 "bug ad9361fd20 case 1" aXaaaa -body {
    string range [string insert [string repeat a 0x80000000] end-0x7fffffff X] 0 5







|
|
|
|










|
|
|










|
|
|
|
|
|
|
|
|







309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
# string map
bigtestRO string-map-bigdata-1 {string map} {5 0 0 5} -body {
    # Unset explicitly before setting to save memory as bigtestRO runs the
    # script below twice.
    unset -nocomplain s2
    set s2 [string map {0 5 5 0} $s]
    list \
	[string index $s2 0] \
	[string index $s2 5] \
	[string index $s2 end] \
	[string index $s2 end-5]
} -setup {
    set s [bigString 0x100000000]
} -cleanup {
    bigClean
} -constraints bug-takesTooLong

#
# string match
bigtestRO string-match-bigdata-1 {string match} {1 0 1} -body {
    list \
	[string match 0*5 $s] \
	[string match 0*4 $s] \
	[string match $s $s]
} -setup {
    set s [bigString 0x100000000]
} -cleanup {
    bigClean
}

#
# string range
bigtestRO string-range-bigdata-1 "string range" {6 7 5 {} 5 4 {} 9 {}} -body {
    list \
	[string range $s 0x100000000 0x100000000] \
	[string range $s 0x100000000+1 0x100000000+1] \
	[string range $s 0x100000000-1 0x100000000-1] \
	[string range $s 0x10000000a 0x10000000a] \
	[string range $s end end] \
	[string range $s end-1 end-1] \
	[string range $s end+1 end+1] \
	[string range $s end-0x100000000 end-0x100000000] \
	[string range $s end-0x10000000a end-0x10000000a]
} -setup {
    set s [bigString 0x10000000a]
} -cleanup {
    bigClean
}
bigtestRO string-range-bigdata-2 "bug ad9361fd20 case 1" aXaaaa -body {
    string range [string insert [string repeat a 0x80000000] end-0x7fffffff X] 0 5
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
# string repeat - use bigtest, not bigtestRO !!
bigtest string-repeat-bigdata-1 "string repeat single char length > UINT_MAX" 4294967296 -body {
    string length [string repeat x 0x100000000]
}
bigtest string-repeat-bigdata-2 "string repeat multiple char" {4294967296 0123456789abcdef 0123456789abcdef} -body {
    set s [string repeat 0123456789abcdef [expr 0x100000000/16]]
    list \
        [string length $s] \
        [string range $s 0 15] \
        [string range $s end-15 end]
} -cleanup {
    bigClean
}

#
# string replace
bigtestRO string-replace-bigdata-1 "string replace" {789012345 012345678 XYZ789012345 012345678XYZ} -body {







|
|
|







370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
# string repeat - use bigtest, not bigtestRO !!
bigtest string-repeat-bigdata-1 "string repeat single char length > UINT_MAX" 4294967296 -body {
    string length [string repeat x 0x100000000]
}
bigtest string-repeat-bigdata-2 "string repeat multiple char" {4294967296 0123456789abcdef 0123456789abcdef} -body {
    set s [string repeat 0123456789abcdef [expr 0x100000000/16]]
    list \
	[string length $s] \
	[string range $s 0 15] \
	[string range $s end-15 end]
} -cleanup {
    bigClean
}

#
# string replace
bigtestRO string-replace-bigdata-1 "string replace" {789012345 012345678 XYZ789012345 012345678XYZ} -body {
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818

#
# foreach
bigtestRO foreach-bigdata-1 "foreach" 1 -body {
    # Unset explicitly before setting as bigtestRO runs the script twice.
    unset -nocomplain l2
    foreach x $l {
        lappend l2 $x
    }
    testlutil equal $l $l2
} -setup {
    set l [bigList 0x100000000]
} -cleanup {
    bigClean
}







|







804
805
806
807
808
809
810
811
812
813
814
815
816
817
818

#
# foreach
bigtestRO foreach-bigdata-1 "foreach" 1 -body {
    # Unset explicitly before setting as bigtestRO runs the script twice.
    unset -nocomplain l2
    foreach x $l {
	lappend l2 $x
    }
    testlutil equal $l $l2
} -setup {
    set l [bigList 0x100000000]
} -cleanup {
    bigClean
}
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
    bigClean
} -constraints memory-allocation-panic

#
# lindex
bigtestRO lindex-bigdata-1 "lindex" {6 7 5 {} 5 4 {} 9 {}} -body {
    list \
        [lindex $l 0x100000000] \
        [lindex $l 0x100000000+1] \
        [lindex $l 0x100000000-1] \
        [lindex $l 0x10000000a] \
        [lindex $l end] \
        [lindex $l end-1] \
        [lindex $l end+1] \
        [lindex $l end-0x100000000] \
        [lindex $l end-0x10000000a]
} -setup {
    set l [bigList 0x10000000a]
} -cleanup {
    bigClean
}
# TODO nested index

#
# linsert
# Cannot use bigtestRO here because 16GB memory not enough to have two 4G sized lists
# Have to throw away source list every time. Also means we cannot compare entire lists
# and instead just compare the affected range
bigtest linsert-bigdata-1 "linsert" {4294967330 1} -body {
    # Note insert at multiple of 10 to enable comparison against generated string
    set ins [split abcdefghij ""]
    set pat [split 0123456789 ""]
    set insidx 2000000000
    set l [linsert [bigList 4294967320] $insidx {*}$ins]
    list \
        [llength $l] \
        [testlutil equal [lrange $l $insidx-10 $insidx+19] [concat $pat $ins $pat]]
} -cleanup {
    bigClean
}

#
# list and {*}
# TODO - compiled and uncompiled behave differently so tested separately







|
|
|
|
|
|
|
|
|



















|
|







871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
    bigClean
} -constraints memory-allocation-panic

#
# lindex
bigtestRO lindex-bigdata-1 "lindex" {6 7 5 {} 5 4 {} 9 {}} -body {
    list \
	[lindex $l 0x100000000] \
	[lindex $l 0x100000000+1] \
	[lindex $l 0x100000000-1] \
	[lindex $l 0x10000000a] \
	[lindex $l end] \
	[lindex $l end-1] \
	[lindex $l end+1] \
	[lindex $l end-0x100000000] \
	[lindex $l end-0x10000000a]
} -setup {
    set l [bigList 0x10000000a]
} -cleanup {
    bigClean
}
# TODO nested index

#
# linsert
# Cannot use bigtestRO here because 16GB memory not enough to have two 4G sized lists
# Have to throw away source list every time. Also means we cannot compare entire lists
# and instead just compare the affected range
bigtest linsert-bigdata-1 "linsert" {4294967330 1} -body {
    # Note insert at multiple of 10 to enable comparison against generated string
    set ins [split abcdefghij ""]
    set pat [split 0123456789 ""]
    set insidx 2000000000
    set l [linsert [bigList 4294967320] $insidx {*}$ins]
    list \
	[llength $l] \
	[testlutil equal [lrange $l $insidx-10 $insidx+19] [concat $pat $ins $pat]]
} -cleanup {
    bigClean
}

#
# list and {*}
# TODO - compiled and uncompiled behave differently so tested separately
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
}

#
# lmap
bigtestRO lmap-bigdata-1 "lmap" 4294967296 -body {
    set n 0
    if {0} {
        # TODO - This is the right test but runs out of memory
        testlutil equal $l [lmap e $l {set e}]
    } else {
        lmap e $l {incr n; continue}
    }
    set n
} -setup {
    set l [bigList 0x100000000]
} -cleanup {
    bigClean
    puts ""
}

#
# lrange
bigtestRO lrange-bigdata-1 "lrange" {6 {6 7} 7 5 {} 5 4 {} 9 {8 9} {}} -body {
    list \
        [lrange $l 0x100000000 0x100000000] \
        [lrange $l 0x100000000 0x100000001] \
        [lrange $l 0x100000000+1 0x100000000+1] \
        [lrange $l 0x100000000-1 0x100000000-1] \
        [lrange $l 0x10000000a 0x10000000a] \
        [lrange $l end end] \
        [lrange $l end-1 end-1] \
        [lrange $l end+1 end+1] \
        [lrange $l end-0x100000000 end-0x100000000] \
        [lrange $l end-0x100000001 end-0x100000000] \
        [lrange $l end-0x10000000a end-0x10000000a]
} -setup {
    set l [bigList 0x10000000a]
} -cleanup {
    bigClean
}
# TODO - add tests for large result range








|
|

|













|
|
|
|
|
|
|
|
|
|
|







942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
}

#
# lmap
bigtestRO lmap-bigdata-1 "lmap" 4294967296 -body {
    set n 0
    if {0} {
	# TODO - This is the right test but runs out of memory
	testlutil equal $l [lmap e $l {set e}]
    } else {
	lmap e $l {incr n; continue}
    }
    set n
} -setup {
    set l [bigList 0x100000000]
} -cleanup {
    bigClean
    puts ""
}

#
# lrange
bigtestRO lrange-bigdata-1 "lrange" {6 {6 7} 7 5 {} 5 4 {} 9 {8 9} {}} -body {
    list \
	[lrange $l 0x100000000 0x100000000] \
	[lrange $l 0x100000000 0x100000001] \
	[lrange $l 0x100000000+1 0x100000000+1] \
	[lrange $l 0x100000000-1 0x100000000-1] \
	[lrange $l 0x10000000a 0x10000000a] \
	[lrange $l end end] \
	[lrange $l end-1 end-1] \
	[lrange $l end+1 end+1] \
	[lrange $l end-0x100000000 end-0x100000000] \
	[lrange $l end-0x100000001 end-0x100000000] \
	[lrange $l end-0x10000000a end-0x10000000a]
} -setup {
    set l [bigList 0x10000000a]
} -cleanup {
    bigClean
}
# TODO - add tests for large result range

995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
} -cleanup {
    bigClean
}

#
# lreplace
bigtestRO lreplace-bigdata-1 "lreplace - small result" [list \
                                             [split 789012345 ""] \
                                             [split 012345678 ""] \
                                             [split XYZ789012345 ""] \
                                             [split 012345678XYZ ""] \
                                            ] -body {
    # Unset explicitly before setting to save memory as bigtestRO runs the
    # script below twice.
    unset -nocomplain result
    lappend result [lreplace $l 0 0x100000000]
    lappend result [lreplace $l end-0x100000000 end]
    lappend result [lreplace $l 0 0x100000000 X Y Z]
    lappend result [lreplace $l end-0x100000000 end X Y Z]







|
|
|
|
|







995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
} -cleanup {
    bigClean
}

#
# lreplace
bigtestRO lreplace-bigdata-1 "lreplace - small result" [list \
					     [split 789012345 ""] \
					     [split 012345678 ""] \
					     [split XYZ789012345 ""] \
					     [split 012345678XYZ ""] \
					    ] -body {
    # Unset explicitly before setting to save memory as bigtestRO runs the
    # script below twice.
    unset -nocomplain result
    lappend result [lreplace $l 0 0x100000000]
    lappend result [lreplace $l end-0x100000000 end]
    lappend result [lreplace $l 0 0x100000000 X Y Z]
    lappend result [lreplace $l end-0x100000000 end X Y Z]
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
    bigClean
} -constraints bug-outofmemorypanic

#
# lsearch
bigtestRO lsearch-bigdata-1 "lsearch" {4294967300 4294967310 -1}  -body {
    list \
        [lsearch -exact $l X] \
        [lsearch -exact -start 4294967291 $l 0] \
        [lsearch -exact $l Y]
} -setup {
    set l [bigList 0x100000010 4294967300]
} -cleanup {
    bigClean
}
# TODO - stride, inline, all








|
|
|







1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
    bigClean
} -constraints bug-outofmemorypanic

#
# lsearch
bigtestRO lsearch-bigdata-1 "lsearch" {4294967300 4294967310 -1}  -body {
    list \
	[lsearch -exact $l X] \
	[lsearch -exact -start 4294967291 $l 0] \
	[lsearch -exact $l Y]
} -setup {
    set l [bigList 0x100000010 4294967300]
} -cleanup {
    bigClean
}
# TODO - stride, inline, all

Changes to tests/binary.test.
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
} PR
test binary-8.9 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format c2 {0x50}
} -result {number of elements in list does not match count}
test binary-8.10 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    set a {0x50 0x51}
    binary format c $a
} -result "expected integer but got \"0x50 0x51\""
test binary-8.11 {Tcl_BinaryObjCmd: format} {
    set a {0x50 0x51}
    binary format c1 $a
} P

test binary-9.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format s







|







308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
} PR
test binary-8.9 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format c2 {0x50}
} -result {number of elements in list does not match count}
test binary-8.10 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    set a {0x50 0x51}
    binary format c $a
} -result "expected integer but got a list"
test binary-8.11 {Tcl_BinaryObjCmd: format} {
    set a {0x50 0x51}
    binary format c1 $a
} P

test binary-9.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format s
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
} P\x00R\x00
test binary-9.10 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format s2 {0x50}
} -result {number of elements in list does not match count}
test binary-9.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    set a {0x50 0x51}
    binary format s $a
} -result "expected integer but got \"0x50 0x51\""
test binary-9.12 {Tcl_BinaryObjCmd: format} {
    set a {0x50 0x51}
    binary format s1 $a
} P\x00

test binary-10.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format S







|







347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
} P\x00R\x00
test binary-9.10 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format s2 {0x50}
} -result {number of elements in list does not match count}
test binary-9.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    set a {0x50 0x51}
    binary format s $a
} -result "expected integer but got a list"
test binary-9.12 {Tcl_BinaryObjCmd: format} {
    set a {0x50 0x51}
    binary format s1 $a
} P\x00

test binary-10.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format S
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
} \x00P\x00R
test binary-10.10 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format S2 {0x50}
} -result {number of elements in list does not match count}
test binary-10.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    set a {0x50 0x51}
    binary format S $a
} -result "expected integer but got \"0x50 0x51\""
test binary-10.12 {Tcl_BinaryObjCmd: format} {
    set a {0x50 0x51}
    binary format S1 $a
} \x00P

test binary-11.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format i







|







386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
} \x00P\x00R
test binary-10.10 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format S2 {0x50}
} -result {number of elements in list does not match count}
test binary-10.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    set a {0x50 0x51}
    binary format S $a
} -result "expected integer but got a list"
test binary-10.12 {Tcl_BinaryObjCmd: format} {
    set a {0x50 0x51}
    binary format S1 $a
} \x00P

test binary-11.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format i
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
} SRQPR\x00\x00\x00
test binary-11.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format i2 {0x50}
} -result {number of elements in list does not match count}
test binary-11.12 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    set a {0x50 0x51}
    binary format i $a
} -result "expected integer but got \"0x50 0x51\""
test binary-11.13 {Tcl_BinaryObjCmd: format} {
    set a {0x50 0x51}
    binary format i1 $a
} P\x00\x00\x00

test binary-12.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format I







|







428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
} SRQPR\x00\x00\x00
test binary-11.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format i2 {0x50}
} -result {number of elements in list does not match count}
test binary-11.12 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    set a {0x50 0x51}
    binary format i $a
} -result "expected integer but got a list"
test binary-11.13 {Tcl_BinaryObjCmd: format} {
    set a {0x50 0x51}
    binary format i1 $a
} P\x00\x00\x00

test binary-12.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format I
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
} PQRS\x00\x00\x00R
test binary-12.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format i2 {0x50}
} -result {number of elements in list does not match count}
test binary-12.12 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    set a {0x50 0x51}
    binary format I $a
} -result "expected integer but got \"0x50 0x51\""
test binary-12.13 {Tcl_BinaryObjCmd: format} {
    set a {0x50 0x51}
    binary format I1 $a
} \x00\x00\x00P

test binary-13.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format f







|







470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
} PQRS\x00\x00\x00R
test binary-12.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format i2 {0x50}
} -result {number of elements in list does not match count}
test binary-12.12 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    set a {0x50 0x51}
    binary format I $a
} -result "expected integer but got a list"
test binary-12.13 {Tcl_BinaryObjCmd: format} {
    set a {0x50 0x51}
    binary format I1 $a
} \x00\x00\x00P

test binary-13.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format f
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
} \x00\x00\x00\x80
test binary-13.16 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format f2 {1.6}
} -result {number of elements in list does not match count}
test binary-13.17 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    set a {1.6 3.4}
    binary format f $a
} -result "expected floating-point number but got \"1.6 3.4\""
test binary-13.18 {Tcl_BinaryObjCmd: format} bigEndian {
    set a {1.6 3.4}
    binary format f1 $a
} \x3F\xCC\xCC\xCD
test binary-13.19 {Tcl_BinaryObjCmd: format} littleEndian {
    set a {1.6 3.4}
    binary format f1 $a







|







527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
} \x00\x00\x00\x80
test binary-13.16 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format f2 {1.6}
} -result {number of elements in list does not match count}
test binary-13.17 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    set a {1.6 3.4}
    binary format f $a
} -result "expected floating-point number but got a list"
test binary-13.18 {Tcl_BinaryObjCmd: format} bigEndian {
    set a {1.6 3.4}
    binary format f1 $a
} \x3F\xCC\xCC\xCD
test binary-13.19 {Tcl_BinaryObjCmd: format} littleEndian {
    set a {1.6 3.4}
    binary format f1 $a
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
} \x9A\x99\x99\x99\x99\x99\xF9\x3F\x33\x33\x33\x33\x33\x33\x0B\x40
test binary-14.14 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format d2 {1.6}
} -result {number of elements in list does not match count}
test binary-14.15 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    set a {1.6 3.4}
    binary format d $a
} -result "expected floating-point number but got \"1.6 3.4\""
test binary-14.16 {Tcl_BinaryObjCmd: format} bigEndian {
    set a {1.6 3.4}
    binary format d1 $a
} \x3F\xF9\x99\x99\x99\x99\x99\x9A
test binary-14.17 {Tcl_BinaryObjCmd: format} littleEndian {
    set a {1.6 3.4}
    binary format d1 $a







|







588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
} \x9A\x99\x99\x99\x99\x99\xF9\x3F\x33\x33\x33\x33\x33\x33\x0B\x40
test binary-14.14 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format d2 {1.6}
} -result {number of elements in list does not match count}
test binary-14.15 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    set a {1.6 3.4}
    binary format d $a
} -result "expected floating-point number but got a list"
test binary-14.16 {Tcl_BinaryObjCmd: format} bigEndian {
    set a {1.6 3.4}
    binary format d1 $a
} \x3F\xF9\x99\x99\x99\x99\x99\x9A
test binary-14.17 {Tcl_BinaryObjCmd: format} littleEndian {
    set a {1.6 3.4}
    binary format d1 $a
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
} P\x00R\x00
test binary-48.16 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format t2 {0x50}
} -result {number of elements in list does not match count}
test binary-48.17 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    set a {0x50 0x51}
    binary format t $a
} -result "expected integer but got \"0x50 0x51\""
test binary-48.18 {Tcl_BinaryObjCmd: format} bigEndian {
    set a {0x50 0x51}
    binary format t1 $a
} \x00P
test binary-48.19 {Tcl_BinaryObjCmd: format} littleEndian {
    set a {0x50 0x51}
    binary format t1 $a







|







1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
} P\x00R\x00
test binary-48.16 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format t2 {0x50}
} -result {number of elements in list does not match count}
test binary-48.17 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    set a {0x50 0x51}
    binary format t $a
} -result "expected integer but got a list"
test binary-48.18 {Tcl_BinaryObjCmd: format} bigEndian {
    set a {0x50 0x51}
    binary format t1 $a
} \x00P
test binary-48.19 {Tcl_BinaryObjCmd: format} littleEndian {
    set a {0x50 0x51}
    binary format t1 $a
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
} SRQPR\x00\x00\x00
test binary-49.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format n2 {0x50}
} -result {number of elements in list does not match count}
test binary-49.12 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    set a {0x50 0x51}
    binary format n $a
} -result "expected integer but got \"0x50 0x51\""
test binary-49.13 {Tcl_BinaryObjCmd: format} littleEndian {
    set a {0x50 0x51}
    binary format n1 $a
} P\x00\x00\x00
test binary-49.14 {Tcl_BinaryObjCmd: format} bigEndian {
    binary format n 0x50
} \x00\x00\x00P







|







1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
} SRQPR\x00\x00\x00
test binary-49.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format n2 {0x50}
} -result {number of elements in list does not match count}
test binary-49.12 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    set a {0x50 0x51}
    binary format n $a
} -result "expected integer but got a list"
test binary-49.13 {Tcl_BinaryObjCmd: format} littleEndian {
    set a {0x50 0x51}
    binary format n1 $a
} P\x00\x00\x00
test binary-49.14 {Tcl_BinaryObjCmd: format} bigEndian {
    binary format n 0x50
} \x00\x00\x00P
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
} \x9A\x99\x99\x99\x99\x99\xF9\x3F\x33\x33\x33\x33\x33\x33\x0B\x40
test binary-51.14 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format q2 {1.6}
} -result {number of elements in list does not match count}
test binary-51.15 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    set a {1.6 3.4}
    binary format q $a
} -result "expected floating-point number but got \"1.6 3.4\""
test binary-51.16 {Tcl_BinaryObjCmd: format} {} {
    set a {1.6 3.4}
    binary format Q1 $a
} \x3F\xF9\x99\x99\x99\x99\x99\x9A
test binary-51.17 {Tcl_BinaryObjCmd: format} {} {
    set a {1.6 3.4}
    binary format q1 $a







|







1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
} \x9A\x99\x99\x99\x99\x99\xF9\x3F\x33\x33\x33\x33\x33\x33\x0B\x40
test binary-51.14 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format q2 {1.6}
} -result {number of elements in list does not match count}
test binary-51.15 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    set a {1.6 3.4}
    binary format q $a
} -result "expected floating-point number but got a list"
test binary-51.16 {Tcl_BinaryObjCmd: format} {} {
    set a {1.6 3.4}
    binary format Q1 $a
} \x3F\xF9\x99\x99\x99\x99\x99\x9A
test binary-51.17 {Tcl_BinaryObjCmd: format} {} {
    set a {1.6 3.4}
    binary format q1 $a
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
} \x00\x00\x00\x80
test binary-53.16 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format r2 {1.6}
} -result {number of elements in list does not match count}
test binary-53.17 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    set a {1.6 3.4}
    binary format r $a
} -result "expected floating-point number but got \"1.6 3.4\""
test binary-53.18 {Tcl_BinaryObjCmd: format} {} {
    set a {1.6 3.4}
    binary format R1 $a
} \x3F\xCC\xCC\xCD
test binary-53.19 {Tcl_BinaryObjCmd: format} {} {
    set a {1.6 3.4}
    binary format r1 $a







|







2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
} \x00\x00\x00\x80
test binary-53.16 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    binary format r2 {1.6}
} -result {number of elements in list does not match count}
test binary-53.17 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
    set a {1.6 3.4}
    binary format r $a
} -result "expected floating-point number but got a list"
test binary-53.18 {Tcl_BinaryObjCmd: format} {} {
    set a {1.6 3.4}
    binary format R1 $a
} \x3F\xCC\xCC\xCD
test binary-53.19 {Tcl_BinaryObjCmd: format} {} {
    set a {1.6 3.4}
    binary format r1 $a
Changes to tests/chan.test.
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
    chan pending input $f
} -result 8 -cleanup {
    catch {chan close $f}
    catch {removeFile $file}
}
test chan-16.9 {chan command: pending input subcommand} -setup {
    proc chan-16.9-accept {sock addr port} {
        chan configure $sock -blocking 0 -buffering line -buffersize 32
        chan event $sock readable [list chan-16.9-readable $sock]
    }

    proc chan-16.9-readable {sock} {
        set r [chan gets $sock line]
        set l [string length $line]
        set e [chan eof $sock]
        set b [chan blocked $sock]
        set i [chan pending input $sock]

        lappend ::chan-16.9-data $r $l $e $b $i

        if {$r >= 0 || $e || $l || !$b || $i > 128} {
            set data [read $sock $i]
            lappend ::chan-16.9-data [string range $data 0 2]
            lappend ::chan-16.9-data [string range $data end-2 end]
            set ::chan-16.9-done 1
            chan event $sock readable {}
        } else {
	    after idle chan-16.9-client
	}
    }

    proc chan-16.9-client {} {
        chan puts -nonewline $::client ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
        chan flush $::client
    }

    set ::server [socket -server chan-16.9-accept -myaddr 127.0.0.1 0]
    set ::client [socket 127.0.0.1 [lindex [fconfigure $::server -sockname] 2]]
    set ::chan-16.9-data [list]
    set ::chan-16.9-done 0
} -body {







|
|



|
|
|
|
|

|

|
|
|
|
|
|
|





|
|







169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
    chan pending input $f
} -result 8 -cleanup {
    catch {chan close $f}
    catch {removeFile $file}
}
test chan-16.9 {chan command: pending input subcommand} -setup {
    proc chan-16.9-accept {sock addr port} {
	chan configure $sock -blocking 0 -buffering line -buffersize 32
	chan event $sock readable [list chan-16.9-readable $sock]
    }

    proc chan-16.9-readable {sock} {
	set r [chan gets $sock line]
	set l [string length $line]
	set e [chan eof $sock]
	set b [chan blocked $sock]
	set i [chan pending input $sock]

	lappend ::chan-16.9-data $r $l $e $b $i

	if {$r >= 0 || $e || $l || !$b || $i > 128} {
	    set data [read $sock $i]
	    lappend ::chan-16.9-data [string range $data 0 2]
	    lappend ::chan-16.9-data [string range $data end-2 end]
	    set ::chan-16.9-done 1
	    chan event $sock readable {}
	} else {
	    after idle chan-16.9-client
	}
    }

    proc chan-16.9-client {} {
	chan puts -nonewline $::client ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
	chan flush $::client
    }

    set ::server [socket -server chan-16.9-accept -myaddr 127.0.0.1 0]
    set ::client [socket 127.0.0.1 [lindex [fconfigure $::server -sockname] 2]]
    set ::chan-16.9-data [list]
    set ::chan-16.9-done 0
} -body {
Changes to tests/chanio.test.
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
} -result hello
test chan-io-14.9 {reuse of stdio special channels} -setup {
    file delete $path(script)
    file delete $path(test1)
} -constraints {stdio fileevent} -body {
    set f [open $path(script) w]
    chan puts $f {
        array set path [lindex $argv 0]
	set f [open $path(test1) w]
	chan puts $f hello
	chan close $f
	chan close stderr
	set f [open "|[list [info nameofexecutable] $path(cat) $path(test1)]" r]
	chan puts [chan gets $f]
    }







|







1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
} -result hello
test chan-io-14.9 {reuse of stdio special channels} -setup {
    file delete $path(script)
    file delete $path(test1)
} -constraints {stdio fileevent} -body {
    set f [open $path(script) w]
    chan puts $f {
	array set path [lindex $argv 0]
	set f [open $path(test1) w]
	chan puts $f hello
	chan close $f
	chan close stderr
	set f [open "|[list [info nameofexecutable] $path(cat) $path(test1)]" r]
	chan puts [chan gets $f]
    }
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
	    chan puts -nonewline $f [chan read stdin 1024]
	}
	chan close $f
    }
    chan close $f
    set x 01234567890123456789012345678901
    for {set i 0} {$i < 11} {incr i} {
        set x "$x$x"
    }
    set f [open $path(output) w]
    chan close $f
    set f [openpipe w $path(pipe)]
    chan configure $f -blocking off
    chan puts -nonewline $f $x
    chan close $f
    set counter 0
    while {([file size $path(output)] < 65536) && ($counter < 1000)} {
	after 20 [list incr [namespace which -variable counter]]
	vwait [namespace which -variable counter]
    }
    if {$counter == 1000} {
        set result "file size only [file size $path(output)]"
    } else {
        set result ok
    }
} -result ok

# Tests closing a channel. The functions tested are Chan CloseChannel and
# Tcl_Chan Close.

test chan-io-28.1 {Chan CloseChannel called when all references are dropped} -setup {







|













|

|







2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
	    chan puts -nonewline $f [chan read stdin 1024]
	}
	chan close $f
    }
    chan close $f
    set x 01234567890123456789012345678901
    for {set i 0} {$i < 11} {incr i} {
	set x "$x$x"
    }
    set f [open $path(output) w]
    chan close $f
    set f [openpipe w $path(pipe)]
    chan configure $f -blocking off
    chan puts -nonewline $f $x
    chan close $f
    set counter 0
    while {([file size $path(output)] < 65536) && ($counter < 1000)} {
	after 20 [list incr [namespace which -variable counter]]
	vwait [namespace which -variable counter]
    }
    if {$counter == 1000} {
	set result "file size only [file size $path(output)]"
    } else {
	set result ok
    }
} -result ok

# Tests closing a channel. The functions tested are Chan CloseChannel and
# Tcl_Chan Close.

test chan-io-28.1 {Chan CloseChannel called when all references are dropped} -setup {
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
	    chan puts -nonewline $f [chan read stdin 1024]
	}
	chan close $f
    }
    chan close $f
    set x 01234567890123456789012345678901
    for {set i 0} {$i < 11} {incr i} {
        set x "$x$x"
    }
    set f [open $path(output) w]
    chan close $f
    set f [openpipe r+ $path(pipe)]
    chan configure $f -blocking off
    chan puts -nonewline $f $x
    chan close $f
    set counter 0
    while {([file size $path(output)] < 20480) && ($counter < 1000)} {
	after 20 [list incr [namespace which -variable counter]]
	vwait [namespace which -variable counter]
    }
    if {$counter == 1000} {
        set result probably_broken
    } else {
        set result ok
    }
} -result ok
test chan-io-28.4 {Tcl_Chan Close} -constraints {testchannel} -setup {
    file delete $path(test1)
    set l ""
} -body {
    lappend l [lsort [testchannel open]]







|













|

|







2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
	    chan puts -nonewline $f [chan read stdin 1024]
	}
	chan close $f
    }
    chan close $f
    set x 01234567890123456789012345678901
    for {set i 0} {$i < 11} {incr i} {
	set x "$x$x"
    }
    set f [open $path(output) w]
    chan close $f
    set f [openpipe r+ $path(pipe)]
    chan configure $f -blocking off
    chan puts -nonewline $f $x
    chan close $f
    set counter 0
    while {([file size $path(output)] < 20480) && ($counter < 1000)} {
	after 20 [list incr [namespace which -variable counter]]
	vwait [namespace which -variable counter]
    }
    if {$counter == 1000} {
	set result probably_broken
    } else {
	set result ok
    }
} -result ok
test chan-io-28.4 {Tcl_Chan Close} -constraints {testchannel} -setup {
    file delete $path(test1)
    set l ""
} -body {
    lappend l [lsort [testchannel open]]
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
    set sock [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
    lappend l [chan configure $sock -eofchar] \
	[chan configure $sock -translation]
} -cleanup {
    chan close $sock
} -result {{} auto}
test chan-io-39.24 {Tcl_SetChannelOption, server socket is not readable or\
        writable so we can't change -eofchar or -translation} -setup {
    set l [list]
} -body {
    set sock [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
    chan configure $sock -eofchar D -translation lf
    lappend l [chan configure $sock -eofchar] \
	[chan configure $sock -translation]
} -cleanup {







|







5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
    set sock [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
    lappend l [chan configure $sock -eofchar] \
	[chan configure $sock -translation]
} -cleanup {
    chan close $sock
} -result {{} auto}
test chan-io-39.24 {Tcl_SetChannelOption, server socket is not readable or\
	writable so we can't change -eofchar or -translation} -setup {
    set l [list]
} -body {
    set sock [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
    chan configure $sock -eofchar D -translation lf
    lappend l [chan configure $sock -eofchar] \
	[chan configure $sock -translation]
} -cleanup {
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
    after cancel $timer
    testfevent cmd {chan close $f}
    list [testfevent cmd {set x}] [testfevent cmd {info commands after}]
} {{f triggered: foo bar} after}
test chan-io-46.2 {Tcl event loop vs multiple interpreters} testfevent {
    testfevent create
    testfevent cmd {
        variable x 0
        after 100 {set x triggered}
        vwait [namespace which -variable x]
        set x
    }
} {triggered}
test chan-io-46.3 {Tcl event loop vs multiple interpreters} testfevent {
    testfevent create
    testfevent cmd {
        set x 0
        after 10 {lappend x timer}
        after 30
        set result $x
        update idletasks
        lappend result $x
        update
        lappend result $x
    }
} {0 0 {0 timer}}

test chan-io-47.1 {chan event vs multiple interpreters} -setup {
    set f  [open $path(foo) r]
    set f2 [open $path(foo) r]
    set f3 [open $path(foo) r]
    set x {}
} -constraints {testfevent fileevent} -body {
    chan event $f readable {script 1}
    testfevent create
    testfevent share $f2
    testfevent cmd "chan event $f2 readable {script 2}"
    chan event $f3 readable {sript 3}
    lappend x [chan event $f2 readable]
    testfevent delete
    lappend x [chan event $f readable] [chan event $f2 readable] \
        [chan event $f3 readable]
} -cleanup {
    chan close $f
    chan close $f2
    chan close $f3
} -result {{} {script 1} {} {sript 3}}
test chan-io-47.2 {deleting chan event on interpreter delete} -setup {
    set f  [open $path(foo) r]
    set f2 [open $path(foo) r]
    set f3 [open $path(foo) r]
    set f4 [open $path(foo) r]
} -constraints {testfevent fileevent} -body {
    chan event $f readable {script 1}
    testfevent create
    testfevent share $f2
    testfevent share $f3
    testfevent cmd "chan event $f2 readable {script 2}
        chan event $f3 readable {script 3}"
    chan event $f4 readable {script 4}
    testfevent delete
    list [chan event $f readable] [chan event $f2 readable] \
	[chan event $f3 readable] [chan event $f4 readable]
} -cleanup {
    chan close $f
    chan close $f2







|
|
|
|





|
|
|
|
|
|
|
|

















|
















|







5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
    after cancel $timer
    testfevent cmd {chan close $f}
    list [testfevent cmd {set x}] [testfevent cmd {info commands after}]
} {{f triggered: foo bar} after}
test chan-io-46.2 {Tcl event loop vs multiple interpreters} testfevent {
    testfevent create
    testfevent cmd {
	variable x 0
	after 100 {set x triggered}
	vwait [namespace which -variable x]
	set x
    }
} {triggered}
test chan-io-46.3 {Tcl event loop vs multiple interpreters} testfevent {
    testfevent create
    testfevent cmd {
	set x 0
	after 10 {lappend x timer}
	after 30
	set result $x
	update idletasks
	lappend result $x
	update
	lappend result $x
    }
} {0 0 {0 timer}}

test chan-io-47.1 {chan event vs multiple interpreters} -setup {
    set f  [open $path(foo) r]
    set f2 [open $path(foo) r]
    set f3 [open $path(foo) r]
    set x {}
} -constraints {testfevent fileevent} -body {
    chan event $f readable {script 1}
    testfevent create
    testfevent share $f2
    testfevent cmd "chan event $f2 readable {script 2}"
    chan event $f3 readable {sript 3}
    lappend x [chan event $f2 readable]
    testfevent delete
    lappend x [chan event $f readable] [chan event $f2 readable] \
	[chan event $f3 readable]
} -cleanup {
    chan close $f
    chan close $f2
    chan close $f3
} -result {{} {script 1} {} {sript 3}}
test chan-io-47.2 {deleting chan event on interpreter delete} -setup {
    set f  [open $path(foo) r]
    set f2 [open $path(foo) r]
    set f3 [open $path(foo) r]
    set f4 [open $path(foo) r]
} -constraints {testfevent fileevent} -body {
    chan event $f readable {script 1}
    testfevent create
    testfevent share $f2
    testfevent share $f3
    testfevent cmd "chan event $f2 readable {script 2}
	chan event $f3 readable {script 3}"
    chan event $f4 readable {script 4}
    testfevent delete
    list [chan event $f readable] [chan event $f2 readable] \
	[chan event $f3 readable] [chan event $f4 readable]
} -cleanup {
    chan close $f
    chan close $f2
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
    set s0 [chan copy $f1 $f2]
    set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
    chan close $f1
    chan close $f2
    set s1 [file size $thisScript]
    set s2 [file size $path(test1)]
    if {($s1 == $s2) && ($s0 == $s1)} {
        lappend result ok
    }
    return $result
} -result {0 0 ok}
test chan-io-52.4 {TclCopyChannel} -constraints {fcopy} -setup {
    file delete $path(test1)
} -body {
    set f1 [open $thisScript]







|







6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
    set s0 [chan copy $f1 $f2]
    set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
    chan close $f1
    chan close $f2
    set s1 [file size $thisScript]
    set s2 [file size $path(test1)]
    if {($s1 == $s2) && ($s0 == $s1)} {
	lappend result ok
    }
    return $result
} -result {0 0 ok}
test chan-io-52.4 {TclCopyChannel} -constraints {fcopy} -setup {
    file delete $path(test1)
} -body {
    set f1 [open $thisScript]
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
    chan configure $f1 -translation binary -blocking 0
    chan configure $f2 -translation binary -blocking 0
    chan copy $f1 $f2 -size -1 ;# -1 means 'copy all', same as if no -size specified.
    set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
    chan close $f1
    chan close $f2
    if {[file size $thisScript] == [file size $path(test1)]} {
        lappend result ok
    }
    return $result
} -result {0 0 ok}
test chan-io-52.5a {TclCopyChannel, all, other negative value} -setup {
    file delete $path(test1)
} -constraints {fcopy} -body {
    set f1 [open $thisScript]
    set f2 [open $path(test1) w]
    chan configure $f1 -translation binary -blocking 0
    chan configure $f2 -translation binary -blocking 0
    chan copy $f1 $f2 -size -2 ;# < 0 behaves like -1, copy all
    set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
    chan close $f1
    chan close $f2
    if {[file size $thisScript] == [file size $path(test1)]} {
        lappend result ok
    }
    return $result
} -result {0 0 ok}
test chan-io-52.5b {TclCopyChannel, all, wrap to negative value} -setup {
    file delete $path(test1)
} -constraints {fcopy} -body {
    set f1 [open $thisScript]
    set f2 [open $path(test1) w]
    chan configure $f1 -translation binary -blocking 0
    chan configure $f2 -translation binary -blocking 0
    chan copy $f1 $f2 -size 3221176172 ;# Wrapped to < 0, behaves like -1, copy all
    set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
    chan close $f1
    chan close $f2
    if {[file size $thisScript] ==  [file size $path(test1)]} {
        lappend result ok
    }
    return $result
} -result {0 0 ok}
test chan-io-52.6 {TclCopyChannel} -setup {
    file delete $path(test1)
} -constraints {fcopy} -body {
    set f1 [open $thisScript]
    set f2 [open $path(test1) w]
    chan configure $f1 -translation binary -blocking 0
    chan configure $f2 -translation binary -blocking 0
    set s0 [chan copy $f1 $f2 -size [expr {[file size $thisScript] + 5}]]
    set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
    chan close $f1
    chan close $f2
    set s1 [file size $thisScript]
    set s2 [file size $path(test1)]
    if {($s1 == $s2) && ($s0 == $s1)} {
        lappend result ok
    }
    return $result
} -result {0 0 ok}
test chan-io-52.7 {TclCopyChannel} -constraints {fcopy} -setup {
    file delete $path(test1)
} -body {
    set f1 [open $thisScript]
    set f2 [open $path(test1) w]
    chan configure $f1 -translation binary -blocking 0
    chan configure $f2 -translation binary -blocking 0
    chan copy $f1 $f2
    set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
    if {[file size $thisScript] == [file size $path(test1)]} {
        lappend result ok
    }
    return $result
} -cleanup {
    chan close $f1
    chan close $f2
} -result {0 0 ok}
test chan-io-52.8 {TclCopyChannel} -setup {







|















|















|

















|













|







6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
    chan configure $f1 -translation binary -blocking 0
    chan configure $f2 -translation binary -blocking 0
    chan copy $f1 $f2 -size -1 ;# -1 means 'copy all', same as if no -size specified.
    set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
    chan close $f1
    chan close $f2
    if {[file size $thisScript] == [file size $path(test1)]} {
	lappend result ok
    }
    return $result
} -result {0 0 ok}
test chan-io-52.5a {TclCopyChannel, all, other negative value} -setup {
    file delete $path(test1)
} -constraints {fcopy} -body {
    set f1 [open $thisScript]
    set f2 [open $path(test1) w]
    chan configure $f1 -translation binary -blocking 0
    chan configure $f2 -translation binary -blocking 0
    chan copy $f1 $f2 -size -2 ;# < 0 behaves like -1, copy all
    set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
    chan close $f1
    chan close $f2
    if {[file size $thisScript] == [file size $path(test1)]} {
	lappend result ok
    }
    return $result
} -result {0 0 ok}
test chan-io-52.5b {TclCopyChannel, all, wrap to negative value} -setup {
    file delete $path(test1)
} -constraints {fcopy} -body {
    set f1 [open $thisScript]
    set f2 [open $path(test1) w]
    chan configure $f1 -translation binary -blocking 0
    chan configure $f2 -translation binary -blocking 0
    chan copy $f1 $f2 -size 3221176172 ;# Wrapped to < 0, behaves like -1, copy all
    set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
    chan close $f1
    chan close $f2
    if {[file size $thisScript] ==  [file size $path(test1)]} {
	lappend result ok
    }
    return $result
} -result {0 0 ok}
test chan-io-52.6 {TclCopyChannel} -setup {
    file delete $path(test1)
} -constraints {fcopy} -body {
    set f1 [open $thisScript]
    set f2 [open $path(test1) w]
    chan configure $f1 -translation binary -blocking 0
    chan configure $f2 -translation binary -blocking 0
    set s0 [chan copy $f1 $f2 -size [expr {[file size $thisScript] + 5}]]
    set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
    chan close $f1
    chan close $f2
    set s1 [file size $thisScript]
    set s2 [file size $path(test1)]
    if {($s1 == $s2) && ($s0 == $s1)} {
	lappend result ok
    }
    return $result
} -result {0 0 ok}
test chan-io-52.7 {TclCopyChannel} -constraints {fcopy} -setup {
    file delete $path(test1)
} -body {
    set f1 [open $thisScript]
    set f2 [open $path(test1) w]
    chan configure $f1 -translation binary -blocking 0
    chan configure $f2 -translation binary -blocking 0
    chan copy $f1 $f2
    set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
    if {[file size $thisScript] == [file size $path(test1)]} {
	lappend result ok
    }
    return $result
} -cleanup {
    chan close $f1
    chan close $f2
} -result {0 0 ok}
test chan-io-52.8 {TclCopyChannel} -setup {
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
    variable s0
    vwait [namespace which -variable s0]
    chan close $f1
    chan close $f2
    set s1 [file size $thisScript]
    set s2 [file size $path(test1)]
    if {($s1 == $s2) && ($s0 == $s1)} {
        lappend result ok
    }
    return $result
} -result {0 0 ok}
test chan-io-53.3 {CopyData: background read underflow} -setup {
    file delete $path(test1)
    file delete $path(pipe)
} -constraints {stdio unix fcopy} -body {







|







6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
    variable s0
    vwait [namespace which -variable s0]
    chan close $f1
    chan close $f2
    set s1 [file size $thisScript]
    set s2 [file size $path(test1)]
    if {($s1 == $s2) && ($s0 == $s1)} {
	lappend result ok
    }
    return $result
} -result {0 0 ok}
test chan-io-53.3 {CopyData: background read underflow} -setup {
    file delete $path(test1)
    file delete $path(pipe)
} -constraints {stdio unix fcopy} -body {
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
    variable fcopyTestCount
    incr fcopyTestCount $bytes
    if {[string length $error]} {
	set fcopyTestDone 1
    } elseif {[chan eof $in]} {
	set fcopyTestDone 0
    } else {
        # Delay next chan copy to wait for size>0 input bytes
        after 100 [list chan copy $in $out -size 1000 \
		-command [namespace code [list doFcopy $in $out]]]
    }
}
test chan-io-53.7 {CopyData: Flooding chan copy from pipe} -setup {
    variable fcopyTestDone
    file delete $path(pipe)
    catch {unset fcopyTestDone}
} -constraints {stdio fcopy} -body {
    set fcopyTestCount 0
    set f1 [open $path(pipe) w]
    chan puts $f1 {
	# Write  10 bytes / 10 msec
	proc Write {count} {
	    chan puts -nonewline "1234567890"
	    if {[incr count -1]} {
	        after 10 [list Write $count]
	    } else {
	        set ::ready 1
	    }
	}
	chan configure stdout -buffering none
	Write 345 ;# 3450 bytes ~3.45 sec
	vwait ready
	exit 0
    }







|
|















|

|







7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
    variable fcopyTestCount
    incr fcopyTestCount $bytes
    if {[string length $error]} {
	set fcopyTestDone 1
    } elseif {[chan eof $in]} {
	set fcopyTestDone 0
    } else {
	# Delay next chan copy to wait for size>0 input bytes
	after 100 [list chan copy $in $out -size 1000 \
		-command [namespace code [list doFcopy $in $out]]]
    }
}
test chan-io-53.7 {CopyData: Flooding chan copy from pipe} -setup {
    variable fcopyTestDone
    file delete $path(pipe)
    catch {unset fcopyTestDone}
} -constraints {stdio fcopy} -body {
    set fcopyTestCount 0
    set f1 [open $path(pipe) w]
    chan puts $f1 {
	# Write  10 bytes / 10 msec
	proc Write {count} {
	    chan puts -nonewline "1234567890"
	    if {[incr count -1]} {
		after 10 [list Write $count]
	    } else {
		set ::ready 1
	    }
	}
	chan configure stdout -buffering none
	Write 345 ;# 3450 bytes ~3.45 sec
	vwait ready
	exit 0
    }
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
    catch {after cancel $token}
    set ::forever
} -cleanup {
    chan close $pipe
    rename ::done {}
    if {[testConstraint win]} {
	after 1000;		# Allow Windows time to figure out that the
                                # process is gone
    }
    catch {close $out}
    catch {removeFile out}
    catch {removeFile err}
    catch {unset ::forever}
} -result OK
test chan-io-53.10 {Bug 1350564, multi-directional fcopy} -setup {







|







7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
    catch {after cancel $token}
    set ::forever
} -cleanup {
    chan close $pipe
    rename ::done {}
    if {[testConstraint win]} {
	after 1000;		# Allow Windows time to figure out that the
				# process is gone
    }
    catch {close $out}
    catch {removeFile out}
    catch {removeFile err}
    catch {unset ::forever}
} -result OK
test chan-io-53.10 {Bug 1350564, multi-directional fcopy} -setup {
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
		chan puts stderr 2COPY
	    }
	    chan puts stderr ...
	}
	chan puts stderr SRV
	set l {}
	set srv [socket -server new -myaddr 127.0.0.1 0]
        set port [lindex [chan configure $srv -sockname] 2]
	chan puts stderr WAITING
	chan event stdin readable bye
	puts "OK $port"
	vwait forever
    }
    # wait for OK from server.
    lassign [chan gets $pipe] ok port







|







7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
		chan puts stderr 2COPY
	    }
	    chan puts stderr ...
	}
	chan puts stderr SRV
	set l {}
	set srv [socket -server new -myaddr 127.0.0.1 0]
	set port [lindex [chan configure $srv -sockname] 2]
	chan puts stderr WAITING
	chan event stdin readable bye
	puts "OK $port"
	vwait forever
    }
    # wait for OK from server.
    lassign [chan gets $pipe] ok port
Changes to tests/clock.test.
14806
14807
14808
14809
14810
14811
14812
14813
14814
14815
14816
14817
14818
14819
14820
14821
14822
14823
14824
14825
14826
14827
14828
14829
14830
14831
14832
14833
14834
14835
14836
14837
14838
14839
14840
14841
14842
14843
14844
14845
14846
14847
14848
14849
14850
14851
14852
14853
14854
14855
14856
14857
14858
14859
14860
14861
14862
14863
14864
14865
14866
14867
14868
14869
14870
14871
14872
14873
14874
14875
14876
14877
14878
14879
14880
14881
14882
14883
14884
14885
14886
14887
14888
14889
14890
14891
14892
14893
14894
14895
14896
14897
14898
14899
14900
14901
14902
14903
14904
14905
14906
14907
14908
14909
14910
14911
14912
14913
14914
14915
14916
14917
14918
14919
14920
14921
14922
14923
14924
14925
14926
14927
14928
14929
14930
14931
14932
14933
14934
14935
14936
14937
14938
14939
14940
14941
14942
14943
14944
14945
14946
14947
14948
14949
14950
14951
14952
14953
14954
14955
14956
14957
14958
14959
14960
14961
14962
14963
14964
14965
14966
14967
14968
14969
14970
14971
14972
14973
14974
14975
14976
14977
14978
14979
14980
14981
14982
14983
14984
14985
14986
14987
14988
14989
14990
14991
14992
14993
14994
14995
14996
14997
14998
14999
15000
15001
15002
15003
15004
15005
15006
15007
15008
15009
15010
15011
15012
15013
15014
15015
15016
15017
15018
15019
15020
15021
15022
15023
15024
15025
15026
15027
15028
15029
15030
15031
15032
15033
15034
15035
15036
15037
15038
15039
15040
15041
15042
15043
15044
15045
15046
15047
15048
15049
15050
15051
15052
15053
15054
15055
15056
15057
15058
15059
15060
15061
15062
15063
15064
15065
15066
15067
15068
15069
15070
15071
15072
15073
15074
15075
15076
15077
15078
15079
15080
15081
15082
15083
15084
15085
15086
15087
15088
15089
15090
15091
15092
15093
15094
15095
15096
15097
15098
15099
15100
15101
15102
15103
15104
15105
15106
15107
15108
15109
15110
15111
15112
15113
15114
15115
15116
15117
15118
15119
15120
15121
15122
15123
15124
15125
15126
15127
15128
15129
15130
15131
15132
15133
15134
15135
15136
15137
15138
15139
15140
15141
15142
15143
15144
15145
15146
15147
15148
15149
15150
15151
15152
15153
15154
15155
15156
15157
15158
15159
15160
15161
15162
15163
15164
15165
15166
15167
15168
15169
15170
15171
15172
15173
15174
15175
15176
15177
15178
15179
15180
15181
15182
15183
15184
15185
15186
15187
15188
15189
15190
15191
15192
15193
15194
15195
15196
15197
15198
15199
15200
15201
15202
15203
15204
15205
15206
15207
15208
15209
15210
15211
15212
15213
15214
15215
15216
15217
15218
15219
15220
15221
15222
15223
15224
15225
15226
15227
15228
15229
15230
15231
15232
15233
15234
15235
15236
15237
15238
15239
15240
15241
15242
15243
15244
15245
15246
15247
15248
15249
15250
15251
15252
15253
15254
15255
15256
15257
15258
15259
15260
15261
15262
15263
15264
15265
15266
15267
15268
15269
15270
15271
15272
15273
15274
15275
15276
15277
15278
15279
15280
15281
15282
15283
15284
15285
15286
15287
15288
15289
15290
15291
15292
15293
15294
15295
15296
15297
15298
15299
15300
15301
15302
15303
15304
15305
15306
15307
15308
15309
15310
15311
15312
15313
15314
15315
15316
15317
15318
15319
15320
15321
15322
15323
15324
15325
15326
15327
15328
15329
15330
15331
15332
15333
15334
15335
15336
15337
15338
15339
15340
15341
15342
15343
15344
15345
15346
15347
15348
15349
15350
15351
15352
15353
15354
15355
15356
15357
15358
15359
15360
15361
15362
15363
15364
15365
15366
15367
15368
15369
15370
15371
15372
15373
15374
15375
15376
15377
15378
15379
15380
15381
15382
15383
15384
15385
15386
15387
15388
15389
15390
15391
15392
# BEGIN testcases4

# Test formatting of time of day
# Format groups tested: %H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+

test clock-4.1 { format time of day 00:00:00 } {
    clock format 0 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {00 ? 12 xii  0 ? 12 xii 00 ? AM am 12:00:00 am 00:00 00 ? 00:00:00 00:00:00 ? h ? m ? s Thu Jan  1 00:00:00 GMT 1970}
test clock-4.2 { format time of day 00:00:01 } {
    clock format 1 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {00 ? 12 xii  0 ? 12 xii 00 ? AM am 12:00:01 am 00:00 01 i 00:00:01 00:00:01 ? h ? m i s Thu Jan  1 00:00:01 GMT 1970}
test clock-4.3 { format time of day 00:00:58 } {
    clock format 58 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {00 ? 12 xii  0 ? 12 xii 00 ? AM am 12:00:58 am 00:00 58 lviii 00:00:58 00:00:58 ? h ? m lviii s Thu Jan  1 00:00:58 GMT 1970}
test clock-4.4 { format time of day 00:00:59 } {
    clock format 59 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {00 ? 12 xii  0 ? 12 xii 00 ? AM am 12:00:59 am 00:00 59 lix 00:00:59 00:00:59 ? h ? m lix s Thu Jan  1 00:00:59 GMT 1970}
test clock-4.5 { format time of day 00:01:00 } {
    clock format 60 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {00 ? 12 xii  0 ? 12 xii 01 i AM am 12:01:00 am 00:01 00 ? 00:01:00 00:01:00 ? h i m ? s Thu Jan  1 00:01:00 GMT 1970}
test clock-4.6 { format time of day 00:01:01 } {
    clock format 61 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {00 ? 12 xii  0 ? 12 xii 01 i AM am 12:01:01 am 00:01 01 i 00:01:01 00:01:01 ? h i m i s Thu Jan  1 00:01:01 GMT 1970}
test clock-4.7 { format time of day 00:01:58 } {
    clock format 118 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {00 ? 12 xii  0 ? 12 xii 01 i AM am 12:01:58 am 00:01 58 lviii 00:01:58 00:01:58 ? h i m lviii s Thu Jan  1 00:01:58 GMT 1970}
test clock-4.8 { format time of day 00:01:59 } {
    clock format 119 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {00 ? 12 xii  0 ? 12 xii 01 i AM am 12:01:59 am 00:01 59 lix 00:01:59 00:01:59 ? h i m lix s Thu Jan  1 00:01:59 GMT 1970}
test clock-4.9 { format time of day 00:58:00 } {
    clock format 3480 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {00 ? 12 xii  0 ? 12 xii 58 lviii AM am 12:58:00 am 00:58 00 ? 00:58:00 00:58:00 ? h lviii m ? s Thu Jan  1 00:58:00 GMT 1970}
test clock-4.10 { format time of day 00:58:01 } {
    clock format 3481 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {00 ? 12 xii  0 ? 12 xii 58 lviii AM am 12:58:01 am 00:58 01 i 00:58:01 00:58:01 ? h lviii m i s Thu Jan  1 00:58:01 GMT 1970}
test clock-4.11 { format time of day 00:58:58 } {
    clock format 3538 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {00 ? 12 xii  0 ? 12 xii 58 lviii AM am 12:58:58 am 00:58 58 lviii 00:58:58 00:58:58 ? h lviii m lviii s Thu Jan  1 00:58:58 GMT 1970}
test clock-4.12 { format time of day 00:58:59 } {
    clock format 3539 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {00 ? 12 xii  0 ? 12 xii 58 lviii AM am 12:58:59 am 00:58 59 lix 00:58:59 00:58:59 ? h lviii m lix s Thu Jan  1 00:58:59 GMT 1970}
test clock-4.13 { format time of day 00:59:00 } {
    clock format 3540 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {00 ? 12 xii  0 ? 12 xii 59 lix AM am 12:59:00 am 00:59 00 ? 00:59:00 00:59:00 ? h lix m ? s Thu Jan  1 00:59:00 GMT 1970}
test clock-4.14 { format time of day 00:59:01 } {
    clock format 3541 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {00 ? 12 xii  0 ? 12 xii 59 lix AM am 12:59:01 am 00:59 01 i 00:59:01 00:59:01 ? h lix m i s Thu Jan  1 00:59:01 GMT 1970}
test clock-4.15 { format time of day 00:59:58 } {
    clock format 3598 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {00 ? 12 xii  0 ? 12 xii 59 lix AM am 12:59:58 am 00:59 58 lviii 00:59:58 00:59:58 ? h lix m lviii s Thu Jan  1 00:59:58 GMT 1970}
test clock-4.16 { format time of day 00:59:59 } {
    clock format 3599 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {00 ? 12 xii  0 ? 12 xii 59 lix AM am 12:59:59 am 00:59 59 lix 00:59:59 00:59:59 ? h lix m lix s Thu Jan  1 00:59:59 GMT 1970}
test clock-4.17 { format time of day 01:00:00 } {
    clock format 3600 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {01 i 01 i  1 i  1 i 00 ? AM am 01:00:00 am 01:00 00 ? 01:00:00 01:00:00 i h ? m ? s Thu Jan  1 01:00:00 GMT 1970}
test clock-4.18 { format time of day 01:00:01 } {
    clock format 3601 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {01 i 01 i  1 i  1 i 00 ? AM am 01:00:01 am 01:00 01 i 01:00:01 01:00:01 i h ? m i s Thu Jan  1 01:00:01 GMT 1970}
test clock-4.19 { format time of day 01:00:58 } {
    clock format 3658 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {01 i 01 i  1 i  1 i 00 ? AM am 01:00:58 am 01:00 58 lviii 01:00:58 01:00:58 i h ? m lviii s Thu Jan  1 01:00:58 GMT 1970}
test clock-4.20 { format time of day 01:00:59 } {
    clock format 3659 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {01 i 01 i  1 i  1 i 00 ? AM am 01:00:59 am 01:00 59 lix 01:00:59 01:00:59 i h ? m lix s Thu Jan  1 01:00:59 GMT 1970}
test clock-4.21 { format time of day 01:01:00 } {
    clock format 3660 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {01 i 01 i  1 i  1 i 01 i AM am 01:01:00 am 01:01 00 ? 01:01:00 01:01:00 i h i m ? s Thu Jan  1 01:01:00 GMT 1970}
test clock-4.22 { format time of day 01:01:01 } {
    clock format 3661 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {01 i 01 i  1 i  1 i 01 i AM am 01:01:01 am 01:01 01 i 01:01:01 01:01:01 i h i m i s Thu Jan  1 01:01:01 GMT 1970}
test clock-4.23 { format time of day 01:01:58 } {
    clock format 3718 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {01 i 01 i  1 i  1 i 01 i AM am 01:01:58 am 01:01 58 lviii 01:01:58 01:01:58 i h i m lviii s Thu Jan  1 01:01:58 GMT 1970}
test clock-4.24 { format time of day 01:01:59 } {
    clock format 3719 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {01 i 01 i  1 i  1 i 01 i AM am 01:01:59 am 01:01 59 lix 01:01:59 01:01:59 i h i m lix s Thu Jan  1 01:01:59 GMT 1970}
test clock-4.25 { format time of day 01:58:00 } {
    clock format 7080 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {01 i 01 i  1 i  1 i 58 lviii AM am 01:58:00 am 01:58 00 ? 01:58:00 01:58:00 i h lviii m ? s Thu Jan  1 01:58:00 GMT 1970}
test clock-4.26 { format time of day 01:58:01 } {
    clock format 7081 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {01 i 01 i  1 i  1 i 58 lviii AM am 01:58:01 am 01:58 01 i 01:58:01 01:58:01 i h lviii m i s Thu Jan  1 01:58:01 GMT 1970}
test clock-4.27 { format time of day 01:58:58 } {
    clock format 7138 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {01 i 01 i  1 i  1 i 58 lviii AM am 01:58:58 am 01:58 58 lviii 01:58:58 01:58:58 i h lviii m lviii s Thu Jan  1 01:58:58 GMT 1970}
test clock-4.28 { format time of day 01:58:59 } {
    clock format 7139 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {01 i 01 i  1 i  1 i 58 lviii AM am 01:58:59 am 01:58 59 lix 01:58:59 01:58:59 i h lviii m lix s Thu Jan  1 01:58:59 GMT 1970}
test clock-4.29 { format time of day 01:59:00 } {
    clock format 7140 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {01 i 01 i  1 i  1 i 59 lix AM am 01:59:00 am 01:59 00 ? 01:59:00 01:59:00 i h lix m ? s Thu Jan  1 01:59:00 GMT 1970}
test clock-4.30 { format time of day 01:59:01 } {
    clock format 7141 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {01 i 01 i  1 i  1 i 59 lix AM am 01:59:01 am 01:59 01 i 01:59:01 01:59:01 i h lix m i s Thu Jan  1 01:59:01 GMT 1970}
test clock-4.31 { format time of day 01:59:58 } {
    clock format 7198 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {01 i 01 i  1 i  1 i 59 lix AM am 01:59:58 am 01:59 58 lviii 01:59:58 01:59:58 i h lix m lviii s Thu Jan  1 01:59:58 GMT 1970}
test clock-4.32 { format time of day 01:59:59 } {
    clock format 7199 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {01 i 01 i  1 i  1 i 59 lix AM am 01:59:59 am 01:59 59 lix 01:59:59 01:59:59 i h lix m lix s Thu Jan  1 01:59:59 GMT 1970}
test clock-4.33 { format time of day 11:00:00 } {
    clock format 39600 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {11 xi 11 xi 11 xi 11 xi 00 ? AM am 11:00:00 am 11:00 00 ? 11:00:00 11:00:00 xi h ? m ? s Thu Jan  1 11:00:00 GMT 1970}
test clock-4.34 { format time of day 11:00:01 } {
    clock format 39601 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {11 xi 11 xi 11 xi 11 xi 00 ? AM am 11:00:01 am 11:00 01 i 11:00:01 11:00:01 xi h ? m i s Thu Jan  1 11:00:01 GMT 1970}
test clock-4.35 { format time of day 11:00:58 } {
    clock format 39658 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {11 xi 11 xi 11 xi 11 xi 00 ? AM am 11:00:58 am 11:00 58 lviii 11:00:58 11:00:58 xi h ? m lviii s Thu Jan  1 11:00:58 GMT 1970}
test clock-4.36 { format time of day 11:00:59 } {
    clock format 39659 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {11 xi 11 xi 11 xi 11 xi 00 ? AM am 11:00:59 am 11:00 59 lix 11:00:59 11:00:59 xi h ? m lix s Thu Jan  1 11:00:59 GMT 1970}
test clock-4.37 { format time of day 11:01:00 } {
    clock format 39660 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {11 xi 11 xi 11 xi 11 xi 01 i AM am 11:01:00 am 11:01 00 ? 11:01:00 11:01:00 xi h i m ? s Thu Jan  1 11:01:00 GMT 1970}
test clock-4.38 { format time of day 11:01:01 } {
    clock format 39661 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {11 xi 11 xi 11 xi 11 xi 01 i AM am 11:01:01 am 11:01 01 i 11:01:01 11:01:01 xi h i m i s Thu Jan  1 11:01:01 GMT 1970}
test clock-4.39 { format time of day 11:01:58 } {
    clock format 39718 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {11 xi 11 xi 11 xi 11 xi 01 i AM am 11:01:58 am 11:01 58 lviii 11:01:58 11:01:58 xi h i m lviii s Thu Jan  1 11:01:58 GMT 1970}
test clock-4.40 { format time of day 11:01:59 } {
    clock format 39719 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {11 xi 11 xi 11 xi 11 xi 01 i AM am 11:01:59 am 11:01 59 lix 11:01:59 11:01:59 xi h i m lix s Thu Jan  1 11:01:59 GMT 1970}
test clock-4.41 { format time of day 11:58:00 } {
    clock format 43080 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {11 xi 11 xi 11 xi 11 xi 58 lviii AM am 11:58:00 am 11:58 00 ? 11:58:00 11:58:00 xi h lviii m ? s Thu Jan  1 11:58:00 GMT 1970}
test clock-4.42 { format time of day 11:58:01 } {
    clock format 43081 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {11 xi 11 xi 11 xi 11 xi 58 lviii AM am 11:58:01 am 11:58 01 i 11:58:01 11:58:01 xi h lviii m i s Thu Jan  1 11:58:01 GMT 1970}
test clock-4.43 { format time of day 11:58:58 } {
    clock format 43138 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {11 xi 11 xi 11 xi 11 xi 58 lviii AM am 11:58:58 am 11:58 58 lviii 11:58:58 11:58:58 xi h lviii m lviii s Thu Jan  1 11:58:58 GMT 1970}
test clock-4.44 { format time of day 11:58:59 } {
    clock format 43139 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {11 xi 11 xi 11 xi 11 xi 58 lviii AM am 11:58:59 am 11:58 59 lix 11:58:59 11:58:59 xi h lviii m lix s Thu Jan  1 11:58:59 GMT 1970}
test clock-4.45 { format time of day 11:59:00 } {
    clock format 43140 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {11 xi 11 xi 11 xi 11 xi 59 lix AM am 11:59:00 am 11:59 00 ? 11:59:00 11:59:00 xi h lix m ? s Thu Jan  1 11:59:00 GMT 1970}
test clock-4.46 { format time of day 11:59:01 } {
    clock format 43141 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {11 xi 11 xi 11 xi 11 xi 59 lix AM am 11:59:01 am 11:59 01 i 11:59:01 11:59:01 xi h lix m i s Thu Jan  1 11:59:01 GMT 1970}
test clock-4.47 { format time of day 11:59:58 } {
    clock format 43198 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {11 xi 11 xi 11 xi 11 xi 59 lix AM am 11:59:58 am 11:59 58 lviii 11:59:58 11:59:58 xi h lix m lviii s Thu Jan  1 11:59:58 GMT 1970}
test clock-4.48 { format time of day 11:59:59 } {
    clock format 43199 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {11 xi 11 xi 11 xi 11 xi 59 lix AM am 11:59:59 am 11:59 59 lix 11:59:59 11:59:59 xi h lix m lix s Thu Jan  1 11:59:59 GMT 1970}
test clock-4.49 { format time of day 12:00:00 } {
    clock format 43200 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {12 xii 12 xii 12 xii 12 xii 00 ? PM pm 12:00:00 pm 12:00 00 ? 12:00:00 12:00:00 xii h ? m ? s Thu Jan  1 12:00:00 GMT 1970}
test clock-4.50 { format time of day 12:00:01 } {
    clock format 43201 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {12 xii 12 xii 12 xii 12 xii 00 ? PM pm 12:00:01 pm 12:00 01 i 12:00:01 12:00:01 xii h ? m i s Thu Jan  1 12:00:01 GMT 1970}
test clock-4.51 { format time of day 12:00:58 } {
    clock format 43258 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {12 xii 12 xii 12 xii 12 xii 00 ? PM pm 12:00:58 pm 12:00 58 lviii 12:00:58 12:00:58 xii h ? m lviii s Thu Jan  1 12:00:58 GMT 1970}
test clock-4.52 { format time of day 12:00:59 } {
    clock format 43259 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {12 xii 12 xii 12 xii 12 xii 00 ? PM pm 12:00:59 pm 12:00 59 lix 12:00:59 12:00:59 xii h ? m lix s Thu Jan  1 12:00:59 GMT 1970}
test clock-4.53 { format time of day 12:01:00 } {
    clock format 43260 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {12 xii 12 xii 12 xii 12 xii 01 i PM pm 12:01:00 pm 12:01 00 ? 12:01:00 12:01:00 xii h i m ? s Thu Jan  1 12:01:00 GMT 1970}
test clock-4.54 { format time of day 12:01:01 } {
    clock format 43261 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {12 xii 12 xii 12 xii 12 xii 01 i PM pm 12:01:01 pm 12:01 01 i 12:01:01 12:01:01 xii h i m i s Thu Jan  1 12:01:01 GMT 1970}
test clock-4.55 { format time of day 12:01:58 } {
    clock format 43318 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {12 xii 12 xii 12 xii 12 xii 01 i PM pm 12:01:58 pm 12:01 58 lviii 12:01:58 12:01:58 xii h i m lviii s Thu Jan  1 12:01:58 GMT 1970}
test clock-4.56 { format time of day 12:01:59 } {
    clock format 43319 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {12 xii 12 xii 12 xii 12 xii 01 i PM pm 12:01:59 pm 12:01 59 lix 12:01:59 12:01:59 xii h i m lix s Thu Jan  1 12:01:59 GMT 1970}
test clock-4.57 { format time of day 12:58:00 } {
    clock format 46680 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {12 xii 12 xii 12 xii 12 xii 58 lviii PM pm 12:58:00 pm 12:58 00 ? 12:58:00 12:58:00 xii h lviii m ? s Thu Jan  1 12:58:00 GMT 1970}
test clock-4.58 { format time of day 12:58:01 } {
    clock format 46681 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {12 xii 12 xii 12 xii 12 xii 58 lviii PM pm 12:58:01 pm 12:58 01 i 12:58:01 12:58:01 xii h lviii m i s Thu Jan  1 12:58:01 GMT 1970}
test clock-4.59 { format time of day 12:58:58 } {
    clock format 46738 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {12 xii 12 xii 12 xii 12 xii 58 lviii PM pm 12:58:58 pm 12:58 58 lviii 12:58:58 12:58:58 xii h lviii m lviii s Thu Jan  1 12:58:58 GMT 1970}
test clock-4.60 { format time of day 12:58:59 } {
    clock format 46739 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {12 xii 12 xii 12 xii 12 xii 58 lviii PM pm 12:58:59 pm 12:58 59 lix 12:58:59 12:58:59 xii h lviii m lix s Thu Jan  1 12:58:59 GMT 1970}
test clock-4.61 { format time of day 12:59:00 } {
    clock format 46740 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {12 xii 12 xii 12 xii 12 xii 59 lix PM pm 12:59:00 pm 12:59 00 ? 12:59:00 12:59:00 xii h lix m ? s Thu Jan  1 12:59:00 GMT 1970}
test clock-4.62 { format time of day 12:59:01 } {
    clock format 46741 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {12 xii 12 xii 12 xii 12 xii 59 lix PM pm 12:59:01 pm 12:59 01 i 12:59:01 12:59:01 xii h lix m i s Thu Jan  1 12:59:01 GMT 1970}
test clock-4.63 { format time of day 12:59:58 } {
    clock format 46798 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {12 xii 12 xii 12 xii 12 xii 59 lix PM pm 12:59:58 pm 12:59 58 lviii 12:59:58 12:59:58 xii h lix m lviii s Thu Jan  1 12:59:58 GMT 1970}
test clock-4.64 { format time of day 12:59:59 } {
    clock format 46799 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {12 xii 12 xii 12 xii 12 xii 59 lix PM pm 12:59:59 pm 12:59 59 lix 12:59:59 12:59:59 xii h lix m lix s Thu Jan  1 12:59:59 GMT 1970}
test clock-4.65 { format time of day 13:00:00 } {
    clock format 46800 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {13 xiii 01 i 13 xiii  1 i 00 ? PM pm 01:00:00 pm 13:00 00 ? 13:00:00 13:00:00 xiii h ? m ? s Thu Jan  1 13:00:00 GMT 1970}
test clock-4.66 { format time of day 13:00:01 } {
    clock format 46801 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {13 xiii 01 i 13 xiii  1 i 00 ? PM pm 01:00:01 pm 13:00 01 i 13:00:01 13:00:01 xiii h ? m i s Thu Jan  1 13:00:01 GMT 1970}
test clock-4.67 { format time of day 13:00:58 } {
    clock format 46858 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {13 xiii 01 i 13 xiii  1 i 00 ? PM pm 01:00:58 pm 13:00 58 lviii 13:00:58 13:00:58 xiii h ? m lviii s Thu Jan  1 13:00:58 GMT 1970}
test clock-4.68 { format time of day 13:00:59 } {
    clock format 46859 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {13 xiii 01 i 13 xiii  1 i 00 ? PM pm 01:00:59 pm 13:00 59 lix 13:00:59 13:00:59 xiii h ? m lix s Thu Jan  1 13:00:59 GMT 1970}
test clock-4.69 { format time of day 13:01:00 } {
    clock format 46860 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {13 xiii 01 i 13 xiii  1 i 01 i PM pm 01:01:00 pm 13:01 00 ? 13:01:00 13:01:00 xiii h i m ? s Thu Jan  1 13:01:00 GMT 1970}
test clock-4.70 { format time of day 13:01:01 } {
    clock format 46861 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {13 xiii 01 i 13 xiii  1 i 01 i PM pm 01:01:01 pm 13:01 01 i 13:01:01 13:01:01 xiii h i m i s Thu Jan  1 13:01:01 GMT 1970}
test clock-4.71 { format time of day 13:01:58 } {
    clock format 46918 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {13 xiii 01 i 13 xiii  1 i 01 i PM pm 01:01:58 pm 13:01 58 lviii 13:01:58 13:01:58 xiii h i m lviii s Thu Jan  1 13:01:58 GMT 1970}
test clock-4.72 { format time of day 13:01:59 } {
    clock format 46919 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {13 xiii 01 i 13 xiii  1 i 01 i PM pm 01:01:59 pm 13:01 59 lix 13:01:59 13:01:59 xiii h i m lix s Thu Jan  1 13:01:59 GMT 1970}
test clock-4.73 { format time of day 13:58:00 } {
    clock format 50280 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {13 xiii 01 i 13 xiii  1 i 58 lviii PM pm 01:58:00 pm 13:58 00 ? 13:58:00 13:58:00 xiii h lviii m ? s Thu Jan  1 13:58:00 GMT 1970}
test clock-4.74 { format time of day 13:58:01 } {
    clock format 50281 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {13 xiii 01 i 13 xiii  1 i 58 lviii PM pm 01:58:01 pm 13:58 01 i 13:58:01 13:58:01 xiii h lviii m i s Thu Jan  1 13:58:01 GMT 1970}
test clock-4.75 { format time of day 13:58:58 } {
    clock format 50338 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {13 xiii 01 i 13 xiii  1 i 58 lviii PM pm 01:58:58 pm 13:58 58 lviii 13:58:58 13:58:58 xiii h lviii m lviii s Thu Jan  1 13:58:58 GMT 1970}
test clock-4.76 { format time of day 13:58:59 } {
    clock format 50339 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {13 xiii 01 i 13 xiii  1 i 58 lviii PM pm 01:58:59 pm 13:58 59 lix 13:58:59 13:58:59 xiii h lviii m lix s Thu Jan  1 13:58:59 GMT 1970}
test clock-4.77 { format time of day 13:59:00 } {
    clock format 50340 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {13 xiii 01 i 13 xiii  1 i 59 lix PM pm 01:59:00 pm 13:59 00 ? 13:59:00 13:59:00 xiii h lix m ? s Thu Jan  1 13:59:00 GMT 1970}
test clock-4.78 { format time of day 13:59:01 } {
    clock format 50341 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {13 xiii 01 i 13 xiii  1 i 59 lix PM pm 01:59:01 pm 13:59 01 i 13:59:01 13:59:01 xiii h lix m i s Thu Jan  1 13:59:01 GMT 1970}
test clock-4.79 { format time of day 13:59:58 } {
    clock format 50398 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {13 xiii 01 i 13 xiii  1 i 59 lix PM pm 01:59:58 pm 13:59 58 lviii 13:59:58 13:59:58 xiii h lix m lviii s Thu Jan  1 13:59:58 GMT 1970}
test clock-4.80 { format time of day 13:59:59 } {
    clock format 50399 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {13 xiii 01 i 13 xiii  1 i 59 lix PM pm 01:59:59 pm 13:59 59 lix 13:59:59 13:59:59 xiii h lix m lix s Thu Jan  1 13:59:59 GMT 1970}
test clock-4.81 { format time of day 23:00:00 } {
    clock format 82800 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 00 ? PM pm 11:00:00 pm 23:00 00 ? 23:00:00 23:00:00 xxiii h ? m ? s Thu Jan  1 23:00:00 GMT 1970}
test clock-4.82 { format time of day 23:00:01 } {
    clock format 82801 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 00 ? PM pm 11:00:01 pm 23:00 01 i 23:00:01 23:00:01 xxiii h ? m i s Thu Jan  1 23:00:01 GMT 1970}
test clock-4.83 { format time of day 23:00:58 } {
    clock format 82858 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 00 ? PM pm 11:00:58 pm 23:00 58 lviii 23:00:58 23:00:58 xxiii h ? m lviii s Thu Jan  1 23:00:58 GMT 1970}
test clock-4.84 { format time of day 23:00:59 } {
    clock format 82859 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 00 ? PM pm 11:00:59 pm 23:00 59 lix 23:00:59 23:00:59 xxiii h ? m lix s Thu Jan  1 23:00:59 GMT 1970}
test clock-4.85 { format time of day 23:01:00 } {
    clock format 82860 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 01 i PM pm 11:01:00 pm 23:01 00 ? 23:01:00 23:01:00 xxiii h i m ? s Thu Jan  1 23:01:00 GMT 1970}
test clock-4.86 { format time of day 23:01:01 } {
    clock format 82861 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 01 i PM pm 11:01:01 pm 23:01 01 i 23:01:01 23:01:01 xxiii h i m i s Thu Jan  1 23:01:01 GMT 1970}
test clock-4.87 { format time of day 23:01:58 } {
    clock format 82918 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 01 i PM pm 11:01:58 pm 23:01 58 lviii 23:01:58 23:01:58 xxiii h i m lviii s Thu Jan  1 23:01:58 GMT 1970}
test clock-4.88 { format time of day 23:01:59 } {
    clock format 82919 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 01 i PM pm 11:01:59 pm 23:01 59 lix 23:01:59 23:01:59 xxiii h i m lix s Thu Jan  1 23:01:59 GMT 1970}
test clock-4.89 { format time of day 23:58:00 } {
    clock format 86280 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 58 lviii PM pm 11:58:00 pm 23:58 00 ? 23:58:00 23:58:00 xxiii h lviii m ? s Thu Jan  1 23:58:00 GMT 1970}
test clock-4.90 { format time of day 23:58:01 } {
    clock format 86281 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 58 lviii PM pm 11:58:01 pm 23:58 01 i 23:58:01 23:58:01 xxiii h lviii m i s Thu Jan  1 23:58:01 GMT 1970}
test clock-4.91 { format time of day 23:58:58 } {
    clock format 86338 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 58 lviii PM pm 11:58:58 pm 23:58 58 lviii 23:58:58 23:58:58 xxiii h lviii m lviii s Thu Jan  1 23:58:58 GMT 1970}
test clock-4.92 { format time of day 23:58:59 } {
    clock format 86339 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 58 lviii PM pm 11:58:59 pm 23:58 59 lix 23:58:59 23:58:59 xxiii h lviii m lix s Thu Jan  1 23:58:59 GMT 1970}
test clock-4.93 { format time of day 23:59:00 } {
    clock format 86340 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 59 lix PM pm 11:59:00 pm 23:59 00 ? 23:59:00 23:59:00 xxiii h lix m ? s Thu Jan  1 23:59:00 GMT 1970}
test clock-4.94 { format time of day 23:59:01 } {
    clock format 86341 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 59 lix PM pm 11:59:01 pm 23:59 01 i 23:59:01 23:59:01 xxiii h lix m i s Thu Jan  1 23:59:01 GMT 1970}
test clock-4.95 { format time of day 23:59:58 } {
    clock format 86398 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 59 lix PM pm 11:59:58 pm 23:59 58 lviii 23:59:58 23:59:58 xxiii h lix m lviii s Thu Jan  1 23:59:58 GMT 1970}
test clock-4.96 { format time of day 23:59:59 } {
    clock format 86399 \
        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
        -gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 59 lix PM pm 11:59:59 pm 23:59 59 lix 23:59:59 23:59:59 xxiii h lix m lix s Thu Jan  1 23:59:59 GMT 1970}

test clock-4.97.1 { format JDN/JD (calendar and astronomical) } {
    clock format 0 -format {%J %EJ %Ej} -gmt true
} {2440588 2440588.0 2440587.5}
test clock-4.97.2 { format JDN/JD (calendar and astronomical) } {
    clock format 43200 -format {%J %EJ %Ej} -gmt true







|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|







14806
14807
14808
14809
14810
14811
14812
14813
14814
14815
14816
14817
14818
14819
14820
14821
14822
14823
14824
14825
14826
14827
14828
14829
14830
14831
14832
14833
14834
14835
14836
14837
14838
14839
14840
14841
14842
14843
14844
14845
14846
14847
14848
14849
14850
14851
14852
14853
14854
14855
14856
14857
14858
14859
14860
14861
14862
14863
14864
14865
14866
14867
14868
14869
14870
14871
14872
14873
14874
14875
14876
14877
14878
14879
14880
14881
14882
14883
14884
14885
14886
14887
14888
14889
14890
14891
14892
14893
14894
14895
14896
14897
14898
14899
14900
14901
14902
14903
14904
14905
14906
14907
14908
14909
14910
14911
14912
14913
14914
14915
14916
14917
14918
14919
14920
14921
14922
14923
14924
14925
14926
14927
14928
14929
14930
14931
14932
14933
14934
14935
14936
14937
14938
14939
14940
14941
14942
14943
14944
14945
14946
14947
14948
14949
14950
14951
14952
14953
14954
14955
14956
14957
14958
14959
14960
14961
14962
14963
14964
14965
14966
14967
14968
14969
14970
14971
14972
14973
14974
14975
14976
14977
14978
14979
14980
14981
14982
14983
14984
14985
14986
14987
14988
14989
14990
14991
14992
14993
14994
14995
14996
14997
14998
14999
15000
15001
15002
15003
15004
15005
15006
15007
15008
15009
15010
15011
15012
15013
15014
15015
15016
15017
15018
15019
15020
15021
15022
15023
15024
15025
15026
15027
15028
15029
15030
15031
15032
15033
15034
15035
15036
15037
15038
15039
15040
15041
15042
15043
15044
15045
15046
15047
15048
15049
15050
15051
15052
15053
15054
15055
15056
15057
15058
15059
15060
15061
15062
15063
15064
15065
15066
15067
15068
15069
15070
15071
15072
15073
15074
15075
15076
15077
15078
15079
15080
15081
15082
15083
15084
15085
15086
15087
15088
15089
15090
15091
15092
15093
15094
15095
15096
15097
15098
15099
15100
15101
15102
15103
15104
15105
15106
15107
15108
15109
15110
15111
15112
15113
15114
15115
15116
15117
15118
15119
15120
15121
15122
15123
15124
15125
15126
15127
15128
15129
15130
15131
15132
15133
15134
15135
15136
15137
15138
15139
15140
15141
15142
15143
15144
15145
15146
15147
15148
15149
15150
15151
15152
15153
15154
15155
15156
15157
15158
15159
15160
15161
15162
15163
15164
15165
15166
15167
15168
15169
15170
15171
15172
15173
15174
15175
15176
15177
15178
15179
15180
15181
15182
15183
15184
15185
15186
15187
15188
15189
15190
15191
15192
15193
15194
15195
15196
15197
15198
15199
15200
15201
15202
15203
15204
15205
15206
15207
15208
15209
15210
15211
15212
15213
15214
15215
15216
15217
15218
15219
15220
15221
15222
15223
15224
15225
15226
15227
15228
15229
15230
15231
15232
15233
15234
15235
15236
15237
15238
15239
15240
15241
15242
15243
15244
15245
15246
15247
15248
15249
15250
15251
15252
15253
15254
15255
15256
15257
15258
15259
15260
15261
15262
15263
15264
15265
15266
15267
15268
15269
15270
15271
15272
15273
15274
15275
15276
15277
15278
15279
15280
15281
15282
15283
15284
15285
15286
15287
15288
15289
15290
15291
15292
15293
15294
15295
15296
15297
15298
15299
15300
15301
15302
15303
15304
15305
15306
15307
15308
15309
15310
15311
15312
15313
15314
15315
15316
15317
15318
15319
15320
15321
15322
15323
15324
15325
15326
15327
15328
15329
15330
15331
15332
15333
15334
15335
15336
15337
15338
15339
15340
15341
15342
15343
15344
15345
15346
15347
15348
15349
15350
15351
15352
15353
15354
15355
15356
15357
15358
15359
15360
15361
15362
15363
15364
15365
15366
15367
15368
15369
15370
15371
15372
15373
15374
15375
15376
15377
15378
15379
15380
15381
15382
15383
15384
15385
15386
15387
15388
15389
15390
15391
15392
# BEGIN testcases4

# Test formatting of time of day
# Format groups tested: %H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+

test clock-4.1 { format time of day 00:00:00 } {
    clock format 0 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {00 ? 12 xii  0 ? 12 xii 00 ? AM am 12:00:00 am 00:00 00 ? 00:00:00 00:00:00 ? h ? m ? s Thu Jan  1 00:00:00 GMT 1970}
test clock-4.2 { format time of day 00:00:01 } {
    clock format 1 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {00 ? 12 xii  0 ? 12 xii 00 ? AM am 12:00:01 am 00:00 01 i 00:00:01 00:00:01 ? h ? m i s Thu Jan  1 00:00:01 GMT 1970}
test clock-4.3 { format time of day 00:00:58 } {
    clock format 58 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {00 ? 12 xii  0 ? 12 xii 00 ? AM am 12:00:58 am 00:00 58 lviii 00:00:58 00:00:58 ? h ? m lviii s Thu Jan  1 00:00:58 GMT 1970}
test clock-4.4 { format time of day 00:00:59 } {
    clock format 59 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {00 ? 12 xii  0 ? 12 xii 00 ? AM am 12:00:59 am 00:00 59 lix 00:00:59 00:00:59 ? h ? m lix s Thu Jan  1 00:00:59 GMT 1970}
test clock-4.5 { format time of day 00:01:00 } {
    clock format 60 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {00 ? 12 xii  0 ? 12 xii 01 i AM am 12:01:00 am 00:01 00 ? 00:01:00 00:01:00 ? h i m ? s Thu Jan  1 00:01:00 GMT 1970}
test clock-4.6 { format time of day 00:01:01 } {
    clock format 61 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {00 ? 12 xii  0 ? 12 xii 01 i AM am 12:01:01 am 00:01 01 i 00:01:01 00:01:01 ? h i m i s Thu Jan  1 00:01:01 GMT 1970}
test clock-4.7 { format time of day 00:01:58 } {
    clock format 118 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {00 ? 12 xii  0 ? 12 xii 01 i AM am 12:01:58 am 00:01 58 lviii 00:01:58 00:01:58 ? h i m lviii s Thu Jan  1 00:01:58 GMT 1970}
test clock-4.8 { format time of day 00:01:59 } {
    clock format 119 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {00 ? 12 xii  0 ? 12 xii 01 i AM am 12:01:59 am 00:01 59 lix 00:01:59 00:01:59 ? h i m lix s Thu Jan  1 00:01:59 GMT 1970}
test clock-4.9 { format time of day 00:58:00 } {
    clock format 3480 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {00 ? 12 xii  0 ? 12 xii 58 lviii AM am 12:58:00 am 00:58 00 ? 00:58:00 00:58:00 ? h lviii m ? s Thu Jan  1 00:58:00 GMT 1970}
test clock-4.10 { format time of day 00:58:01 } {
    clock format 3481 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {00 ? 12 xii  0 ? 12 xii 58 lviii AM am 12:58:01 am 00:58 01 i 00:58:01 00:58:01 ? h lviii m i s Thu Jan  1 00:58:01 GMT 1970}
test clock-4.11 { format time of day 00:58:58 } {
    clock format 3538 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {00 ? 12 xii  0 ? 12 xii 58 lviii AM am 12:58:58 am 00:58 58 lviii 00:58:58 00:58:58 ? h lviii m lviii s Thu Jan  1 00:58:58 GMT 1970}
test clock-4.12 { format time of day 00:58:59 } {
    clock format 3539 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {00 ? 12 xii  0 ? 12 xii 58 lviii AM am 12:58:59 am 00:58 59 lix 00:58:59 00:58:59 ? h lviii m lix s Thu Jan  1 00:58:59 GMT 1970}
test clock-4.13 { format time of day 00:59:00 } {
    clock format 3540 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {00 ? 12 xii  0 ? 12 xii 59 lix AM am 12:59:00 am 00:59 00 ? 00:59:00 00:59:00 ? h lix m ? s Thu Jan  1 00:59:00 GMT 1970}
test clock-4.14 { format time of day 00:59:01 } {
    clock format 3541 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {00 ? 12 xii  0 ? 12 xii 59 lix AM am 12:59:01 am 00:59 01 i 00:59:01 00:59:01 ? h lix m i s Thu Jan  1 00:59:01 GMT 1970}
test clock-4.15 { format time of day 00:59:58 } {
    clock format 3598 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {00 ? 12 xii  0 ? 12 xii 59 lix AM am 12:59:58 am 00:59 58 lviii 00:59:58 00:59:58 ? h lix m lviii s Thu Jan  1 00:59:58 GMT 1970}
test clock-4.16 { format time of day 00:59:59 } {
    clock format 3599 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {00 ? 12 xii  0 ? 12 xii 59 lix AM am 12:59:59 am 00:59 59 lix 00:59:59 00:59:59 ? h lix m lix s Thu Jan  1 00:59:59 GMT 1970}
test clock-4.17 { format time of day 01:00:00 } {
    clock format 3600 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {01 i 01 i  1 i  1 i 00 ? AM am 01:00:00 am 01:00 00 ? 01:00:00 01:00:00 i h ? m ? s Thu Jan  1 01:00:00 GMT 1970}
test clock-4.18 { format time of day 01:00:01 } {
    clock format 3601 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {01 i 01 i  1 i  1 i 00 ? AM am 01:00:01 am 01:00 01 i 01:00:01 01:00:01 i h ? m i s Thu Jan  1 01:00:01 GMT 1970}
test clock-4.19 { format time of day 01:00:58 } {
    clock format 3658 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {01 i 01 i  1 i  1 i 00 ? AM am 01:00:58 am 01:00 58 lviii 01:00:58 01:00:58 i h ? m lviii s Thu Jan  1 01:00:58 GMT 1970}
test clock-4.20 { format time of day 01:00:59 } {
    clock format 3659 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {01 i 01 i  1 i  1 i 00 ? AM am 01:00:59 am 01:00 59 lix 01:00:59 01:00:59 i h ? m lix s Thu Jan  1 01:00:59 GMT 1970}
test clock-4.21 { format time of day 01:01:00 } {
    clock format 3660 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {01 i 01 i  1 i  1 i 01 i AM am 01:01:00 am 01:01 00 ? 01:01:00 01:01:00 i h i m ? s Thu Jan  1 01:01:00 GMT 1970}
test clock-4.22 { format time of day 01:01:01 } {
    clock format 3661 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {01 i 01 i  1 i  1 i 01 i AM am 01:01:01 am 01:01 01 i 01:01:01 01:01:01 i h i m i s Thu Jan  1 01:01:01 GMT 1970}
test clock-4.23 { format time of day 01:01:58 } {
    clock format 3718 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {01 i 01 i  1 i  1 i 01 i AM am 01:01:58 am 01:01 58 lviii 01:01:58 01:01:58 i h i m lviii s Thu Jan  1 01:01:58 GMT 1970}
test clock-4.24 { format time of day 01:01:59 } {
    clock format 3719 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {01 i 01 i  1 i  1 i 01 i AM am 01:01:59 am 01:01 59 lix 01:01:59 01:01:59 i h i m lix s Thu Jan  1 01:01:59 GMT 1970}
test clock-4.25 { format time of day 01:58:00 } {
    clock format 7080 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {01 i 01 i  1 i  1 i 58 lviii AM am 01:58:00 am 01:58 00 ? 01:58:00 01:58:00 i h lviii m ? s Thu Jan  1 01:58:00 GMT 1970}
test clock-4.26 { format time of day 01:58:01 } {
    clock format 7081 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {01 i 01 i  1 i  1 i 58 lviii AM am 01:58:01 am 01:58 01 i 01:58:01 01:58:01 i h lviii m i s Thu Jan  1 01:58:01 GMT 1970}
test clock-4.27 { format time of day 01:58:58 } {
    clock format 7138 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {01 i 01 i  1 i  1 i 58 lviii AM am 01:58:58 am 01:58 58 lviii 01:58:58 01:58:58 i h lviii m lviii s Thu Jan  1 01:58:58 GMT 1970}
test clock-4.28 { format time of day 01:58:59 } {
    clock format 7139 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {01 i 01 i  1 i  1 i 58 lviii AM am 01:58:59 am 01:58 59 lix 01:58:59 01:58:59 i h lviii m lix s Thu Jan  1 01:58:59 GMT 1970}
test clock-4.29 { format time of day 01:59:00 } {
    clock format 7140 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {01 i 01 i  1 i  1 i 59 lix AM am 01:59:00 am 01:59 00 ? 01:59:00 01:59:00 i h lix m ? s Thu Jan  1 01:59:00 GMT 1970}
test clock-4.30 { format time of day 01:59:01 } {
    clock format 7141 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {01 i 01 i  1 i  1 i 59 lix AM am 01:59:01 am 01:59 01 i 01:59:01 01:59:01 i h lix m i s Thu Jan  1 01:59:01 GMT 1970}
test clock-4.31 { format time of day 01:59:58 } {
    clock format 7198 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {01 i 01 i  1 i  1 i 59 lix AM am 01:59:58 am 01:59 58 lviii 01:59:58 01:59:58 i h lix m lviii s Thu Jan  1 01:59:58 GMT 1970}
test clock-4.32 { format time of day 01:59:59 } {
    clock format 7199 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {01 i 01 i  1 i  1 i 59 lix AM am 01:59:59 am 01:59 59 lix 01:59:59 01:59:59 i h lix m lix s Thu Jan  1 01:59:59 GMT 1970}
test clock-4.33 { format time of day 11:00:00 } {
    clock format 39600 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {11 xi 11 xi 11 xi 11 xi 00 ? AM am 11:00:00 am 11:00 00 ? 11:00:00 11:00:00 xi h ? m ? s Thu Jan  1 11:00:00 GMT 1970}
test clock-4.34 { format time of day 11:00:01 } {
    clock format 39601 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {11 xi 11 xi 11 xi 11 xi 00 ? AM am 11:00:01 am 11:00 01 i 11:00:01 11:00:01 xi h ? m i s Thu Jan  1 11:00:01 GMT 1970}
test clock-4.35 { format time of day 11:00:58 } {
    clock format 39658 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {11 xi 11 xi 11 xi 11 xi 00 ? AM am 11:00:58 am 11:00 58 lviii 11:00:58 11:00:58 xi h ? m lviii s Thu Jan  1 11:00:58 GMT 1970}
test clock-4.36 { format time of day 11:00:59 } {
    clock format 39659 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {11 xi 11 xi 11 xi 11 xi 00 ? AM am 11:00:59 am 11:00 59 lix 11:00:59 11:00:59 xi h ? m lix s Thu Jan  1 11:00:59 GMT 1970}
test clock-4.37 { format time of day 11:01:00 } {
    clock format 39660 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {11 xi 11 xi 11 xi 11 xi 01 i AM am 11:01:00 am 11:01 00 ? 11:01:00 11:01:00 xi h i m ? s Thu Jan  1 11:01:00 GMT 1970}
test clock-4.38 { format time of day 11:01:01 } {
    clock format 39661 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {11 xi 11 xi 11 xi 11 xi 01 i AM am 11:01:01 am 11:01 01 i 11:01:01 11:01:01 xi h i m i s Thu Jan  1 11:01:01 GMT 1970}
test clock-4.39 { format time of day 11:01:58 } {
    clock format 39718 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {11 xi 11 xi 11 xi 11 xi 01 i AM am 11:01:58 am 11:01 58 lviii 11:01:58 11:01:58 xi h i m lviii s Thu Jan  1 11:01:58 GMT 1970}
test clock-4.40 { format time of day 11:01:59 } {
    clock format 39719 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {11 xi 11 xi 11 xi 11 xi 01 i AM am 11:01:59 am 11:01 59 lix 11:01:59 11:01:59 xi h i m lix s Thu Jan  1 11:01:59 GMT 1970}
test clock-4.41 { format time of day 11:58:00 } {
    clock format 43080 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {11 xi 11 xi 11 xi 11 xi 58 lviii AM am 11:58:00 am 11:58 00 ? 11:58:00 11:58:00 xi h lviii m ? s Thu Jan  1 11:58:00 GMT 1970}
test clock-4.42 { format time of day 11:58:01 } {
    clock format 43081 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {11 xi 11 xi 11 xi 11 xi 58 lviii AM am 11:58:01 am 11:58 01 i 11:58:01 11:58:01 xi h lviii m i s Thu Jan  1 11:58:01 GMT 1970}
test clock-4.43 { format time of day 11:58:58 } {
    clock format 43138 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {11 xi 11 xi 11 xi 11 xi 58 lviii AM am 11:58:58 am 11:58 58 lviii 11:58:58 11:58:58 xi h lviii m lviii s Thu Jan  1 11:58:58 GMT 1970}
test clock-4.44 { format time of day 11:58:59 } {
    clock format 43139 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {11 xi 11 xi 11 xi 11 xi 58 lviii AM am 11:58:59 am 11:58 59 lix 11:58:59 11:58:59 xi h lviii m lix s Thu Jan  1 11:58:59 GMT 1970}
test clock-4.45 { format time of day 11:59:00 } {
    clock format 43140 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {11 xi 11 xi 11 xi 11 xi 59 lix AM am 11:59:00 am 11:59 00 ? 11:59:00 11:59:00 xi h lix m ? s Thu Jan  1 11:59:00 GMT 1970}
test clock-4.46 { format time of day 11:59:01 } {
    clock format 43141 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {11 xi 11 xi 11 xi 11 xi 59 lix AM am 11:59:01 am 11:59 01 i 11:59:01 11:59:01 xi h lix m i s Thu Jan  1 11:59:01 GMT 1970}
test clock-4.47 { format time of day 11:59:58 } {
    clock format 43198 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {11 xi 11 xi 11 xi 11 xi 59 lix AM am 11:59:58 am 11:59 58 lviii 11:59:58 11:59:58 xi h lix m lviii s Thu Jan  1 11:59:58 GMT 1970}
test clock-4.48 { format time of day 11:59:59 } {
    clock format 43199 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {11 xi 11 xi 11 xi 11 xi 59 lix AM am 11:59:59 am 11:59 59 lix 11:59:59 11:59:59 xi h lix m lix s Thu Jan  1 11:59:59 GMT 1970}
test clock-4.49 { format time of day 12:00:00 } {
    clock format 43200 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {12 xii 12 xii 12 xii 12 xii 00 ? PM pm 12:00:00 pm 12:00 00 ? 12:00:00 12:00:00 xii h ? m ? s Thu Jan  1 12:00:00 GMT 1970}
test clock-4.50 { format time of day 12:00:01 } {
    clock format 43201 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {12 xii 12 xii 12 xii 12 xii 00 ? PM pm 12:00:01 pm 12:00 01 i 12:00:01 12:00:01 xii h ? m i s Thu Jan  1 12:00:01 GMT 1970}
test clock-4.51 { format time of day 12:00:58 } {
    clock format 43258 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {12 xii 12 xii 12 xii 12 xii 00 ? PM pm 12:00:58 pm 12:00 58 lviii 12:00:58 12:00:58 xii h ? m lviii s Thu Jan  1 12:00:58 GMT 1970}
test clock-4.52 { format time of day 12:00:59 } {
    clock format 43259 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {12 xii 12 xii 12 xii 12 xii 00 ? PM pm 12:00:59 pm 12:00 59 lix 12:00:59 12:00:59 xii h ? m lix s Thu Jan  1 12:00:59 GMT 1970}
test clock-4.53 { format time of day 12:01:00 } {
    clock format 43260 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {12 xii 12 xii 12 xii 12 xii 01 i PM pm 12:01:00 pm 12:01 00 ? 12:01:00 12:01:00 xii h i m ? s Thu Jan  1 12:01:00 GMT 1970}
test clock-4.54 { format time of day 12:01:01 } {
    clock format 43261 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {12 xii 12 xii 12 xii 12 xii 01 i PM pm 12:01:01 pm 12:01 01 i 12:01:01 12:01:01 xii h i m i s Thu Jan  1 12:01:01 GMT 1970}
test clock-4.55 { format time of day 12:01:58 } {
    clock format 43318 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {12 xii 12 xii 12 xii 12 xii 01 i PM pm 12:01:58 pm 12:01 58 lviii 12:01:58 12:01:58 xii h i m lviii s Thu Jan  1 12:01:58 GMT 1970}
test clock-4.56 { format time of day 12:01:59 } {
    clock format 43319 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {12 xii 12 xii 12 xii 12 xii 01 i PM pm 12:01:59 pm 12:01 59 lix 12:01:59 12:01:59 xii h i m lix s Thu Jan  1 12:01:59 GMT 1970}
test clock-4.57 { format time of day 12:58:00 } {
    clock format 46680 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {12 xii 12 xii 12 xii 12 xii 58 lviii PM pm 12:58:00 pm 12:58 00 ? 12:58:00 12:58:00 xii h lviii m ? s Thu Jan  1 12:58:00 GMT 1970}
test clock-4.58 { format time of day 12:58:01 } {
    clock format 46681 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {12 xii 12 xii 12 xii 12 xii 58 lviii PM pm 12:58:01 pm 12:58 01 i 12:58:01 12:58:01 xii h lviii m i s Thu Jan  1 12:58:01 GMT 1970}
test clock-4.59 { format time of day 12:58:58 } {
    clock format 46738 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {12 xii 12 xii 12 xii 12 xii 58 lviii PM pm 12:58:58 pm 12:58 58 lviii 12:58:58 12:58:58 xii h lviii m lviii s Thu Jan  1 12:58:58 GMT 1970}
test clock-4.60 { format time of day 12:58:59 } {
    clock format 46739 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {12 xii 12 xii 12 xii 12 xii 58 lviii PM pm 12:58:59 pm 12:58 59 lix 12:58:59 12:58:59 xii h lviii m lix s Thu Jan  1 12:58:59 GMT 1970}
test clock-4.61 { format time of day 12:59:00 } {
    clock format 46740 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {12 xii 12 xii 12 xii 12 xii 59 lix PM pm 12:59:00 pm 12:59 00 ? 12:59:00 12:59:00 xii h lix m ? s Thu Jan  1 12:59:00 GMT 1970}
test clock-4.62 { format time of day 12:59:01 } {
    clock format 46741 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {12 xii 12 xii 12 xii 12 xii 59 lix PM pm 12:59:01 pm 12:59 01 i 12:59:01 12:59:01 xii h lix m i s Thu Jan  1 12:59:01 GMT 1970}
test clock-4.63 { format time of day 12:59:58 } {
    clock format 46798 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {12 xii 12 xii 12 xii 12 xii 59 lix PM pm 12:59:58 pm 12:59 58 lviii 12:59:58 12:59:58 xii h lix m lviii s Thu Jan  1 12:59:58 GMT 1970}
test clock-4.64 { format time of day 12:59:59 } {
    clock format 46799 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {12 xii 12 xii 12 xii 12 xii 59 lix PM pm 12:59:59 pm 12:59 59 lix 12:59:59 12:59:59 xii h lix m lix s Thu Jan  1 12:59:59 GMT 1970}
test clock-4.65 { format time of day 13:00:00 } {
    clock format 46800 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {13 xiii 01 i 13 xiii  1 i 00 ? PM pm 01:00:00 pm 13:00 00 ? 13:00:00 13:00:00 xiii h ? m ? s Thu Jan  1 13:00:00 GMT 1970}
test clock-4.66 { format time of day 13:00:01 } {
    clock format 46801 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {13 xiii 01 i 13 xiii  1 i 00 ? PM pm 01:00:01 pm 13:00 01 i 13:00:01 13:00:01 xiii h ? m i s Thu Jan  1 13:00:01 GMT 1970}
test clock-4.67 { format time of day 13:00:58 } {
    clock format 46858 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {13 xiii 01 i 13 xiii  1 i 00 ? PM pm 01:00:58 pm 13:00 58 lviii 13:00:58 13:00:58 xiii h ? m lviii s Thu Jan  1 13:00:58 GMT 1970}
test clock-4.68 { format time of day 13:00:59 } {
    clock format 46859 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {13 xiii 01 i 13 xiii  1 i 00 ? PM pm 01:00:59 pm 13:00 59 lix 13:00:59 13:00:59 xiii h ? m lix s Thu Jan  1 13:00:59 GMT 1970}
test clock-4.69 { format time of day 13:01:00 } {
    clock format 46860 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {13 xiii 01 i 13 xiii  1 i 01 i PM pm 01:01:00 pm 13:01 00 ? 13:01:00 13:01:00 xiii h i m ? s Thu Jan  1 13:01:00 GMT 1970}
test clock-4.70 { format time of day 13:01:01 } {
    clock format 46861 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {13 xiii 01 i 13 xiii  1 i 01 i PM pm 01:01:01 pm 13:01 01 i 13:01:01 13:01:01 xiii h i m i s Thu Jan  1 13:01:01 GMT 1970}
test clock-4.71 { format time of day 13:01:58 } {
    clock format 46918 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {13 xiii 01 i 13 xiii  1 i 01 i PM pm 01:01:58 pm 13:01 58 lviii 13:01:58 13:01:58 xiii h i m lviii s Thu Jan  1 13:01:58 GMT 1970}
test clock-4.72 { format time of day 13:01:59 } {
    clock format 46919 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {13 xiii 01 i 13 xiii  1 i 01 i PM pm 01:01:59 pm 13:01 59 lix 13:01:59 13:01:59 xiii h i m lix s Thu Jan  1 13:01:59 GMT 1970}
test clock-4.73 { format time of day 13:58:00 } {
    clock format 50280 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {13 xiii 01 i 13 xiii  1 i 58 lviii PM pm 01:58:00 pm 13:58 00 ? 13:58:00 13:58:00 xiii h lviii m ? s Thu Jan  1 13:58:00 GMT 1970}
test clock-4.74 { format time of day 13:58:01 } {
    clock format 50281 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {13 xiii 01 i 13 xiii  1 i 58 lviii PM pm 01:58:01 pm 13:58 01 i 13:58:01 13:58:01 xiii h lviii m i s Thu Jan  1 13:58:01 GMT 1970}
test clock-4.75 { format time of day 13:58:58 } {
    clock format 50338 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {13 xiii 01 i 13 xiii  1 i 58 lviii PM pm 01:58:58 pm 13:58 58 lviii 13:58:58 13:58:58 xiii h lviii m lviii s Thu Jan  1 13:58:58 GMT 1970}
test clock-4.76 { format time of day 13:58:59 } {
    clock format 50339 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {13 xiii 01 i 13 xiii  1 i 58 lviii PM pm 01:58:59 pm 13:58 59 lix 13:58:59 13:58:59 xiii h lviii m lix s Thu Jan  1 13:58:59 GMT 1970}
test clock-4.77 { format time of day 13:59:00 } {
    clock format 50340 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {13 xiii 01 i 13 xiii  1 i 59 lix PM pm 01:59:00 pm 13:59 00 ? 13:59:00 13:59:00 xiii h lix m ? s Thu Jan  1 13:59:00 GMT 1970}
test clock-4.78 { format time of day 13:59:01 } {
    clock format 50341 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {13 xiii 01 i 13 xiii  1 i 59 lix PM pm 01:59:01 pm 13:59 01 i 13:59:01 13:59:01 xiii h lix m i s Thu Jan  1 13:59:01 GMT 1970}
test clock-4.79 { format time of day 13:59:58 } {
    clock format 50398 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {13 xiii 01 i 13 xiii  1 i 59 lix PM pm 01:59:58 pm 13:59 58 lviii 13:59:58 13:59:58 xiii h lix m lviii s Thu Jan  1 13:59:58 GMT 1970}
test clock-4.80 { format time of day 13:59:59 } {
    clock format 50399 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {13 xiii 01 i 13 xiii  1 i 59 lix PM pm 01:59:59 pm 13:59 59 lix 13:59:59 13:59:59 xiii h lix m lix s Thu Jan  1 13:59:59 GMT 1970}
test clock-4.81 { format time of day 23:00:00 } {
    clock format 82800 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 00 ? PM pm 11:00:00 pm 23:00 00 ? 23:00:00 23:00:00 xxiii h ? m ? s Thu Jan  1 23:00:00 GMT 1970}
test clock-4.82 { format time of day 23:00:01 } {
    clock format 82801 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 00 ? PM pm 11:00:01 pm 23:00 01 i 23:00:01 23:00:01 xxiii h ? m i s Thu Jan  1 23:00:01 GMT 1970}
test clock-4.83 { format time of day 23:00:58 } {
    clock format 82858 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 00 ? PM pm 11:00:58 pm 23:00 58 lviii 23:00:58 23:00:58 xxiii h ? m lviii s Thu Jan  1 23:00:58 GMT 1970}
test clock-4.84 { format time of day 23:00:59 } {
    clock format 82859 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 00 ? PM pm 11:00:59 pm 23:00 59 lix 23:00:59 23:00:59 xxiii h ? m lix s Thu Jan  1 23:00:59 GMT 1970}
test clock-4.85 { format time of day 23:01:00 } {
    clock format 82860 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 01 i PM pm 11:01:00 pm 23:01 00 ? 23:01:00 23:01:00 xxiii h i m ? s Thu Jan  1 23:01:00 GMT 1970}
test clock-4.86 { format time of day 23:01:01 } {
    clock format 82861 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 01 i PM pm 11:01:01 pm 23:01 01 i 23:01:01 23:01:01 xxiii h i m i s Thu Jan  1 23:01:01 GMT 1970}
test clock-4.87 { format time of day 23:01:58 } {
    clock format 82918 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 01 i PM pm 11:01:58 pm 23:01 58 lviii 23:01:58 23:01:58 xxiii h i m lviii s Thu Jan  1 23:01:58 GMT 1970}
test clock-4.88 { format time of day 23:01:59 } {
    clock format 82919 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 01 i PM pm 11:01:59 pm 23:01 59 lix 23:01:59 23:01:59 xxiii h i m lix s Thu Jan  1 23:01:59 GMT 1970}
test clock-4.89 { format time of day 23:58:00 } {
    clock format 86280 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 58 lviii PM pm 11:58:00 pm 23:58 00 ? 23:58:00 23:58:00 xxiii h lviii m ? s Thu Jan  1 23:58:00 GMT 1970}
test clock-4.90 { format time of day 23:58:01 } {
    clock format 86281 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 58 lviii PM pm 11:58:01 pm 23:58 01 i 23:58:01 23:58:01 xxiii h lviii m i s Thu Jan  1 23:58:01 GMT 1970}
test clock-4.91 { format time of day 23:58:58 } {
    clock format 86338 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 58 lviii PM pm 11:58:58 pm 23:58 58 lviii 23:58:58 23:58:58 xxiii h lviii m lviii s Thu Jan  1 23:58:58 GMT 1970}
test clock-4.92 { format time of day 23:58:59 } {
    clock format 86339 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 58 lviii PM pm 11:58:59 pm 23:58 59 lix 23:58:59 23:58:59 xxiii h lviii m lix s Thu Jan  1 23:58:59 GMT 1970}
test clock-4.93 { format time of day 23:59:00 } {
    clock format 86340 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 59 lix PM pm 11:59:00 pm 23:59 00 ? 23:59:00 23:59:00 xxiii h lix m ? s Thu Jan  1 23:59:00 GMT 1970}
test clock-4.94 { format time of day 23:59:01 } {
    clock format 86341 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 59 lix PM pm 11:59:01 pm 23:59 01 i 23:59:01 23:59:01 xxiii h lix m i s Thu Jan  1 23:59:01 GMT 1970}
test clock-4.95 { format time of day 23:59:58 } {
    clock format 86398 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 59 lix PM pm 11:59:58 pm 23:59 58 lviii 23:59:58 23:59:58 xxiii h lix m lviii s Thu Jan  1 23:59:58 GMT 1970}
test clock-4.96 { format time of day 23:59:59 } {
    clock format 86399 \
	-format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
	  -locale en_US_roman \
	-gmt true
} {23 xxiii 11 xi 23 xxiii 11 xi 59 lix PM pm 11:59:59 pm 23:59 59 lix 23:59:59 23:59:59 xxiii h lix m lix s Thu Jan  1 23:59:59 GMT 1970}

test clock-4.97.1 { format JDN/JD (calendar and astronomical) } {
    clock format 0 -format {%J %EJ %Ej} -gmt true
} {2440588 2440588.0 2440587.5}
test clock-4.97.2 { format JDN/JD (calendar and astronomical) } {
    clock format 43200 -format {%J %EJ %Ej} -gmt true
15422
15423
15424
15425
15426
15427
15428
15429
15430
15431
15432
15433
15434
15435
15436
15437
15438
    }
    set res
} [list \
   -172800 {B.C.E. 4713-01-03 00:00:00 -- 0000002 2.0 1.5} \
   -129600 {B.C.E. 4713-01-02 12:00:00 -- 0000001 1.5 1.0} \
    -86400 {B.C.E. 4713-01-02 00:00:00 -- 0000001 1.0 0.5} \
    -43200 {B.C.E. 4713-01-01 12:00:00 -- 0000000 0.5 0.0} \
        -1 {B.C.E. 4713-01-01 00:00:01 -- 0000000 0.00001157 -0.49998843} \
         0 {B.C.E. 4713-01-01 00:00:00 -- 0000000 0.0 -0.5} \
         1 {B.C.E. 4714-12-31 23:59:59 -- -000001 -0.00001157 -0.50001157} \
     21600 {B.C.E. 4714-12-31 18:00:00 -- -000001 -0.25 -0.75} \
     43199 {B.C.E. 4714-12-31 12:00:01 -- -000001 -0.49998843 -0.99998843} \
     43200 {B.C.E. 4714-12-31 12:00:00 -- -000001 -0.5 -1.0} \
     86399 {B.C.E. 4714-12-31 00:00:01 -- -000001 -0.99998843 -1.49998843} \
     86400 {B.C.E. 4714-12-31 00:00:00 -- -000001 -1.0 -1.5} \
     86401 {B.C.E. 4714-12-30 23:59:59 -- -000002 -1.00001157 -1.50001157} \
    108000 {B.C.E. 4714-12-30 18:00:00 -- -000002 -1.25 -1.75} \







|
|
|







15422
15423
15424
15425
15426
15427
15428
15429
15430
15431
15432
15433
15434
15435
15436
15437
15438
    }
    set res
} [list \
   -172800 {B.C.E. 4713-01-03 00:00:00 -- 0000002 2.0 1.5} \
   -129600 {B.C.E. 4713-01-02 12:00:00 -- 0000001 1.5 1.0} \
    -86400 {B.C.E. 4713-01-02 00:00:00 -- 0000001 1.0 0.5} \
    -43200 {B.C.E. 4713-01-01 12:00:00 -- 0000000 0.5 0.0} \
	-1 {B.C.E. 4713-01-01 00:00:01 -- 0000000 0.00001157 -0.49998843} \
	 0 {B.C.E. 4713-01-01 00:00:00 -- 0000000 0.0 -0.5} \
	 1 {B.C.E. 4714-12-31 23:59:59 -- -000001 -0.00001157 -0.50001157} \
     21600 {B.C.E. 4714-12-31 18:00:00 -- -000001 -0.25 -0.75} \
     43199 {B.C.E. 4714-12-31 12:00:01 -- -000001 -0.49998843 -0.99998843} \
     43200 {B.C.E. 4714-12-31 12:00:00 -- -000001 -0.5 -1.0} \
     86399 {B.C.E. 4714-12-31 00:00:01 -- -000001 -0.99998843 -1.49998843} \
     86400 {B.C.E. 4714-12-31 00:00:00 -- -000001 -1.0 -1.5} \
     86401 {B.C.E. 4714-12-30 23:59:59 -- -000002 -1.00001157 -1.50001157} \
    108000 {B.C.E. 4714-12-30 18:00:00 -- -000002 -1.25 -1.75} \
15449
15450
15451
15452
15453
15454
15455
15456
15457
15458
15459
15460
15461
15462
15463
15464
15465
15466
15467
15468
15469
15470
15471
15472
15473
15474
15475
15476
15477
15478
15479
15480
15481
15482
15483
15484
15485
15486
15487
15488
15489
15490
15491
15492
15493
15494
15495
15496
15497
15498
15499
15500
15501
15502
15503
15504
15505
15506
15507
15508
15509
15510
15511
15512
15513
15514
15515
15516
15517
15518
15519
15520
15521
15522
15523
15524
15525
15526
15527
15528
15529
15530
15531
15532
15533
15534
15535
15536
15537
15538
15539
15540
15541
15542
15543
15544
15545
15546
15547
15548
15549
15550
15551
15552
15553
15554
15555
15556
15557
15558
15559
15560
15561
15562
15563
15564
15565
15566
15567
15568
15569
15570
15571
15572
15573
15574
15575
15576
15577
15578
15579
15580
15581
15582
15583
15584
15585
15586
15587
15588
15589
15590
15591
15592
15593
15594
15595
15596
15597
15598
15599
15600
15601
15602
15603
15604
15605
15606
15607
15608
15609
15610
15611
15612
15613
15614
15615
15616
15617
15618
15619
15620
15621
15622
15623
15624
15625
15626
15627
15628
15629
15630
15631
15632
15633
15634
15635
15636
15637
15638
15639
15640
15641
15642
15643
15644
15645
15646
15647
15648
15649
15650
15651
15652
15653
15654
15655
15656
15657
15658
15659
15660
15661
15662
15663
15664
15665
15666
15667
15668
15669
15670
15671
15672
15673
15674
15675
15676
15677
15678
15679
15680
15681
15682
15683
15684
15685
15686
15687
15688
15689
15690
15691
15692
15693
15694
15695
15696
15697
15698
15699
15700
15701
15702
15703
15704
15705
15706
15707
15708
15709
15710
15711
15712
15713
15714
15715
15716
15717
15718
15719
15720
15721
15722
15723
15724
15725
15726
15727
15728
15729
15730
15731
15732
15733
15734
15735
15736
15737
15738
15739
15740
15741
15742
15743
15744
15745
15746
15747
15748
15749
15750
15751
15752
15753
15754
15755
15756
15757
15758
15759
15760
15761
15762
15763
15764
15765
15766
15767
15768
15769
15770
15771
15772
15773
15774
15775
15776
15777
15778
15779
15780
15781
15782
15783
15784
15785
15786
15787
15788
15789
15790
15791
15792
15793
15794
15795
15796
15797
15798
15799
15800
15801
15802
15803
15804
15805
15806
15807
15808
15809
15810
15811
15812
15813
15814
15815
15816
15817
15818
15819
15820
15821
15822
15823
15824
15825
15826
15827
15828
15829
15830
15831
15832
15833
15834
15835
15836
15837
15838
15839
15840
15841
15842
15843
15844
15845
15846
15847
15848
15849
15850
15851
15852
15853
15854
15855
15856
15857
15858
15859
15860
15861
15862
15863
15864
15865
15866
15867
15868
15869
15870
15871
15872
15873
15874
15875
15876
15877
15878
15879
15880
15881
15882
15883
15884
15885
15886
15887
15888
15889
15890
15891
15892
15893
15894
15895
15896
15897
15898
15899
15900
15901
15902
15903
15904
15905
15906
15907
15908
15909
15910
15911
15912
15913
15914
15915
15916
15917
15918
15919
15920
15921
15922
15923
15924
15925
15926
15927
15928
15929
15930
15931
15932
15933
15934
15935
15936
15937
15938
15939
15940
15941
15942
15943
15944
15945
15946
15947
15948
15949
15950
15951
15952
15953
15954
15955
15956
15957
15958
15959
15960
15961
15962
15963
15964
15965
15966
15967
15968
15969
15970
15971
15972
15973
15974
15975
15976
15977
15978
15979
15980
15981
15982
15983
15984
15985
15986
15987
15988
15989
15990
15991
15992
15993
15994
15995
15996
15997
15998
15999
16000
16001
16002
16003
16004
16005
16006
16007
16008
16009
16010
16011
16012
16013
16014
16015
16016
16017
16018
16019
16020
16021
16022
16023
16024
16025
16026
16027
16028
16029
16030
16031
16032
16033
16034
16035
16036
16037
16038
16039
16040
16041
16042
16043
16044
16045
16046
16047
16048
16049
16050
16051
16052
16053
16054
16055
16056
16057
16058
16059
16060
16061
16062
16063
16064
16065
16066
16067
16068
16069
16070
16071
16072
16073
16074
16075
16076
16077
16078
16079
16080
16081
16082
16083
16084
16085
16086
16087
16088
16089
16090
16091
16092
16093
16094
16095
16096
16097
16098
16099
16100
16101
16102
16103
16104
16105
16106
16107
16108
16109
16110
16111
16112
16113
16114
16115
16116
16117
16118
16119
16120
16121
16122
16123
16124
16125
16126
16127
16128
16129
16130
16131
16132
16133
16134
16135
16136
16137
16138
16139
16140
16141
16142
16143
16144
16145
16146
16147
16148
16149
16150
16151
16152
16153
16154
16155
16156
16157
16158
16159
16160
16161
16162
16163
16164
16165
16166
16167
16168
16169
16170
16171
16172
16173
16174
16175
16176
16177
16178
16179
16180
16181
16182
16183
16184
16185
16186
16187
16188
16189
16190
16191
16192
16193
16194
16195
16196
16197
16198
16199
16200
16201
16202
16203
16204
16205
16206
16207
16208
16209
16210
16211
16212
16213
16214
16215
16216
16217
16218
16219
16220
16221
16222
16223
16224
16225
16226
16227
16228
16229
16230
16231
16232
16233
16234
16235
16236
16237
16238
16239
16240
16241
16242
16243
16244
16245
16246
16247
16248
16249
16250
16251
16252
16253
16254
16255
16256
16257
16258
16259
16260
16261
16262
16263
16264
16265
16266
16267
16268
16269
16270
16271
16272
16273
16274
16275
16276
16277
16278
16279
16280
16281
16282
16283
16284
16285
16286
16287
16288
16289
16290
16291
16292
16293
16294
16295
16296
16297
16298
16299
16300
16301
16302
16303
16304
16305
16306
16307
16308
16309
16310
16311
16312
16313
16314
16315
16316
16317
16318
16319
16320
16321
16322
16323
16324
16325
16326
16327
16328
16329
16330
16331
16332
16333
16334
16335
16336
16337
16338
16339
16340
16341
16342
16343
16344
16345
16346
16347
16348
16349
16350
16351
16352
16353
16354
16355
16356
16357
16358
16359
16360
16361
16362
16363
16364
16365
16366
16367
16368
16369
16370
16371
16372
16373
16374
16375
16376
16377
16378
16379
16380
16381
16382
16383
16384
16385
16386
16387
16388
16389
16390
16391
16392
16393
16394
16395
16396
16397
16398
16399
16400
16401
16402
16403
16404
16405
16406
16407
16408
16409
16410
16411
16412
16413
16414
16415
16416
16417
16418
16419
16420
16421
16422
16423
16424
16425
16426
16427
16428
16429
16430
16431
16432
16433
16434
16435
16436
16437
16438
16439
16440
16441
16442
16443
16444
16445
16446
16447
16448
16449
16450
16451
16452
16453
16454
16455
16456
16457
16458
16459
16460
16461
16462
16463
16464
16465
16466
16467
16468
16469
16470
16471
16472
16473
16474
16475
16476
16477
16478
16479
16480
16481
16482
16483
16484
16485
16486
16487
16488
16489
16490
16491
16492
16493
16494
16495
16496
16497
16498
16499
16500
16501
16502
16503
16504
16505
16506
16507
16508
16509
16510
16511
16512
16513
16514
16515
16516
16517
16518
16519
16520
16521
16522
16523
16524
16525
16526
16527
16528
16529
16530
16531
16532
16533
16534
16535
16536
16537
16538
16539
16540
16541
16542
16543
16544
16545
16546
16547
16548
16549
16550
16551
16552
16553
16554
16555
16556
16557
16558
16559
16560
16561
16562
16563
16564
16565
16566
16567
16568
16569
16570
16571
16572
16573
16574
16575
16576
16577
16578
16579
16580
16581
16582
16583
16584
16585
16586
16587
16588
16589
16590
16591
16592
16593
16594
16595
16596
16597
16598
16599
16600
16601
16602
16603
16604
16605
16606
16607
16608
16609
16610
16611
16612
16613
16614
16615
16616
16617
16618
16619
16620
16621
16622
16623
16624
16625
16626
16627
16628
16629
16630
16631
16632
16633
16634
16635
16636
16637
16638
16639
16640
16641
16642
16643
16644
16645
16646
16647
16648
16649
16650
16651
16652
16653
16654
16655
16656
16657
16658
16659
16660
16661
16662
16663
16664
16665
16666
16667
16668
16669
16670
16671
16672
16673
16674
16675
16676
16677
16678
16679
16680
16681
16682
16683
16684
16685
16686
16687
16688
16689
16690
16691
16692
16693
16694
16695
16696
16697
16698
16699
16700
16701
16702
16703
16704
16705
16706
16707
16708
16709
16710
16711
16712
16713
16714
16715
16716
16717
16718
16719
16720
16721
16722
16723
16724
16725
16726
16727
16728
16729
16730
16731
16732
16733
16734
16735
16736
16737
16738
16739
16740
16741
16742
16743
16744
16745
16746
16747
16748
16749
16750
16751
16752
16753
16754
16755
16756
16757
16758
16759
16760
16761
16762
16763
16764
16765
16766
16767
16768
16769
16770
16771
16772
16773
16774
16775
16776
16777
16778
16779
16780
16781
16782
16783
16784
16785
16786
16787
16788
16789
16790
16791
16792
16793
16794
16795
16796
16797
16798
16799
16800
16801
16802
16803
16804
16805
16806
16807
16808
16809
16810
16811
16812
16813
16814
16815
16816
16817
16818
16819
16820
16821
16822
16823
16824
16825
16826
16827
16828
16829
16830
16831
16832
16833
16834
16835
16836
16837
16838
16839
16840
16841
16842
16843
16844
16845
16846
16847
16848
16849
16850
16851
16852
16853
16854
16855
16856
16857
16858
16859
16860
16861
16862
16863
16864
16865
16866
16867
16868
16869
16870
16871
16872
16873
16874
16875
16876
16877
16878
16879
16880
16881
16882
16883
16884
16885
16886
16887
16888
16889
16890
16891
16892
16893
16894
16895
16896
16897
16898
16899
16900
16901
16902
16903
16904
16905
16906
16907
16908
16909
16910
16911
16912
16913
16914
16915
16916
16917
16918
16919
16920
16921
16922
16923
16924
16925
16926
16927
16928
16929
16930
16931
16932
16933
16934
16935
16936
16937
16938
16939
16940
16941
16942
16943
16944
16945
16946
16947
16948
16949
16950
16951
16952
16953
16954
16955
16956
16957
16958
16959
16960
16961
16962
16963
16964
16965
16966
16967
16968
16969
16970
16971
16972
16973
16974
16975
16976
16977
16978
16979
16980
16981
16982
16983
16984
16985
16986
16987
16988
16989
16990
16991
16992
16993
16994
16995
16996
16997
16998
16999
17000
17001
17002
17003
17004
17005
17006
17007
17008
17009
17010
17011
17012
17013
17014
17015
17016
17017
17018
17019
17020
17021
17022
17023
17024
17025
17026
17027
17028
17029
17030
17031
17032
17033
17034
17035
17036
17037
17038
17039
17040
17041
17042
17043
17044
17045
17046
17047
17048
17049
17050
17051
17052
17053
17054
17055
17056
17057
17058
17059
17060
17061
17062
17063
17064
17065
17066
17067
17068
17069
17070
17071
17072
17073
17074
17075
17076
17077
17078
17079
17080
17081
17082
17083
17084
17085
17086
17087
17088
17089
17090
17091
17092
17093
17094
17095
17096
17097
17098
17099
17100
17101
17102
17103
17104
17105
17106
17107
17108
17109
17110
17111
17112
17113
17114
17115
17116
17117
17118
17119
17120
17121
17122
17123
17124
17125
17126
17127
17128
17129
17130
17131
17132
17133
17134
17135
17136
17137
17138
17139
17140
17141
17142
17143
17144
17145
17146
17147
17148
17149
17150
17151
17152
17153
17154
17155
17156
17157
17158
17159
17160
17161
17162
17163
17164
17165
17166
17167
17168
17169
17170
17171
17172
17173
17174
17175
17176
17177
17178
17179
17180
17181
17182
17183
17184
17185
17186
17187
17188
17189
17190
17191
17192
17193
17194
17195
17196
17197
17198
17199
17200
17201
17202
17203
17204
17205
17206
17207
17208
17209
17210
17211
17212
17213
17214
17215
17216
17217
17218
17219
17220
17221
17222
17223
17224
17225
17226
17227
17228
17229
17230
17231
17232
17233
17234
17235
17236
17237
17238
17239
17240
17241
17242
17243
17244
17245
17246
17247
17248
17249
17250
17251
17252
17253
17254
17255
17256
17257
17258
17259
17260
17261
17262
17263
17264
17265
17266
17267
17268
17269
17270
17271
17272
17273
17274
17275
17276
17277
17278
17279
17280
17281
17282
17283
17284
17285
17286
17287
17288
17289
17290
17291
17292
17293
17294
17295
17296
17297
17298
17299
17300
17301
17302
17303
17304
17305
17306
17307
17308
17309
17310
17311
17312
17313
17314
17315
17316
17317
17318
17319
17320
17321
17322
17323
17324
17325
17326
17327
17328
17329
17330
17331
17332
17333
17334
17335
17336
17337
17338
17339
17340
17341
17342
17343
17344
17345
17346
17347
17348
17349
17350
17351
17352
17353
17354
17355
17356
17357
17358
17359
17360
17361
17362
17363
17364
17365
17366
17367
17368
17369
17370
17371
17372
17373
17374
17375
17376
17377
17378
17379
17380
17381
17382
17383
17384
17385
17386
17387
17388
17389
17390
17391
17392
17393
17394
17395
17396
17397
17398
17399
17400
17401
17402
17403
17404
17405
17406
17407
17408
17409
17410
17411
17412
17413
17414
17415
17416
17417
17418
17419
17420
17421
17422
17423
17424
17425
17426
17427
17428
17429
17430
17431
17432
17433
17434
17435
17436
17437
17438
17439
17440
17441
17442
17443
17444
17445
17446
17447
17448
17449
17450
17451
17452
17453
17454
17455
17456
17457
17458
17459
17460
17461
17462
17463
17464
17465
17466
17467
17468
17469
17470
17471
17472
17473
17474
17475
17476
17477
17478
17479
17480
17481
17482
17483
17484
17485
17486
17487
17488
17489
17490
17491
17492
17493
17494
17495
17496
17497
17498
17499
17500
17501
17502
17503
17504
17505
17506
17507
17508
17509
17510
17511
17512
17513
17514
17515
17516
17517
17518
17519
17520
17521
17522
17523
17524
17525
17526
17527
17528
17529
17530
17531
17532
17533
17534
17535
17536
17537
17538
17539
17540
17541
17542
17543
17544
17545
17546
17547
17548
17549
17550
17551
17552
17553
17554
17555
17556
17557
17558
17559
17560
17561
17562
17563
17564
17565
17566
17567
17568
17569
17570
17571
17572
17573
17574
17575
17576
17577
17578
17579
17580
17581
17582
17583
17584
17585
17586
17587
17588
17589
17590
17591
17592
17593
17594
17595
17596
17597
17598
17599
17600
17601
17602
17603
17604
17605
17606
17607
17608
17609
17610
17611
17612
17613
17614
17615
17616
17617
17618
17619
17620
17621
17622
17623
17624
17625
17626
17627
17628
17629
17630
17631
17632
17633
17634
17635
17636
17637
17638
17639
17640
17641
17642
17643
17644
17645
17646
17647
17648
17649
17650
17651
17652
17653
17654
17655
17656
17657
17658
17659
17660
17661
17662
17663
17664
17665
17666
17667
17668
17669
17670
17671
17672
17673
17674
17675
17676
17677
17678
17679
17680
17681
17682
17683
17684
17685
17686
17687
17688
17689
17690
17691
17692
17693
17694
17695
17696
17697
17698
17699
17700
17701
17702
17703
17704
17705
17706
17707
17708
17709
17710
17711
17712
17713
17714
17715
17716
17717
17718
17719
17720
17721
17722
17723
17724
17725
17726
17727
17728
17729
17730
17731
17732
17733
17734
17735
17736
17737
17738
17739
17740
17741
17742
17743
17744
17745
17746
17747
17748
17749
17750
17751
17752
17753
17754
17755
17756
17757
17758
17759
17760
17761
17762
17763
17764
17765
17766
17767
17768
17769
17770
17771
17772
17773
17774
17775
17776
17777
17778
17779
17780
17781
17782
17783
17784
17785
17786
17787
17788
17789
17790
17791
17792
17793
17794
17795
17796
17797
17798
17799
17800
17801
17802
17803
17804
17805
17806
17807
17808
17809
17810
17811
17812
17813
17814
17815
17816
17817
17818
17819
17820
17821
17822
17823
17824
17825
17826
17827
17828
17829
17830
17831
17832
17833
17834
17835
17836
17837
17838
17839
17840
17841
17842
17843
17844
17845
17846
17847
17848
17849
17850
17851
17852
17853
17854
17855
17856
17857
17858
17859
17860
17861
17862
17863
17864
17865
17866
17867
17868
17869
17870
17871
17872
17873
17874
17875
17876
17877
17878
17879
17880
17881
17882
17883
17884
17885
17886
17887
17888
17889
17890
17891
17892
17893
17894
17895
17896
17897
17898
17899
17900
17901
17902
17903
17904
17905
17906
17907
17908
17909
17910
17911
17912
17913
17914
17915
17916
17917
17918
17919
17920
17921
17922
17923
17924
17925
17926
17927
17928
17929
17930
17931
17932
17933
17934
17935
17936
17937
17938
17939
17940
17941
17942
17943
17944
17945
17946
17947
17948
17949
17950
17951
17952
17953
17954
17955
17956
17957
17958
17959
17960
17961
17962
17963
17964
17965
17966
17967
17968
17969
17970
17971
17972
17973
17974
17975
17976
17977
17978
17979
17980
17981
17982
17983
17984
17985
17986
17987
17988
17989
17990
17991
17992
17993
17994
17995
17996
17997
17998
17999
18000
18001
18002
18003
18004
18005
18006
18007
18008
18009
18010
18011
18012
18013
18014
18015
18016
18017
18018
18019
18020
18021
18022
18023
18024
18025
18026
18027
18028
18029
18030
18031
18032
18033
18034
18035
18036
18037
18038
18039
18040
18041
18042
18043
18044
18045
18046
18047
18048
18049
18050
18051
18052
18053
18054
18055
18056
18057
18058
18059
18060
18061
18062
18063
18064
18065
18066
18067
18068
18069
18070
18071
18072
18073
18074
18075
18076
18077
18078
18079
18080
18081
18082
18083
18084
18085
18086
18087
18088
18089
18090
18091
18092
18093
18094
18095
18096
18097
18098
18099
18100
18101
18102
18103
18104
18105
18106
18107
18108
18109
18110
18111
18112
18113
18114
18115
18116
18117
18118
18119
18120
18121
18122
18123
18124
18125
18126
18127
18128
18129
18130
18131
18132
18133
18134
18135
18136
18137
18138
18139
18140
18141
18142
18143
18144
18145
18146
18147
18148
18149
18150
18151
18152
18153
18154
18155
18156
18157
18158
18159
18160
18161
18162
18163
18164
18165
18166
18167
18168
18169
18170
18171
18172
18173
18174
18175
18176
18177
18178
18179
18180
18181
18182
18183
18184
18185
18186
18187
18188
18189
18190
18191
18192
18193
18194
18195
18196
18197
18198
18199
18200
18201
18202
18203
18204
18205
18206
18207
18208
18209
18210
18211
18212
18213
18214
18215
18216
18217
18218
18219
18220
18221
18222
18223
18224
18225
18226
18227
18228
18229
18230
18231
18232
18233
18234
18235
18236
18237
18238
18239
18240
18241
18242
18243
18244
18245
18246
18247
18248
18249
18250
18251
18252
18253
18254
18255
18256
18257
18258
18259
18260
18261
18262
18263
18264
18265
18266
18267
18268
18269
18270
18271
18272
18273
18274
18275
18276
18277
18278
18279
18280
18281
18282
18283
18284
18285
18286
18287
18288
18289
18290
18291
18292
18293
18294
18295
18296
18297
18298
18299
18300
18301
18302
18303
18304
18305
18306
18307
18308
18309
18310
18311
18312
18313
18314
18315
18316
18317
18318
18319
18320
18321
18322
18323
18324
18325
18326
18327
18328
18329
18330
18331
18332
18333
18334
18335
18336
18337
18338
18339
18340
18341
18342
18343
18344
18345
18346
18347
18348
18349
18350
18351
18352
18353
18354
18355
18356
18357
18358
18359
18360
18361
18362
18363
18364
18365
18366
18367
18368
18369
18370
18371
18372
18373
18374
18375
18376
18377
18378
18379
18380
18381
18382
18383
18384
18385
18386
18387
18388
18389
18390
18391
18392
18393
18394
18395
18396
18397
18398
18399
18400
18401
18402
18403
18404
18405
18406
18407
18408
18409
18410
18411
18412
18413
18414
18415
18416
18417
18418
18419
18420
18421
18422
18423
18424
18425
18426
18427
18428
18429
18430
18431
18432
18433
18434
18435
18436
18437
18438
18439
18440
18441
18442
18443
18444
18445
18446
18447
18448
18449
18450
18451
18452
18453
18454
18455
18456
18457
18458
18459
18460
18461
18462
18463
18464
18465
18466
18467
18468
18469
18470
18471
18472
18473
18474
18475
18476
18477
18478
18479
18480
18481
18482
18483
18484
18485
18486
18487
18488
18489
18490
18491
18492
18493
18494
18495
18496
18497
18498
18499
18500
18501
18502
18503
18504
18505
18506
18507
18508
18509
18510
18511
18512
18513
18514
18515
18516
18517
18518
18519
18520
18521
18522
18523
18524
18525
18526
18527
18528
18529
18530
18531
18532
18533
18534
18535
18536
18537
18538
18539
18540
18541
18542
18543
18544
18545
18546
18547
18548
18549
18550
18551
18552
18553
18554
18555
18556
18557
18558
18559
18560
18561
18562
18563
18564
18565
18566
18567
18568
18569
18570
18571
18572
18573
18574
18575
18576
18577
18578
18579
18580
18581
18582
18583
18584
18585
18586
18587
18588
18589
18590
18591
18592
18593
18594
18595
18596
18597
18598
18599
18600
18601
18602
18603
18604
18605
18606
18607
18608
18609
18610
18611
18612
18613
18614
18615
18616
18617
18618
18619
18620
18621
18622
18623
18624
18625
18626
18627
18628
18629
18630
18631
18632
18633
18634
18635
18636
18637
18638
18639
18640
18641
18642
18643
18644
18645
18646
18647
18648
18649
18650
18651
18652
18653
18654
18655
18656
18657
18658
18659
18660
18661
18662
18663
18664
18665
18666
18667
18668
18669
18670
	lappend res $i [clock format [expr {653133196800 + $i}] \
	    -format {%Y-%m-%d %T -- %J %EJ %Ej} -gmt true]
    }
    set res
} [list \
    -86400 {22666-12-19 00:00:00 -- 9999999 9999999.0 9999998.5} \
    -43200 {22666-12-19 12:00:00 -- 9999999 9999999.5 9999999.0} \
        -1 {22666-12-19 23:59:59 -- 9999999 9999999.99998843 9999999.49998843} \
         0 {22666-12-20 00:00:00 -- 10000000 10000000.0 9999999.5} \
         1 {22666-12-20 00:00:01 -- 10000000 10000000.00001157 9999999.50001157} \
     43199 {22666-12-20 11:59:59 -- 10000000 10000000.49998843 9999999.99998843} \
     43200 {22666-12-20 12:00:00 -- 10000000 10000000.5 10000000.0} \
     43201 {22666-12-20 12:00:01 -- 10000000 10000000.50001157 10000000.00001157} \
     86400 {22666-12-21 00:00:00 -- 10000001 10000001.0 10000000.5} \
]

# END testcases4

# BEGIN testcases5

# Test formatting of Daylight Saving Time

test clock-5.1 {does Detroit exist} {
    clock format 0 -format {} -timezone :America/Detroit
    concat
} {}
test clock-5.2 {does Detroit have a Y2038 problem} detroit {
    if { [clock format 2158894800 -format %z -timezone :America/Detroit] ne {-0400} } {
        concat {y2038 problem}
    } else {
        concat {ok}
    }
} ok
test clock-5.3 {time zone boundary case 1904-12-31 23:59:59} detroit {
    clock format -2051202470 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {23:59:59 -053211 LMT}
test clock-5.4 {time zone boundary case 1904-12-31 23:32:11} detroit {
    clock format -2051202469 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {23:32:11 -0600 CST}
test clock-5.5 {time zone boundary case 1904-12-31 23:32:12} detroit {
    clock format -2051202468 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {23:32:12 -0600 CST}
test clock-5.6 {time zone boundary case 1915-05-15 01:59:59} detroit {
    clock format -1724083201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0600 CST}
test clock-5.7 {time zone boundary case 1915-05-15 03:00:00} detroit {
    clock format -1724083200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0500 EST}
test clock-5.8 {time zone boundary case 1915-05-15 03:00:01} detroit {
    clock format -1724083199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0500 EST}
test clock-5.9 {time zone boundary case 1941-12-31 23:59:59} detroit {
    clock format -883594801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {23:59:59 -0500 EST}
test clock-5.10 {time zone boundary case 1942-01-01 00:00:00} detroit {
    clock format -883594800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {00:00:00 -0500 EST}
test clock-5.11 {time zone boundary case 1942-01-01 00:00:01} detroit {
    clock format -883594799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {00:00:01 -0500 EST}
test clock-5.12 {time zone boundary case 1942-02-09 01:59:59} detroit {
    clock format -880218001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.13 {time zone boundary case 1942-02-09 03:00:00} detroit {
    clock format -880218000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EWT}
test clock-5.14 {time zone boundary case 1942-02-09 03:00:01} detroit {
    clock format -880217999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EWT}
test clock-5.15 {time zone boundary case 1945-08-14 18:59:59} detroit {
    clock format -769395601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {18:59:59 -0400 EWT}
test clock-5.16 {time zone boundary case 1945-08-14 19:00:00} detroit {
    clock format -769395600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {19:00:00 -0400 EPT}
test clock-5.17 {time zone boundary case 1945-08-14 19:00:01} detroit {
    clock format -769395599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {19:00:01 -0400 EPT}
test clock-5.18 {time zone boundary case 1945-09-30 01:59:59} detroit {
    clock format -765396001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EPT}
test clock-5.19 {time zone boundary case 1945-09-30 01:00:00} detroit {
    clock format -765396000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.20 {time zone boundary case 1945-09-30 01:00:01} detroit {
    clock format -765395999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.21 {time zone boundary case 1945-12-31 23:59:59} detroit {
    clock format -757364401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {23:59:59 -0500 EST}
test clock-5.22 {time zone boundary case 1946-01-01 00:00:00} detroit {
    clock format -757364400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {00:00:00 -0500 EST}
test clock-5.23 {time zone boundary case 1946-01-01 00:00:01} detroit {
    clock format -757364399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {00:00:01 -0500 EST}
test clock-5.24 {time zone boundary case 1948-04-25 01:59:59} detroit {
    clock format -684349201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.25 {time zone boundary case 1948-04-25 03:00:00} detroit {
    clock format -684349200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.26 {time zone boundary case 1948-04-25 03:00:01} detroit {
    clock format -684349199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.27 {time zone boundary case 1948-09-26 01:59:59} detroit {
    clock format -671047201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.28 {time zone boundary case 1948-09-26 01:00:00} detroit {
    clock format -671047200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.29 {time zone boundary case 1948-09-26 01:00:01} detroit {
    clock format -671047199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}

# Detroit did not observe Daylight Saving Time in 1967

test clock-5.36 {time zone boundary case 1972-12-31 23:59:59} detroit {
    clock format 94712399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {23:59:59 -0500 EST}
test clock-5.37 {time zone boundary case 1973-01-01 00:00:00} detroit {
    clock format 94712400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {00:00:00 -0500 EST}
test clock-5.38 {time zone boundary case 1973-01-01 00:00:01} detroit {
    clock format 94712401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {00:00:01 -0500 EST}
test clock-5.39 {time zone boundary case 1973-04-29 01:59:59} detroit {
    clock format 104914799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.40 {time zone boundary case 1973-04-29 03:00:00} detroit {
    clock format 104914800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.41 {time zone boundary case 1973-04-29 03:00:01} detroit {
    clock format 104914801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.42 {time zone boundary case 1973-10-28 01:59:59} detroit {
    clock format 120635999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.43 {time zone boundary case 1973-10-28 01:00:00} detroit {
    clock format 120636000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.44 {time zone boundary case 1973-10-28 01:00:01} detroit {
    clock format 120636001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.45 {time zone boundary case 1974-01-06 01:59:59} detroit {
    clock format 126687599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.46 {time zone boundary case 1974-01-06 03:00:00} detroit {
    clock format 126687600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.47 {time zone boundary case 1974-01-06 03:00:01} detroit {
    clock format 126687601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.48 {time zone boundary case 1974-10-27 01:59:59} detroit {
    clock format 152085599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.49 {time zone boundary case 1974-10-27 01:00:00} detroit {
    clock format 152085600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.50 {time zone boundary case 1974-10-27 01:00:01} detroit {
    clock format 152085601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.51 {time zone boundary case 1974-12-31 23:59:59} detroit {
    clock format 157784399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {23:59:59 -0500 EST}
test clock-5.52 {time zone boundary case 1975-01-01 00:00:00} detroit {
    clock format 157784400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {00:00:00 -0500 EST}
test clock-5.53 {time zone boundary case 1975-01-01 00:00:01} detroit {
    clock format 157784401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {00:00:01 -0500 EST}
test clock-5.54 {time zone boundary case 1975-04-27 01:59:59} detroit {
    clock format 167813999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.55 {time zone boundary case 1975-04-27 03:00:00} detroit {
    clock format 167814000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.56 {time zone boundary case 1975-04-27 03:00:01} detroit {
    clock format 167814001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.57 {time zone boundary case 1975-10-26 01:59:59} detroit {
    clock format 183535199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.58 {time zone boundary case 1975-10-26 01:00:00} detroit {
    clock format 183535200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.59 {time zone boundary case 1975-10-26 01:00:01} detroit {
    clock format 183535201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.60 {time zone boundary case 1976-04-25 01:59:59} detroit {
    clock format 199263599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.61 {time zone boundary case 1976-04-25 03:00:00} detroit {
    clock format 199263600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.62 {time zone boundary case 1976-04-25 03:00:01} detroit {
    clock format 199263601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.63 {time zone boundary case 1976-10-31 01:59:59} detroit {
    clock format 215589599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.64 {time zone boundary case 1976-10-31 01:00:00} detroit {
    clock format 215589600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.65 {time zone boundary case 1976-10-31 01:00:01} detroit {
    clock format 215589601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.66 {time zone boundary case 1977-04-24 01:59:59} detroit {
    clock format 230713199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.67 {time zone boundary case 1977-04-24 03:00:00} detroit {
    clock format 230713200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.68 {time zone boundary case 1977-04-24 03:00:01} detroit {
    clock format 230713201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.69 {time zone boundary case 1977-10-30 01:59:59} detroit {
    clock format 247039199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.70 {time zone boundary case 1977-10-30 01:00:00} detroit {
    clock format 247039200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.71 {time zone boundary case 1977-10-30 01:00:01} detroit {
    clock format 247039201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.72 {time zone boundary case 1978-04-30 01:59:59} detroit {
    clock format 262767599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.73 {time zone boundary case 1978-04-30 03:00:00} detroit {
    clock format 262767600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.74 {time zone boundary case 1978-04-30 03:00:01} detroit {
    clock format 262767601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.75 {time zone boundary case 1978-10-29 01:59:59} detroit {
    clock format 278488799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.76 {time zone boundary case 1978-10-29 01:00:00} detroit {
    clock format 278488800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.77 {time zone boundary case 1978-10-29 01:00:01} detroit {
    clock format 278488801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.78 {time zone boundary case 1979-04-29 01:59:59} detroit {
    clock format 294217199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.79 {time zone boundary case 1979-04-29 03:00:00} detroit {
    clock format 294217200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.80 {time zone boundary case 1979-04-29 03:00:01} detroit {
    clock format 294217201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.81 {time zone boundary case 1979-10-28 01:59:59} detroit {
    clock format 309938399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.82 {time zone boundary case 1979-10-28 01:00:00} detroit {
    clock format 309938400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.83 {time zone boundary case 1979-10-28 01:00:01} detroit {
    clock format 309938401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.84 {time zone boundary case 1980-04-27 01:59:59} detroit {
    clock format 325666799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.85 {time zone boundary case 1980-04-27 03:00:00} detroit {
    clock format 325666800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.86 {time zone boundary case 1980-04-27 03:00:01} detroit {
    clock format 325666801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.87 {time zone boundary case 1980-10-26 01:59:59} detroit {
    clock format 341387999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.88 {time zone boundary case 1980-10-26 01:00:00} detroit {
    clock format 341388000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.89 {time zone boundary case 1980-10-26 01:00:01} detroit {
    clock format 341388001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.90 {time zone boundary case 1981-04-26 01:59:59} detroit {
    clock format 357116399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.91 {time zone boundary case 1981-04-26 03:00:00} detroit {
    clock format 357116400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.92 {time zone boundary case 1981-04-26 03:00:01} detroit {
    clock format 357116401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.93 {time zone boundary case 1981-10-25 01:59:59} detroit {
    clock format 372837599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.94 {time zone boundary case 1981-10-25 01:00:00} detroit {
    clock format 372837600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.95 {time zone boundary case 1981-10-25 01:00:01} detroit {
    clock format 372837601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.96 {time zone boundary case 1982-04-25 01:59:59} detroit {
    clock format 388565999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.97 {time zone boundary case 1982-04-25 03:00:00} detroit {
    clock format 388566000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.98 {time zone boundary case 1982-04-25 03:00:01} detroit {
    clock format 388566001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.99 {time zone boundary case 1982-10-31 01:59:59} detroit {
    clock format 404891999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.100 {time zone boundary case 1982-10-31 01:00:00} detroit {
    clock format 404892000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.101 {time zone boundary case 1982-10-31 01:00:01} detroit {
    clock format 404892001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.102 {time zone boundary case 1983-04-24 01:59:59} detroit {
    clock format 420015599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.103 {time zone boundary case 1983-04-24 03:00:00} detroit {
    clock format 420015600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.104 {time zone boundary case 1983-04-24 03:00:01} detroit {
    clock format 420015601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.105 {time zone boundary case 1983-10-30 01:59:59} detroit {
    clock format 436341599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.106 {time zone boundary case 1983-10-30 01:00:00} detroit {
    clock format 436341600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.107 {time zone boundary case 1983-10-30 01:00:01} detroit {
    clock format 436341601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.108 {time zone boundary case 1984-04-29 01:59:59} detroit {
    clock format 452069999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.109 {time zone boundary case 1984-04-29 03:00:00} detroit {
    clock format 452070000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.110 {time zone boundary case 1984-04-29 03:00:01} detroit {
    clock format 452070001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.111 {time zone boundary case 1984-10-28 01:59:59} detroit {
    clock format 467791199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.112 {time zone boundary case 1984-10-28 01:00:00} detroit {
    clock format 467791200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.113 {time zone boundary case 1984-10-28 01:00:01} detroit {
    clock format 467791201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.114 {time zone boundary case 1985-04-28 01:59:59} detroit {
    clock format 483519599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.115 {time zone boundary case 1985-04-28 03:00:00} detroit {
    clock format 483519600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.116 {time zone boundary case 1985-04-28 03:00:01} detroit {
    clock format 483519601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.117 {time zone boundary case 1985-10-27 01:59:59} detroit {
    clock format 499240799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.118 {time zone boundary case 1985-10-27 01:00:00} detroit {
    clock format 499240800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.119 {time zone boundary case 1985-10-27 01:00:01} detroit {
    clock format 499240801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.120 {time zone boundary case 1986-04-27 01:59:59} detroit {
    clock format 514969199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.121 {time zone boundary case 1986-04-27 03:00:00} detroit {
    clock format 514969200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.122 {time zone boundary case 1986-04-27 03:00:01} detroit {
    clock format 514969201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.123 {time zone boundary case 1986-10-26 01:59:59} detroit {
    clock format 530690399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.124 {time zone boundary case 1986-10-26 01:00:00} detroit {
    clock format 530690400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.125 {time zone boundary case 1986-10-26 01:00:01} detroit {
    clock format 530690401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.126 {time zone boundary case 1987-04-05 01:59:59} detroit {
    clock format 544604399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.127 {time zone boundary case 1987-04-05 03:00:00} detroit {
    clock format 544604400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.128 {time zone boundary case 1987-04-05 03:00:01} detroit {
    clock format 544604401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.129 {time zone boundary case 1987-10-25 01:59:59} detroit {
    clock format 562139999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.130 {time zone boundary case 1987-10-25 01:00:00} detroit {
    clock format 562140000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.131 {time zone boundary case 1987-10-25 01:00:01} detroit {
    clock format 562140001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.132 {time zone boundary case 1988-04-03 01:59:59} detroit {
    clock format 576053999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.133 {time zone boundary case 1988-04-03 03:00:00} detroit {
    clock format 576054000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.134 {time zone boundary case 1988-04-03 03:00:01} detroit {
    clock format 576054001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.135 {time zone boundary case 1988-10-30 01:59:59} detroit {
    clock format 594194399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.136 {time zone boundary case 1988-10-30 01:00:00} detroit {
    clock format 594194400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.137 {time zone boundary case 1988-10-30 01:00:01} detroit {
    clock format 594194401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.138 {time zone boundary case 1989-04-02 01:59:59} detroit {
    clock format 607503599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.139 {time zone boundary case 1989-04-02 03:00:00} detroit {
    clock format 607503600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.140 {time zone boundary case 1989-04-02 03:00:01} detroit {
    clock format 607503601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.141 {time zone boundary case 1989-10-29 01:59:59} detroit {
    clock format 625643999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.142 {time zone boundary case 1989-10-29 01:00:00} detroit {
    clock format 625644000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.143 {time zone boundary case 1989-10-29 01:00:01} detroit {
    clock format 625644001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.144 {time zone boundary case 1990-04-01 01:59:59} detroit {
    clock format 638953199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.145 {time zone boundary case 1990-04-01 03:00:00} detroit {
    clock format 638953200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.146 {time zone boundary case 1990-04-01 03:00:01} detroit {
    clock format 638953201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.147 {time zone boundary case 1990-10-28 01:59:59} detroit {
    clock format 657093599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.148 {time zone boundary case 1990-10-28 01:00:00} detroit {
    clock format 657093600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.149 {time zone boundary case 1990-10-28 01:00:01} detroit {
    clock format 657093601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.150 {time zone boundary case 1991-04-07 01:59:59} detroit {
    clock format 671007599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.151 {time zone boundary case 1991-04-07 03:00:00} detroit {
    clock format 671007600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.152 {time zone boundary case 1991-04-07 03:00:01} detroit {
    clock format 671007601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.153 {time zone boundary case 1991-10-27 01:59:59} detroit {
    clock format 688543199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.154 {time zone boundary case 1991-10-27 01:00:00} detroit {
    clock format 688543200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.155 {time zone boundary case 1991-10-27 01:00:01} detroit {
    clock format 688543201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.156 {time zone boundary case 1992-04-05 01:59:59} detroit {
    clock format 702457199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.157 {time zone boundary case 1992-04-05 03:00:00} detroit {
    clock format 702457200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.158 {time zone boundary case 1992-04-05 03:00:01} detroit {
    clock format 702457201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.159 {time zone boundary case 1992-10-25 01:59:59} detroit {
    clock format 719992799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.160 {time zone boundary case 1992-10-25 01:00:00} detroit {
    clock format 719992800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.161 {time zone boundary case 1992-10-25 01:00:01} detroit {
    clock format 719992801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.162 {time zone boundary case 1993-04-04 01:59:59} detroit {
    clock format 733906799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.163 {time zone boundary case 1993-04-04 03:00:00} detroit {
    clock format 733906800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.164 {time zone boundary case 1993-04-04 03:00:01} detroit {
    clock format 733906801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.165 {time zone boundary case 1993-10-31 01:59:59} detroit {
    clock format 752047199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.166 {time zone boundary case 1993-10-31 01:00:00} detroit {
    clock format 752047200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.167 {time zone boundary case 1993-10-31 01:00:01} detroit {
    clock format 752047201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.168 {time zone boundary case 1994-04-03 01:59:59} detroit {
    clock format 765356399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.169 {time zone boundary case 1994-04-03 03:00:00} detroit {
    clock format 765356400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.170 {time zone boundary case 1994-04-03 03:00:01} detroit {
    clock format 765356401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.171 {time zone boundary case 1994-10-30 01:59:59} detroit {
    clock format 783496799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.172 {time zone boundary case 1994-10-30 01:00:00} detroit {
    clock format 783496800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.173 {time zone boundary case 1994-10-30 01:00:01} detroit {
    clock format 783496801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.174 {time zone boundary case 1995-04-02 01:59:59} detroit {
    clock format 796805999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.175 {time zone boundary case 1995-04-02 03:00:00} detroit {
    clock format 796806000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.176 {time zone boundary case 1995-04-02 03:00:01} detroit {
    clock format 796806001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.177 {time zone boundary case 1995-10-29 01:59:59} detroit {
    clock format 814946399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.178 {time zone boundary case 1995-10-29 01:00:00} detroit {
    clock format 814946400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.179 {time zone boundary case 1995-10-29 01:00:01} detroit {
    clock format 814946401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.180 {time zone boundary case 1996-04-07 01:59:59} detroit {
    clock format 828860399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.181 {time zone boundary case 1996-04-07 03:00:00} detroit {
    clock format 828860400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.182 {time zone boundary case 1996-04-07 03:00:01} detroit {
    clock format 828860401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.183 {time zone boundary case 1996-10-27 01:59:59} detroit {
    clock format 846395999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.184 {time zone boundary case 1996-10-27 01:00:00} detroit {
    clock format 846396000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.185 {time zone boundary case 1996-10-27 01:00:01} detroit {
    clock format 846396001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.186 {time zone boundary case 1997-04-06 01:59:59} detroit {
    clock format 860309999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.187 {time zone boundary case 1997-04-06 03:00:00} detroit {
    clock format 860310000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.188 {time zone boundary case 1997-04-06 03:00:01} detroit {
    clock format 860310001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.189 {time zone boundary case 1997-10-26 01:59:59} detroit {
    clock format 877845599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.190 {time zone boundary case 1997-10-26 01:00:00} detroit {
    clock format 877845600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.191 {time zone boundary case 1997-10-26 01:00:01} detroit {
    clock format 877845601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.192 {time zone boundary case 1998-04-05 01:59:59} detroit {
    clock format 891759599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.193 {time zone boundary case 1998-04-05 03:00:00} detroit {
    clock format 891759600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.194 {time zone boundary case 1998-04-05 03:00:01} detroit {
    clock format 891759601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.195 {time zone boundary case 1998-10-25 01:59:59} detroit {
    clock format 909295199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.196 {time zone boundary case 1998-10-25 01:00:00} detroit {
    clock format 909295200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.197 {time zone boundary case 1998-10-25 01:00:01} detroit {
    clock format 909295201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.198 {time zone boundary case 1999-04-04 01:59:59} detroit {
    clock format 923209199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.199 {time zone boundary case 1999-04-04 03:00:00} detroit {
    clock format 923209200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.200 {time zone boundary case 1999-04-04 03:00:01} detroit {
    clock format 923209201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.201 {time zone boundary case 1999-10-31 01:59:59} detroit {
    clock format 941349599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.202 {time zone boundary case 1999-10-31 01:00:00} detroit {
    clock format 941349600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.203 {time zone boundary case 1999-10-31 01:00:01} detroit {
    clock format 941349601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.204 {time zone boundary case 2000-04-02 01:59:59} detroit {
    clock format 954658799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.205 {time zone boundary case 2000-04-02 03:00:00} detroit {
    clock format 954658800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.206 {time zone boundary case 2000-04-02 03:00:01} detroit {
    clock format 954658801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.207 {time zone boundary case 2000-10-29 01:59:59} detroit {
    clock format 972799199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.208 {time zone boundary case 2000-10-29 01:00:00} detroit {
    clock format 972799200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.209 {time zone boundary case 2000-10-29 01:00:01} detroit {
    clock format 972799201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.210 {time zone boundary case 2001-04-01 01:59:59} detroit {
    clock format 986108399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.211 {time zone boundary case 2001-04-01 03:00:00} detroit {
    clock format 986108400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.212 {time zone boundary case 2001-04-01 03:00:01} detroit {
    clock format 986108401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.213 {time zone boundary case 2001-10-28 01:59:59} detroit {
    clock format 1004248799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.214 {time zone boundary case 2001-10-28 01:00:00} detroit {
    clock format 1004248800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.215 {time zone boundary case 2001-10-28 01:00:01} detroit {
    clock format 1004248801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.216 {time zone boundary case 2002-04-07 01:59:59} detroit {
    clock format 1018162799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.217 {time zone boundary case 2002-04-07 03:00:00} detroit {
    clock format 1018162800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.218 {time zone boundary case 2002-04-07 03:00:01} detroit {
    clock format 1018162801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.219 {time zone boundary case 2002-10-27 01:59:59} detroit {
    clock format 1035698399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.220 {time zone boundary case 2002-10-27 01:00:00} detroit {
    clock format 1035698400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.221 {time zone boundary case 2002-10-27 01:00:01} detroit {
    clock format 1035698401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.222 {time zone boundary case 2003-04-06 01:59:59} detroit {
    clock format 1049612399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.223 {time zone boundary case 2003-04-06 03:00:00} detroit {
    clock format 1049612400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.224 {time zone boundary case 2003-04-06 03:00:01} detroit {
    clock format 1049612401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.225 {time zone boundary case 2003-10-26 01:59:59} detroit {
    clock format 1067147999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.226 {time zone boundary case 2003-10-26 01:00:00} detroit {
    clock format 1067148000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.227 {time zone boundary case 2003-10-26 01:00:01} detroit {
    clock format 1067148001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.228 {time zone boundary case 2004-04-04 01:59:59} detroit {
    clock format 1081061999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.229 {time zone boundary case 2004-04-04 03:00:00} detroit {
    clock format 1081062000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.230 {time zone boundary case 2004-04-04 03:00:01} detroit {
    clock format 1081062001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.231 {time zone boundary case 2004-10-31 01:59:59} detroit {
    clock format 1099202399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.232 {time zone boundary case 2004-10-31 01:00:00} detroit {
    clock format 1099202400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.233 {time zone boundary case 2004-10-31 01:00:01} detroit {
    clock format 1099202401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.234 {time zone boundary case 2005-04-03 01:59:59} detroit {
    clock format 1112511599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.235 {time zone boundary case 2005-04-03 03:00:00} detroit {
    clock format 1112511600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.236 {time zone boundary case 2005-04-03 03:00:01} detroit {
    clock format 1112511601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.237 {time zone boundary case 2005-10-30 01:59:59} detroit {
    clock format 1130651999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.238 {time zone boundary case 2005-10-30 01:00:00} detroit {
    clock format 1130652000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.239 {time zone boundary case 2005-10-30 01:00:01} detroit {
    clock format 1130652001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.240 {time zone boundary case 2006-04-02 01:59:59} detroit {
    clock format 1143961199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.241 {time zone boundary case 2006-04-02 03:00:00} detroit {
    clock format 1143961200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.242 {time zone boundary case 2006-04-02 03:00:01} detroit {
    clock format 1143961201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.243 {time zone boundary case 2006-10-29 01:59:59} detroit {
    clock format 1162101599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.244 {time zone boundary case 2006-10-29 01:00:00} detroit {
    clock format 1162101600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.245 {time zone boundary case 2006-10-29 01:00:01} detroit {
    clock format 1162101601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.246 {time zone boundary case 2007-03-11 01:59:59} detroit {
    clock format 1173596399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.247 {time zone boundary case 2007-03-11 03:00:00} detroit {
    clock format 1173596400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.248 {time zone boundary case 2007-03-11 03:00:01} detroit {
    clock format 1173596401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.249 {time zone boundary case 2007-11-04 01:59:59} detroit {
    clock format 1194155999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.250 {time zone boundary case 2007-11-04 01:00:00} detroit {
    clock format 1194156000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.251 {time zone boundary case 2007-11-04 01:00:01} detroit {
    clock format 1194156001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.252 {time zone boundary case 2008-03-09 01:59:59} detroit {
    clock format 1205045999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.253 {time zone boundary case 2008-03-09 03:00:00} detroit {
    clock format 1205046000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.254 {time zone boundary case 2008-03-09 03:00:01} detroit {
    clock format 1205046001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.255 {time zone boundary case 2008-11-02 01:59:59} detroit {
    clock format 1225605599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.256 {time zone boundary case 2008-11-02 01:00:00} detroit {
    clock format 1225605600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.257 {time zone boundary case 2008-11-02 01:00:01} detroit {
    clock format 1225605601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.258 {time zone boundary case 2009-03-08 01:59:59} detroit {
    clock format 1236495599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.259 {time zone boundary case 2009-03-08 03:00:00} detroit {
    clock format 1236495600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.260 {time zone boundary case 2009-03-08 03:00:01} detroit {
    clock format 1236495601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.261 {time zone boundary case 2009-11-01 01:59:59} detroit {
    clock format 1257055199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.262 {time zone boundary case 2009-11-01 01:00:00} detroit {
    clock format 1257055200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.263 {time zone boundary case 2009-11-01 01:00:01} detroit {
    clock format 1257055201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.264 {time zone boundary case 2010-03-14 01:59:59} detroit {
    clock format 1268549999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.265 {time zone boundary case 2010-03-14 03:00:00} detroit {
    clock format 1268550000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.266 {time zone boundary case 2010-03-14 03:00:01} detroit {
    clock format 1268550001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.267 {time zone boundary case 2010-11-07 01:59:59} detroit {
    clock format 1289109599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.268 {time zone boundary case 2010-11-07 01:00:00} detroit {
    clock format 1289109600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.269 {time zone boundary case 2010-11-07 01:00:01} detroit {
    clock format 1289109601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.270 {time zone boundary case 2011-03-13 01:59:59} detroit {
    clock format 1299999599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.271 {time zone boundary case 2011-03-13 03:00:00} detroit {
    clock format 1299999600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.272 {time zone boundary case 2011-03-13 03:00:01} detroit {
    clock format 1299999601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.273 {time zone boundary case 2011-11-06 01:59:59} detroit {
    clock format 1320559199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.274 {time zone boundary case 2011-11-06 01:00:00} detroit {
    clock format 1320559200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.275 {time zone boundary case 2011-11-06 01:00:01} detroit {
    clock format 1320559201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.276 {time zone boundary case 2012-03-11 01:59:59} detroit {
    clock format 1331449199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.277 {time zone boundary case 2012-03-11 03:00:00} detroit {
    clock format 1331449200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.278 {time zone boundary case 2012-03-11 03:00:01} detroit {
    clock format 1331449201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.279 {time zone boundary case 2012-11-04 01:59:59} detroit {
    clock format 1352008799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.280 {time zone boundary case 2012-11-04 01:00:00} detroit {
    clock format 1352008800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.281 {time zone boundary case 2012-11-04 01:00:01} detroit {
    clock format 1352008801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.282 {time zone boundary case 2013-03-10 01:59:59} detroit {
    clock format 1362898799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.283 {time zone boundary case 2013-03-10 03:00:00} detroit {
    clock format 1362898800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.284 {time zone boundary case 2013-03-10 03:00:01} detroit {
    clock format 1362898801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.285 {time zone boundary case 2013-11-03 01:59:59} detroit {
    clock format 1383458399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.286 {time zone boundary case 2013-11-03 01:00:00} detroit {
    clock format 1383458400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.287 {time zone boundary case 2013-11-03 01:00:01} detroit {
    clock format 1383458401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.288 {time zone boundary case 2014-03-09 01:59:59} detroit {
    clock format 1394348399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.289 {time zone boundary case 2014-03-09 03:00:00} detroit {
    clock format 1394348400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.290 {time zone boundary case 2014-03-09 03:00:01} detroit {
    clock format 1394348401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.291 {time zone boundary case 2014-11-02 01:59:59} detroit {
    clock format 1414907999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.292 {time zone boundary case 2014-11-02 01:00:00} detroit {
    clock format 1414908000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.293 {time zone boundary case 2014-11-02 01:00:01} detroit {
    clock format 1414908001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.294 {time zone boundary case 2015-03-08 01:59:59} detroit {
    clock format 1425797999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.295 {time zone boundary case 2015-03-08 03:00:00} detroit {
    clock format 1425798000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.296 {time zone boundary case 2015-03-08 03:00:01} detroit {
    clock format 1425798001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.297 {time zone boundary case 2015-11-01 01:59:59} detroit {
    clock format 1446357599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.298 {time zone boundary case 2015-11-01 01:00:00} detroit {
    clock format 1446357600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.299 {time zone boundary case 2015-11-01 01:00:01} detroit {
    clock format 1446357601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.300 {time zone boundary case 2016-03-13 01:59:59} detroit {
    clock format 1457852399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.301 {time zone boundary case 2016-03-13 03:00:00} detroit {
    clock format 1457852400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.302 {time zone boundary case 2016-03-13 03:00:01} detroit {
    clock format 1457852401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.303 {time zone boundary case 2016-11-06 01:59:59} detroit {
    clock format 1478411999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.304 {time zone boundary case 2016-11-06 01:00:00} detroit {
    clock format 1478412000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.305 {time zone boundary case 2016-11-06 01:00:01} detroit {
    clock format 1478412001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.306 {time zone boundary case 2017-03-12 01:59:59} detroit {
    clock format 1489301999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.307 {time zone boundary case 2017-03-12 03:00:00} detroit {
    clock format 1489302000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.308 {time zone boundary case 2017-03-12 03:00:01} detroit {
    clock format 1489302001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.309 {time zone boundary case 2017-11-05 01:59:59} detroit {
    clock format 1509861599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.310 {time zone boundary case 2017-11-05 01:00:00} detroit {
    clock format 1509861600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.311 {time zone boundary case 2017-11-05 01:00:01} detroit {
    clock format 1509861601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.312 {time zone boundary case 2018-03-11 01:59:59} detroit {
    clock format 1520751599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.313 {time zone boundary case 2018-03-11 03:00:00} detroit {
    clock format 1520751600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.314 {time zone boundary case 2018-03-11 03:00:01} detroit {
    clock format 1520751601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.315 {time zone boundary case 2018-11-04 01:59:59} detroit {
    clock format 1541311199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.316 {time zone boundary case 2018-11-04 01:00:00} detroit {
    clock format 1541311200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.317 {time zone boundary case 2018-11-04 01:00:01} detroit {
    clock format 1541311201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.318 {time zone boundary case 2019-03-10 01:59:59} detroit {
    clock format 1552201199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.319 {time zone boundary case 2019-03-10 03:00:00} detroit {
    clock format 1552201200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.320 {time zone boundary case 2019-03-10 03:00:01} detroit {
    clock format 1552201201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.321 {time zone boundary case 2019-11-03 01:59:59} detroit {
    clock format 1572760799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.322 {time zone boundary case 2019-11-03 01:00:00} detroit {
    clock format 1572760800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.323 {time zone boundary case 2019-11-03 01:00:01} detroit {
    clock format 1572760801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.324 {time zone boundary case 2020-03-08 01:59:59} detroit {
    clock format 1583650799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.325 {time zone boundary case 2020-03-08 03:00:00} detroit {
    clock format 1583650800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.326 {time zone boundary case 2020-03-08 03:00:01} detroit {
    clock format 1583650801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.327 {time zone boundary case 2020-11-01 01:59:59} detroit {
    clock format 1604210399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.328 {time zone boundary case 2020-11-01 01:00:00} detroit {
    clock format 1604210400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.329 {time zone boundary case 2020-11-01 01:00:01} detroit {
    clock format 1604210401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.330 {time zone boundary case 2021-03-14 01:59:59} detroit {
    clock format 1615705199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.331 {time zone boundary case 2021-03-14 03:00:00} detroit {
    clock format 1615705200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.332 {time zone boundary case 2021-03-14 03:00:01} detroit {
    clock format 1615705201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.333 {time zone boundary case 2021-11-07 01:59:59} detroit {
    clock format 1636264799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.334 {time zone boundary case 2021-11-07 01:00:00} detroit {
    clock format 1636264800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.335 {time zone boundary case 2021-11-07 01:00:01} detroit {
    clock format 1636264801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.336 {time zone boundary case 2022-03-13 01:59:59} detroit {
    clock format 1647154799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.337 {time zone boundary case 2022-03-13 03:00:00} detroit {
    clock format 1647154800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.338 {time zone boundary case 2022-03-13 03:00:01} detroit {
    clock format 1647154801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.339 {time zone boundary case 2022-11-06 01:59:59} detroit {
    clock format 1667714399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.340 {time zone boundary case 2022-11-06 01:00:00} detroit {
    clock format 1667714400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.341 {time zone boundary case 2022-11-06 01:00:01} detroit {
    clock format 1667714401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.342 {time zone boundary case 2023-03-12 01:59:59} detroit {
    clock format 1678604399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.343 {time zone boundary case 2023-03-12 03:00:00} detroit {
    clock format 1678604400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.344 {time zone boundary case 2023-03-12 03:00:01} detroit {
    clock format 1678604401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.345 {time zone boundary case 2023-11-05 01:59:59} detroit {
    clock format 1699163999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.346 {time zone boundary case 2023-11-05 01:00:00} detroit {
    clock format 1699164000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.347 {time zone boundary case 2023-11-05 01:00:01} detroit {
    clock format 1699164001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.348 {time zone boundary case 2024-03-10 01:59:59} detroit {
    clock format 1710053999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.349 {time zone boundary case 2024-03-10 03:00:00} detroit {
    clock format 1710054000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.350 {time zone boundary case 2024-03-10 03:00:01} detroit {
    clock format 1710054001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.351 {time zone boundary case 2024-11-03 01:59:59} detroit {
    clock format 1730613599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.352 {time zone boundary case 2024-11-03 01:00:00} detroit {
    clock format 1730613600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.353 {time zone boundary case 2024-11-03 01:00:01} detroit {
    clock format 1730613601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.354 {time zone boundary case 2025-03-09 01:59:59} detroit {
    clock format 1741503599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.355 {time zone boundary case 2025-03-09 03:00:00} detroit {
    clock format 1741503600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.356 {time zone boundary case 2025-03-09 03:00:01} detroit {
    clock format 1741503601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.357 {time zone boundary case 2025-11-02 01:59:59} detroit {
    clock format 1762063199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.358 {time zone boundary case 2025-11-02 01:00:00} detroit {
    clock format 1762063200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.359 {time zone boundary case 2025-11-02 01:00:01} detroit {
    clock format 1762063201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.360 {time zone boundary case 2026-03-08 01:59:59} detroit {
    clock format 1772953199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.361 {time zone boundary case 2026-03-08 03:00:00} detroit {
    clock format 1772953200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.362 {time zone boundary case 2026-03-08 03:00:01} detroit {
    clock format 1772953201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.363 {time zone boundary case 2026-11-01 01:59:59} detroit {
    clock format 1793512799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.364 {time zone boundary case 2026-11-01 01:00:00} detroit {
    clock format 1793512800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.365 {time zone boundary case 2026-11-01 01:00:01} detroit {
    clock format 1793512801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.366 {time zone boundary case 2027-03-14 01:59:59} detroit {
    clock format 1805007599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.367 {time zone boundary case 2027-03-14 03:00:00} detroit {
    clock format 1805007600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.368 {time zone boundary case 2027-03-14 03:00:01} detroit {
    clock format 1805007601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.369 {time zone boundary case 2027-11-07 01:59:59} detroit {
    clock format 1825567199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.370 {time zone boundary case 2027-11-07 01:00:00} detroit {
    clock format 1825567200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.371 {time zone boundary case 2027-11-07 01:00:01} detroit {
    clock format 1825567201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.372 {time zone boundary case 2028-03-12 01:59:59} detroit {
    clock format 1836457199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.373 {time zone boundary case 2028-03-12 03:00:00} detroit {
    clock format 1836457200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.374 {time zone boundary case 2028-03-12 03:00:01} detroit {
    clock format 1836457201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.375 {time zone boundary case 2028-11-05 01:59:59} detroit {
    clock format 1857016799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.376 {time zone boundary case 2028-11-05 01:00:00} detroit {
    clock format 1857016800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.377 {time zone boundary case 2028-11-05 01:00:01} detroit {
    clock format 1857016801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.378 {time zone boundary case 2029-03-11 01:59:59} detroit {
    clock format 1867906799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.379 {time zone boundary case 2029-03-11 03:00:00} detroit {
    clock format 1867906800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.380 {time zone boundary case 2029-03-11 03:00:01} detroit {
    clock format 1867906801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.381 {time zone boundary case 2029-11-04 01:59:59} detroit {
    clock format 1888466399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.382 {time zone boundary case 2029-11-04 01:00:00} detroit {
    clock format 1888466400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.383 {time zone boundary case 2029-11-04 01:00:01} detroit {
    clock format 1888466401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.384 {time zone boundary case 2030-03-10 01:59:59} detroit {
    clock format 1899356399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.385 {time zone boundary case 2030-03-10 03:00:00} detroit {
    clock format 1899356400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.386 {time zone boundary case 2030-03-10 03:00:01} detroit {
    clock format 1899356401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.387 {time zone boundary case 2030-11-03 01:59:59} detroit {
    clock format 1919915999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.388 {time zone boundary case 2030-11-03 01:00:00} detroit {
    clock format 1919916000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.389 {time zone boundary case 2030-11-03 01:00:01} detroit {
    clock format 1919916001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.390 {time zone boundary case 2031-03-09 01:59:59} detroit {
    clock format 1930805999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.391 {time zone boundary case 2031-03-09 03:00:00} detroit {
    clock format 1930806000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.392 {time zone boundary case 2031-03-09 03:00:01} detroit {
    clock format 1930806001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.393 {time zone boundary case 2031-11-02 01:59:59} detroit {
    clock format 1951365599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.394 {time zone boundary case 2031-11-02 01:00:00} detroit {
    clock format 1951365600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.395 {time zone boundary case 2031-11-02 01:00:01} detroit {
    clock format 1951365601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.396 {time zone boundary case 2032-03-14 01:59:59} detroit {
    clock format 1962860399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.397 {time zone boundary case 2032-03-14 03:00:00} detroit {
    clock format 1962860400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.398 {time zone boundary case 2032-03-14 03:00:01} detroit {
    clock format 1962860401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.399 {time zone boundary case 2032-11-07 01:59:59} detroit {
    clock format 1983419999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.400 {time zone boundary case 2032-11-07 01:00:00} detroit {
    clock format 1983420000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.401 {time zone boundary case 2032-11-07 01:00:01} detroit {
    clock format 1983420001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.402 {time zone boundary case 2033-03-13 01:59:59} detroit {
    clock format 1994309999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.403 {time zone boundary case 2033-03-13 03:00:00} detroit {
    clock format 1994310000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.404 {time zone boundary case 2033-03-13 03:00:01} detroit {
    clock format 1994310001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.405 {time zone boundary case 2033-11-06 01:59:59} detroit {
    clock format 2014869599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.406 {time zone boundary case 2033-11-06 01:00:00} detroit {
    clock format 2014869600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.407 {time zone boundary case 2033-11-06 01:00:01} detroit {
    clock format 2014869601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.408 {time zone boundary case 2034-03-12 01:59:59} detroit {
    clock format 2025759599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.409 {time zone boundary case 2034-03-12 03:00:00} detroit {
    clock format 2025759600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.410 {time zone boundary case 2034-03-12 03:00:01} detroit {
    clock format 2025759601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.411 {time zone boundary case 2034-11-05 01:59:59} detroit {
    clock format 2046319199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.412 {time zone boundary case 2034-11-05 01:00:00} detroit {
    clock format 2046319200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.413 {time zone boundary case 2034-11-05 01:00:01} detroit {
    clock format 2046319201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.414 {time zone boundary case 2035-03-11 01:59:59} detroit {
    clock format 2057209199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.415 {time zone boundary case 2035-03-11 03:00:00} detroit {
    clock format 2057209200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.416 {time zone boundary case 2035-03-11 03:00:01} detroit {
    clock format 2057209201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.417 {time zone boundary case 2035-11-04 01:59:59} detroit {
    clock format 2077768799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.418 {time zone boundary case 2035-11-04 01:00:00} detroit {
    clock format 2077768800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.419 {time zone boundary case 2035-11-04 01:00:01} detroit {
    clock format 2077768801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.420 {time zone boundary case 2036-03-09 01:59:59} detroit {
    clock format 2088658799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.421 {time zone boundary case 2036-03-09 03:00:00} detroit {
    clock format 2088658800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.422 {time zone boundary case 2036-03-09 03:00:01} detroit {
    clock format 2088658801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.423 {time zone boundary case 2036-11-02 01:59:59} detroit {
    clock format 2109218399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.424 {time zone boundary case 2036-11-02 01:00:00} detroit {
    clock format 2109218400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.425 {time zone boundary case 2036-11-02 01:00:01} detroit {
    clock format 2109218401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.426 {time zone boundary case 2037-03-08 01:59:59} detroit {
    clock format 2120108399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.427 {time zone boundary case 2037-03-08 03:00:00} detroit {
    clock format 2120108400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.428 {time zone boundary case 2037-03-08 03:00:01} detroit {
    clock format 2120108401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.429 {time zone boundary case 2037-11-01 01:59:59} detroit {
    clock format 2140667999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.430 {time zone boundary case 2037-11-01 01:00:00} detroit {
    clock format 2140668000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.431 {time zone boundary case 2037-11-01 01:00:01} detroit {
    clock format 2140668001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.432 {time zone boundary case 2038-03-14 01:59:59} {detroit y2038} {
    clock format 2152162799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.433 {time zone boundary case 2038-03-14 03:00:00} {detroit y2038} {
    clock format 2152162800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.434 {time zone boundary case 2038-03-14 03:00:01} {detroit y2038} {
    clock format 2152162801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.435 {time zone boundary case 2038-11-07 01:59:59} {detroit y2038} {
    clock format 2172722399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.436 {time zone boundary case 2038-11-07 01:00:00} {detroit y2038} {
    clock format 2172722400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.437 {time zone boundary case 2038-11-07 01:00:01} {detroit y2038} {
    clock format 2172722401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.438 {time zone boundary case 2039-03-13 01:59:59} {detroit y2038} {
    clock format 2183612399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.439 {time zone boundary case 2039-03-13 03:00:00} {detroit y2038} {
    clock format 2183612400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.440 {time zone boundary case 2039-03-13 03:00:01} {detroit y2038} {
    clock format 2183612401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.441 {time zone boundary case 2039-11-06 01:59:59} {detroit y2038} {
    clock format 2204171999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.442 {time zone boundary case 2039-11-06 01:00:00} {detroit y2038} {
    clock format 2204172000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.443 {time zone boundary case 2039-11-06 01:00:01} {detroit y2038} {
    clock format 2204172001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.444 {time zone boundary case 2040-03-11 01:59:59} {detroit y2038} {
    clock format 2215061999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.445 {time zone boundary case 2040-03-11 03:00:00} {detroit y2038} {
    clock format 2215062000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.446 {time zone boundary case 2040-03-11 03:00:01} {detroit y2038} {
    clock format 2215062001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.447 {time zone boundary case 2040-11-04 01:59:59} {detroit y2038} {
    clock format 2235621599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.448 {time zone boundary case 2040-11-04 01:00:00} {detroit y2038} {
    clock format 2235621600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.449 {time zone boundary case 2040-11-04 01:00:01} {detroit y2038} {
    clock format 2235621601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.450 {time zone boundary case 2041-03-10 01:59:59} {detroit y2038} {
    clock format 2246511599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.451 {time zone boundary case 2041-03-10 03:00:00} {detroit y2038} {
    clock format 2246511600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.452 {time zone boundary case 2041-03-10 03:00:01} {detroit y2038} {
    clock format 2246511601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.453 {time zone boundary case 2041-11-03 01:59:59} {detroit y2038} {
    clock format 2267071199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.454 {time zone boundary case 2041-11-03 01:00:00} {detroit y2038} {
    clock format 2267071200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.455 {time zone boundary case 2041-11-03 01:00:01} {detroit y2038} {
    clock format 2267071201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.456 {time zone boundary case 2042-03-09 01:59:59} {detroit y2038} {
    clock format 2277961199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.457 {time zone boundary case 2042-03-09 03:00:00} {detroit y2038} {
    clock format 2277961200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.458 {time zone boundary case 2042-03-09 03:00:01} {detroit y2038} {
    clock format 2277961201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.459 {time zone boundary case 2042-11-02 01:59:59} {detroit y2038} {
    clock format 2298520799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.460 {time zone boundary case 2042-11-02 01:00:00} {detroit y2038} {
    clock format 2298520800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.461 {time zone boundary case 2042-11-02 01:00:01} {detroit y2038} {
    clock format 2298520801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.462 {time zone boundary case 2043-03-08 01:59:59} {detroit y2038} {
    clock format 2309410799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.463 {time zone boundary case 2043-03-08 03:00:00} {detroit y2038} {
    clock format 2309410800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.464 {time zone boundary case 2043-03-08 03:00:01} {detroit y2038} {
    clock format 2309410801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.465 {time zone boundary case 2043-11-01 01:59:59} {detroit y2038} {
    clock format 2329970399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.466 {time zone boundary case 2043-11-01 01:00:00} {detroit y2038} {
    clock format 2329970400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.467 {time zone boundary case 2043-11-01 01:00:01} {detroit y2038} {
    clock format 2329970401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.468 {time zone boundary case 2044-03-13 01:59:59} {detroit y2038} {
    clock format 2341465199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.469 {time zone boundary case 2044-03-13 03:00:00} {detroit y2038} {
    clock format 2341465200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.470 {time zone boundary case 2044-03-13 03:00:01} {detroit y2038} {
    clock format 2341465201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.471 {time zone boundary case 2044-11-06 01:59:59} {detroit y2038} {
    clock format 2362024799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.472 {time zone boundary case 2044-11-06 01:00:00} {detroit y2038} {
    clock format 2362024800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.473 {time zone boundary case 2044-11-06 01:00:01} {detroit y2038} {
    clock format 2362024801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.474 {time zone boundary case 2045-03-12 01:59:59} {detroit y2038} {
    clock format 2372914799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.475 {time zone boundary case 2045-03-12 03:00:00} {detroit y2038} {
    clock format 2372914800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.476 {time zone boundary case 2045-03-12 03:00:01} {detroit y2038} {
    clock format 2372914801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.477 {time zone boundary case 2045-11-05 01:59:59} {detroit y2038} {
    clock format 2393474399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.478 {time zone boundary case 2045-11-05 01:00:00} {detroit y2038} {
    clock format 2393474400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.479 {time zone boundary case 2045-11-05 01:00:01} {detroit y2038} {
    clock format 2393474401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.480 {time zone boundary case 2046-03-11 01:59:59} {detroit y2038} {
    clock format 2404364399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.481 {time zone boundary case 2046-03-11 03:00:00} {detroit y2038} {
    clock format 2404364400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.482 {time zone boundary case 2046-03-11 03:00:01} {detroit y2038} {
    clock format 2404364401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.483 {time zone boundary case 2046-11-04 01:59:59} {detroit y2038} {
    clock format 2424923999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.484 {time zone boundary case 2046-11-04 01:00:00} {detroit y2038} {
    clock format 2424924000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.485 {time zone boundary case 2046-11-04 01:00:01} {detroit y2038} {
    clock format 2424924001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.486 {time zone boundary case 2047-03-10 01:59:59} {detroit y2038} {
    clock format 2435813999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.487 {time zone boundary case 2047-03-10 03:00:00} {detroit y2038} {
    clock format 2435814000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.488 {time zone boundary case 2047-03-10 03:00:01} {detroit y2038} {
    clock format 2435814001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.489 {time zone boundary case 2047-11-03 01:59:59} {detroit y2038} {
    clock format 2456373599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.490 {time zone boundary case 2047-11-03 01:00:00} {detroit y2038} {
    clock format 2456373600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.491 {time zone boundary case 2047-11-03 01:00:01} {detroit y2038} {
    clock format 2456373601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.492 {time zone boundary case 2048-03-08 01:59:59} {detroit y2038} {
    clock format 2467263599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.493 {time zone boundary case 2048-03-08 03:00:00} {detroit y2038} {
    clock format 2467263600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.494 {time zone boundary case 2048-03-08 03:00:01} {detroit y2038} {
    clock format 2467263601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.495 {time zone boundary case 2048-11-01 01:59:59} {detroit y2038} {
    clock format 2487823199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.496 {time zone boundary case 2048-11-01 01:00:00} {detroit y2038} {
    clock format 2487823200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.497 {time zone boundary case 2048-11-01 01:00:01} {detroit y2038} {
    clock format 2487823201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.498 {time zone boundary case 2049-03-14 01:59:59} {detroit y2038} {
    clock format 2499317999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.499 {time zone boundary case 2049-03-14 03:00:00} {detroit y2038} {
    clock format 2499318000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.500 {time zone boundary case 2049-03-14 03:00:01} {detroit y2038} {
    clock format 2499318001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.501 {time zone boundary case 2049-11-07 01:59:59} {detroit y2038} {
    clock format 2519877599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.502 {time zone boundary case 2049-11-07 01:00:00} {detroit y2038} {
    clock format 2519877600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.503 {time zone boundary case 2049-11-07 01:00:01} {detroit y2038} {
    clock format 2519877601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.504 {time zone boundary case 2050-03-13 01:59:59} {detroit y2038} {
    clock format 2530767599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.505 {time zone boundary case 2050-03-13 03:00:00} {detroit y2038} {
    clock format 2530767600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.506 {time zone boundary case 2050-03-13 03:00:01} {detroit y2038} {
    clock format 2530767601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.507 {time zone boundary case 2050-11-06 01:59:59} {detroit y2038} {
    clock format 2551327199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.508 {time zone boundary case 2050-11-06 01:00:00} {detroit y2038} {
    clock format 2551327200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.509 {time zone boundary case 2050-11-06 01:00:01} {detroit y2038} {
    clock format 2551327201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.510 {time zone boundary case 2051-03-12 01:59:59} {detroit y2038} {
    clock format 2562217199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.511 {time zone boundary case 2051-03-12 03:00:00} {detroit y2038} {
    clock format 2562217200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.512 {time zone boundary case 2051-03-12 03:00:01} {detroit y2038} {
    clock format 2562217201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.513 {time zone boundary case 2051-11-05 01:59:59} {detroit y2038} {
    clock format 2582776799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.514 {time zone boundary case 2051-11-05 01:00:00} {detroit y2038} {
    clock format 2582776800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.515 {time zone boundary case 2051-11-05 01:00:01} {detroit y2038} {
    clock format 2582776801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.516 {time zone boundary case 2052-03-10 01:59:59} {detroit y2038} {
    clock format 2593666799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.517 {time zone boundary case 2052-03-10 03:00:00} {detroit y2038} {
    clock format 2593666800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.518 {time zone boundary case 2052-03-10 03:00:01} {detroit y2038} {
    clock format 2593666801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.519 {time zone boundary case 2052-11-03 01:59:59} {detroit y2038} {
    clock format 2614226399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.520 {time zone boundary case 2052-11-03 01:00:00} {detroit y2038} {
    clock format 2614226400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.521 {time zone boundary case 2052-11-03 01:00:01} {detroit y2038} {
    clock format 2614226401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.522 {time zone boundary case 2053-03-09 01:59:59} {detroit y2038} {
    clock format 2625116399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.523 {time zone boundary case 2053-03-09 03:00:00} {detroit y2038} {
    clock format 2625116400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.524 {time zone boundary case 2053-03-09 03:00:01} {detroit y2038} {
    clock format 2625116401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.525 {time zone boundary case 2053-11-02 01:59:59} {detroit y2038} {
    clock format 2645675999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.526 {time zone boundary case 2053-11-02 01:00:00} {detroit y2038} {
    clock format 2645676000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.527 {time zone boundary case 2053-11-02 01:00:01} {detroit y2038} {
    clock format 2645676001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.528 {time zone boundary case 2054-03-08 01:59:59} {detroit y2038} {
    clock format 2656565999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.529 {time zone boundary case 2054-03-08 03:00:00} {detroit y2038} {
    clock format 2656566000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.530 {time zone boundary case 2054-03-08 03:00:01} {detroit y2038} {
    clock format 2656566001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.531 {time zone boundary case 2054-11-01 01:59:59} {detroit y2038} {
    clock format 2677125599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.532 {time zone boundary case 2054-11-01 01:00:00} {detroit y2038} {
    clock format 2677125600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.533 {time zone boundary case 2054-11-01 01:00:01} {detroit y2038} {
    clock format 2677125601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.534 {time zone boundary case 2055-03-14 01:59:59} {detroit y2038} {
    clock format 2688620399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.535 {time zone boundary case 2055-03-14 03:00:00} {detroit y2038} {
    clock format 2688620400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.536 {time zone boundary case 2055-03-14 03:00:01} {detroit y2038} {
    clock format 2688620401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.537 {time zone boundary case 2055-11-07 01:59:59} {detroit y2038} {
    clock format 2709179999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.538 {time zone boundary case 2055-11-07 01:00:00} {detroit y2038} {
    clock format 2709180000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.539 {time zone boundary case 2055-11-07 01:00:01} {detroit y2038} {
    clock format 2709180001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.540 {time zone boundary case 2056-03-12 01:59:59} {detroit y2038} {
    clock format 2720069999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.541 {time zone boundary case 2056-03-12 03:00:00} {detroit y2038} {
    clock format 2720070000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.542 {time zone boundary case 2056-03-12 03:00:01} {detroit y2038} {
    clock format 2720070001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.543 {time zone boundary case 2056-11-05 01:59:59} {detroit y2038} {
    clock format 2740629599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.544 {time zone boundary case 2056-11-05 01:00:00} {detroit y2038} {
    clock format 2740629600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.545 {time zone boundary case 2056-11-05 01:00:01} {detroit y2038} {
    clock format 2740629601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.546 {time zone boundary case 2057-03-11 01:59:59} {detroit y2038} {
    clock format 2751519599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.547 {time zone boundary case 2057-03-11 03:00:00} {detroit y2038} {
    clock format 2751519600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.548 {time zone boundary case 2057-03-11 03:00:01} {detroit y2038} {
    clock format 2751519601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.549 {time zone boundary case 2057-11-04 01:59:59} {detroit y2038} {
    clock format 2772079199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.550 {time zone boundary case 2057-11-04 01:00:00} {detroit y2038} {
    clock format 2772079200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.551 {time zone boundary case 2057-11-04 01:00:01} {detroit y2038} {
    clock format 2772079201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.552 {time zone boundary case 2058-03-10 01:59:59} {detroit y2038} {
    clock format 2782969199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.553 {time zone boundary case 2058-03-10 03:00:00} {detroit y2038} {
    clock format 2782969200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.554 {time zone boundary case 2058-03-10 03:00:01} {detroit y2038} {
    clock format 2782969201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.555 {time zone boundary case 2058-11-03 01:59:59} {detroit y2038} {
    clock format 2803528799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.556 {time zone boundary case 2058-11-03 01:00:00} {detroit y2038} {
    clock format 2803528800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.557 {time zone boundary case 2058-11-03 01:00:01} {detroit y2038} {
    clock format 2803528801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.558 {time zone boundary case 2059-03-09 01:59:59} {detroit y2038} {
    clock format 2814418799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.559 {time zone boundary case 2059-03-09 03:00:00} {detroit y2038} {
    clock format 2814418800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.560 {time zone boundary case 2059-03-09 03:00:01} {detroit y2038} {
    clock format 2814418801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.561 {time zone boundary case 2059-11-02 01:59:59} {detroit y2038} {
    clock format 2834978399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.562 {time zone boundary case 2059-11-02 01:00:00} {detroit y2038} {
    clock format 2834978400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.563 {time zone boundary case 2059-11-02 01:00:01} {detroit y2038} {
    clock format 2834978401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.564 {time zone boundary case 2060-03-14 01:59:59} {detroit y2038} {
    clock format 2846473199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.565 {time zone boundary case 2060-03-14 03:00:00} {detroit y2038} {
    clock format 2846473200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.566 {time zone boundary case 2060-03-14 03:00:01} {detroit y2038} {
    clock format 2846473201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.567 {time zone boundary case 2060-11-07 01:59:59} {detroit y2038} {
    clock format 2867032799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.568 {time zone boundary case 2060-11-07 01:00:00} {detroit y2038} {
    clock format 2867032800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.569 {time zone boundary case 2060-11-07 01:00:01} {detroit y2038} {
    clock format 2867032801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.570 {time zone boundary case 2061-03-13 01:59:59} {detroit y2038} {
    clock format 2877922799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.571 {time zone boundary case 2061-03-13 03:00:00} {detroit y2038} {
    clock format 2877922800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.572 {time zone boundary case 2061-03-13 03:00:01} {detroit y2038} {
    clock format 2877922801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.573 {time zone boundary case 2061-11-06 01:59:59} {detroit y2038} {
    clock format 2898482399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.574 {time zone boundary case 2061-11-06 01:00:00} {detroit y2038} {
    clock format 2898482400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.575 {time zone boundary case 2061-11-06 01:00:01} {detroit y2038} {
    clock format 2898482401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.576 {time zone boundary case 2062-03-12 01:59:59} {detroit y2038} {
    clock format 2909372399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.577 {time zone boundary case 2062-03-12 03:00:00} {detroit y2038} {
    clock format 2909372400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.578 {time zone boundary case 2062-03-12 03:00:01} {detroit y2038} {
    clock format 2909372401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.579 {time zone boundary case 2062-11-05 01:59:59} {detroit y2038} {
    clock format 2929931999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.580 {time zone boundary case 2062-11-05 01:00:00} {detroit y2038} {
    clock format 2929932000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.581 {time zone boundary case 2062-11-05 01:00:01} {detroit y2038} {
    clock format 2929932001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.582 {time zone boundary case 2063-03-11 01:59:59} {detroit y2038} {
    clock format 2940821999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.583 {time zone boundary case 2063-03-11 03:00:00} {detroit y2038} {
    clock format 2940822000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.584 {time zone boundary case 2063-03-11 03:00:01} {detroit y2038} {
    clock format 2940822001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.585 {time zone boundary case 2063-11-04 01:59:59} {detroit y2038} {
    clock format 2961381599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.586 {time zone boundary case 2063-11-04 01:00:00} {detroit y2038} {
    clock format 2961381600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.587 {time zone boundary case 2063-11-04 01:00:01} {detroit y2038} {
    clock format 2961381601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.588 {time zone boundary case 2064-03-09 01:59:59} {detroit y2038} {
    clock format 2972271599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.589 {time zone boundary case 2064-03-09 03:00:00} {detroit y2038} {
    clock format 2972271600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.590 {time zone boundary case 2064-03-09 03:00:01} {detroit y2038} {
    clock format 2972271601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.591 {time zone boundary case 2064-11-02 01:59:59} {detroit y2038} {
    clock format 2992831199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.592 {time zone boundary case 2064-11-02 01:00:00} {detroit y2038} {
    clock format 2992831200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.593 {time zone boundary case 2064-11-02 01:00:01} {detroit y2038} {
    clock format 2992831201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.594 {time zone boundary case 2065-03-08 01:59:59} {detroit y2038} {
    clock format 3003721199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.595 {time zone boundary case 2065-03-08 03:00:00} {detroit y2038} {
    clock format 3003721200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.596 {time zone boundary case 2065-03-08 03:00:01} {detroit y2038} {
    clock format 3003721201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.597 {time zone boundary case 2065-11-01 01:59:59} {detroit y2038} {
    clock format 3024280799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.598 {time zone boundary case 2065-11-01 01:00:00} {detroit y2038} {
    clock format 3024280800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.599 {time zone boundary case 2065-11-01 01:00:01} {detroit y2038} {
    clock format 3024280801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.600 {time zone boundary case 2066-03-14 01:59:59} {detroit y2038} {
    clock format 3035775599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.601 {time zone boundary case 2066-03-14 03:00:00} {detroit y2038} {
    clock format 3035775600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.602 {time zone boundary case 2066-03-14 03:00:01} {detroit y2038} {
    clock format 3035775601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.603 {time zone boundary case 2066-11-07 01:59:59} {detroit y2038} {
    clock format 3056335199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.604 {time zone boundary case 2066-11-07 01:00:00} {detroit y2038} {
    clock format 3056335200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.605 {time zone boundary case 2066-11-07 01:00:01} {detroit y2038} {
    clock format 3056335201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.606 {time zone boundary case 2067-03-13 01:59:59} {detroit y2038} {
    clock format 3067225199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.607 {time zone boundary case 2067-03-13 03:00:00} {detroit y2038} {
    clock format 3067225200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.608 {time zone boundary case 2067-03-13 03:00:01} {detroit y2038} {
    clock format 3067225201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.609 {time zone boundary case 2067-11-06 01:59:59} {detroit y2038} {
    clock format 3087784799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.610 {time zone boundary case 2067-11-06 01:00:00} {detroit y2038} {
    clock format 3087784800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.611 {time zone boundary case 2067-11-06 01:00:01} {detroit y2038} {
    clock format 3087784801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.612 {time zone boundary case 2068-03-11 01:59:59} {detroit y2038} {
    clock format 3098674799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.613 {time zone boundary case 2068-03-11 03:00:00} {detroit y2038} {
    clock format 3098674800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.614 {time zone boundary case 2068-03-11 03:00:01} {detroit y2038} {
    clock format 3098674801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.615 {time zone boundary case 2068-11-04 01:59:59} {detroit y2038} {
    clock format 3119234399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.616 {time zone boundary case 2068-11-04 01:00:00} {detroit y2038} {
    clock format 3119234400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.617 {time zone boundary case 2068-11-04 01:00:01} {detroit y2038} {
    clock format 3119234401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.618 {time zone boundary case 2069-03-10 01:59:59} {detroit y2038} {
    clock format 3130124399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.619 {time zone boundary case 2069-03-10 03:00:00} {detroit y2038} {
    clock format 3130124400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.620 {time zone boundary case 2069-03-10 03:00:01} {detroit y2038} {
    clock format 3130124401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.621 {time zone boundary case 2069-11-03 01:59:59} {detroit y2038} {
    clock format 3150683999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.622 {time zone boundary case 2069-11-03 01:00:00} {detroit y2038} {
    clock format 3150684000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.623 {time zone boundary case 2069-11-03 01:00:01} {detroit y2038} {
    clock format 3150684001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.624 {time zone boundary case 2070-03-09 01:59:59} {detroit y2038} {
    clock format 3161573999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.625 {time zone boundary case 2070-03-09 03:00:00} {detroit y2038} {
    clock format 3161574000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.626 {time zone boundary case 2070-03-09 03:00:01} {detroit y2038} {
    clock format 3161574001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.627 {time zone boundary case 2070-11-02 01:59:59} {detroit y2038} {
    clock format 3182133599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.628 {time zone boundary case 2070-11-02 01:00:00} {detroit y2038} {
    clock format 3182133600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.629 {time zone boundary case 2070-11-02 01:00:01} {detroit y2038} {
    clock format 3182133601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.630 {time zone boundary case 2071-03-08 01:59:59} {detroit y2038} {
    clock format 3193023599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.631 {time zone boundary case 2071-03-08 03:00:00} {detroit y2038} {
    clock format 3193023600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.632 {time zone boundary case 2071-03-08 03:00:01} {detroit y2038} {
    clock format 3193023601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.633 {time zone boundary case 2071-11-01 01:59:59} {detroit y2038} {
    clock format 3213583199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.634 {time zone boundary case 2071-11-01 01:00:00} {detroit y2038} {
    clock format 3213583200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.635 {time zone boundary case 2071-11-01 01:00:01} {detroit y2038} {
    clock format 3213583201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.636 {time zone boundary case 2072-03-13 01:59:59} {detroit y2038} {
    clock format 3225077999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.637 {time zone boundary case 2072-03-13 03:00:00} {detroit y2038} {
    clock format 3225078000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.638 {time zone boundary case 2072-03-13 03:00:01} {detroit y2038} {
    clock format 3225078001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.639 {time zone boundary case 2072-11-06 01:59:59} {detroit y2038} {
    clock format 3245637599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.640 {time zone boundary case 2072-11-06 01:00:00} {detroit y2038} {
    clock format 3245637600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.641 {time zone boundary case 2072-11-06 01:00:01} {detroit y2038} {
    clock format 3245637601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.642 {time zone boundary case 2073-03-12 01:59:59} {detroit y2038} {
    clock format 3256527599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.643 {time zone boundary case 2073-03-12 03:00:00} {detroit y2038} {
    clock format 3256527600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.644 {time zone boundary case 2073-03-12 03:00:01} {detroit y2038} {
    clock format 3256527601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.645 {time zone boundary case 2073-11-05 01:59:59} {detroit y2038} {
    clock format 3277087199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.646 {time zone boundary case 2073-11-05 01:00:00} {detroit y2038} {
    clock format 3277087200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.647 {time zone boundary case 2073-11-05 01:00:01} {detroit y2038} {
    clock format 3277087201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.648 {time zone boundary case 2074-03-11 01:59:59} {detroit y2038} {
    clock format 3287977199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.649 {time zone boundary case 2074-03-11 03:00:00} {detroit y2038} {
    clock format 3287977200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.650 {time zone boundary case 2074-03-11 03:00:01} {detroit y2038} {
    clock format 3287977201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.651 {time zone boundary case 2074-11-04 01:59:59} {detroit y2038} {
    clock format 3308536799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.652 {time zone boundary case 2074-11-04 01:00:00} {detroit y2038} {
    clock format 3308536800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.653 {time zone boundary case 2074-11-04 01:00:01} {detroit y2038} {
    clock format 3308536801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.654 {time zone boundary case 2075-03-10 01:59:59} {detroit y2038} {
    clock format 3319426799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.655 {time zone boundary case 2075-03-10 03:00:00} {detroit y2038} {
    clock format 3319426800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.656 {time zone boundary case 2075-03-10 03:00:01} {detroit y2038} {
    clock format 3319426801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.657 {time zone boundary case 2075-11-03 01:59:59} {detroit y2038} {
    clock format 3339986399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.658 {time zone boundary case 2075-11-03 01:00:00} {detroit y2038} {
    clock format 3339986400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.659 {time zone boundary case 2075-11-03 01:00:01} {detroit y2038} {
    clock format 3339986401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.660 {time zone boundary case 2076-03-08 01:59:59} {detroit y2038} {
    clock format 3350876399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.661 {time zone boundary case 2076-03-08 03:00:00} {detroit y2038} {
    clock format 3350876400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.662 {time zone boundary case 2076-03-08 03:00:01} {detroit y2038} {
    clock format 3350876401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.663 {time zone boundary case 2076-11-01 01:59:59} {detroit y2038} {
    clock format 3371435999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.664 {time zone boundary case 2076-11-01 01:00:00} {detroit y2038} {
    clock format 3371436000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.665 {time zone boundary case 2076-11-01 01:00:01} {detroit y2038} {
    clock format 3371436001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.666 {time zone boundary case 2077-03-14 01:59:59} {detroit y2038} {
    clock format 3382930799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.667 {time zone boundary case 2077-03-14 03:00:00} {detroit y2038} {
    clock format 3382930800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.668 {time zone boundary case 2077-03-14 03:00:01} {detroit y2038} {
    clock format 3382930801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.669 {time zone boundary case 2077-11-07 01:59:59} {detroit y2038} {
    clock format 3403490399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.670 {time zone boundary case 2077-11-07 01:00:00} {detroit y2038} {
    clock format 3403490400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.671 {time zone boundary case 2077-11-07 01:00:01} {detroit y2038} {
    clock format 3403490401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.672 {time zone boundary case 2078-03-13 01:59:59} {detroit y2038} {
    clock format 3414380399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.673 {time zone boundary case 2078-03-13 03:00:00} {detroit y2038} {
    clock format 3414380400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.674 {time zone boundary case 2078-03-13 03:00:01} {detroit y2038} {
    clock format 3414380401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.675 {time zone boundary case 2078-11-06 01:59:59} {detroit y2038} {
    clock format 3434939999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.676 {time zone boundary case 2078-11-06 01:00:00} {detroit y2038} {
    clock format 3434940000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.677 {time zone boundary case 2078-11-06 01:00:01} {detroit y2038} {
    clock format 3434940001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.678 {time zone boundary case 2079-03-12 01:59:59} {detroit y2038} {
    clock format 3445829999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.679 {time zone boundary case 2079-03-12 03:00:00} {detroit y2038} {
    clock format 3445830000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.680 {time zone boundary case 2079-03-12 03:00:01} {detroit y2038} {
    clock format 3445830001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.681 {time zone boundary case 2079-11-05 01:59:59} {detroit y2038} {
    clock format 3466389599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.682 {time zone boundary case 2079-11-05 01:00:00} {detroit y2038} {
    clock format 3466389600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.683 {time zone boundary case 2079-11-05 01:00:01} {detroit y2038} {
    clock format 3466389601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.684 {time zone boundary case 2080-03-10 01:59:59} {detroit y2038} {
    clock format 3477279599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.685 {time zone boundary case 2080-03-10 03:00:00} {detroit y2038} {
    clock format 3477279600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.686 {time zone boundary case 2080-03-10 03:00:01} {detroit y2038} {
    clock format 3477279601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.687 {time zone boundary case 2080-11-03 01:59:59} {detroit y2038} {
    clock format 3497839199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.688 {time zone boundary case 2080-11-03 01:00:00} {detroit y2038} {
    clock format 3497839200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.689 {time zone boundary case 2080-11-03 01:00:01} {detroit y2038} {
    clock format 3497839201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.690 {time zone boundary case 2081-03-09 01:59:59} {detroit y2038} {
    clock format 3508729199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.691 {time zone boundary case 2081-03-09 03:00:00} {detroit y2038} {
    clock format 3508729200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.692 {time zone boundary case 2081-03-09 03:00:01} {detroit y2038} {
    clock format 3508729201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.693 {time zone boundary case 2081-11-02 01:59:59} {detroit y2038} {
    clock format 3529288799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.694 {time zone boundary case 2081-11-02 01:00:00} {detroit y2038} {
    clock format 3529288800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.695 {time zone boundary case 2081-11-02 01:00:01} {detroit y2038} {
    clock format 3529288801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.696 {time zone boundary case 2082-03-08 01:59:59} {detroit y2038} {
    clock format 3540178799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.697 {time zone boundary case 2082-03-08 03:00:00} {detroit y2038} {
    clock format 3540178800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.698 {time zone boundary case 2082-03-08 03:00:01} {detroit y2038} {
    clock format 3540178801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.699 {time zone boundary case 2082-11-01 01:59:59} {detroit y2038} {
    clock format 3560738399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.700 {time zone boundary case 2082-11-01 01:00:00} {detroit y2038} {
    clock format 3560738400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.701 {time zone boundary case 2082-11-01 01:00:01} {detroit y2038} {
    clock format 3560738401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.702 {time zone boundary case 2083-03-14 01:59:59} {detroit y2038} {
    clock format 3572233199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.703 {time zone boundary case 2083-03-14 03:00:00} {detroit y2038} {
    clock format 3572233200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.704 {time zone boundary case 2083-03-14 03:00:01} {detroit y2038} {
    clock format 3572233201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.705 {time zone boundary case 2083-11-07 01:59:59} {detroit y2038} {
    clock format 3592792799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.706 {time zone boundary case 2083-11-07 01:00:00} {detroit y2038} {
    clock format 3592792800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.707 {time zone boundary case 2083-11-07 01:00:01} {detroit y2038} {
    clock format 3592792801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.708 {time zone boundary case 2084-03-12 01:59:59} {detroit y2038} {
    clock format 3603682799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.709 {time zone boundary case 2084-03-12 03:00:00} {detroit y2038} {
    clock format 3603682800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.710 {time zone boundary case 2084-03-12 03:00:01} {detroit y2038} {
    clock format 3603682801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.711 {time zone boundary case 2084-11-05 01:59:59} {detroit y2038} {
    clock format 3624242399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.712 {time zone boundary case 2084-11-05 01:00:00} {detroit y2038} {
    clock format 3624242400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.713 {time zone boundary case 2084-11-05 01:00:01} {detroit y2038} {
    clock format 3624242401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.714 {time zone boundary case 2085-03-11 01:59:59} {detroit y2038} {
    clock format 3635132399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.715 {time zone boundary case 2085-03-11 03:00:00} {detroit y2038} {
    clock format 3635132400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.716 {time zone boundary case 2085-03-11 03:00:01} {detroit y2038} {
    clock format 3635132401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.717 {time zone boundary case 2085-11-04 01:59:59} {detroit y2038} {
    clock format 3655691999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.718 {time zone boundary case 2085-11-04 01:00:00} {detroit y2038} {
    clock format 3655692000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.719 {time zone boundary case 2085-11-04 01:00:01} {detroit y2038} {
    clock format 3655692001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.720 {time zone boundary case 2086-03-10 01:59:59} {detroit y2038} {
    clock format 3666581999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.721 {time zone boundary case 2086-03-10 03:00:00} {detroit y2038} {
    clock format 3666582000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.722 {time zone boundary case 2086-03-10 03:00:01} {detroit y2038} {
    clock format 3666582001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.723 {time zone boundary case 2086-11-03 01:59:59} {detroit y2038} {
    clock format 3687141599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.724 {time zone boundary case 2086-11-03 01:00:00} {detroit y2038} {
    clock format 3687141600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.725 {time zone boundary case 2086-11-03 01:00:01} {detroit y2038} {
    clock format 3687141601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.726 {time zone boundary case 2087-03-09 01:59:59} {detroit y2038} {
    clock format 3698031599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.727 {time zone boundary case 2087-03-09 03:00:00} {detroit y2038} {
    clock format 3698031600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.728 {time zone boundary case 2087-03-09 03:00:01} {detroit y2038} {
    clock format 3698031601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.729 {time zone boundary case 2087-11-02 01:59:59} {detroit y2038} {
    clock format 3718591199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.730 {time zone boundary case 2087-11-02 01:00:00} {detroit y2038} {
    clock format 3718591200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.731 {time zone boundary case 2087-11-02 01:00:01} {detroit y2038} {
    clock format 3718591201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.732 {time zone boundary case 2088-03-14 01:59:59} {detroit y2038} {
    clock format 3730085999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.733 {time zone boundary case 2088-03-14 03:00:00} {detroit y2038} {
    clock format 3730086000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.734 {time zone boundary case 2088-03-14 03:00:01} {detroit y2038} {
    clock format 3730086001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.735 {time zone boundary case 2088-11-07 01:59:59} {detroit y2038} {
    clock format 3750645599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.736 {time zone boundary case 2088-11-07 01:00:00} {detroit y2038} {
    clock format 3750645600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.737 {time zone boundary case 2088-11-07 01:00:01} {detroit y2038} {
    clock format 3750645601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.738 {time zone boundary case 2089-03-13 01:59:59} {detroit y2038} {
    clock format 3761535599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.739 {time zone boundary case 2089-03-13 03:00:00} {detroit y2038} {
    clock format 3761535600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.740 {time zone boundary case 2089-03-13 03:00:01} {detroit y2038} {
    clock format 3761535601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.741 {time zone boundary case 2089-11-06 01:59:59} {detroit y2038} {
    clock format 3782095199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.742 {time zone boundary case 2089-11-06 01:00:00} {detroit y2038} {
    clock format 3782095200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.743 {time zone boundary case 2089-11-06 01:00:01} {detroit y2038} {
    clock format 3782095201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.744 {time zone boundary case 2090-03-12 01:59:59} {detroit y2038} {
    clock format 3792985199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.745 {time zone boundary case 2090-03-12 03:00:00} {detroit y2038} {
    clock format 3792985200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.746 {time zone boundary case 2090-03-12 03:00:01} {detroit y2038} {
    clock format 3792985201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.747 {time zone boundary case 2090-11-05 01:59:59} {detroit y2038} {
    clock format 3813544799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.748 {time zone boundary case 2090-11-05 01:00:00} {detroit y2038} {
    clock format 3813544800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.749 {time zone boundary case 2090-11-05 01:00:01} {detroit y2038} {
    clock format 3813544801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.750 {time zone boundary case 2091-03-11 01:59:59} {detroit y2038} {
    clock format 3824434799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.751 {time zone boundary case 2091-03-11 03:00:00} {detroit y2038} {
    clock format 3824434800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.752 {time zone boundary case 2091-03-11 03:00:01} {detroit y2038} {
    clock format 3824434801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.753 {time zone boundary case 2091-11-04 01:59:59} {detroit y2038} {
    clock format 3844994399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.754 {time zone boundary case 2091-11-04 01:00:00} {detroit y2038} {
    clock format 3844994400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.755 {time zone boundary case 2091-11-04 01:00:01} {detroit y2038} {
    clock format 3844994401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.756 {time zone boundary case 2092-03-09 01:59:59} {detroit y2038} {
    clock format 3855884399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.757 {time zone boundary case 2092-03-09 03:00:00} {detroit y2038} {
    clock format 3855884400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.758 {time zone boundary case 2092-03-09 03:00:01} {detroit y2038} {
    clock format 3855884401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.759 {time zone boundary case 2092-11-02 01:59:59} {detroit y2038} {
    clock format 3876443999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.760 {time zone boundary case 2092-11-02 01:00:00} {detroit y2038} {
    clock format 3876444000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.761 {time zone boundary case 2092-11-02 01:00:01} {detroit y2038} {
    clock format 3876444001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.762 {time zone boundary case 2093-03-08 01:59:59} {detroit y2038} {
    clock format 3887333999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.763 {time zone boundary case 2093-03-08 03:00:00} {detroit y2038} {
    clock format 3887334000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.764 {time zone boundary case 2093-03-08 03:00:01} {detroit y2038} {
    clock format 3887334001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.765 {time zone boundary case 2093-11-01 01:59:59} {detroit y2038} {
    clock format 3907893599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.766 {time zone boundary case 2093-11-01 01:00:00} {detroit y2038} {
    clock format 3907893600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.767 {time zone boundary case 2093-11-01 01:00:01} {detroit y2038} {
    clock format 3907893601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.768 {time zone boundary case 2094-03-14 01:59:59} {detroit y2038} {
    clock format 3919388399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.769 {time zone boundary case 2094-03-14 03:00:00} {detroit y2038} {
    clock format 3919388400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.770 {time zone boundary case 2094-03-14 03:00:01} {detroit y2038} {
    clock format 3919388401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.771 {time zone boundary case 2094-11-07 01:59:59} {detroit y2038} {
    clock format 3939947999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.772 {time zone boundary case 2094-11-07 01:00:00} {detroit y2038} {
    clock format 3939948000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.773 {time zone boundary case 2094-11-07 01:00:01} {detroit y2038} {
    clock format 3939948001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.774 {time zone boundary case 2095-03-13 01:59:59} {detroit y2038} {
    clock format 3950837999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.775 {time zone boundary case 2095-03-13 03:00:00} {detroit y2038} {
    clock format 3950838000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.776 {time zone boundary case 2095-03-13 03:00:01} {detroit y2038} {
    clock format 3950838001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.777 {time zone boundary case 2095-11-06 01:59:59} {detroit y2038} {
    clock format 3971397599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.778 {time zone boundary case 2095-11-06 01:00:00} {detroit y2038} {
    clock format 3971397600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.779 {time zone boundary case 2095-11-06 01:00:01} {detroit y2038} {
    clock format 3971397601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.780 {time zone boundary case 2096-03-11 01:59:59} {detroit y2038} {
    clock format 3982287599 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.781 {time zone boundary case 2096-03-11 03:00:00} {detroit y2038} {
    clock format 3982287600 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.782 {time zone boundary case 2096-03-11 03:00:01} {detroit y2038} {
    clock format 3982287601 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.783 {time zone boundary case 2096-11-04 01:59:59} {detroit y2038} {
    clock format 4002847199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.784 {time zone boundary case 2096-11-04 01:00:00} {detroit y2038} {
    clock format 4002847200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.785 {time zone boundary case 2096-11-04 01:00:01} {detroit y2038} {
    clock format 4002847201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.786 {time zone boundary case 2097-03-10 01:59:59} {detroit y2038} {
    clock format 4013737199 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.787 {time zone boundary case 2097-03-10 03:00:00} {detroit y2038} {
    clock format 4013737200 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.788 {time zone boundary case 2097-03-10 03:00:01} {detroit y2038} {
    clock format 4013737201 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.789 {time zone boundary case 2097-11-03 01:59:59} {detroit y2038} {
    clock format 4034296799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.790 {time zone boundary case 2097-11-03 01:00:00} {detroit y2038} {
    clock format 4034296800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.791 {time zone boundary case 2097-11-03 01:00:01} {detroit y2038} {
    clock format 4034296801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.792 {time zone boundary case 2098-03-09 01:59:59} {detroit y2038} {
    clock format 4045186799 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.793 {time zone boundary case 2098-03-09 03:00:00} {detroit y2038} {
    clock format 4045186800 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.794 {time zone boundary case 2098-03-09 03:00:01} {detroit y2038} {
    clock format 4045186801 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.795 {time zone boundary case 2098-11-02 01:59:59} {detroit y2038} {
    clock format 4065746399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.796 {time zone boundary case 2098-11-02 01:00:00} {detroit y2038} {
    clock format 4065746400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.797 {time zone boundary case 2098-11-02 01:00:01} {detroit y2038} {
    clock format 4065746401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.798 {time zone boundary case 2099-03-08 01:59:59} {detroit y2038} {
    clock format 4076636399 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.799 {time zone boundary case 2099-03-08 03:00:00} {detroit y2038} {
    clock format 4076636400 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.800 {time zone boundary case 2099-03-08 03:00:01} {detroit y2038} {
    clock format 4076636401 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.801 {time zone boundary case 2099-11-01 01:59:59} {detroit y2038} {
    clock format 4097195999 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.802 {time zone boundary case 2099-11-01 01:00:00} {detroit y2038} {
    clock format 4097196000 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.803 {time zone boundary case 2099-11-01 01:00:01} {detroit y2038} {
    clock format 4097196001 -format {%H:%M:%S %z %Z} \
        -timezone :America/Detroit
} {01:00:01 -0500 EST}
# END testcases5

# Test input conversions.

test clock-6.0 {input of seconds} {
    clock scan {-9223372036854775808} -format %s -gmt true







|
|
|


















|

|




|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|






|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|







15449
15450
15451
15452
15453
15454
15455
15456
15457
15458
15459
15460
15461
15462
15463
15464
15465
15466
15467
15468
15469
15470
15471
15472
15473
15474
15475
15476
15477
15478
15479
15480
15481
15482
15483
15484
15485
15486
15487
15488
15489
15490
15491
15492
15493
15494
15495
15496
15497
15498
15499
15500
15501
15502
15503
15504
15505
15506
15507
15508
15509
15510
15511
15512
15513
15514
15515
15516
15517
15518
15519
15520
15521
15522
15523
15524
15525
15526
15527
15528
15529
15530
15531
15532
15533
15534
15535
15536
15537
15538
15539
15540
15541
15542
15543
15544
15545
15546
15547
15548
15549
15550
15551
15552
15553
15554
15555
15556
15557
15558
15559
15560
15561
15562
15563
15564
15565
15566
15567
15568
15569
15570
15571
15572
15573
15574
15575
15576
15577
15578
15579
15580
15581
15582
15583
15584
15585
15586
15587
15588
15589
15590
15591
15592
15593
15594
15595
15596
15597
15598
15599
15600
15601
15602
15603
15604
15605
15606
15607
15608
15609
15610
15611
15612
15613
15614
15615
15616
15617
15618
15619
15620
15621
15622
15623
15624
15625
15626
15627
15628
15629
15630
15631
15632
15633
15634
15635
15636
15637
15638
15639
15640
15641
15642
15643
15644
15645
15646
15647
15648
15649
15650
15651
15652
15653
15654
15655
15656
15657
15658
15659
15660
15661
15662
15663
15664
15665
15666
15667
15668
15669
15670
15671
15672
15673
15674
15675
15676
15677
15678
15679
15680
15681
15682
15683
15684
15685
15686
15687
15688
15689
15690
15691
15692
15693
15694
15695
15696
15697
15698
15699
15700
15701
15702
15703
15704
15705
15706
15707
15708
15709
15710
15711
15712
15713
15714
15715
15716
15717
15718
15719
15720
15721
15722
15723
15724
15725
15726
15727
15728
15729
15730
15731
15732
15733
15734
15735
15736
15737
15738
15739
15740
15741
15742
15743
15744
15745
15746
15747
15748
15749
15750
15751
15752
15753
15754
15755
15756
15757
15758
15759
15760
15761
15762
15763
15764
15765
15766
15767
15768
15769
15770
15771
15772
15773
15774
15775
15776
15777
15778
15779
15780
15781
15782
15783
15784
15785
15786
15787
15788
15789
15790
15791
15792
15793
15794
15795
15796
15797
15798
15799
15800
15801
15802
15803
15804
15805
15806
15807
15808
15809
15810
15811
15812
15813
15814
15815
15816
15817
15818
15819
15820
15821
15822
15823
15824
15825
15826
15827
15828
15829
15830
15831
15832
15833
15834
15835
15836
15837
15838
15839
15840
15841
15842
15843
15844
15845
15846
15847
15848
15849
15850
15851
15852
15853
15854
15855
15856
15857
15858
15859
15860
15861
15862
15863
15864
15865
15866
15867
15868
15869
15870
15871
15872
15873
15874
15875
15876
15877
15878
15879
15880
15881
15882
15883
15884
15885
15886
15887
15888
15889
15890
15891
15892
15893
15894
15895
15896
15897
15898
15899
15900
15901
15902
15903
15904
15905
15906
15907
15908
15909
15910
15911
15912
15913
15914
15915
15916
15917
15918
15919
15920
15921
15922
15923
15924
15925
15926
15927
15928
15929
15930
15931
15932
15933
15934
15935
15936
15937
15938
15939
15940
15941
15942
15943
15944
15945
15946
15947
15948
15949
15950
15951
15952
15953
15954
15955
15956
15957
15958
15959
15960
15961
15962
15963
15964
15965
15966
15967
15968
15969
15970
15971
15972
15973
15974
15975
15976
15977
15978
15979
15980
15981
15982
15983
15984
15985
15986
15987
15988
15989
15990
15991
15992
15993
15994
15995
15996
15997
15998
15999
16000
16001
16002
16003
16004
16005
16006
16007
16008
16009
16010
16011
16012
16013
16014
16015
16016
16017
16018
16019
16020
16021
16022
16023
16024
16025
16026
16027
16028
16029
16030
16031
16032
16033
16034
16035
16036
16037
16038
16039
16040
16041
16042
16043
16044
16045
16046
16047
16048
16049
16050
16051
16052
16053
16054
16055
16056
16057
16058
16059
16060
16061
16062
16063
16064
16065
16066
16067
16068
16069
16070
16071
16072
16073
16074
16075
16076
16077
16078
16079
16080
16081
16082
16083
16084
16085
16086
16087
16088
16089
16090
16091
16092
16093
16094
16095
16096
16097
16098
16099
16100
16101
16102
16103
16104
16105
16106
16107
16108
16109
16110
16111
16112
16113
16114
16115
16116
16117
16118
16119
16120
16121
16122
16123
16124
16125
16126
16127
16128
16129
16130
16131
16132
16133
16134
16135
16136
16137
16138
16139
16140
16141
16142
16143
16144
16145
16146
16147
16148
16149
16150
16151
16152
16153
16154
16155
16156
16157
16158
16159
16160
16161
16162
16163
16164
16165
16166
16167
16168
16169
16170
16171
16172
16173
16174
16175
16176
16177
16178
16179
16180
16181
16182
16183
16184
16185
16186
16187
16188
16189
16190
16191
16192
16193
16194
16195
16196
16197
16198
16199
16200
16201
16202
16203
16204
16205
16206
16207
16208
16209
16210
16211
16212
16213
16214
16215
16216
16217
16218
16219
16220
16221
16222
16223
16224
16225
16226
16227
16228
16229
16230
16231
16232
16233
16234
16235
16236
16237
16238
16239
16240
16241
16242
16243
16244
16245
16246
16247
16248
16249
16250
16251
16252
16253
16254
16255
16256
16257
16258
16259
16260
16261
16262
16263
16264
16265
16266
16267
16268
16269
16270
16271
16272
16273
16274
16275
16276
16277
16278
16279
16280
16281
16282
16283
16284
16285
16286
16287
16288
16289
16290
16291
16292
16293
16294
16295
16296
16297
16298
16299
16300
16301
16302
16303
16304
16305
16306
16307
16308
16309
16310
16311
16312
16313
16314
16315
16316
16317
16318
16319
16320
16321
16322
16323
16324
16325
16326
16327
16328
16329
16330
16331
16332
16333
16334
16335
16336
16337
16338
16339
16340
16341
16342
16343
16344
16345
16346
16347
16348
16349
16350
16351
16352
16353
16354
16355
16356
16357
16358
16359
16360
16361
16362
16363
16364
16365
16366
16367
16368
16369
16370
16371
16372
16373
16374
16375
16376
16377
16378
16379
16380
16381
16382
16383
16384
16385
16386
16387
16388
16389
16390
16391
16392
16393
16394
16395
16396
16397
16398
16399
16400
16401
16402
16403
16404
16405
16406
16407
16408
16409
16410
16411
16412
16413
16414
16415
16416
16417
16418
16419
16420
16421
16422
16423
16424
16425
16426
16427
16428
16429
16430
16431
16432
16433
16434
16435
16436
16437
16438
16439
16440
16441
16442
16443
16444
16445
16446
16447
16448
16449
16450
16451
16452
16453
16454
16455
16456
16457
16458
16459
16460
16461
16462
16463
16464
16465
16466
16467
16468
16469
16470
16471
16472
16473
16474
16475
16476
16477
16478
16479
16480
16481
16482
16483
16484
16485
16486
16487
16488
16489
16490
16491
16492
16493
16494
16495
16496
16497
16498
16499
16500
16501
16502
16503
16504
16505
16506
16507
16508
16509
16510
16511
16512
16513
16514
16515
16516
16517
16518
16519
16520
16521
16522
16523
16524
16525
16526
16527
16528
16529
16530
16531
16532
16533
16534
16535
16536
16537
16538
16539
16540
16541
16542
16543
16544
16545
16546
16547
16548
16549
16550
16551
16552
16553
16554
16555
16556
16557
16558
16559
16560
16561
16562
16563
16564
16565
16566
16567
16568
16569
16570
16571
16572
16573
16574
16575
16576
16577
16578
16579
16580
16581
16582
16583
16584
16585
16586
16587
16588
16589
16590
16591
16592
16593
16594
16595
16596
16597
16598
16599
16600
16601
16602
16603
16604
16605
16606
16607
16608
16609
16610
16611
16612
16613
16614
16615
16616
16617
16618
16619
16620
16621
16622
16623
16624
16625
16626
16627
16628
16629
16630
16631
16632
16633
16634
16635
16636
16637
16638
16639
16640
16641
16642
16643
16644
16645
16646
16647
16648
16649
16650
16651
16652
16653
16654
16655
16656
16657
16658
16659
16660
16661
16662
16663
16664
16665
16666
16667
16668
16669
16670
16671
16672
16673
16674
16675
16676
16677
16678
16679
16680
16681
16682
16683
16684
16685
16686
16687
16688
16689
16690
16691
16692
16693
16694
16695
16696
16697
16698
16699
16700
16701
16702
16703
16704
16705
16706
16707
16708
16709
16710
16711
16712
16713
16714
16715
16716
16717
16718
16719
16720
16721
16722
16723
16724
16725
16726
16727
16728
16729
16730
16731
16732
16733
16734
16735
16736
16737
16738
16739
16740
16741
16742
16743
16744
16745
16746
16747
16748
16749
16750
16751
16752
16753
16754
16755
16756
16757
16758
16759
16760
16761
16762
16763
16764
16765
16766
16767
16768
16769
16770
16771
16772
16773
16774
16775
16776
16777
16778
16779
16780
16781
16782
16783
16784
16785
16786
16787
16788
16789
16790
16791
16792
16793
16794
16795
16796
16797
16798
16799
16800
16801
16802
16803
16804
16805
16806
16807
16808
16809
16810
16811
16812
16813
16814
16815
16816
16817
16818
16819
16820
16821
16822
16823
16824
16825
16826
16827
16828
16829
16830
16831
16832
16833
16834
16835
16836
16837
16838
16839
16840
16841
16842
16843
16844
16845
16846
16847
16848
16849
16850
16851
16852
16853
16854
16855
16856
16857
16858
16859
16860
16861
16862
16863
16864
16865
16866
16867
16868
16869
16870
16871
16872
16873
16874
16875
16876
16877
16878
16879
16880
16881
16882
16883
16884
16885
16886
16887
16888
16889
16890
16891
16892
16893
16894
16895
16896
16897
16898
16899
16900
16901
16902
16903
16904
16905
16906
16907
16908
16909
16910
16911
16912
16913
16914
16915
16916
16917
16918
16919
16920
16921
16922
16923
16924
16925
16926
16927
16928
16929
16930
16931
16932
16933
16934
16935
16936
16937
16938
16939
16940
16941
16942
16943
16944
16945
16946
16947
16948
16949
16950
16951
16952
16953
16954
16955
16956
16957
16958
16959
16960
16961
16962
16963
16964
16965
16966
16967
16968
16969
16970
16971
16972
16973
16974
16975
16976
16977
16978
16979
16980
16981
16982
16983
16984
16985
16986
16987
16988
16989
16990
16991
16992
16993
16994
16995
16996
16997
16998
16999
17000
17001
17002
17003
17004
17005
17006
17007
17008
17009
17010
17011
17012
17013
17014
17015
17016
17017
17018
17019
17020
17021
17022
17023
17024
17025
17026
17027
17028
17029
17030
17031
17032
17033
17034
17035
17036
17037
17038
17039
17040
17041
17042
17043
17044
17045
17046
17047
17048
17049
17050
17051
17052
17053
17054
17055
17056
17057
17058
17059
17060
17061
17062
17063
17064
17065
17066
17067
17068
17069
17070
17071
17072
17073
17074
17075
17076
17077
17078
17079
17080
17081
17082
17083
17084
17085
17086
17087
17088
17089
17090
17091
17092
17093
17094
17095
17096
17097
17098
17099
17100
17101
17102
17103
17104
17105
17106
17107
17108
17109
17110
17111
17112
17113
17114
17115
17116
17117
17118
17119
17120
17121
17122
17123
17124
17125
17126
17127
17128
17129
17130
17131
17132
17133
17134
17135
17136
17137
17138
17139
17140
17141
17142
17143
17144
17145
17146
17147
17148
17149
17150
17151
17152
17153
17154
17155
17156
17157
17158
17159
17160
17161
17162
17163
17164
17165
17166
17167
17168
17169
17170
17171
17172
17173
17174
17175
17176
17177
17178
17179
17180
17181
17182
17183
17184
17185
17186
17187
17188
17189
17190
17191
17192
17193
17194
17195
17196
17197
17198
17199
17200
17201
17202
17203
17204
17205
17206
17207
17208
17209
17210
17211
17212
17213
17214
17215
17216
17217
17218
17219
17220
17221
17222
17223
17224
17225
17226
17227
17228
17229
17230
17231
17232
17233
17234
17235
17236
17237
17238
17239
17240
17241
17242
17243
17244
17245
17246
17247
17248
17249
17250
17251
17252
17253
17254
17255
17256
17257
17258
17259
17260
17261
17262
17263
17264
17265
17266
17267
17268
17269
17270
17271
17272
17273
17274
17275
17276
17277
17278
17279
17280
17281
17282
17283
17284
17285
17286
17287
17288
17289
17290
17291
17292
17293
17294
17295
17296
17297
17298
17299
17300
17301
17302
17303
17304
17305
17306
17307
17308
17309
17310
17311
17312
17313
17314
17315
17316
17317
17318
17319
17320
17321
17322
17323
17324
17325
17326
17327
17328
17329
17330
17331
17332
17333
17334
17335
17336
17337
17338
17339
17340
17341
17342
17343
17344
17345
17346
17347
17348
17349
17350
17351
17352
17353
17354
17355
17356
17357
17358
17359
17360
17361
17362
17363
17364
17365
17366
17367
17368
17369
17370
17371
17372
17373
17374
17375
17376
17377
17378
17379
17380
17381
17382
17383
17384
17385
17386
17387
17388
17389
17390
17391
17392
17393
17394
17395
17396
17397
17398
17399
17400
17401
17402
17403
17404
17405
17406
17407
17408
17409
17410
17411
17412
17413
17414
17415
17416
17417
17418
17419
17420
17421
17422
17423
17424
17425
17426
17427
17428
17429
17430
17431
17432
17433
17434
17435
17436
17437
17438
17439
17440
17441
17442
17443
17444
17445
17446
17447
17448
17449
17450
17451
17452
17453
17454
17455
17456
17457
17458
17459
17460
17461
17462
17463
17464
17465
17466
17467
17468
17469
17470
17471
17472
17473
17474
17475
17476
17477
17478
17479
17480
17481
17482
17483
17484
17485
17486
17487
17488
17489
17490
17491
17492
17493
17494
17495
17496
17497
17498
17499
17500
17501
17502
17503
17504
17505
17506
17507
17508
17509
17510
17511
17512
17513
17514
17515
17516
17517
17518
17519
17520
17521
17522
17523
17524
17525
17526
17527
17528
17529
17530
17531
17532
17533
17534
17535
17536
17537
17538
17539
17540
17541
17542
17543
17544
17545
17546
17547
17548
17549
17550
17551
17552
17553
17554
17555
17556
17557
17558
17559
17560
17561
17562
17563
17564
17565
17566
17567
17568
17569
17570
17571
17572
17573
17574
17575
17576
17577
17578
17579
17580
17581
17582
17583
17584
17585
17586
17587
17588
17589
17590
17591
17592
17593
17594
17595
17596
17597
17598
17599
17600
17601
17602
17603
17604
17605
17606
17607
17608
17609
17610
17611
17612
17613
17614
17615
17616
17617
17618
17619
17620
17621
17622
17623
17624
17625
17626
17627
17628
17629
17630
17631
17632
17633
17634
17635
17636
17637
17638
17639
17640
17641
17642
17643
17644
17645
17646
17647
17648
17649
17650
17651
17652
17653
17654
17655
17656
17657
17658
17659
17660
17661
17662
17663
17664
17665
17666
17667
17668
17669
17670
17671
17672
17673
17674
17675
17676
17677
17678
17679
17680
17681
17682
17683
17684
17685
17686
17687
17688
17689
17690
17691
17692
17693
17694
17695
17696
17697
17698
17699
17700
17701
17702
17703
17704
17705
17706
17707
17708
17709
17710
17711
17712
17713
17714
17715
17716
17717
17718
17719
17720
17721
17722
17723
17724
17725
17726
17727
17728
17729
17730
17731
17732
17733
17734
17735
17736
17737
17738
17739
17740
17741
17742
17743
17744
17745
17746
17747
17748
17749
17750
17751
17752
17753
17754
17755
17756
17757
17758
17759
17760
17761
17762
17763
17764
17765
17766
17767
17768
17769
17770
17771
17772
17773
17774
17775
17776
17777
17778
17779
17780
17781
17782
17783
17784
17785
17786
17787
17788
17789
17790
17791
17792
17793
17794
17795
17796
17797
17798
17799
17800
17801
17802
17803
17804
17805
17806
17807
17808
17809
17810
17811
17812
17813
17814
17815
17816
17817
17818
17819
17820
17821
17822
17823
17824
17825
17826
17827
17828
17829
17830
17831
17832
17833
17834
17835
17836
17837
17838
17839
17840
17841
17842
17843
17844
17845
17846
17847
17848
17849
17850
17851
17852
17853
17854
17855
17856
17857
17858
17859
17860
17861
17862
17863
17864
17865
17866
17867
17868
17869
17870
17871
17872
17873
17874
17875
17876
17877
17878
17879
17880
17881
17882
17883
17884
17885
17886
17887
17888
17889
17890
17891
17892
17893
17894
17895
17896
17897
17898
17899
17900
17901
17902
17903
17904
17905
17906
17907
17908
17909
17910
17911
17912
17913
17914
17915
17916
17917
17918
17919
17920
17921
17922
17923
17924
17925
17926
17927
17928
17929
17930
17931
17932
17933
17934
17935
17936
17937
17938
17939
17940
17941
17942
17943
17944
17945
17946
17947
17948
17949
17950
17951
17952
17953
17954
17955
17956
17957
17958
17959
17960
17961
17962
17963
17964
17965
17966
17967
17968
17969
17970
17971
17972
17973
17974
17975
17976
17977
17978
17979
17980
17981
17982
17983
17984
17985
17986
17987
17988
17989
17990
17991
17992
17993
17994
17995
17996
17997
17998
17999
18000
18001
18002
18003
18004
18005
18006
18007
18008
18009
18010
18011
18012
18013
18014
18015
18016
18017
18018
18019
18020
18021
18022
18023
18024
18025
18026
18027
18028
18029
18030
18031
18032
18033
18034
18035
18036
18037
18038
18039
18040
18041
18042
18043
18044
18045
18046
18047
18048
18049
18050
18051
18052
18053
18054
18055
18056
18057
18058
18059
18060
18061
18062
18063
18064
18065
18066
18067
18068
18069
18070
18071
18072
18073
18074
18075
18076
18077
18078
18079
18080
18081
18082
18083
18084
18085
18086
18087
18088
18089
18090
18091
18092
18093
18094
18095
18096
18097
18098
18099
18100
18101
18102
18103
18104
18105
18106
18107
18108
18109
18110
18111
18112
18113
18114
18115
18116
18117
18118
18119
18120
18121
18122
18123
18124
18125
18126
18127
18128
18129
18130
18131
18132
18133
18134
18135
18136
18137
18138
18139
18140
18141
18142
18143
18144
18145
18146
18147
18148
18149
18150
18151
18152
18153
18154
18155
18156
18157
18158
18159
18160
18161
18162
18163
18164
18165
18166
18167
18168
18169
18170
18171
18172
18173
18174
18175
18176
18177
18178
18179
18180
18181
18182
18183
18184
18185
18186
18187
18188
18189
18190
18191
18192
18193
18194
18195
18196
18197
18198
18199
18200
18201
18202
18203
18204
18205
18206
18207
18208
18209
18210
18211
18212
18213
18214
18215
18216
18217
18218
18219
18220
18221
18222
18223
18224
18225
18226
18227
18228
18229
18230
18231
18232
18233
18234
18235
18236
18237
18238
18239
18240
18241
18242
18243
18244
18245
18246
18247
18248
18249
18250
18251
18252
18253
18254
18255
18256
18257
18258
18259
18260
18261
18262
18263
18264
18265
18266
18267
18268
18269
18270
18271
18272
18273
18274
18275
18276
18277
18278
18279
18280
18281
18282
18283
18284
18285
18286
18287
18288
18289
18290
18291
18292
18293
18294
18295
18296
18297
18298
18299
18300
18301
18302
18303
18304
18305
18306
18307
18308
18309
18310
18311
18312
18313
18314
18315
18316
18317
18318
18319
18320
18321
18322
18323
18324
18325
18326
18327
18328
18329
18330
18331
18332
18333
18334
18335
18336
18337
18338
18339
18340
18341
18342
18343
18344
18345
18346
18347
18348
18349
18350
18351
18352
18353
18354
18355
18356
18357
18358
18359
18360
18361
18362
18363
18364
18365
18366
18367
18368
18369
18370
18371
18372
18373
18374
18375
18376
18377
18378
18379
18380
18381
18382
18383
18384
18385
18386
18387
18388
18389
18390
18391
18392
18393
18394
18395
18396
18397
18398
18399
18400
18401
18402
18403
18404
18405
18406
18407
18408
18409
18410
18411
18412
18413
18414
18415
18416
18417
18418
18419
18420
18421
18422
18423
18424
18425
18426
18427
18428
18429
18430
18431
18432
18433
18434
18435
18436
18437
18438
18439
18440
18441
18442
18443
18444
18445
18446
18447
18448
18449
18450
18451
18452
18453
18454
18455
18456
18457
18458
18459
18460
18461
18462
18463
18464
18465
18466
18467
18468
18469
18470
18471
18472
18473
18474
18475
18476
18477
18478
18479
18480
18481
18482
18483
18484
18485
18486
18487
18488
18489
18490
18491
18492
18493
18494
18495
18496
18497
18498
18499
18500
18501
18502
18503
18504
18505
18506
18507
18508
18509
18510
18511
18512
18513
18514
18515
18516
18517
18518
18519
18520
18521
18522
18523
18524
18525
18526
18527
18528
18529
18530
18531
18532
18533
18534
18535
18536
18537
18538
18539
18540
18541
18542
18543
18544
18545
18546
18547
18548
18549
18550
18551
18552
18553
18554
18555
18556
18557
18558
18559
18560
18561
18562
18563
18564
18565
18566
18567
18568
18569
18570
18571
18572
18573
18574
18575
18576
18577
18578
18579
18580
18581
18582
18583
18584
18585
18586
18587
18588
18589
18590
18591
18592
18593
18594
18595
18596
18597
18598
18599
18600
18601
18602
18603
18604
18605
18606
18607
18608
18609
18610
18611
18612
18613
18614
18615
18616
18617
18618
18619
18620
18621
18622
18623
18624
18625
18626
18627
18628
18629
18630
18631
18632
18633
18634
18635
18636
18637
18638
18639
18640
18641
18642
18643
18644
18645
18646
18647
18648
18649
18650
18651
18652
18653
18654
18655
18656
18657
18658
18659
18660
18661
18662
18663
18664
18665
18666
18667
18668
18669
18670
	lappend res $i [clock format [expr {653133196800 + $i}] \
	    -format {%Y-%m-%d %T -- %J %EJ %Ej} -gmt true]
    }
    set res
} [list \
    -86400 {22666-12-19 00:00:00 -- 9999999 9999999.0 9999998.5} \
    -43200 {22666-12-19 12:00:00 -- 9999999 9999999.5 9999999.0} \
	-1 {22666-12-19 23:59:59 -- 9999999 9999999.99998843 9999999.49998843} \
	 0 {22666-12-20 00:00:00 -- 10000000 10000000.0 9999999.5} \
	 1 {22666-12-20 00:00:01 -- 10000000 10000000.00001157 9999999.50001157} \
     43199 {22666-12-20 11:59:59 -- 10000000 10000000.49998843 9999999.99998843} \
     43200 {22666-12-20 12:00:00 -- 10000000 10000000.5 10000000.0} \
     43201 {22666-12-20 12:00:01 -- 10000000 10000000.50001157 10000000.00001157} \
     86400 {22666-12-21 00:00:00 -- 10000001 10000001.0 10000000.5} \
]

# END testcases4

# BEGIN testcases5

# Test formatting of Daylight Saving Time

test clock-5.1 {does Detroit exist} {
    clock format 0 -format {} -timezone :America/Detroit
    concat
} {}
test clock-5.2 {does Detroit have a Y2038 problem} detroit {
    if { [clock format 2158894800 -format %z -timezone :America/Detroit] ne {-0400} } {
	concat {y2038 problem}
    } else {
	concat {ok}
    }
} ok
test clock-5.3 {time zone boundary case 1904-12-31 23:59:59} detroit {
    clock format -2051202470 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {23:59:59 -053211 LMT}
test clock-5.4 {time zone boundary case 1904-12-31 23:32:11} detroit {
    clock format -2051202469 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {23:32:11 -0600 CST}
test clock-5.5 {time zone boundary case 1904-12-31 23:32:12} detroit {
    clock format -2051202468 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {23:32:12 -0600 CST}
test clock-5.6 {time zone boundary case 1915-05-15 01:59:59} detroit {
    clock format -1724083201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0600 CST}
test clock-5.7 {time zone boundary case 1915-05-15 03:00:00} detroit {
    clock format -1724083200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0500 EST}
test clock-5.8 {time zone boundary case 1915-05-15 03:00:01} detroit {
    clock format -1724083199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0500 EST}
test clock-5.9 {time zone boundary case 1941-12-31 23:59:59} detroit {
    clock format -883594801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {23:59:59 -0500 EST}
test clock-5.10 {time zone boundary case 1942-01-01 00:00:00} detroit {
    clock format -883594800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {00:00:00 -0500 EST}
test clock-5.11 {time zone boundary case 1942-01-01 00:00:01} detroit {
    clock format -883594799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {00:00:01 -0500 EST}
test clock-5.12 {time zone boundary case 1942-02-09 01:59:59} detroit {
    clock format -880218001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.13 {time zone boundary case 1942-02-09 03:00:00} detroit {
    clock format -880218000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EWT}
test clock-5.14 {time zone boundary case 1942-02-09 03:00:01} detroit {
    clock format -880217999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EWT}
test clock-5.15 {time zone boundary case 1945-08-14 18:59:59} detroit {
    clock format -769395601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {18:59:59 -0400 EWT}
test clock-5.16 {time zone boundary case 1945-08-14 19:00:00} detroit {
    clock format -769395600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {19:00:00 -0400 EPT}
test clock-5.17 {time zone boundary case 1945-08-14 19:00:01} detroit {
    clock format -769395599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {19:00:01 -0400 EPT}
test clock-5.18 {time zone boundary case 1945-09-30 01:59:59} detroit {
    clock format -765396001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EPT}
test clock-5.19 {time zone boundary case 1945-09-30 01:00:00} detroit {
    clock format -765396000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.20 {time zone boundary case 1945-09-30 01:00:01} detroit {
    clock format -765395999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.21 {time zone boundary case 1945-12-31 23:59:59} detroit {
    clock format -757364401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {23:59:59 -0500 EST}
test clock-5.22 {time zone boundary case 1946-01-01 00:00:00} detroit {
    clock format -757364400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {00:00:00 -0500 EST}
test clock-5.23 {time zone boundary case 1946-01-01 00:00:01} detroit {
    clock format -757364399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {00:00:01 -0500 EST}
test clock-5.24 {time zone boundary case 1948-04-25 01:59:59} detroit {
    clock format -684349201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.25 {time zone boundary case 1948-04-25 03:00:00} detroit {
    clock format -684349200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.26 {time zone boundary case 1948-04-25 03:00:01} detroit {
    clock format -684349199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.27 {time zone boundary case 1948-09-26 01:59:59} detroit {
    clock format -671047201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.28 {time zone boundary case 1948-09-26 01:00:00} detroit {
    clock format -671047200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.29 {time zone boundary case 1948-09-26 01:00:01} detroit {
    clock format -671047199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}

# Detroit did not observe Daylight Saving Time in 1967

test clock-5.36 {time zone boundary case 1972-12-31 23:59:59} detroit {
    clock format 94712399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {23:59:59 -0500 EST}
test clock-5.37 {time zone boundary case 1973-01-01 00:00:00} detroit {
    clock format 94712400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {00:00:00 -0500 EST}
test clock-5.38 {time zone boundary case 1973-01-01 00:00:01} detroit {
    clock format 94712401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {00:00:01 -0500 EST}
test clock-5.39 {time zone boundary case 1973-04-29 01:59:59} detroit {
    clock format 104914799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.40 {time zone boundary case 1973-04-29 03:00:00} detroit {
    clock format 104914800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.41 {time zone boundary case 1973-04-29 03:00:01} detroit {
    clock format 104914801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.42 {time zone boundary case 1973-10-28 01:59:59} detroit {
    clock format 120635999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.43 {time zone boundary case 1973-10-28 01:00:00} detroit {
    clock format 120636000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.44 {time zone boundary case 1973-10-28 01:00:01} detroit {
    clock format 120636001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.45 {time zone boundary case 1974-01-06 01:59:59} detroit {
    clock format 126687599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.46 {time zone boundary case 1974-01-06 03:00:00} detroit {
    clock format 126687600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.47 {time zone boundary case 1974-01-06 03:00:01} detroit {
    clock format 126687601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.48 {time zone boundary case 1974-10-27 01:59:59} detroit {
    clock format 152085599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.49 {time zone boundary case 1974-10-27 01:00:00} detroit {
    clock format 152085600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.50 {time zone boundary case 1974-10-27 01:00:01} detroit {
    clock format 152085601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.51 {time zone boundary case 1974-12-31 23:59:59} detroit {
    clock format 157784399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {23:59:59 -0500 EST}
test clock-5.52 {time zone boundary case 1975-01-01 00:00:00} detroit {
    clock format 157784400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {00:00:00 -0500 EST}
test clock-5.53 {time zone boundary case 1975-01-01 00:00:01} detroit {
    clock format 157784401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {00:00:01 -0500 EST}
test clock-5.54 {time zone boundary case 1975-04-27 01:59:59} detroit {
    clock format 167813999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.55 {time zone boundary case 1975-04-27 03:00:00} detroit {
    clock format 167814000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.56 {time zone boundary case 1975-04-27 03:00:01} detroit {
    clock format 167814001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.57 {time zone boundary case 1975-10-26 01:59:59} detroit {
    clock format 183535199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.58 {time zone boundary case 1975-10-26 01:00:00} detroit {
    clock format 183535200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.59 {time zone boundary case 1975-10-26 01:00:01} detroit {
    clock format 183535201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.60 {time zone boundary case 1976-04-25 01:59:59} detroit {
    clock format 199263599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.61 {time zone boundary case 1976-04-25 03:00:00} detroit {
    clock format 199263600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.62 {time zone boundary case 1976-04-25 03:00:01} detroit {
    clock format 199263601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.63 {time zone boundary case 1976-10-31 01:59:59} detroit {
    clock format 215589599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.64 {time zone boundary case 1976-10-31 01:00:00} detroit {
    clock format 215589600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.65 {time zone boundary case 1976-10-31 01:00:01} detroit {
    clock format 215589601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.66 {time zone boundary case 1977-04-24 01:59:59} detroit {
    clock format 230713199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.67 {time zone boundary case 1977-04-24 03:00:00} detroit {
    clock format 230713200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.68 {time zone boundary case 1977-04-24 03:00:01} detroit {
    clock format 230713201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.69 {time zone boundary case 1977-10-30 01:59:59} detroit {
    clock format 247039199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.70 {time zone boundary case 1977-10-30 01:00:00} detroit {
    clock format 247039200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.71 {time zone boundary case 1977-10-30 01:00:01} detroit {
    clock format 247039201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.72 {time zone boundary case 1978-04-30 01:59:59} detroit {
    clock format 262767599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.73 {time zone boundary case 1978-04-30 03:00:00} detroit {
    clock format 262767600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.74 {time zone boundary case 1978-04-30 03:00:01} detroit {
    clock format 262767601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.75 {time zone boundary case 1978-10-29 01:59:59} detroit {
    clock format 278488799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.76 {time zone boundary case 1978-10-29 01:00:00} detroit {
    clock format 278488800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.77 {time zone boundary case 1978-10-29 01:00:01} detroit {
    clock format 278488801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.78 {time zone boundary case 1979-04-29 01:59:59} detroit {
    clock format 294217199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.79 {time zone boundary case 1979-04-29 03:00:00} detroit {
    clock format 294217200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.80 {time zone boundary case 1979-04-29 03:00:01} detroit {
    clock format 294217201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.81 {time zone boundary case 1979-10-28 01:59:59} detroit {
    clock format 309938399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.82 {time zone boundary case 1979-10-28 01:00:00} detroit {
    clock format 309938400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.83 {time zone boundary case 1979-10-28 01:00:01} detroit {
    clock format 309938401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.84 {time zone boundary case 1980-04-27 01:59:59} detroit {
    clock format 325666799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.85 {time zone boundary case 1980-04-27 03:00:00} detroit {
    clock format 325666800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.86 {time zone boundary case 1980-04-27 03:00:01} detroit {
    clock format 325666801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.87 {time zone boundary case 1980-10-26 01:59:59} detroit {
    clock format 341387999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.88 {time zone boundary case 1980-10-26 01:00:00} detroit {
    clock format 341388000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.89 {time zone boundary case 1980-10-26 01:00:01} detroit {
    clock format 341388001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.90 {time zone boundary case 1981-04-26 01:59:59} detroit {
    clock format 357116399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.91 {time zone boundary case 1981-04-26 03:00:00} detroit {
    clock format 357116400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.92 {time zone boundary case 1981-04-26 03:00:01} detroit {
    clock format 357116401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.93 {time zone boundary case 1981-10-25 01:59:59} detroit {
    clock format 372837599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.94 {time zone boundary case 1981-10-25 01:00:00} detroit {
    clock format 372837600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.95 {time zone boundary case 1981-10-25 01:00:01} detroit {
    clock format 372837601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.96 {time zone boundary case 1982-04-25 01:59:59} detroit {
    clock format 388565999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.97 {time zone boundary case 1982-04-25 03:00:00} detroit {
    clock format 388566000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.98 {time zone boundary case 1982-04-25 03:00:01} detroit {
    clock format 388566001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.99 {time zone boundary case 1982-10-31 01:59:59} detroit {
    clock format 404891999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.100 {time zone boundary case 1982-10-31 01:00:00} detroit {
    clock format 404892000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.101 {time zone boundary case 1982-10-31 01:00:01} detroit {
    clock format 404892001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.102 {time zone boundary case 1983-04-24 01:59:59} detroit {
    clock format 420015599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.103 {time zone boundary case 1983-04-24 03:00:00} detroit {
    clock format 420015600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.104 {time zone boundary case 1983-04-24 03:00:01} detroit {
    clock format 420015601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.105 {time zone boundary case 1983-10-30 01:59:59} detroit {
    clock format 436341599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.106 {time zone boundary case 1983-10-30 01:00:00} detroit {
    clock format 436341600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.107 {time zone boundary case 1983-10-30 01:00:01} detroit {
    clock format 436341601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.108 {time zone boundary case 1984-04-29 01:59:59} detroit {
    clock format 452069999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.109 {time zone boundary case 1984-04-29 03:00:00} detroit {
    clock format 452070000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.110 {time zone boundary case 1984-04-29 03:00:01} detroit {
    clock format 452070001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.111 {time zone boundary case 1984-10-28 01:59:59} detroit {
    clock format 467791199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.112 {time zone boundary case 1984-10-28 01:00:00} detroit {
    clock format 467791200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.113 {time zone boundary case 1984-10-28 01:00:01} detroit {
    clock format 467791201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.114 {time zone boundary case 1985-04-28 01:59:59} detroit {
    clock format 483519599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.115 {time zone boundary case 1985-04-28 03:00:00} detroit {
    clock format 483519600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.116 {time zone boundary case 1985-04-28 03:00:01} detroit {
    clock format 483519601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.117 {time zone boundary case 1985-10-27 01:59:59} detroit {
    clock format 499240799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.118 {time zone boundary case 1985-10-27 01:00:00} detroit {
    clock format 499240800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.119 {time zone boundary case 1985-10-27 01:00:01} detroit {
    clock format 499240801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.120 {time zone boundary case 1986-04-27 01:59:59} detroit {
    clock format 514969199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.121 {time zone boundary case 1986-04-27 03:00:00} detroit {
    clock format 514969200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.122 {time zone boundary case 1986-04-27 03:00:01} detroit {
    clock format 514969201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.123 {time zone boundary case 1986-10-26 01:59:59} detroit {
    clock format 530690399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.124 {time zone boundary case 1986-10-26 01:00:00} detroit {
    clock format 530690400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.125 {time zone boundary case 1986-10-26 01:00:01} detroit {
    clock format 530690401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.126 {time zone boundary case 1987-04-05 01:59:59} detroit {
    clock format 544604399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.127 {time zone boundary case 1987-04-05 03:00:00} detroit {
    clock format 544604400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.128 {time zone boundary case 1987-04-05 03:00:01} detroit {
    clock format 544604401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.129 {time zone boundary case 1987-10-25 01:59:59} detroit {
    clock format 562139999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.130 {time zone boundary case 1987-10-25 01:00:00} detroit {
    clock format 562140000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.131 {time zone boundary case 1987-10-25 01:00:01} detroit {
    clock format 562140001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.132 {time zone boundary case 1988-04-03 01:59:59} detroit {
    clock format 576053999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.133 {time zone boundary case 1988-04-03 03:00:00} detroit {
    clock format 576054000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.134 {time zone boundary case 1988-04-03 03:00:01} detroit {
    clock format 576054001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.135 {time zone boundary case 1988-10-30 01:59:59} detroit {
    clock format 594194399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.136 {time zone boundary case 1988-10-30 01:00:00} detroit {
    clock format 594194400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.137 {time zone boundary case 1988-10-30 01:00:01} detroit {
    clock format 594194401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.138 {time zone boundary case 1989-04-02 01:59:59} detroit {
    clock format 607503599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.139 {time zone boundary case 1989-04-02 03:00:00} detroit {
    clock format 607503600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.140 {time zone boundary case 1989-04-02 03:00:01} detroit {
    clock format 607503601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.141 {time zone boundary case 1989-10-29 01:59:59} detroit {
    clock format 625643999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.142 {time zone boundary case 1989-10-29 01:00:00} detroit {
    clock format 625644000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.143 {time zone boundary case 1989-10-29 01:00:01} detroit {
    clock format 625644001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.144 {time zone boundary case 1990-04-01 01:59:59} detroit {
    clock format 638953199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.145 {time zone boundary case 1990-04-01 03:00:00} detroit {
    clock format 638953200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.146 {time zone boundary case 1990-04-01 03:00:01} detroit {
    clock format 638953201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.147 {time zone boundary case 1990-10-28 01:59:59} detroit {
    clock format 657093599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.148 {time zone boundary case 1990-10-28 01:00:00} detroit {
    clock format 657093600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.149 {time zone boundary case 1990-10-28 01:00:01} detroit {
    clock format 657093601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.150 {time zone boundary case 1991-04-07 01:59:59} detroit {
    clock format 671007599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.151 {time zone boundary case 1991-04-07 03:00:00} detroit {
    clock format 671007600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.152 {time zone boundary case 1991-04-07 03:00:01} detroit {
    clock format 671007601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.153 {time zone boundary case 1991-10-27 01:59:59} detroit {
    clock format 688543199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.154 {time zone boundary case 1991-10-27 01:00:00} detroit {
    clock format 688543200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.155 {time zone boundary case 1991-10-27 01:00:01} detroit {
    clock format 688543201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.156 {time zone boundary case 1992-04-05 01:59:59} detroit {
    clock format 702457199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.157 {time zone boundary case 1992-04-05 03:00:00} detroit {
    clock format 702457200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.158 {time zone boundary case 1992-04-05 03:00:01} detroit {
    clock format 702457201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.159 {time zone boundary case 1992-10-25 01:59:59} detroit {
    clock format 719992799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.160 {time zone boundary case 1992-10-25 01:00:00} detroit {
    clock format 719992800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.161 {time zone boundary case 1992-10-25 01:00:01} detroit {
    clock format 719992801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.162 {time zone boundary case 1993-04-04 01:59:59} detroit {
    clock format 733906799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.163 {time zone boundary case 1993-04-04 03:00:00} detroit {
    clock format 733906800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.164 {time zone boundary case 1993-04-04 03:00:01} detroit {
    clock format 733906801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.165 {time zone boundary case 1993-10-31 01:59:59} detroit {
    clock format 752047199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.166 {time zone boundary case 1993-10-31 01:00:00} detroit {
    clock format 752047200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.167 {time zone boundary case 1993-10-31 01:00:01} detroit {
    clock format 752047201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.168 {time zone boundary case 1994-04-03 01:59:59} detroit {
    clock format 765356399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.169 {time zone boundary case 1994-04-03 03:00:00} detroit {
    clock format 765356400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.170 {time zone boundary case 1994-04-03 03:00:01} detroit {
    clock format 765356401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.171 {time zone boundary case 1994-10-30 01:59:59} detroit {
    clock format 783496799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.172 {time zone boundary case 1994-10-30 01:00:00} detroit {
    clock format 783496800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.173 {time zone boundary case 1994-10-30 01:00:01} detroit {
    clock format 783496801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.174 {time zone boundary case 1995-04-02 01:59:59} detroit {
    clock format 796805999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.175 {time zone boundary case 1995-04-02 03:00:00} detroit {
    clock format 796806000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.176 {time zone boundary case 1995-04-02 03:00:01} detroit {
    clock format 796806001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.177 {time zone boundary case 1995-10-29 01:59:59} detroit {
    clock format 814946399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.178 {time zone boundary case 1995-10-29 01:00:00} detroit {
    clock format 814946400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.179 {time zone boundary case 1995-10-29 01:00:01} detroit {
    clock format 814946401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.180 {time zone boundary case 1996-04-07 01:59:59} detroit {
    clock format 828860399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.181 {time zone boundary case 1996-04-07 03:00:00} detroit {
    clock format 828860400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.182 {time zone boundary case 1996-04-07 03:00:01} detroit {
    clock format 828860401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.183 {time zone boundary case 1996-10-27 01:59:59} detroit {
    clock format 846395999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.184 {time zone boundary case 1996-10-27 01:00:00} detroit {
    clock format 846396000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.185 {time zone boundary case 1996-10-27 01:00:01} detroit {
    clock format 846396001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.186 {time zone boundary case 1997-04-06 01:59:59} detroit {
    clock format 860309999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.187 {time zone boundary case 1997-04-06 03:00:00} detroit {
    clock format 860310000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.188 {time zone boundary case 1997-04-06 03:00:01} detroit {
    clock format 860310001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.189 {time zone boundary case 1997-10-26 01:59:59} detroit {
    clock format 877845599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.190 {time zone boundary case 1997-10-26 01:00:00} detroit {
    clock format 877845600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.191 {time zone boundary case 1997-10-26 01:00:01} detroit {
    clock format 877845601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.192 {time zone boundary case 1998-04-05 01:59:59} detroit {
    clock format 891759599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.193 {time zone boundary case 1998-04-05 03:00:00} detroit {
    clock format 891759600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.194 {time zone boundary case 1998-04-05 03:00:01} detroit {
    clock format 891759601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.195 {time zone boundary case 1998-10-25 01:59:59} detroit {
    clock format 909295199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.196 {time zone boundary case 1998-10-25 01:00:00} detroit {
    clock format 909295200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.197 {time zone boundary case 1998-10-25 01:00:01} detroit {
    clock format 909295201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.198 {time zone boundary case 1999-04-04 01:59:59} detroit {
    clock format 923209199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.199 {time zone boundary case 1999-04-04 03:00:00} detroit {
    clock format 923209200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.200 {time zone boundary case 1999-04-04 03:00:01} detroit {
    clock format 923209201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.201 {time zone boundary case 1999-10-31 01:59:59} detroit {
    clock format 941349599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.202 {time zone boundary case 1999-10-31 01:00:00} detroit {
    clock format 941349600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.203 {time zone boundary case 1999-10-31 01:00:01} detroit {
    clock format 941349601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.204 {time zone boundary case 2000-04-02 01:59:59} detroit {
    clock format 954658799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.205 {time zone boundary case 2000-04-02 03:00:00} detroit {
    clock format 954658800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.206 {time zone boundary case 2000-04-02 03:00:01} detroit {
    clock format 954658801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.207 {time zone boundary case 2000-10-29 01:59:59} detroit {
    clock format 972799199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.208 {time zone boundary case 2000-10-29 01:00:00} detroit {
    clock format 972799200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.209 {time zone boundary case 2000-10-29 01:00:01} detroit {
    clock format 972799201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.210 {time zone boundary case 2001-04-01 01:59:59} detroit {
    clock format 986108399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.211 {time zone boundary case 2001-04-01 03:00:00} detroit {
    clock format 986108400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.212 {time zone boundary case 2001-04-01 03:00:01} detroit {
    clock format 986108401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.213 {time zone boundary case 2001-10-28 01:59:59} detroit {
    clock format 1004248799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.214 {time zone boundary case 2001-10-28 01:00:00} detroit {
    clock format 1004248800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.215 {time zone boundary case 2001-10-28 01:00:01} detroit {
    clock format 1004248801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.216 {time zone boundary case 2002-04-07 01:59:59} detroit {
    clock format 1018162799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.217 {time zone boundary case 2002-04-07 03:00:00} detroit {
    clock format 1018162800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.218 {time zone boundary case 2002-04-07 03:00:01} detroit {
    clock format 1018162801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.219 {time zone boundary case 2002-10-27 01:59:59} detroit {
    clock format 1035698399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.220 {time zone boundary case 2002-10-27 01:00:00} detroit {
    clock format 1035698400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.221 {time zone boundary case 2002-10-27 01:00:01} detroit {
    clock format 1035698401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.222 {time zone boundary case 2003-04-06 01:59:59} detroit {
    clock format 1049612399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.223 {time zone boundary case 2003-04-06 03:00:00} detroit {
    clock format 1049612400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.224 {time zone boundary case 2003-04-06 03:00:01} detroit {
    clock format 1049612401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.225 {time zone boundary case 2003-10-26 01:59:59} detroit {
    clock format 1067147999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.226 {time zone boundary case 2003-10-26 01:00:00} detroit {
    clock format 1067148000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.227 {time zone boundary case 2003-10-26 01:00:01} detroit {
    clock format 1067148001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.228 {time zone boundary case 2004-04-04 01:59:59} detroit {
    clock format 1081061999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.229 {time zone boundary case 2004-04-04 03:00:00} detroit {
    clock format 1081062000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.230 {time zone boundary case 2004-04-04 03:00:01} detroit {
    clock format 1081062001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.231 {time zone boundary case 2004-10-31 01:59:59} detroit {
    clock format 1099202399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.232 {time zone boundary case 2004-10-31 01:00:00} detroit {
    clock format 1099202400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.233 {time zone boundary case 2004-10-31 01:00:01} detroit {
    clock format 1099202401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.234 {time zone boundary case 2005-04-03 01:59:59} detroit {
    clock format 1112511599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.235 {time zone boundary case 2005-04-03 03:00:00} detroit {
    clock format 1112511600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.236 {time zone boundary case 2005-04-03 03:00:01} detroit {
    clock format 1112511601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.237 {time zone boundary case 2005-10-30 01:59:59} detroit {
    clock format 1130651999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.238 {time zone boundary case 2005-10-30 01:00:00} detroit {
    clock format 1130652000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.239 {time zone boundary case 2005-10-30 01:00:01} detroit {
    clock format 1130652001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.240 {time zone boundary case 2006-04-02 01:59:59} detroit {
    clock format 1143961199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.241 {time zone boundary case 2006-04-02 03:00:00} detroit {
    clock format 1143961200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.242 {time zone boundary case 2006-04-02 03:00:01} detroit {
    clock format 1143961201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.243 {time zone boundary case 2006-10-29 01:59:59} detroit {
    clock format 1162101599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.244 {time zone boundary case 2006-10-29 01:00:00} detroit {
    clock format 1162101600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.245 {time zone boundary case 2006-10-29 01:00:01} detroit {
    clock format 1162101601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.246 {time zone boundary case 2007-03-11 01:59:59} detroit {
    clock format 1173596399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.247 {time zone boundary case 2007-03-11 03:00:00} detroit {
    clock format 1173596400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.248 {time zone boundary case 2007-03-11 03:00:01} detroit {
    clock format 1173596401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.249 {time zone boundary case 2007-11-04 01:59:59} detroit {
    clock format 1194155999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.250 {time zone boundary case 2007-11-04 01:00:00} detroit {
    clock format 1194156000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.251 {time zone boundary case 2007-11-04 01:00:01} detroit {
    clock format 1194156001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.252 {time zone boundary case 2008-03-09 01:59:59} detroit {
    clock format 1205045999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.253 {time zone boundary case 2008-03-09 03:00:00} detroit {
    clock format 1205046000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.254 {time zone boundary case 2008-03-09 03:00:01} detroit {
    clock format 1205046001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.255 {time zone boundary case 2008-11-02 01:59:59} detroit {
    clock format 1225605599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.256 {time zone boundary case 2008-11-02 01:00:00} detroit {
    clock format 1225605600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.257 {time zone boundary case 2008-11-02 01:00:01} detroit {
    clock format 1225605601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.258 {time zone boundary case 2009-03-08 01:59:59} detroit {
    clock format 1236495599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.259 {time zone boundary case 2009-03-08 03:00:00} detroit {
    clock format 1236495600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.260 {time zone boundary case 2009-03-08 03:00:01} detroit {
    clock format 1236495601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.261 {time zone boundary case 2009-11-01 01:59:59} detroit {
    clock format 1257055199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.262 {time zone boundary case 2009-11-01 01:00:00} detroit {
    clock format 1257055200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.263 {time zone boundary case 2009-11-01 01:00:01} detroit {
    clock format 1257055201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.264 {time zone boundary case 2010-03-14 01:59:59} detroit {
    clock format 1268549999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.265 {time zone boundary case 2010-03-14 03:00:00} detroit {
    clock format 1268550000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.266 {time zone boundary case 2010-03-14 03:00:01} detroit {
    clock format 1268550001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.267 {time zone boundary case 2010-11-07 01:59:59} detroit {
    clock format 1289109599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.268 {time zone boundary case 2010-11-07 01:00:00} detroit {
    clock format 1289109600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.269 {time zone boundary case 2010-11-07 01:00:01} detroit {
    clock format 1289109601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.270 {time zone boundary case 2011-03-13 01:59:59} detroit {
    clock format 1299999599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.271 {time zone boundary case 2011-03-13 03:00:00} detroit {
    clock format 1299999600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.272 {time zone boundary case 2011-03-13 03:00:01} detroit {
    clock format 1299999601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.273 {time zone boundary case 2011-11-06 01:59:59} detroit {
    clock format 1320559199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.274 {time zone boundary case 2011-11-06 01:00:00} detroit {
    clock format 1320559200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.275 {time zone boundary case 2011-11-06 01:00:01} detroit {
    clock format 1320559201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.276 {time zone boundary case 2012-03-11 01:59:59} detroit {
    clock format 1331449199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.277 {time zone boundary case 2012-03-11 03:00:00} detroit {
    clock format 1331449200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.278 {time zone boundary case 2012-03-11 03:00:01} detroit {
    clock format 1331449201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.279 {time zone boundary case 2012-11-04 01:59:59} detroit {
    clock format 1352008799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.280 {time zone boundary case 2012-11-04 01:00:00} detroit {
    clock format 1352008800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.281 {time zone boundary case 2012-11-04 01:00:01} detroit {
    clock format 1352008801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.282 {time zone boundary case 2013-03-10 01:59:59} detroit {
    clock format 1362898799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.283 {time zone boundary case 2013-03-10 03:00:00} detroit {
    clock format 1362898800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.284 {time zone boundary case 2013-03-10 03:00:01} detroit {
    clock format 1362898801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.285 {time zone boundary case 2013-11-03 01:59:59} detroit {
    clock format 1383458399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.286 {time zone boundary case 2013-11-03 01:00:00} detroit {
    clock format 1383458400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.287 {time zone boundary case 2013-11-03 01:00:01} detroit {
    clock format 1383458401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.288 {time zone boundary case 2014-03-09 01:59:59} detroit {
    clock format 1394348399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.289 {time zone boundary case 2014-03-09 03:00:00} detroit {
    clock format 1394348400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.290 {time zone boundary case 2014-03-09 03:00:01} detroit {
    clock format 1394348401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.291 {time zone boundary case 2014-11-02 01:59:59} detroit {
    clock format 1414907999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.292 {time zone boundary case 2014-11-02 01:00:00} detroit {
    clock format 1414908000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.293 {time zone boundary case 2014-11-02 01:00:01} detroit {
    clock format 1414908001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.294 {time zone boundary case 2015-03-08 01:59:59} detroit {
    clock format 1425797999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.295 {time zone boundary case 2015-03-08 03:00:00} detroit {
    clock format 1425798000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.296 {time zone boundary case 2015-03-08 03:00:01} detroit {
    clock format 1425798001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.297 {time zone boundary case 2015-11-01 01:59:59} detroit {
    clock format 1446357599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.298 {time zone boundary case 2015-11-01 01:00:00} detroit {
    clock format 1446357600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.299 {time zone boundary case 2015-11-01 01:00:01} detroit {
    clock format 1446357601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.300 {time zone boundary case 2016-03-13 01:59:59} detroit {
    clock format 1457852399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.301 {time zone boundary case 2016-03-13 03:00:00} detroit {
    clock format 1457852400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.302 {time zone boundary case 2016-03-13 03:00:01} detroit {
    clock format 1457852401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.303 {time zone boundary case 2016-11-06 01:59:59} detroit {
    clock format 1478411999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.304 {time zone boundary case 2016-11-06 01:00:00} detroit {
    clock format 1478412000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.305 {time zone boundary case 2016-11-06 01:00:01} detroit {
    clock format 1478412001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.306 {time zone boundary case 2017-03-12 01:59:59} detroit {
    clock format 1489301999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.307 {time zone boundary case 2017-03-12 03:00:00} detroit {
    clock format 1489302000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.308 {time zone boundary case 2017-03-12 03:00:01} detroit {
    clock format 1489302001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.309 {time zone boundary case 2017-11-05 01:59:59} detroit {
    clock format 1509861599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.310 {time zone boundary case 2017-11-05 01:00:00} detroit {
    clock format 1509861600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.311 {time zone boundary case 2017-11-05 01:00:01} detroit {
    clock format 1509861601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.312 {time zone boundary case 2018-03-11 01:59:59} detroit {
    clock format 1520751599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.313 {time zone boundary case 2018-03-11 03:00:00} detroit {
    clock format 1520751600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.314 {time zone boundary case 2018-03-11 03:00:01} detroit {
    clock format 1520751601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.315 {time zone boundary case 2018-11-04 01:59:59} detroit {
    clock format 1541311199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.316 {time zone boundary case 2018-11-04 01:00:00} detroit {
    clock format 1541311200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.317 {time zone boundary case 2018-11-04 01:00:01} detroit {
    clock format 1541311201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.318 {time zone boundary case 2019-03-10 01:59:59} detroit {
    clock format 1552201199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.319 {time zone boundary case 2019-03-10 03:00:00} detroit {
    clock format 1552201200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.320 {time zone boundary case 2019-03-10 03:00:01} detroit {
    clock format 1552201201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.321 {time zone boundary case 2019-11-03 01:59:59} detroit {
    clock format 1572760799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.322 {time zone boundary case 2019-11-03 01:00:00} detroit {
    clock format 1572760800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.323 {time zone boundary case 2019-11-03 01:00:01} detroit {
    clock format 1572760801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.324 {time zone boundary case 2020-03-08 01:59:59} detroit {
    clock format 1583650799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.325 {time zone boundary case 2020-03-08 03:00:00} detroit {
    clock format 1583650800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.326 {time zone boundary case 2020-03-08 03:00:01} detroit {
    clock format 1583650801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.327 {time zone boundary case 2020-11-01 01:59:59} detroit {
    clock format 1604210399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.328 {time zone boundary case 2020-11-01 01:00:00} detroit {
    clock format 1604210400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.329 {time zone boundary case 2020-11-01 01:00:01} detroit {
    clock format 1604210401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.330 {time zone boundary case 2021-03-14 01:59:59} detroit {
    clock format 1615705199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.331 {time zone boundary case 2021-03-14 03:00:00} detroit {
    clock format 1615705200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.332 {time zone boundary case 2021-03-14 03:00:01} detroit {
    clock format 1615705201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.333 {time zone boundary case 2021-11-07 01:59:59} detroit {
    clock format 1636264799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.334 {time zone boundary case 2021-11-07 01:00:00} detroit {
    clock format 1636264800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.335 {time zone boundary case 2021-11-07 01:00:01} detroit {
    clock format 1636264801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.336 {time zone boundary case 2022-03-13 01:59:59} detroit {
    clock format 1647154799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.337 {time zone boundary case 2022-03-13 03:00:00} detroit {
    clock format 1647154800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.338 {time zone boundary case 2022-03-13 03:00:01} detroit {
    clock format 1647154801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.339 {time zone boundary case 2022-11-06 01:59:59} detroit {
    clock format 1667714399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.340 {time zone boundary case 2022-11-06 01:00:00} detroit {
    clock format 1667714400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.341 {time zone boundary case 2022-11-06 01:00:01} detroit {
    clock format 1667714401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.342 {time zone boundary case 2023-03-12 01:59:59} detroit {
    clock format 1678604399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.343 {time zone boundary case 2023-03-12 03:00:00} detroit {
    clock format 1678604400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.344 {time zone boundary case 2023-03-12 03:00:01} detroit {
    clock format 1678604401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.345 {time zone boundary case 2023-11-05 01:59:59} detroit {
    clock format 1699163999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.346 {time zone boundary case 2023-11-05 01:00:00} detroit {
    clock format 1699164000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.347 {time zone boundary case 2023-11-05 01:00:01} detroit {
    clock format 1699164001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.348 {time zone boundary case 2024-03-10 01:59:59} detroit {
    clock format 1710053999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.349 {time zone boundary case 2024-03-10 03:00:00} detroit {
    clock format 1710054000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.350 {time zone boundary case 2024-03-10 03:00:01} detroit {
    clock format 1710054001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.351 {time zone boundary case 2024-11-03 01:59:59} detroit {
    clock format 1730613599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.352 {time zone boundary case 2024-11-03 01:00:00} detroit {
    clock format 1730613600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.353 {time zone boundary case 2024-11-03 01:00:01} detroit {
    clock format 1730613601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.354 {time zone boundary case 2025-03-09 01:59:59} detroit {
    clock format 1741503599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.355 {time zone boundary case 2025-03-09 03:00:00} detroit {
    clock format 1741503600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.356 {time zone boundary case 2025-03-09 03:00:01} detroit {
    clock format 1741503601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.357 {time zone boundary case 2025-11-02 01:59:59} detroit {
    clock format 1762063199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.358 {time zone boundary case 2025-11-02 01:00:00} detroit {
    clock format 1762063200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.359 {time zone boundary case 2025-11-02 01:00:01} detroit {
    clock format 1762063201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.360 {time zone boundary case 2026-03-08 01:59:59} detroit {
    clock format 1772953199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.361 {time zone boundary case 2026-03-08 03:00:00} detroit {
    clock format 1772953200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.362 {time zone boundary case 2026-03-08 03:00:01} detroit {
    clock format 1772953201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.363 {time zone boundary case 2026-11-01 01:59:59} detroit {
    clock format 1793512799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.364 {time zone boundary case 2026-11-01 01:00:00} detroit {
    clock format 1793512800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.365 {time zone boundary case 2026-11-01 01:00:01} detroit {
    clock format 1793512801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.366 {time zone boundary case 2027-03-14 01:59:59} detroit {
    clock format 1805007599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.367 {time zone boundary case 2027-03-14 03:00:00} detroit {
    clock format 1805007600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.368 {time zone boundary case 2027-03-14 03:00:01} detroit {
    clock format 1805007601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.369 {time zone boundary case 2027-11-07 01:59:59} detroit {
    clock format 1825567199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.370 {time zone boundary case 2027-11-07 01:00:00} detroit {
    clock format 1825567200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.371 {time zone boundary case 2027-11-07 01:00:01} detroit {
    clock format 1825567201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.372 {time zone boundary case 2028-03-12 01:59:59} detroit {
    clock format 1836457199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.373 {time zone boundary case 2028-03-12 03:00:00} detroit {
    clock format 1836457200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.374 {time zone boundary case 2028-03-12 03:00:01} detroit {
    clock format 1836457201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.375 {time zone boundary case 2028-11-05 01:59:59} detroit {
    clock format 1857016799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.376 {time zone boundary case 2028-11-05 01:00:00} detroit {
    clock format 1857016800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.377 {time zone boundary case 2028-11-05 01:00:01} detroit {
    clock format 1857016801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.378 {time zone boundary case 2029-03-11 01:59:59} detroit {
    clock format 1867906799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.379 {time zone boundary case 2029-03-11 03:00:00} detroit {
    clock format 1867906800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.380 {time zone boundary case 2029-03-11 03:00:01} detroit {
    clock format 1867906801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.381 {time zone boundary case 2029-11-04 01:59:59} detroit {
    clock format 1888466399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.382 {time zone boundary case 2029-11-04 01:00:00} detroit {
    clock format 1888466400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.383 {time zone boundary case 2029-11-04 01:00:01} detroit {
    clock format 1888466401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.384 {time zone boundary case 2030-03-10 01:59:59} detroit {
    clock format 1899356399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.385 {time zone boundary case 2030-03-10 03:00:00} detroit {
    clock format 1899356400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.386 {time zone boundary case 2030-03-10 03:00:01} detroit {
    clock format 1899356401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.387 {time zone boundary case 2030-11-03 01:59:59} detroit {
    clock format 1919915999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.388 {time zone boundary case 2030-11-03 01:00:00} detroit {
    clock format 1919916000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.389 {time zone boundary case 2030-11-03 01:00:01} detroit {
    clock format 1919916001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.390 {time zone boundary case 2031-03-09 01:59:59} detroit {
    clock format 1930805999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.391 {time zone boundary case 2031-03-09 03:00:00} detroit {
    clock format 1930806000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.392 {time zone boundary case 2031-03-09 03:00:01} detroit {
    clock format 1930806001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.393 {time zone boundary case 2031-11-02 01:59:59} detroit {
    clock format 1951365599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.394 {time zone boundary case 2031-11-02 01:00:00} detroit {
    clock format 1951365600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.395 {time zone boundary case 2031-11-02 01:00:01} detroit {
    clock format 1951365601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.396 {time zone boundary case 2032-03-14 01:59:59} detroit {
    clock format 1962860399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.397 {time zone boundary case 2032-03-14 03:00:00} detroit {
    clock format 1962860400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.398 {time zone boundary case 2032-03-14 03:00:01} detroit {
    clock format 1962860401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.399 {time zone boundary case 2032-11-07 01:59:59} detroit {
    clock format 1983419999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.400 {time zone boundary case 2032-11-07 01:00:00} detroit {
    clock format 1983420000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.401 {time zone boundary case 2032-11-07 01:00:01} detroit {
    clock format 1983420001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.402 {time zone boundary case 2033-03-13 01:59:59} detroit {
    clock format 1994309999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.403 {time zone boundary case 2033-03-13 03:00:00} detroit {
    clock format 1994310000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.404 {time zone boundary case 2033-03-13 03:00:01} detroit {
    clock format 1994310001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.405 {time zone boundary case 2033-11-06 01:59:59} detroit {
    clock format 2014869599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.406 {time zone boundary case 2033-11-06 01:00:00} detroit {
    clock format 2014869600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.407 {time zone boundary case 2033-11-06 01:00:01} detroit {
    clock format 2014869601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.408 {time zone boundary case 2034-03-12 01:59:59} detroit {
    clock format 2025759599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.409 {time zone boundary case 2034-03-12 03:00:00} detroit {
    clock format 2025759600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.410 {time zone boundary case 2034-03-12 03:00:01} detroit {
    clock format 2025759601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.411 {time zone boundary case 2034-11-05 01:59:59} detroit {
    clock format 2046319199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.412 {time zone boundary case 2034-11-05 01:00:00} detroit {
    clock format 2046319200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.413 {time zone boundary case 2034-11-05 01:00:01} detroit {
    clock format 2046319201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.414 {time zone boundary case 2035-03-11 01:59:59} detroit {
    clock format 2057209199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.415 {time zone boundary case 2035-03-11 03:00:00} detroit {
    clock format 2057209200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.416 {time zone boundary case 2035-03-11 03:00:01} detroit {
    clock format 2057209201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.417 {time zone boundary case 2035-11-04 01:59:59} detroit {
    clock format 2077768799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.418 {time zone boundary case 2035-11-04 01:00:00} detroit {
    clock format 2077768800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.419 {time zone boundary case 2035-11-04 01:00:01} detroit {
    clock format 2077768801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.420 {time zone boundary case 2036-03-09 01:59:59} detroit {
    clock format 2088658799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.421 {time zone boundary case 2036-03-09 03:00:00} detroit {
    clock format 2088658800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.422 {time zone boundary case 2036-03-09 03:00:01} detroit {
    clock format 2088658801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.423 {time zone boundary case 2036-11-02 01:59:59} detroit {
    clock format 2109218399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.424 {time zone boundary case 2036-11-02 01:00:00} detroit {
    clock format 2109218400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.425 {time zone boundary case 2036-11-02 01:00:01} detroit {
    clock format 2109218401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.426 {time zone boundary case 2037-03-08 01:59:59} detroit {
    clock format 2120108399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.427 {time zone boundary case 2037-03-08 03:00:00} detroit {
    clock format 2120108400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.428 {time zone boundary case 2037-03-08 03:00:01} detroit {
    clock format 2120108401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.429 {time zone boundary case 2037-11-01 01:59:59} detroit {
    clock format 2140667999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.430 {time zone boundary case 2037-11-01 01:00:00} detroit {
    clock format 2140668000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.431 {time zone boundary case 2037-11-01 01:00:01} detroit {
    clock format 2140668001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.432 {time zone boundary case 2038-03-14 01:59:59} {detroit y2038} {
    clock format 2152162799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.433 {time zone boundary case 2038-03-14 03:00:00} {detroit y2038} {
    clock format 2152162800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.434 {time zone boundary case 2038-03-14 03:00:01} {detroit y2038} {
    clock format 2152162801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.435 {time zone boundary case 2038-11-07 01:59:59} {detroit y2038} {
    clock format 2172722399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.436 {time zone boundary case 2038-11-07 01:00:00} {detroit y2038} {
    clock format 2172722400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.437 {time zone boundary case 2038-11-07 01:00:01} {detroit y2038} {
    clock format 2172722401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.438 {time zone boundary case 2039-03-13 01:59:59} {detroit y2038} {
    clock format 2183612399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.439 {time zone boundary case 2039-03-13 03:00:00} {detroit y2038} {
    clock format 2183612400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.440 {time zone boundary case 2039-03-13 03:00:01} {detroit y2038} {
    clock format 2183612401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.441 {time zone boundary case 2039-11-06 01:59:59} {detroit y2038} {
    clock format 2204171999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.442 {time zone boundary case 2039-11-06 01:00:00} {detroit y2038} {
    clock format 2204172000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.443 {time zone boundary case 2039-11-06 01:00:01} {detroit y2038} {
    clock format 2204172001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.444 {time zone boundary case 2040-03-11 01:59:59} {detroit y2038} {
    clock format 2215061999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.445 {time zone boundary case 2040-03-11 03:00:00} {detroit y2038} {
    clock format 2215062000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.446 {time zone boundary case 2040-03-11 03:00:01} {detroit y2038} {
    clock format 2215062001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.447 {time zone boundary case 2040-11-04 01:59:59} {detroit y2038} {
    clock format 2235621599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.448 {time zone boundary case 2040-11-04 01:00:00} {detroit y2038} {
    clock format 2235621600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.449 {time zone boundary case 2040-11-04 01:00:01} {detroit y2038} {
    clock format 2235621601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.450 {time zone boundary case 2041-03-10 01:59:59} {detroit y2038} {
    clock format 2246511599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.451 {time zone boundary case 2041-03-10 03:00:00} {detroit y2038} {
    clock format 2246511600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.452 {time zone boundary case 2041-03-10 03:00:01} {detroit y2038} {
    clock format 2246511601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.453 {time zone boundary case 2041-11-03 01:59:59} {detroit y2038} {
    clock format 2267071199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.454 {time zone boundary case 2041-11-03 01:00:00} {detroit y2038} {
    clock format 2267071200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.455 {time zone boundary case 2041-11-03 01:00:01} {detroit y2038} {
    clock format 2267071201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.456 {time zone boundary case 2042-03-09 01:59:59} {detroit y2038} {
    clock format 2277961199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.457 {time zone boundary case 2042-03-09 03:00:00} {detroit y2038} {
    clock format 2277961200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.458 {time zone boundary case 2042-03-09 03:00:01} {detroit y2038} {
    clock format 2277961201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.459 {time zone boundary case 2042-11-02 01:59:59} {detroit y2038} {
    clock format 2298520799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.460 {time zone boundary case 2042-11-02 01:00:00} {detroit y2038} {
    clock format 2298520800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.461 {time zone boundary case 2042-11-02 01:00:01} {detroit y2038} {
    clock format 2298520801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.462 {time zone boundary case 2043-03-08 01:59:59} {detroit y2038} {
    clock format 2309410799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.463 {time zone boundary case 2043-03-08 03:00:00} {detroit y2038} {
    clock format 2309410800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.464 {time zone boundary case 2043-03-08 03:00:01} {detroit y2038} {
    clock format 2309410801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.465 {time zone boundary case 2043-11-01 01:59:59} {detroit y2038} {
    clock format 2329970399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.466 {time zone boundary case 2043-11-01 01:00:00} {detroit y2038} {
    clock format 2329970400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.467 {time zone boundary case 2043-11-01 01:00:01} {detroit y2038} {
    clock format 2329970401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.468 {time zone boundary case 2044-03-13 01:59:59} {detroit y2038} {
    clock format 2341465199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.469 {time zone boundary case 2044-03-13 03:00:00} {detroit y2038} {
    clock format 2341465200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.470 {time zone boundary case 2044-03-13 03:00:01} {detroit y2038} {
    clock format 2341465201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.471 {time zone boundary case 2044-11-06 01:59:59} {detroit y2038} {
    clock format 2362024799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.472 {time zone boundary case 2044-11-06 01:00:00} {detroit y2038} {
    clock format 2362024800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.473 {time zone boundary case 2044-11-06 01:00:01} {detroit y2038} {
    clock format 2362024801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.474 {time zone boundary case 2045-03-12 01:59:59} {detroit y2038} {
    clock format 2372914799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.475 {time zone boundary case 2045-03-12 03:00:00} {detroit y2038} {
    clock format 2372914800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.476 {time zone boundary case 2045-03-12 03:00:01} {detroit y2038} {
    clock format 2372914801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.477 {time zone boundary case 2045-11-05 01:59:59} {detroit y2038} {
    clock format 2393474399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.478 {time zone boundary case 2045-11-05 01:00:00} {detroit y2038} {
    clock format 2393474400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.479 {time zone boundary case 2045-11-05 01:00:01} {detroit y2038} {
    clock format 2393474401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.480 {time zone boundary case 2046-03-11 01:59:59} {detroit y2038} {
    clock format 2404364399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.481 {time zone boundary case 2046-03-11 03:00:00} {detroit y2038} {
    clock format 2404364400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.482 {time zone boundary case 2046-03-11 03:00:01} {detroit y2038} {
    clock format 2404364401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.483 {time zone boundary case 2046-11-04 01:59:59} {detroit y2038} {
    clock format 2424923999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.484 {time zone boundary case 2046-11-04 01:00:00} {detroit y2038} {
    clock format 2424924000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.485 {time zone boundary case 2046-11-04 01:00:01} {detroit y2038} {
    clock format 2424924001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.486 {time zone boundary case 2047-03-10 01:59:59} {detroit y2038} {
    clock format 2435813999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.487 {time zone boundary case 2047-03-10 03:00:00} {detroit y2038} {
    clock format 2435814000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.488 {time zone boundary case 2047-03-10 03:00:01} {detroit y2038} {
    clock format 2435814001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.489 {time zone boundary case 2047-11-03 01:59:59} {detroit y2038} {
    clock format 2456373599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.490 {time zone boundary case 2047-11-03 01:00:00} {detroit y2038} {
    clock format 2456373600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.491 {time zone boundary case 2047-11-03 01:00:01} {detroit y2038} {
    clock format 2456373601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.492 {time zone boundary case 2048-03-08 01:59:59} {detroit y2038} {
    clock format 2467263599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.493 {time zone boundary case 2048-03-08 03:00:00} {detroit y2038} {
    clock format 2467263600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.494 {time zone boundary case 2048-03-08 03:00:01} {detroit y2038} {
    clock format 2467263601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.495 {time zone boundary case 2048-11-01 01:59:59} {detroit y2038} {
    clock format 2487823199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.496 {time zone boundary case 2048-11-01 01:00:00} {detroit y2038} {
    clock format 2487823200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.497 {time zone boundary case 2048-11-01 01:00:01} {detroit y2038} {
    clock format 2487823201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.498 {time zone boundary case 2049-03-14 01:59:59} {detroit y2038} {
    clock format 2499317999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.499 {time zone boundary case 2049-03-14 03:00:00} {detroit y2038} {
    clock format 2499318000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.500 {time zone boundary case 2049-03-14 03:00:01} {detroit y2038} {
    clock format 2499318001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.501 {time zone boundary case 2049-11-07 01:59:59} {detroit y2038} {
    clock format 2519877599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.502 {time zone boundary case 2049-11-07 01:00:00} {detroit y2038} {
    clock format 2519877600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.503 {time zone boundary case 2049-11-07 01:00:01} {detroit y2038} {
    clock format 2519877601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.504 {time zone boundary case 2050-03-13 01:59:59} {detroit y2038} {
    clock format 2530767599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.505 {time zone boundary case 2050-03-13 03:00:00} {detroit y2038} {
    clock format 2530767600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.506 {time zone boundary case 2050-03-13 03:00:01} {detroit y2038} {
    clock format 2530767601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.507 {time zone boundary case 2050-11-06 01:59:59} {detroit y2038} {
    clock format 2551327199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.508 {time zone boundary case 2050-11-06 01:00:00} {detroit y2038} {
    clock format 2551327200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.509 {time zone boundary case 2050-11-06 01:00:01} {detroit y2038} {
    clock format 2551327201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.510 {time zone boundary case 2051-03-12 01:59:59} {detroit y2038} {
    clock format 2562217199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.511 {time zone boundary case 2051-03-12 03:00:00} {detroit y2038} {
    clock format 2562217200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.512 {time zone boundary case 2051-03-12 03:00:01} {detroit y2038} {
    clock format 2562217201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.513 {time zone boundary case 2051-11-05 01:59:59} {detroit y2038} {
    clock format 2582776799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.514 {time zone boundary case 2051-11-05 01:00:00} {detroit y2038} {
    clock format 2582776800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.515 {time zone boundary case 2051-11-05 01:00:01} {detroit y2038} {
    clock format 2582776801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.516 {time zone boundary case 2052-03-10 01:59:59} {detroit y2038} {
    clock format 2593666799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.517 {time zone boundary case 2052-03-10 03:00:00} {detroit y2038} {
    clock format 2593666800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.518 {time zone boundary case 2052-03-10 03:00:01} {detroit y2038} {
    clock format 2593666801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.519 {time zone boundary case 2052-11-03 01:59:59} {detroit y2038} {
    clock format 2614226399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.520 {time zone boundary case 2052-11-03 01:00:00} {detroit y2038} {
    clock format 2614226400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.521 {time zone boundary case 2052-11-03 01:00:01} {detroit y2038} {
    clock format 2614226401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.522 {time zone boundary case 2053-03-09 01:59:59} {detroit y2038} {
    clock format 2625116399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.523 {time zone boundary case 2053-03-09 03:00:00} {detroit y2038} {
    clock format 2625116400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.524 {time zone boundary case 2053-03-09 03:00:01} {detroit y2038} {
    clock format 2625116401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.525 {time zone boundary case 2053-11-02 01:59:59} {detroit y2038} {
    clock format 2645675999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.526 {time zone boundary case 2053-11-02 01:00:00} {detroit y2038} {
    clock format 2645676000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.527 {time zone boundary case 2053-11-02 01:00:01} {detroit y2038} {
    clock format 2645676001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.528 {time zone boundary case 2054-03-08 01:59:59} {detroit y2038} {
    clock format 2656565999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.529 {time zone boundary case 2054-03-08 03:00:00} {detroit y2038} {
    clock format 2656566000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.530 {time zone boundary case 2054-03-08 03:00:01} {detroit y2038} {
    clock format 2656566001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.531 {time zone boundary case 2054-11-01 01:59:59} {detroit y2038} {
    clock format 2677125599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.532 {time zone boundary case 2054-11-01 01:00:00} {detroit y2038} {
    clock format 2677125600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.533 {time zone boundary case 2054-11-01 01:00:01} {detroit y2038} {
    clock format 2677125601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.534 {time zone boundary case 2055-03-14 01:59:59} {detroit y2038} {
    clock format 2688620399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.535 {time zone boundary case 2055-03-14 03:00:00} {detroit y2038} {
    clock format 2688620400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.536 {time zone boundary case 2055-03-14 03:00:01} {detroit y2038} {
    clock format 2688620401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.537 {time zone boundary case 2055-11-07 01:59:59} {detroit y2038} {
    clock format 2709179999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.538 {time zone boundary case 2055-11-07 01:00:00} {detroit y2038} {
    clock format 2709180000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.539 {time zone boundary case 2055-11-07 01:00:01} {detroit y2038} {
    clock format 2709180001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.540 {time zone boundary case 2056-03-12 01:59:59} {detroit y2038} {
    clock format 2720069999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.541 {time zone boundary case 2056-03-12 03:00:00} {detroit y2038} {
    clock format 2720070000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.542 {time zone boundary case 2056-03-12 03:00:01} {detroit y2038} {
    clock format 2720070001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.543 {time zone boundary case 2056-11-05 01:59:59} {detroit y2038} {
    clock format 2740629599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.544 {time zone boundary case 2056-11-05 01:00:00} {detroit y2038} {
    clock format 2740629600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.545 {time zone boundary case 2056-11-05 01:00:01} {detroit y2038} {
    clock format 2740629601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.546 {time zone boundary case 2057-03-11 01:59:59} {detroit y2038} {
    clock format 2751519599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.547 {time zone boundary case 2057-03-11 03:00:00} {detroit y2038} {
    clock format 2751519600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.548 {time zone boundary case 2057-03-11 03:00:01} {detroit y2038} {
    clock format 2751519601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.549 {time zone boundary case 2057-11-04 01:59:59} {detroit y2038} {
    clock format 2772079199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.550 {time zone boundary case 2057-11-04 01:00:00} {detroit y2038} {
    clock format 2772079200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.551 {time zone boundary case 2057-11-04 01:00:01} {detroit y2038} {
    clock format 2772079201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.552 {time zone boundary case 2058-03-10 01:59:59} {detroit y2038} {
    clock format 2782969199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.553 {time zone boundary case 2058-03-10 03:00:00} {detroit y2038} {
    clock format 2782969200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.554 {time zone boundary case 2058-03-10 03:00:01} {detroit y2038} {
    clock format 2782969201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.555 {time zone boundary case 2058-11-03 01:59:59} {detroit y2038} {
    clock format 2803528799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.556 {time zone boundary case 2058-11-03 01:00:00} {detroit y2038} {
    clock format 2803528800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.557 {time zone boundary case 2058-11-03 01:00:01} {detroit y2038} {
    clock format 2803528801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.558 {time zone boundary case 2059-03-09 01:59:59} {detroit y2038} {
    clock format 2814418799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.559 {time zone boundary case 2059-03-09 03:00:00} {detroit y2038} {
    clock format 2814418800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.560 {time zone boundary case 2059-03-09 03:00:01} {detroit y2038} {
    clock format 2814418801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.561 {time zone boundary case 2059-11-02 01:59:59} {detroit y2038} {
    clock format 2834978399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.562 {time zone boundary case 2059-11-02 01:00:00} {detroit y2038} {
    clock format 2834978400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.563 {time zone boundary case 2059-11-02 01:00:01} {detroit y2038} {
    clock format 2834978401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.564 {time zone boundary case 2060-03-14 01:59:59} {detroit y2038} {
    clock format 2846473199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.565 {time zone boundary case 2060-03-14 03:00:00} {detroit y2038} {
    clock format 2846473200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.566 {time zone boundary case 2060-03-14 03:00:01} {detroit y2038} {
    clock format 2846473201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.567 {time zone boundary case 2060-11-07 01:59:59} {detroit y2038} {
    clock format 2867032799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.568 {time zone boundary case 2060-11-07 01:00:00} {detroit y2038} {
    clock format 2867032800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.569 {time zone boundary case 2060-11-07 01:00:01} {detroit y2038} {
    clock format 2867032801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.570 {time zone boundary case 2061-03-13 01:59:59} {detroit y2038} {
    clock format 2877922799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.571 {time zone boundary case 2061-03-13 03:00:00} {detroit y2038} {
    clock format 2877922800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.572 {time zone boundary case 2061-03-13 03:00:01} {detroit y2038} {
    clock format 2877922801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.573 {time zone boundary case 2061-11-06 01:59:59} {detroit y2038} {
    clock format 2898482399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.574 {time zone boundary case 2061-11-06 01:00:00} {detroit y2038} {
    clock format 2898482400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.575 {time zone boundary case 2061-11-06 01:00:01} {detroit y2038} {
    clock format 2898482401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.576 {time zone boundary case 2062-03-12 01:59:59} {detroit y2038} {
    clock format 2909372399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.577 {time zone boundary case 2062-03-12 03:00:00} {detroit y2038} {
    clock format 2909372400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.578 {time zone boundary case 2062-03-12 03:00:01} {detroit y2038} {
    clock format 2909372401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.579 {time zone boundary case 2062-11-05 01:59:59} {detroit y2038} {
    clock format 2929931999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.580 {time zone boundary case 2062-11-05 01:00:00} {detroit y2038} {
    clock format 2929932000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.581 {time zone boundary case 2062-11-05 01:00:01} {detroit y2038} {
    clock format 2929932001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.582 {time zone boundary case 2063-03-11 01:59:59} {detroit y2038} {
    clock format 2940821999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.583 {time zone boundary case 2063-03-11 03:00:00} {detroit y2038} {
    clock format 2940822000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.584 {time zone boundary case 2063-03-11 03:00:01} {detroit y2038} {
    clock format 2940822001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.585 {time zone boundary case 2063-11-04 01:59:59} {detroit y2038} {
    clock format 2961381599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.586 {time zone boundary case 2063-11-04 01:00:00} {detroit y2038} {
    clock format 2961381600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.587 {time zone boundary case 2063-11-04 01:00:01} {detroit y2038} {
    clock format 2961381601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.588 {time zone boundary case 2064-03-09 01:59:59} {detroit y2038} {
    clock format 2972271599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.589 {time zone boundary case 2064-03-09 03:00:00} {detroit y2038} {
    clock format 2972271600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.590 {time zone boundary case 2064-03-09 03:00:01} {detroit y2038} {
    clock format 2972271601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.591 {time zone boundary case 2064-11-02 01:59:59} {detroit y2038} {
    clock format 2992831199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.592 {time zone boundary case 2064-11-02 01:00:00} {detroit y2038} {
    clock format 2992831200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.593 {time zone boundary case 2064-11-02 01:00:01} {detroit y2038} {
    clock format 2992831201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.594 {time zone boundary case 2065-03-08 01:59:59} {detroit y2038} {
    clock format 3003721199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.595 {time zone boundary case 2065-03-08 03:00:00} {detroit y2038} {
    clock format 3003721200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.596 {time zone boundary case 2065-03-08 03:00:01} {detroit y2038} {
    clock format 3003721201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.597 {time zone boundary case 2065-11-01 01:59:59} {detroit y2038} {
    clock format 3024280799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.598 {time zone boundary case 2065-11-01 01:00:00} {detroit y2038} {
    clock format 3024280800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.599 {time zone boundary case 2065-11-01 01:00:01} {detroit y2038} {
    clock format 3024280801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.600 {time zone boundary case 2066-03-14 01:59:59} {detroit y2038} {
    clock format 3035775599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.601 {time zone boundary case 2066-03-14 03:00:00} {detroit y2038} {
    clock format 3035775600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.602 {time zone boundary case 2066-03-14 03:00:01} {detroit y2038} {
    clock format 3035775601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.603 {time zone boundary case 2066-11-07 01:59:59} {detroit y2038} {
    clock format 3056335199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.604 {time zone boundary case 2066-11-07 01:00:00} {detroit y2038} {
    clock format 3056335200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.605 {time zone boundary case 2066-11-07 01:00:01} {detroit y2038} {
    clock format 3056335201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.606 {time zone boundary case 2067-03-13 01:59:59} {detroit y2038} {
    clock format 3067225199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.607 {time zone boundary case 2067-03-13 03:00:00} {detroit y2038} {
    clock format 3067225200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.608 {time zone boundary case 2067-03-13 03:00:01} {detroit y2038} {
    clock format 3067225201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.609 {time zone boundary case 2067-11-06 01:59:59} {detroit y2038} {
    clock format 3087784799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.610 {time zone boundary case 2067-11-06 01:00:00} {detroit y2038} {
    clock format 3087784800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.611 {time zone boundary case 2067-11-06 01:00:01} {detroit y2038} {
    clock format 3087784801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.612 {time zone boundary case 2068-03-11 01:59:59} {detroit y2038} {
    clock format 3098674799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.613 {time zone boundary case 2068-03-11 03:00:00} {detroit y2038} {
    clock format 3098674800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.614 {time zone boundary case 2068-03-11 03:00:01} {detroit y2038} {
    clock format 3098674801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.615 {time zone boundary case 2068-11-04 01:59:59} {detroit y2038} {
    clock format 3119234399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.616 {time zone boundary case 2068-11-04 01:00:00} {detroit y2038} {
    clock format 3119234400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.617 {time zone boundary case 2068-11-04 01:00:01} {detroit y2038} {
    clock format 3119234401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.618 {time zone boundary case 2069-03-10 01:59:59} {detroit y2038} {
    clock format 3130124399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.619 {time zone boundary case 2069-03-10 03:00:00} {detroit y2038} {
    clock format 3130124400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.620 {time zone boundary case 2069-03-10 03:00:01} {detroit y2038} {
    clock format 3130124401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.621 {time zone boundary case 2069-11-03 01:59:59} {detroit y2038} {
    clock format 3150683999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.622 {time zone boundary case 2069-11-03 01:00:00} {detroit y2038} {
    clock format 3150684000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.623 {time zone boundary case 2069-11-03 01:00:01} {detroit y2038} {
    clock format 3150684001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.624 {time zone boundary case 2070-03-09 01:59:59} {detroit y2038} {
    clock format 3161573999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.625 {time zone boundary case 2070-03-09 03:00:00} {detroit y2038} {
    clock format 3161574000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.626 {time zone boundary case 2070-03-09 03:00:01} {detroit y2038} {
    clock format 3161574001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.627 {time zone boundary case 2070-11-02 01:59:59} {detroit y2038} {
    clock format 3182133599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.628 {time zone boundary case 2070-11-02 01:00:00} {detroit y2038} {
    clock format 3182133600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.629 {time zone boundary case 2070-11-02 01:00:01} {detroit y2038} {
    clock format 3182133601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.630 {time zone boundary case 2071-03-08 01:59:59} {detroit y2038} {
    clock format 3193023599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.631 {time zone boundary case 2071-03-08 03:00:00} {detroit y2038} {
    clock format 3193023600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.632 {time zone boundary case 2071-03-08 03:00:01} {detroit y2038} {
    clock format 3193023601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.633 {time zone boundary case 2071-11-01 01:59:59} {detroit y2038} {
    clock format 3213583199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.634 {time zone boundary case 2071-11-01 01:00:00} {detroit y2038} {
    clock format 3213583200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.635 {time zone boundary case 2071-11-01 01:00:01} {detroit y2038} {
    clock format 3213583201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.636 {time zone boundary case 2072-03-13 01:59:59} {detroit y2038} {
    clock format 3225077999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.637 {time zone boundary case 2072-03-13 03:00:00} {detroit y2038} {
    clock format 3225078000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.638 {time zone boundary case 2072-03-13 03:00:01} {detroit y2038} {
    clock format 3225078001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.639 {time zone boundary case 2072-11-06 01:59:59} {detroit y2038} {
    clock format 3245637599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.640 {time zone boundary case 2072-11-06 01:00:00} {detroit y2038} {
    clock format 3245637600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.641 {time zone boundary case 2072-11-06 01:00:01} {detroit y2038} {
    clock format 3245637601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.642 {time zone boundary case 2073-03-12 01:59:59} {detroit y2038} {
    clock format 3256527599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.643 {time zone boundary case 2073-03-12 03:00:00} {detroit y2038} {
    clock format 3256527600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.644 {time zone boundary case 2073-03-12 03:00:01} {detroit y2038} {
    clock format 3256527601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.645 {time zone boundary case 2073-11-05 01:59:59} {detroit y2038} {
    clock format 3277087199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.646 {time zone boundary case 2073-11-05 01:00:00} {detroit y2038} {
    clock format 3277087200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.647 {time zone boundary case 2073-11-05 01:00:01} {detroit y2038} {
    clock format 3277087201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.648 {time zone boundary case 2074-03-11 01:59:59} {detroit y2038} {
    clock format 3287977199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.649 {time zone boundary case 2074-03-11 03:00:00} {detroit y2038} {
    clock format 3287977200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.650 {time zone boundary case 2074-03-11 03:00:01} {detroit y2038} {
    clock format 3287977201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.651 {time zone boundary case 2074-11-04 01:59:59} {detroit y2038} {
    clock format 3308536799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.652 {time zone boundary case 2074-11-04 01:00:00} {detroit y2038} {
    clock format 3308536800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.653 {time zone boundary case 2074-11-04 01:00:01} {detroit y2038} {
    clock format 3308536801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.654 {time zone boundary case 2075-03-10 01:59:59} {detroit y2038} {
    clock format 3319426799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.655 {time zone boundary case 2075-03-10 03:00:00} {detroit y2038} {
    clock format 3319426800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.656 {time zone boundary case 2075-03-10 03:00:01} {detroit y2038} {
    clock format 3319426801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.657 {time zone boundary case 2075-11-03 01:59:59} {detroit y2038} {
    clock format 3339986399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.658 {time zone boundary case 2075-11-03 01:00:00} {detroit y2038} {
    clock format 3339986400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.659 {time zone boundary case 2075-11-03 01:00:01} {detroit y2038} {
    clock format 3339986401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.660 {time zone boundary case 2076-03-08 01:59:59} {detroit y2038} {
    clock format 3350876399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.661 {time zone boundary case 2076-03-08 03:00:00} {detroit y2038} {
    clock format 3350876400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.662 {time zone boundary case 2076-03-08 03:00:01} {detroit y2038} {
    clock format 3350876401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.663 {time zone boundary case 2076-11-01 01:59:59} {detroit y2038} {
    clock format 3371435999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.664 {time zone boundary case 2076-11-01 01:00:00} {detroit y2038} {
    clock format 3371436000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.665 {time zone boundary case 2076-11-01 01:00:01} {detroit y2038} {
    clock format 3371436001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.666 {time zone boundary case 2077-03-14 01:59:59} {detroit y2038} {
    clock format 3382930799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.667 {time zone boundary case 2077-03-14 03:00:00} {detroit y2038} {
    clock format 3382930800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.668 {time zone boundary case 2077-03-14 03:00:01} {detroit y2038} {
    clock format 3382930801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.669 {time zone boundary case 2077-11-07 01:59:59} {detroit y2038} {
    clock format 3403490399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.670 {time zone boundary case 2077-11-07 01:00:00} {detroit y2038} {
    clock format 3403490400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.671 {time zone boundary case 2077-11-07 01:00:01} {detroit y2038} {
    clock format 3403490401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.672 {time zone boundary case 2078-03-13 01:59:59} {detroit y2038} {
    clock format 3414380399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.673 {time zone boundary case 2078-03-13 03:00:00} {detroit y2038} {
    clock format 3414380400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.674 {time zone boundary case 2078-03-13 03:00:01} {detroit y2038} {
    clock format 3414380401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.675 {time zone boundary case 2078-11-06 01:59:59} {detroit y2038} {
    clock format 3434939999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.676 {time zone boundary case 2078-11-06 01:00:00} {detroit y2038} {
    clock format 3434940000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.677 {time zone boundary case 2078-11-06 01:00:01} {detroit y2038} {
    clock format 3434940001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.678 {time zone boundary case 2079-03-12 01:59:59} {detroit y2038} {
    clock format 3445829999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.679 {time zone boundary case 2079-03-12 03:00:00} {detroit y2038} {
    clock format 3445830000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.680 {time zone boundary case 2079-03-12 03:00:01} {detroit y2038} {
    clock format 3445830001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.681 {time zone boundary case 2079-11-05 01:59:59} {detroit y2038} {
    clock format 3466389599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.682 {time zone boundary case 2079-11-05 01:00:00} {detroit y2038} {
    clock format 3466389600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.683 {time zone boundary case 2079-11-05 01:00:01} {detroit y2038} {
    clock format 3466389601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.684 {time zone boundary case 2080-03-10 01:59:59} {detroit y2038} {
    clock format 3477279599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.685 {time zone boundary case 2080-03-10 03:00:00} {detroit y2038} {
    clock format 3477279600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.686 {time zone boundary case 2080-03-10 03:00:01} {detroit y2038} {
    clock format 3477279601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.687 {time zone boundary case 2080-11-03 01:59:59} {detroit y2038} {
    clock format 3497839199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.688 {time zone boundary case 2080-11-03 01:00:00} {detroit y2038} {
    clock format 3497839200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.689 {time zone boundary case 2080-11-03 01:00:01} {detroit y2038} {
    clock format 3497839201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.690 {time zone boundary case 2081-03-09 01:59:59} {detroit y2038} {
    clock format 3508729199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.691 {time zone boundary case 2081-03-09 03:00:00} {detroit y2038} {
    clock format 3508729200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.692 {time zone boundary case 2081-03-09 03:00:01} {detroit y2038} {
    clock format 3508729201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.693 {time zone boundary case 2081-11-02 01:59:59} {detroit y2038} {
    clock format 3529288799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.694 {time zone boundary case 2081-11-02 01:00:00} {detroit y2038} {
    clock format 3529288800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.695 {time zone boundary case 2081-11-02 01:00:01} {detroit y2038} {
    clock format 3529288801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.696 {time zone boundary case 2082-03-08 01:59:59} {detroit y2038} {
    clock format 3540178799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.697 {time zone boundary case 2082-03-08 03:00:00} {detroit y2038} {
    clock format 3540178800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.698 {time zone boundary case 2082-03-08 03:00:01} {detroit y2038} {
    clock format 3540178801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.699 {time zone boundary case 2082-11-01 01:59:59} {detroit y2038} {
    clock format 3560738399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.700 {time zone boundary case 2082-11-01 01:00:00} {detroit y2038} {
    clock format 3560738400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.701 {time zone boundary case 2082-11-01 01:00:01} {detroit y2038} {
    clock format 3560738401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.702 {time zone boundary case 2083-03-14 01:59:59} {detroit y2038} {
    clock format 3572233199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.703 {time zone boundary case 2083-03-14 03:00:00} {detroit y2038} {
    clock format 3572233200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.704 {time zone boundary case 2083-03-14 03:00:01} {detroit y2038} {
    clock format 3572233201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.705 {time zone boundary case 2083-11-07 01:59:59} {detroit y2038} {
    clock format 3592792799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.706 {time zone boundary case 2083-11-07 01:00:00} {detroit y2038} {
    clock format 3592792800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.707 {time zone boundary case 2083-11-07 01:00:01} {detroit y2038} {
    clock format 3592792801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.708 {time zone boundary case 2084-03-12 01:59:59} {detroit y2038} {
    clock format 3603682799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.709 {time zone boundary case 2084-03-12 03:00:00} {detroit y2038} {
    clock format 3603682800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.710 {time zone boundary case 2084-03-12 03:00:01} {detroit y2038} {
    clock format 3603682801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.711 {time zone boundary case 2084-11-05 01:59:59} {detroit y2038} {
    clock format 3624242399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.712 {time zone boundary case 2084-11-05 01:00:00} {detroit y2038} {
    clock format 3624242400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.713 {time zone boundary case 2084-11-05 01:00:01} {detroit y2038} {
    clock format 3624242401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.714 {time zone boundary case 2085-03-11 01:59:59} {detroit y2038} {
    clock format 3635132399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.715 {time zone boundary case 2085-03-11 03:00:00} {detroit y2038} {
    clock format 3635132400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.716 {time zone boundary case 2085-03-11 03:00:01} {detroit y2038} {
    clock format 3635132401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.717 {time zone boundary case 2085-11-04 01:59:59} {detroit y2038} {
    clock format 3655691999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.718 {time zone boundary case 2085-11-04 01:00:00} {detroit y2038} {
    clock format 3655692000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.719 {time zone boundary case 2085-11-04 01:00:01} {detroit y2038} {
    clock format 3655692001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.720 {time zone boundary case 2086-03-10 01:59:59} {detroit y2038} {
    clock format 3666581999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.721 {time zone boundary case 2086-03-10 03:00:00} {detroit y2038} {
    clock format 3666582000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.722 {time zone boundary case 2086-03-10 03:00:01} {detroit y2038} {
    clock format 3666582001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.723 {time zone boundary case 2086-11-03 01:59:59} {detroit y2038} {
    clock format 3687141599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.724 {time zone boundary case 2086-11-03 01:00:00} {detroit y2038} {
    clock format 3687141600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.725 {time zone boundary case 2086-11-03 01:00:01} {detroit y2038} {
    clock format 3687141601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.726 {time zone boundary case 2087-03-09 01:59:59} {detroit y2038} {
    clock format 3698031599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.727 {time zone boundary case 2087-03-09 03:00:00} {detroit y2038} {
    clock format 3698031600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.728 {time zone boundary case 2087-03-09 03:00:01} {detroit y2038} {
    clock format 3698031601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.729 {time zone boundary case 2087-11-02 01:59:59} {detroit y2038} {
    clock format 3718591199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.730 {time zone boundary case 2087-11-02 01:00:00} {detroit y2038} {
    clock format 3718591200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.731 {time zone boundary case 2087-11-02 01:00:01} {detroit y2038} {
    clock format 3718591201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.732 {time zone boundary case 2088-03-14 01:59:59} {detroit y2038} {
    clock format 3730085999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.733 {time zone boundary case 2088-03-14 03:00:00} {detroit y2038} {
    clock format 3730086000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.734 {time zone boundary case 2088-03-14 03:00:01} {detroit y2038} {
    clock format 3730086001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.735 {time zone boundary case 2088-11-07 01:59:59} {detroit y2038} {
    clock format 3750645599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.736 {time zone boundary case 2088-11-07 01:00:00} {detroit y2038} {
    clock format 3750645600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.737 {time zone boundary case 2088-11-07 01:00:01} {detroit y2038} {
    clock format 3750645601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.738 {time zone boundary case 2089-03-13 01:59:59} {detroit y2038} {
    clock format 3761535599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.739 {time zone boundary case 2089-03-13 03:00:00} {detroit y2038} {
    clock format 3761535600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.740 {time zone boundary case 2089-03-13 03:00:01} {detroit y2038} {
    clock format 3761535601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.741 {time zone boundary case 2089-11-06 01:59:59} {detroit y2038} {
    clock format 3782095199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.742 {time zone boundary case 2089-11-06 01:00:00} {detroit y2038} {
    clock format 3782095200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.743 {time zone boundary case 2089-11-06 01:00:01} {detroit y2038} {
    clock format 3782095201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.744 {time zone boundary case 2090-03-12 01:59:59} {detroit y2038} {
    clock format 3792985199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.745 {time zone boundary case 2090-03-12 03:00:00} {detroit y2038} {
    clock format 3792985200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.746 {time zone boundary case 2090-03-12 03:00:01} {detroit y2038} {
    clock format 3792985201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.747 {time zone boundary case 2090-11-05 01:59:59} {detroit y2038} {
    clock format 3813544799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.748 {time zone boundary case 2090-11-05 01:00:00} {detroit y2038} {
    clock format 3813544800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.749 {time zone boundary case 2090-11-05 01:00:01} {detroit y2038} {
    clock format 3813544801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.750 {time zone boundary case 2091-03-11 01:59:59} {detroit y2038} {
    clock format 3824434799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.751 {time zone boundary case 2091-03-11 03:00:00} {detroit y2038} {
    clock format 3824434800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.752 {time zone boundary case 2091-03-11 03:00:01} {detroit y2038} {
    clock format 3824434801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.753 {time zone boundary case 2091-11-04 01:59:59} {detroit y2038} {
    clock format 3844994399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.754 {time zone boundary case 2091-11-04 01:00:00} {detroit y2038} {
    clock format 3844994400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.755 {time zone boundary case 2091-11-04 01:00:01} {detroit y2038} {
    clock format 3844994401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.756 {time zone boundary case 2092-03-09 01:59:59} {detroit y2038} {
    clock format 3855884399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.757 {time zone boundary case 2092-03-09 03:00:00} {detroit y2038} {
    clock format 3855884400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.758 {time zone boundary case 2092-03-09 03:00:01} {detroit y2038} {
    clock format 3855884401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.759 {time zone boundary case 2092-11-02 01:59:59} {detroit y2038} {
    clock format 3876443999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.760 {time zone boundary case 2092-11-02 01:00:00} {detroit y2038} {
    clock format 3876444000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.761 {time zone boundary case 2092-11-02 01:00:01} {detroit y2038} {
    clock format 3876444001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.762 {time zone boundary case 2093-03-08 01:59:59} {detroit y2038} {
    clock format 3887333999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.763 {time zone boundary case 2093-03-08 03:00:00} {detroit y2038} {
    clock format 3887334000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.764 {time zone boundary case 2093-03-08 03:00:01} {detroit y2038} {
    clock format 3887334001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.765 {time zone boundary case 2093-11-01 01:59:59} {detroit y2038} {
    clock format 3907893599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.766 {time zone boundary case 2093-11-01 01:00:00} {detroit y2038} {
    clock format 3907893600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.767 {time zone boundary case 2093-11-01 01:00:01} {detroit y2038} {
    clock format 3907893601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.768 {time zone boundary case 2094-03-14 01:59:59} {detroit y2038} {
    clock format 3919388399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.769 {time zone boundary case 2094-03-14 03:00:00} {detroit y2038} {
    clock format 3919388400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.770 {time zone boundary case 2094-03-14 03:00:01} {detroit y2038} {
    clock format 3919388401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.771 {time zone boundary case 2094-11-07 01:59:59} {detroit y2038} {
    clock format 3939947999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.772 {time zone boundary case 2094-11-07 01:00:00} {detroit y2038} {
    clock format 3939948000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.773 {time zone boundary case 2094-11-07 01:00:01} {detroit y2038} {
    clock format 3939948001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.774 {time zone boundary case 2095-03-13 01:59:59} {detroit y2038} {
    clock format 3950837999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.775 {time zone boundary case 2095-03-13 03:00:00} {detroit y2038} {
    clock format 3950838000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.776 {time zone boundary case 2095-03-13 03:00:01} {detroit y2038} {
    clock format 3950838001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.777 {time zone boundary case 2095-11-06 01:59:59} {detroit y2038} {
    clock format 3971397599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.778 {time zone boundary case 2095-11-06 01:00:00} {detroit y2038} {
    clock format 3971397600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.779 {time zone boundary case 2095-11-06 01:00:01} {detroit y2038} {
    clock format 3971397601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.780 {time zone boundary case 2096-03-11 01:59:59} {detroit y2038} {
    clock format 3982287599 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.781 {time zone boundary case 2096-03-11 03:00:00} {detroit y2038} {
    clock format 3982287600 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.782 {time zone boundary case 2096-03-11 03:00:01} {detroit y2038} {
    clock format 3982287601 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.783 {time zone boundary case 2096-11-04 01:59:59} {detroit y2038} {
    clock format 4002847199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.784 {time zone boundary case 2096-11-04 01:00:00} {detroit y2038} {
    clock format 4002847200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.785 {time zone boundary case 2096-11-04 01:00:01} {detroit y2038} {
    clock format 4002847201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.786 {time zone boundary case 2097-03-10 01:59:59} {detroit y2038} {
    clock format 4013737199 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.787 {time zone boundary case 2097-03-10 03:00:00} {detroit y2038} {
    clock format 4013737200 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.788 {time zone boundary case 2097-03-10 03:00:01} {detroit y2038} {
    clock format 4013737201 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.789 {time zone boundary case 2097-11-03 01:59:59} {detroit y2038} {
    clock format 4034296799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.790 {time zone boundary case 2097-11-03 01:00:00} {detroit y2038} {
    clock format 4034296800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.791 {time zone boundary case 2097-11-03 01:00:01} {detroit y2038} {
    clock format 4034296801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.792 {time zone boundary case 2098-03-09 01:59:59} {detroit y2038} {
    clock format 4045186799 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.793 {time zone boundary case 2098-03-09 03:00:00} {detroit y2038} {
    clock format 4045186800 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.794 {time zone boundary case 2098-03-09 03:00:01} {detroit y2038} {
    clock format 4045186801 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.795 {time zone boundary case 2098-11-02 01:59:59} {detroit y2038} {
    clock format 4065746399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.796 {time zone boundary case 2098-11-02 01:00:00} {detroit y2038} {
    clock format 4065746400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.797 {time zone boundary case 2098-11-02 01:00:01} {detroit y2038} {
    clock format 4065746401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
test clock-5.798 {time zone boundary case 2099-03-08 01:59:59} {detroit y2038} {
    clock format 4076636399 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0500 EST}
test clock-5.799 {time zone boundary case 2099-03-08 03:00:00} {detroit y2038} {
    clock format 4076636400 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:00 -0400 EDT}
test clock-5.800 {time zone boundary case 2099-03-08 03:00:01} {detroit y2038} {
    clock format 4076636401 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {03:00:01 -0400 EDT}
test clock-5.801 {time zone boundary case 2099-11-01 01:59:59} {detroit y2038} {
    clock format 4097195999 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:59:59 -0400 EDT}
test clock-5.802 {time zone boundary case 2099-11-01 01:00:00} {detroit y2038} {
    clock format 4097196000 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:00 -0500 EST}
test clock-5.803 {time zone boundary case 2099-11-01 01:00:01} {detroit y2038} {
    clock format 4097196001 -format {%H:%M:%S %z %Z} \
	-timezone :America/Detroit
} {01:00:01 -0500 EST}
# END testcases5

# Test input conversions.

test clock-6.0 {input of seconds} {
    clock scan {-9223372036854775808} -format %s -gmt true
18762
18763
18764
18765
18766
18767
18768
18769
18770
18771
18772
18773
18774
18775
18776
		# ambiguous (expected error):
		set e "input string does not match supplied format"
	    }
	    set s "12 $shm 2001"
	    # scan and format with full month name:
	    catch {clock format \
			[clock scan $s -format "%d %b %Y" -locale en_US_roman -gmt 1] \
	          -format "%d %B %Y" -locale en_US_roman -gmt 1} t
	    # check it corresponds the full form:
	    if {$t ne $e} {
		lappend res "unexpected result converting $s, expected \"$e\", got \"$t\""
	    }
	}
    }
    set res







|







18762
18763
18764
18765
18766
18767
18768
18769
18770
18771
18772
18773
18774
18775
18776
		# ambiguous (expected error):
		set e "input string does not match supplied format"
	    }
	    set s "12 $shm 2001"
	    # scan and format with full month name:
	    catch {clock format \
			[clock scan $s -format "%d %b %Y" -locale en_US_roman -gmt 1] \
		  -format "%d %B %Y" -locale en_US_roman -gmt 1} t
	    # check it corresponds the full form:
	    if {$t ne $e} {
		lappend res "unexpected result converting $s, expected \"$e\", got \"$t\""
	    }
	}
    }
    set res
18799
18800
18801
18802
18803
18804
18805
18806
18807
18808
18809
18810
18811
18812
18813
18814
18815
18816
18817
18818
18819
	 [clock scan "2009-06-30T18:30:00  +02:00" -format "%Y-%m-%dT%H:%M:%S%z" -gmt 1] \
	 [clock scan "2009-06-30T18:30:00Z" -format "%Y-%m-%dT%H:%M:%S%z" -timezone CET] \
	 [clock scan "2009-06-30T18:30:00  Z" -format "%Y-%m-%dT%H:%M:%S%z" -timezone CET]
} {1246379400 1246379400 1246386600 1246386600}

test clock-6.18 {zone token (%z) is optional} {
    list [clock scan "2009-06-30T18:30:00 -01:00" -format "%Y-%m-%dT%H:%M:%S%z" -gmt 1] \
         [clock scan "2009-06-30T18:30:00" -format "%Y-%m-%dT%H:%M:%S%z" -gmt 1] \
	 [clock scan "  2009-06-30T18:30:00  " -format "%Y-%m-%dT%H:%M:%S%z" -gmt 1] \
} {1246390200 1246386600 1246386600}

test clock-6.19 {no token parsing} {
    list [catch { clock scan "%E%O%" -format "%E%O%" }] \
         [catch { clock scan "...%..." -format "...%%..." }]
} {0 0}

test clock-6.20 {special char tokens %n, %t} {
    clock scan "30\t06\t2009\n18\t30" -format "%d%t%m%t%Y%n%H%t%M" -gmt 1
} 1246386600

# Hi, Jeff!







|





|







18799
18800
18801
18802
18803
18804
18805
18806
18807
18808
18809
18810
18811
18812
18813
18814
18815
18816
18817
18818
18819
	 [clock scan "2009-06-30T18:30:00  +02:00" -format "%Y-%m-%dT%H:%M:%S%z" -gmt 1] \
	 [clock scan "2009-06-30T18:30:00Z" -format "%Y-%m-%dT%H:%M:%S%z" -timezone CET] \
	 [clock scan "2009-06-30T18:30:00  Z" -format "%Y-%m-%dT%H:%M:%S%z" -timezone CET]
} {1246379400 1246379400 1246386600 1246386600}

test clock-6.18 {zone token (%z) is optional} {
    list [clock scan "2009-06-30T18:30:00 -01:00" -format "%Y-%m-%dT%H:%M:%S%z" -gmt 1] \
	 [clock scan "2009-06-30T18:30:00" -format "%Y-%m-%dT%H:%M:%S%z" -gmt 1] \
	 [clock scan "  2009-06-30T18:30:00  " -format "%Y-%m-%dT%H:%M:%S%z" -gmt 1] \
} {1246390200 1246386600 1246386600}

test clock-6.19 {no token parsing} {
    list [catch { clock scan "%E%O%" -format "%E%O%" }] \
	 [catch { clock scan "...%..." -format "...%%..." }]
} {0 0}

test clock-6.20 {special char tokens %n, %t} {
    clock scan "30\t06\t2009\n18\t30" -format "%d%t%m%t%Y%n%H%t%M" -gmt 1
} 1246386600

# Hi, Jeff!
18838
18839
18840
18841
18842
18843
18844
18845
18846
18847
18848
18849
18850
18851
18852
18853
18854
18855
18856
18857
18858
18859
18860
18861
18862
18863
18864
18865
18866
18867
18868
18869
	}
	incr i $step
    }
    join $wrong \n
}
test clock-6.21.0 {Stardate 0 day} {
    list [set d [clock format -757382400 -format "%Q" -gmt 1]] \
         [clock scan $d -format "%Q" -gmt 1]
} [list "Stardate 00000.0" -757382400]
test clock-6.21.0.1 {Stardate 0.1 - 1.9 (test negative clock value -> positive Stardate)} {
    _testStarDates -757382400 2 0.1
} {}
test clock-6.21.0.2 {Stardate 10000.1 - 10002.9 (test negative clock value -> positive Stardate)} {
    _testStarDates [clock scan "Stardate 10000.1" -f %Q -g 1] 3 0.1
} {}
test clock-6.21.0.3 {Stardate 80000.1 - 80002.9 (test positive clock value)} {
    _testStarDates [clock scan "Stardate 80001.1" -f %Q -g 1] 3 0.1
} {}
test clock-6.21.1 {Stardate} {
    list [set d [clock format 1482857280 -format "%Q" -gmt 1]] \
         [clock scan $d -format "%Q" -gmt 1]
} [list "Stardate 70986.7" 1482857280]
test clock-6.21.2 {Stardate next time} {
    list [set d [clock format 1482865920 -format "%Q" -gmt 1]] \
         [clock scan $d -format "%Q" -gmt 1]
} [list "Stardate 70986.8" 1482865920]
test clock-6.21.3 {Stardate correct scan over year (leap year, begin, middle and end of the year)} {
    _testStarDates [clock scan "01.01.2016" -f "%d.%m.%Y" -g 1] [expr {366*2}] 1
} {}
rename _testStarDates {}

test clock-6.22.1 {Greedy match} {







|












|



|







18838
18839
18840
18841
18842
18843
18844
18845
18846
18847
18848
18849
18850
18851
18852
18853
18854
18855
18856
18857
18858
18859
18860
18861
18862
18863
18864
18865
18866
18867
18868
18869
	}
	incr i $step
    }
    join $wrong \n
}
test clock-6.21.0 {Stardate 0 day} {
    list [set d [clock format -757382400 -format "%Q" -gmt 1]] \
	 [clock scan $d -format "%Q" -gmt 1]
} [list "Stardate 00000.0" -757382400]
test clock-6.21.0.1 {Stardate 0.1 - 1.9 (test negative clock value -> positive Stardate)} {
    _testStarDates -757382400 2 0.1
} {}
test clock-6.21.0.2 {Stardate 10000.1 - 10002.9 (test negative clock value -> positive Stardate)} {
    _testStarDates [clock scan "Stardate 10000.1" -f %Q -g 1] 3 0.1
} {}
test clock-6.21.0.3 {Stardate 80000.1 - 80002.9 (test positive clock value)} {
    _testStarDates [clock scan "Stardate 80001.1" -f %Q -g 1] 3 0.1
} {}
test clock-6.21.1 {Stardate} {
    list [set d [clock format 1482857280 -format "%Q" -gmt 1]] \
	 [clock scan $d -format "%Q" -gmt 1]
} [list "Stardate 70986.7" 1482857280]
test clock-6.21.2 {Stardate next time} {
    list [set d [clock format 1482865920 -format "%Q" -gmt 1]] \
	 [clock scan $d -format "%Q" -gmt 1]
} [list "Stardate 70986.8" 1482865920]
test clock-6.21.3 {Stardate correct scan over year (leap year, begin, middle and end of the year)} {
    _testStarDates [clock scan "01.01.2016" -f "%d.%m.%Y" -g 1] [expr {366*2}] 1
} {}
rename _testStarDates {}

test clock-6.22.1 {Greedy match} {
26484
26485
26486
26487
26488
26489
26490
26491
26492
26493
26494
26495
26496
26497
26498
26499
26500
26501
26502
26503
26504
26505
26506
26507
26508
26509
26510
26511
26512
26513
26514
26515
26516
26517
26518
26519
26520
26521
26522
26523
26524
26525
26526
26527
26528
26529
26530
26531
26532
26533
26534
26535
26536
26537
26538
26539
26540
26541
26542
26543
26544
26545
26546
26547
26548
26549
26550
26551
26552
26553
26554
26555
26556
26557
26558
26559
26560
26561
26562
26563
26564
26565
26566
26567
26568
26569
26570
26571
26572
26573
26574
26575
26576
26577
26578
26579
26580
26581
26582
26583
26584
26585
26586
26587
26588
26589
26590
26591
26592
26593
26594
26595
26596
26597
26598
26599
26600
26601
26602
26603
26604
26605
26606
26607
26608
26609
26610
26611
26612
26613
26614
26615
26616
26617
26618
26619
26620
26621
26622
26623
26624
26625
26626
26627
26628
26629
26630
26631
26632
26633
26634
26635
26636
26637
26638
26639
26640
26641
26642
26643
26644
26645
26646
26647
26648
26649
26650
26651
26652
26653
26654
26655
26656
26657
26658
26659
26660
26661
26662
26663
26664
26665
26666
26667
26668
26669
26670
26671
26672
26673
26674
26675
26676
26677
26678
26679
26680
26681
26682
26683
26684
26685
26686
26687
26688
26689
26690
26691
26692
26693
26694
26695
26696
26697
26698
26699
26700
26701
26702
26703
26704
26705
26706
26707
26708
26709
26710
26711
26712
26713
26714
26715
26716
26717
26718
26719
26720
26721
26722
26723
26724
26725
26726
26727
26728
26729
26730
26731
26732
26733
26734
26735
26736
26737
26738
26739
26740
26741
26742
26743
26744
26745
26746
26747
26748
26749
26750
26751
26752
26753
26754
26755
26756
26757
26758
26759
26760
26761
26762
26763
26764
26765
26766
26767
26768
26769
26770
26771
26772
26773
26774
26775
26776
26777
26778
26779
26780
26781
26782
26783
26784
26785
26786
26787
26788
26789
26790
26791
26792
26793
26794
26795
26796
26797
26798
26799
26800
26801
26802
26803
26804
26805
26806
26807
26808
26809
26810
26811
26812
26813
26814
26815
26816
26817
26818
26819
26820
26821
26822
26823
26824
26825
26826
26827
26828
26829
26830
26831
26832
26833
26834
26835
26836
26837
26838
26839
26840
26841
26842
26843
26844
26845
26846
26847
26848
26849
26850
26851
26852
26853
26854
26855
26856
26857
26858
26859
26860
26861
26862
26863
26864
26865
26866
26867
26868
26869
26870
26871
26872
26873
26874
26875
26876
26877
26878
26879
26880
26881
26882
26883
26884
26885
26886
26887
26888
26889
26890
26891
26892
26893
26894
26895
26896
26897
26898
26899
26900
26901
26902
26903
26904
26905
26906
26907
26908
26909
26910
26911
26912
26913
26914
26915
26916
26917
26918
26919
26920
26921
26922
26923
26924
26925
26926
26927
26928
26929
26930
26931
26932
26933
26934
26935
26936
26937
26938
26939
26940
26941
26942
26943
26944
26945
26946
26947
26948
26949
26950
26951
26952
26953
26954
26955
26956
26957
26958
26959
26960
26961
26962
26963
26964
26965
26966
26967
26968
26969
26970
26971
26972
26973
26974
26975
26976
26977
26978
26979
26980
26981
26982
26983
26984
26985
26986
26987
26988
26989
26990
26991
26992
26993
26994
26995
26996
26997
26998
26999
27000
27001
27002
27003
27004
27005
27006
27007
27008
27009
27010
27011
27012
27013
27014
27015
27016
27017
27018
27019
27020
27021
27022
27023
27024
27025
27026
27027
27028
27029
27030
27031
27032
27033
27034
27035
27036
27037
27038
27039
27040
27041
27042
27043
27044
27045
27046
27047
27048
27049
27050
27051
27052
27053
27054
27055
27056
27057
27058
27059
27060
27061
27062
27063
27064
27065
27066
27067
27068
27069
27070
27071
27072
27073
27074
27075
27076
27077
27078
27079
27080
27081
27082
27083
27084
27085
27086
27087
27088
27089
27090
27091
27092
27093
27094
27095
27096
27097
27098
27099
27100
27101
27102
27103
27104
27105
27106
27107
27108
27109
27110
27111
27112
27113
27114
27115
27116
27117
27118
27119
27120
27121
27122
27123
27124
27125
27126
27127
27128
27129
27130
27131
27132
27133
27134
27135
27136
27137
27138
27139
27140
27141
27142
27143
27144
27145
27146
27147
27148
27149
27150
27151
27152
27153
27154
27155
27156
27157
27158
27159
27160
27161
27162
27163
27164
27165
27166
27167
27168
27169
27170
27171
27172
27173
27174
27175
27176
27177
27178
27179
27180
27181
27182
27183
27184
27185
27186
27187
27188
27189
27190
27191
27192
27193
27194
27195
27196
27197
27198
27199
27200
27201
27202
27203
27204
27205
27206
27207
27208
27209
27210
27211
27212
27213
27214
27215
27216
27217
27218
27219
27220
27221
27222
27223
27224
27225
27226
27227
27228
27229
27230
27231
27232
27233
27234
27235
27236
27237
27238
27239
27240
27241
27242
27243
27244
27245
27246
27247
27248
27249
27250
27251
27252
27253
27254
27255
27256
27257
27258
27259
27260
27261
27262
27263
27264
27265
27266
27267
27268
27269
27270
27271
27272
27273
27274
27275
27276
27277
27278
27279
27280
27281
27282
27283
27284
27285
27286
27287
27288
27289
27290
27291
27292
27293
27294
27295
27296
27297
27298
27299
27300
27301
27302
27303
27304
27305
27306
27307
27308
27309
27310
27311
27312
27313
27314
27315
27316
27317
27318
27319
27320
27321
27322
27323
27324
27325
27326
27327
27328
27329
27330
27331
27332
27333
27334
27335
27336
27337
27338
27339
27340
27341
27342
27343
27344
27345
27346
27347
27348
27349
27350
27351
27352
27353
27354
27355
27356
27357
27358
27359
27360
27361
27362
27363
27364
27365
27366
27367
27368
27369
27370
27371
27372
27373
27374
27375
27376
27377
27378
27379
27380
27381
27382
27383
27384
27385
27386
27387
27388
27389
27390
27391
27392
27393
27394
27395
27396
27397
27398
27399
27400
27401
27402
27403
27404
27405
27406
27407
27408
27409
27410
27411
27412
27413
27414
27415
27416
27417
27418
27419
27420
27421
27422
27423
27424
27425
27426
27427
27428
27429
27430
27431
27432
27433
27434
27435
27436
27437
27438
27439
27440
27441
27442
27443
27444
27445
27446
27447
27448
27449
27450
27451
27452
27453
27454
27455
27456
27457
27458
27459
27460
27461
27462
27463
27464
27465
27466
27467
27468
27469
27470
27471
27472
27473
27474
27475
27476
27477
27478
27479
27480
27481
27482
27483
27484
27485
27486
27487
27488
27489
27490
27491
27492
27493
27494
27495
27496
27497
27498
27499
27500
27501
27502
27503
27504
27505
27506
27507
27508
27509
27510
27511
27512
27513
27514
27515
27516
27517
27518
27519
27520
27521
27522
27523
27524
27525
27526
27527
27528
27529
27530
27531
27532
27533
27534
27535
27536
27537
27538
27539
27540
27541
27542
27543
27544
27545
27546
27547
27548
27549
27550
27551
27552
27553
27554
27555
27556
27557
27558
27559
27560
27561
27562
27563
27564
27565
27566
27567
27568
27569
27570
27571
27572
27573
27574
27575
27576
27577
27578
27579
27580
27581
27582
27583
27584
27585
27586
27587
27588
27589
27590
27591
27592
27593
27594
27595
27596
27597
27598
27599
27600
27601
27602
27603
27604
27605
27606
27607
27608
27609
27610
27611
27612
27613
27614
27615
27616
27617
27618
27619
27620
27621
27622
27623
27624
27625
27626
27627
27628
27629
27630
27631
27632
27633
27634
27635
27636
27637
27638
27639
27640
27641
27642
27643
27644
27645
27646
27647
27648
27649
27650
27651
27652
27653
27654
27655
27656
27657
27658
27659
27660
27661
27662
27663
27664
27665
27666
27667
27668
27669
27670
27671
27672
27673
27674
27675
27676
27677
27678
27679
27680
27681
27682
27683
27684
27685
27686
27687
27688
27689
27690
27691
27692
27693
27694
27695
27696
27697
27698
27699
27700
27701
27702
27703
27704
27705
27706
27707
27708
27709
27710
27711
27712
27713
27714
27715
27716
27717
27718
27719
27720
27721
27722
27723
27724
27725
27726
27727
27728
27729
27730
27731
27732
27733
27734
27735
27736
27737
27738
27739
27740
27741
27742
27743
27744
27745
27746
27747
27748
27749
27750
27751
27752
27753
27754
27755
27756
27757
27758
27759
27760
27761
27762
27763
27764
27765
27766
27767
27768
27769
27770
27771
27772
27773
27774
27775
27776
27777
27778
27779
27780
27781
27782
27783
27784
27785
27786
27787
27788
27789
27790
27791
27792
27793
27794
27795
27796
27797
27798
27799
27800
27801
27802
27803
27804
27805
27806
27807
27808
27809
27810
27811
27812
27813
27814
27815
27816
27817
27818
27819
27820
27821
27822
27823
27824
27825
27826
27827
27828
27829
27830
27831
27832
27833
27834
27835
27836
27837
27838
27839
27840
27841
27842
27843
27844
27845
27846
27847
27848
27849
27850
27851
27852
27853
27854
27855
27856
27857
27858
27859
27860
27861
27862
27863
27864
27865
27866
27867
27868
27869
27870
27871
27872
27873
27874
27875
27876
27877
27878
27879
27880
27881
27882
27883
27884
27885
27886
27887
27888
27889
27890
27891
27892
27893
27894
27895
27896
27897
27898
27899
27900
27901
27902
27903
27904
27905
27906
27907
27908
27909
27910
27911
27912
27913
27914
27915
27916
27917
27918
27919
27920
27921
27922
27923
27924
27925
27926
27927
27928
27929
27930
27931
27932
27933
27934
27935
27936
27937
27938
27939
27940
27941
27942
27943
27944
27945
27946
27947
27948
27949
27950
27951
27952
27953
27954
27955
27956
27957
27958
27959
27960
27961
27962
27963
27964
27965
27966
27967
27968
27969
27970
27971
27972
27973
27974
27975
27976
27977
27978
27979
27980
27981
27982
27983
27984
27985
27986
27987
27988
27989
27990
27991
27992
27993
27994
27995
27996
27997
27998
27999
28000
28001
28002
28003
28004
28005
28006
28007
28008
28009
28010
28011
28012
28013
28014
28015
28016
28017
28018
28019
28020
28021
28022
28023
28024
28025
28026
28027
28028
28029
28030
28031
28032
28033
28034
28035
28036
28037
28038
28039
28040
28041
28042
28043
28044
28045
28046
28047
28048
28049
28050
28051
28052
28053
28054
28055
28056
28057
28058
28059
28060
28061
28062
28063
28064
28065
28066
28067
28068
28069
28070
28071
28072
28073
28074
28075
28076
28077
28078
28079
28080
28081
28082
28083
28084
28085
28086
28087
28088
28089
28090
28091
28092
28093
28094
28095
28096
28097
28098
28099
28100
28101
28102
28103
28104
28105
28106
28107
28108
28109
28110
28111
28112
28113
28114
28115
28116
28117
28118
28119
28120
28121
28122
28123
28124
28125
28126
28127
28128
28129
28130
28131
28132
28133
28134
28135
28136
28137
28138
28139
28140
28141
28142
28143
28144
28145
28146
28147
28148
28149
28150
28151
28152
28153
28154
28155
28156
28157
28158
28159
28160
28161
28162
28163
28164
28165
28166
28167
28168
28169
28170
28171
28172
28173
28174
28175
28176
28177
28178
28179
28180
28181
28182
28183
28184
28185
28186
28187
28188
28189
28190
28191
28192
28193
28194
28195
28196
28197
28198
28199
28200
28201
28202
28203
28204
28205
28206
28207
28208
28209
28210
28211
28212
28213
28214
28215
28216
28217
28218
28219
28220
28221
28222
28223
28224
28225
28226
28227
28228
28229
28230
28231
28232
28233
28234
28235
28236
28237
28238
28239
28240
28241
28242
28243
28244
28245
28246
28247
28248
28249
28250
28251
28252
28253
28254
28255
28256
28257
28258
28259
28260
28261
28262
28263
28264
28265
28266
28267
28268
28269
28270
28271
28272
28273
28274
28275
28276
28277
28278
28279
28280
28281
28282
28283
28284
28285
28286
28287
28288
28289
28290
28291
28292
28293
28294
28295
28296
28297
28298
28299
28300
28301
28302
28303
28304
28305
28306
28307
28308
28309
28310
28311
28312
28313
28314
28315
28316
28317
28318
28319
28320
28321
28322
28323
28324
28325
28326
28327
28328
28329
28330
28331
28332
28333
28334
28335
28336
28337
28338
28339
28340
28341
28342
28343
28344
28345
28346
28347
28348
28349
28350
28351
28352
28353
28354
28355
28356
28357
28358
28359
28360
28361
28362
28363
28364
28365
28366
28367
28368
28369
28370
28371
28372
28373
28374
28375
28376
28377
28378
28379
28380
28381
28382
28383
28384
28385
28386
28387
28388
28389
28390
28391
28392
28393
28394
28395
28396
28397
28398
28399
28400
28401
28402
28403
28404
28405
28406
28407
28408
28409
28410
28411
28412
28413
28414
28415
28416
28417
28418
28419
28420
28421
28422
28423
28424
28425
28426
28427
28428
28429
28430
28431
28432
28433
28434
28435
28436
28437
28438
28439
28440
28441
28442
28443
28444
28445
28446
28447
28448
28449
28450
28451
28452
28453
28454
28455
28456
28457
28458
28459
28460
28461
28462
28463
28464
28465
28466
28467
28468
28469
28470
28471
28472
28473
28474
28475
28476
28477
28478
28479
28480
28481
28482
28483
28484
28485
28486
28487
28488
28489
28490
28491
28492
28493
28494
28495
28496
28497
28498
28499
28500
28501
28502
28503
28504
28505
28506
28507
28508
28509
28510
28511
28512
28513
28514
28515
28516
28517
28518
28519
28520
28521
28522
28523
28524
28525
28526
28527
28528
28529
28530
28531
28532
28533
28534
28535
28536
28537
28538
28539
28540
28541
28542
28543
28544
28545
28546
28547
28548
28549
28550
28551
28552
28553
28554
28555
28556
28557
28558
28559
28560
28561
28562
28563
28564
28565
28566
28567
28568
28569
28570
28571
28572
28573
28574
28575
28576
28577
28578
28579
28580
28581
28582
28583
28584
28585
28586
28587
28588
28589
28590
28591
28592
28593
28594
28595
28596
28597
28598
28599
28600
28601
28602
28603
28604
28605
28606
28607
28608
28609
28610
28611
28612
28613
28614
28615
28616
28617
28618
28619
28620
28621
28622
28623
28624
28625
28626
28627
28628
28629
28630
28631
28632
28633
28634
28635
28636
28637
28638
28639
28640
28641
28642
28643
28644
28645
28646
28647
28648
28649
28650
28651
28652
28653
28654
28655
28656
28657
28658
28659
28660
28661
28662
28663
28664
28665
28666
28667
28668
28669
28670
28671
28672
28673
28674
28675
28676
28677
28678
28679
28680
28681
28682
28683
28684
28685
28686
28687
28688
28689
28690
28691
28692
28693
28694
28695
28696
28697
28698
28699
28700
28701
28702
28703
28704
28705
28706
28707
28708
28709
28710
28711
28712
28713
28714
28715
28716
28717
28718
28719
28720
28721
28722
28723
28724
28725
28726
28727
28728
28729
28730
28731
28732
28733
28734
28735
28736
28737
28738
28739
28740
28741
28742
28743
28744
28745
28746
28747
28748
28749
28750
28751
28752
28753
28754
28755
28756
28757
28758
28759
28760
28761
28762
28763
28764
28765
28766
28767
28768
28769
28770
28771
28772
28773
28774
28775
28776
28777
28778
28779
28780
28781
28782
28783
28784
28785
28786
28787
28788
28789
28790
28791
28792
28793
28794
28795
28796
28797
28798
28799
28800
28801
28802
28803
28804
28805
28806
28807
28808
28809
28810
28811
28812
28813
28814
28815
28816
28817
28818
28819
28820
28821
28822
28823
28824
28825
28826
28827
28828
28829
28830
28831
28832
28833
28834
28835
28836
28837
28838
28839
28840
28841
28842
28843
28844
28845
28846
28847
28848
28849
28850
28851
28852
28853
28854
28855
28856
28857
28858
28859
28860
28861
28862
28863
28864
28865
28866
28867
28868
28869
28870
28871
28872
28873
28874
28875
28876
28877
28878
28879
28880
28881
28882
28883
28884
28885
28886
28887
28888
28889
28890
28891
28892
28893
28894
28895
28896
28897
28898
28899
28900
28901
28902
28903
28904
28905
28906
28907
28908
28909
28910
28911
28912
28913
28914
28915
28916
28917
28918
28919
28920
28921
28922
28923
28924
28925
28926
28927
28928
28929
28930
28931
28932
28933
28934
28935
28936
28937
28938
28939
28940
28941
28942
28943
28944
28945
28946
28947
28948
28949
28950
28951
28952
28953
28954
28955
28956
28957
28958
28959
28960
28961
28962
28963
28964
28965
28966
28967
28968
28969
28970
28971
28972
28973
28974
28975
28976
28977
28978
28979
28980
28981
28982
28983
28984
28985
28986
28987
28988
28989
28990
28991
28992
28993
28994
28995
28996
28997
28998
28999
29000
29001
29002
29003
29004
29005
29006
29007
29008
29009
29010
29011
29012
29013
29014
29015
29016
29017
29018
29019
29020
29021
29022
29023
29024
29025
29026
29027
29028
29029
29030
29031
29032
29033
29034
29035
29036
29037
29038
29039
29040
29041
29042
29043
29044
29045
29046
29047
29048
29049
29050
29051
29052
29053
29054
29055
29056
29057
29058
29059
29060
29061
29062
29063
29064
29065
29066
29067
29068
29069
29070
29071
29072
29073
29074
29075
29076
29077
29078
29079
29080
29081
29082
29083
29084
29085
29086
29087
29088
29089
29090
29091
29092
29093
29094
29095
29096
29097
29098
29099
29100
29101
29102
29103
29104
29105
29106
29107
29108
29109
29110
29111
29112
29113
29114
29115
29116
29117
29118
29119
29120
29121
29122
29123
29124
29125
29126
29127
29128
29129
29130
29131
29132
29133
29134
29135
29136
29137
29138
29139
29140
29141
29142
29143
29144
29145
29146
29147
29148
29149
29150
29151
29152
29153
29154
29155
29156
29157
29158
29159
29160
29161
29162
29163
29164
29165
29166
29167
29168
29169
29170
29171
29172
29173
29174
29175
29176
29177
29178
29179
29180
29181
29182
29183
29184
29185
29186
29187
29188
29189
29190
29191
29192
29193
29194
29195
29196
29197
29198
29199
29200
29201
29202
29203
29204
29205
29206
29207
29208
29209
29210
29211
29212
29213
29214
29215
29216
29217
29218
29219
29220
29221
29222
29223
29224
29225
29226
29227
29228
29229
29230
29231
29232
29233
29234
29235
29236
29237
29238
29239
29240
29241
29242
29243
29244
29245
29246
29247
29248
29249
29250
29251
29252
29253
29254
29255
29256
29257
29258
29259
29260
29261
29262
29263
29264
29265
29266
29267
29268
29269
29270
29271
29272
29273
29274
29275
29276
29277
29278
29279
29280
29281
29282
29283
29284
29285
29286
29287
29288
29289
29290
29291
29292
29293
29294
29295
29296
29297
29298
29299
29300
29301
29302
29303
29304
29305
29306
29307
29308
29309
29310
29311
29312
29313
29314
29315
29316
29317
29318
29319
29320
29321
29322
29323
29324
29325
29326
29327
29328
29329
29330
29331
29332
29333
29334
29335
29336
29337
29338
29339
29340
29341
29342
29343
29344
29345
29346
29347
29348
29349
29350
29351
29352
29353
29354
29355
29356
29357
29358
29359
29360
29361
29362
29363
29364
29365
29366
29367
29368
29369
29370
29371
29372
29373
29374
29375
29376
29377
29378
29379
29380
29381
29382
29383
29384
29385
29386
29387
29388
29389
29390
29391
29392
29393
29394
29395
29396
29397
29398
29399
29400
29401
29402
29403
29404
29405
29406
29407
29408
29409
29410
29411
29412
29413
29414
29415
29416
29417
29418
29419
29420
29421
29422
29423
29424
29425
29426
29427
29428
29429
29430
29431
29432
29433
29434
29435
29436
29437
29438
29439
29440
29441
29442
29443
29444
29445
29446
29447
29448
29449
29450
29451
29452
29453
29454
29455
29456
29457
29458
29459
29460
29461
29462
29463
29464
29465
29466
29467
29468
29469
29470
29471
29472
29473
29474
29475
29476
29477
29478
29479
29480
29481
29482
29483
29484
29485
29486
29487
29488
29489
29490
29491
29492
29493
29494
29495
29496
29497
29498
29499
29500
29501
29502
29503
29504
29505
29506
29507
29508
29509
29510
29511
29512
29513
29514
29515
29516
29517
29518
29519
29520
29521
29522
29523
29524
29525
29526
29527
29528
29529
29530
29531
29532
29533
29534
29535
29536
29537
29538
29539
29540
29541
29542
29543
29544
29545
29546
29547
29548
29549
29550
29551
29552
29553
29554
29555
29556
29557
29558
29559
29560
29561
29562
29563
29564
29565
29566
29567
29568
29569
29570
29571
29572
29573
29574
29575
29576
29577
29578
29579
29580
29581
29582
29583
29584
29585
29586
29587
29588
29589
29590
29591
29592
29593
29594
29595
29596
29597
29598
29599
29600
29601
29602
29603
29604
29605
29606
29607
29608
29609
29610
29611
29612
29613
29614
29615
29616
29617
29618
29619
29620
29621
29622
29623
29624
29625
29626
29627
29628
29629
29630
29631
29632
29633
29634
29635
29636
29637
29638
29639
29640
29641
29642
29643
29644
29645
29646
29647
29648
29649
29650
29651
29652
29653
29654
29655
29656
29657
29658
29659
29660
29661
29662
29663
29664
29665
29666
29667
29668
29669
29670
29671
29672
29673
29674
29675
29676
29677
29678
29679
29680
29681
29682
29683
29684
29685
29686
29687
29688
29689
29690
29691
29692
29693
29694
29695
29696
29697
29698
29699
29700
29701
29702
29703
29704
29705
29706
29707
29708
29709
29710
29711
29712
29713
29714
29715
29716
29717
29718
29719
29720
29721
29722
29723
29724
29725
29726
29727
29728
29729
29730
29731
29732
29733
29734
29735
29736
29737
29738
29739
29740
29741
29742
29743
29744
29745
29746
29747
29748
29749
29750
29751
29752
29753
29754
29755
29756
29757
29758
29759
29760
29761
29762
29763
29764
29765
29766
29767
29768
29769
29770
29771
29772
29773
29774
29775
29776
29777
29778
29779
29780
29781
29782
29783
29784
29785
29786
29787
29788
29789
29790
29791
29792
29793
29794
29795
29796
29797
29798
29799
29800
29801
29802
29803
29804
29805
29806
29807
29808
29809
29810
29811
29812
29813
29814
29815
29816
29817
29818
29819
29820
29821
29822
29823
29824
29825
29826
29827
29828
29829
29830
29831
29832
29833
29834
29835
29836
29837
29838
29839
29840
29841
29842
29843
29844
29845
29846
29847
29848
29849
29850
29851
29852
29853
29854
29855
29856
29857
29858
29859
29860
29861
29862
29863
29864
29865
29866
29867
29868
29869
29870
29871
29872
29873
29874
29875
29876
29877
29878
29879
29880
29881
29882
29883
29884
29885
29886
29887
29888
29889
29890
29891
29892
29893
29894
29895
29896
29897
29898
29899
29900
29901
29902
29903
29904
29905
29906
29907
29908
29909
29910
29911
29912
29913
29914
29915
29916
29917
29918
29919
29920
29921
29922
29923
29924
29925
29926
29927
29928
29929
29930
29931
29932
29933
29934
29935
29936
29937
29938
29939
29940
29941
29942
29943
29944
29945
29946
29947
29948
29949
29950
29951
29952
29953
29954
29955
29956
29957
29958
29959
29960
29961
29962
29963
29964
29965
29966
29967
29968
29969
29970
29971
29972
29973
29974
29975
29976
29977
29978
29979
29980
29981
29982
29983
29984
29985
29986
29987
29988
29989
29990
29991
29992
29993
29994
29995
29996
29997
29998
29999
30000
30001
30002
30003
30004
30005
30006
30007
30008
30009
30010
30011
30012
30013
30014
30015
30016
30017
30018
30019
30020
30021
30022
30023
30024
30025
30026
30027
30028
30029
30030
30031
30032
30033
30034
30035
30036
30037
30038
30039
30040
30041
30042
30043
30044
30045
30046
30047
30048
30049
30050
30051
30052
30053
30054
30055
30056
30057
30058
30059
30060
30061
30062
30063
30064
30065
30066
30067
30068
30069
30070
30071
30072
30073
30074
30075
30076
30077
30078
30079
30080
30081
30082
30083
30084
30085
30086
30087
30088
30089
30090
30091
30092
30093
30094
30095
30096
30097
30098
30099
30100
30101
30102
30103
30104
30105
30106
30107
30108
30109
30110
30111
30112
30113
30114
30115
30116
30117
30118
30119
30120
30121
30122
30123
30124
30125
30126
30127
30128
30129
30130
30131
30132
30133
30134
30135
30136
30137
30138
30139
30140
30141
30142
30143
30144
30145
30146
30147
30148
30149
30150
30151
30152
30153
30154
30155
30156
30157
30158
30159
30160
30161
30162
30163
30164
30165
30166
30167
30168
30169
30170
30171
30172
30173
30174
30175
30176
30177
30178
30179
30180
30181
30182
30183
30184
30185
30186
30187
30188
30189
30190
30191
30192
30193
30194
30195
30196
30197
30198
30199
30200
30201
30202
30203
30204
30205
30206
30207
30208
30209
30210
30211
30212
30213
30214
30215
30216
30217
30218
30219
30220
30221
30222
30223
30224
30225
30226
30227
30228
30229
30230
30231
30232
30233
30234
30235
30236
30237
30238
30239
30240
30241
30242
30243
30244
30245
30246
30247
30248
30249
30250
30251
30252
30253
30254
30255
30256
30257
30258
30259
30260
30261
30262
30263
30264
30265
30266
30267
30268
30269
30270
30271
30272
30273
30274
30275
30276
30277
30278
30279
30280
30281
30282
30283
30284
30285
30286
30287
30288
30289
30290
30291
30292
30293
30294
30295
30296
30297
30298
30299
30300
30301
30302
30303
30304
30305
30306
30307
30308
30309
30310
30311
30312
30313
30314
30315
30316
30317
30318
30319
30320
30321
30322
30323
30324
30325
30326
30327
30328
30329
30330
30331
30332
30333
30334
30335
30336
30337
30338
30339
30340
30341
30342
30343
30344
30345
30346
30347
30348
30349
30350
30351
30352
30353
30354
30355
30356
30357
30358
30359
30360
30361
30362
30363
30364
30365
30366
30367
30368
30369
30370
30371
30372
30373
30374
30375
30376
30377
30378
30379
30380
30381
30382
30383
30384
30385
30386
30387
30388
30389
30390
30391
30392
30393
30394
30395
30396
30397
30398
30399
30400
30401
30402
30403
30404
30405
30406
30407
30408
30409
30410
30411
30412
30413
30414
30415
30416
30417
30418
30419
30420
30421
30422
30423
30424
30425
30426
30427
30428
30429
30430
30431
30432
30433
30434
30435
30436
30437
30438
30439
30440
30441
30442
30443
30444
30445
30446
30447
30448
30449
30450
30451
30452
30453
30454
30455
30456
30457
30458
30459
30460
30461
30462
30463
30464
30465
30466
30467
30468
30469
30470
30471
30472
30473
30474
30475
30476
30477
30478
30479
30480
30481
30482
30483
30484
30485
30486
30487
30488
30489
30490
30491
30492
30493
30494
30495
30496
30497
30498
30499
30500
30501
30502
30503
30504
30505
30506
30507
30508
30509
30510
30511
30512
30513
30514
30515
30516
30517
30518
30519
30520
30521
30522
30523
30524
30525
30526
30527
30528
30529
30530
30531
30532
30533
30534
30535
30536
30537
30538
30539
30540
30541
30542
30543
30544
30545
30546
30547
30548
30549
30550
30551
30552
30553
30554
30555
30556
30557
30558
30559
30560
30561
30562
30563
30564
30565
30566
30567
30568
30569
30570
30571
30572
30573
30574
30575
30576
30577
30578
30579
30580
30581
30582
30583
30584
30585
30586
30587
30588
30589
30590
30591
30592
30593
30594
30595
30596
30597
30598
30599
30600
30601
30602
30603
30604
30605
30606
30607
30608
30609
30610
30611
30612
30613
30614
30615
30616
30617
30618
30619
30620
30621
30622
30623
30624
30625
30626
30627
30628
30629
30630
30631
30632
30633
30634
30635
30636
30637
30638
30639
30640
30641
30642
30643
30644
30645
30646
30647
30648
30649
30650
30651
30652
30653
30654
30655
30656
30657
30658
30659
30660
30661
30662
30663
30664
30665
30666
30667
30668
30669
30670
30671
30672
30673
30674
30675
30676
30677
30678
30679
30680
30681
30682
30683
30684
30685
30686
30687
30688
30689
30690
30691
30692
30693
30694
30695
30696
30697
30698
30699
30700
30701
30702
30703
30704
30705
30706
30707
30708
30709
30710
30711
30712
30713
30714
30715
30716
30717
30718
30719
30720
30721
30722
30723
30724
30725
30726
30727
30728
30729
30730
30731
30732
30733
30734
30735
30736
30737
30738
30739
30740
30741
30742
30743
30744
30745
30746
30747
30748
30749
30750
30751
30752
30753
30754
30755
30756
30757
30758
30759
30760
30761
30762
30763
30764
30765
30766
30767
30768
30769
30770
30771
30772
30773
30774
30775
30776
30777
30778
30779
30780
30781
30782
30783
30784
30785
30786
30787
30788
30789
30790
30791
30792
30793
30794
30795
30796
30797
30798
30799
30800
30801
30802
30803
30804
30805
30806
30807
30808
30809
30810
30811
30812
30813
30814
30815
30816
30817
30818
30819
30820
30821
30822
30823
30824
30825
30826
30827
30828
30829
30830
30831
30832
30833
30834
30835
30836
30837
30838
30839
30840
30841
30842
30843
30844
30845
30846
30847
30848
30849
30850
30851
30852
30853
30854
30855
30856
30857
30858
30859
30860
30861
30862
30863
30864
30865
30866
30867
30868
30869
30870
30871
30872
30873
30874
30875
30876
30877
30878
30879
30880
30881
30882
30883
30884
30885
30886
30887
30888
30889
30890
30891
30892
30893
30894
30895
30896
30897
30898
30899
30900
30901
30902
30903
30904
30905
30906
30907
30908
30909
30910
30911
30912
30913
30914
30915
30916
30917
30918
30919
30920
30921
30922
30923
30924
30925
30926
30927
30928
30929
30930
30931
30932
30933
30934
30935
30936
30937
30938
30939
30940
30941
30942
30943
30944
30945
30946
30947
30948
30949
30950
30951
30952
30953
30954
30955
30956
30957
30958
30959
30960
30961
30962
30963
30964
30965
30966
30967
30968
30969
30970
30971
30972
30973
30974
30975
30976
30977
30978
30979
30980
30981
30982
30983
30984
30985
30986
30987
30988
30989
30990
30991
30992
30993
30994
30995
30996
30997
30998
30999
31000
31001
31002
31003
31004
31005
31006
31007
31008
31009
31010
31011
31012
31013
31014
31015
31016
31017
31018
31019
31020
31021
31022
31023
31024
31025
31026
31027
31028
31029
31030
31031
31032
31033
31034
31035
31036
31037
31038
31039
31040
31041
31042
31043
31044
31045
31046
31047
31048
31049
31050
31051
31052
31053
31054
31055
31056
31057
31058
31059
31060
31061
31062
31063
31064
31065
31066
31067
31068
31069
31070
31071
31072
31073
31074
31075
31076
31077
31078
31079
31080
31081
31082
31083
31084
31085
31086
31087
31088
31089
31090
31091
31092
31093
31094
31095
31096
31097
31098
31099
31100
31101
31102
31103
31104
31105
31106
31107
31108
31109
31110
31111
31112
31113
31114
31115
31116
31117
31118
31119
31120
31121
31122
31123
31124
31125
31126
31127
31128
31129
31130
31131
31132
31133
31134
31135
31136
31137
31138
31139
31140
31141
31142
31143
31144
31145
31146
31147
31148
31149
31150
31151
31152
31153
31154
31155
31156
31157
31158
31159
31160
31161
31162
31163
31164
31165
31166
31167
31168
31169
31170
31171
31172
31173
31174
31175
31176
31177
31178
31179
31180
31181
31182
31183
31184
31185
31186
31187
31188
31189
31190
31191
31192
31193
31194
31195
31196
31197
31198
31199
31200
31201
31202
31203
31204
31205
31206
31207
31208
31209
31210
31211
31212
31213
31214
31215
31216
31217
31218
31219
31220
31221
31222
31223
31224
31225
31226
31227
31228
31229
31230
31231
31232
31233
31234
31235
31236
31237
31238
31239
31240
31241
31242
31243
31244
31245
31246
31247
31248
31249
31250
31251
31252
31253
31254
31255
31256
31257
31258
31259
31260
31261
31262
31263
31264
31265
31266
31267
31268
31269
31270
31271
31272
31273
31274
31275
31276
31277
31278
31279
31280
31281
31282
31283
31284
31285
31286
31287
31288
31289
31290
31291
31292
31293
31294
31295
31296
31297
31298
31299
31300
31301
31302
31303
31304
31305
31306
31307
31308
31309
31310
31311
31312
31313
31314
31315
31316
31317
31318
31319
31320
31321
31322
31323
31324
31325
31326
31327
31328
31329
31330
31331
31332
31333
31334
31335
31336
31337
31338
31339
31340
31341
31342
31343
31344
31345
31346
31347
31348
31349
31350
31351
31352
31353
31354
31355
31356
31357
31358
31359
31360
31361
31362
31363
31364
31365
31366
31367
31368
31369
31370
31371
31372
31373
31374
31375
31376
31377
31378
31379
31380
31381
31382
31383
31384
31385
31386
31387
31388
31389
31390
31391
31392
31393
31394
31395
31396
31397
31398
31399
31400
31401
31402
31403
31404
31405
31406
31407
31408
31409
31410
31411
31412
31413
31414
31415
31416
31417
31418
31419
31420
31421
31422
31423
31424
31425
31426
31427
31428
31429
31430
31431
31432
31433
31434
31435
31436
31437
31438
31439
31440
31441
31442
31443
31444
31445
31446
31447
31448
31449
31450
31451
31452
31453
31454
31455
31456
31457
31458
31459
31460
31461
31462
31463
31464
31465
31466
31467
31468
31469
31470
31471
31472
31473
31474
31475
31476
31477
31478
31479
31480
31481
31482
31483
31484
31485
31486
31487
31488
31489
31490
31491
31492
31493
31494
31495
31496
31497
31498
31499
31500
31501
31502
31503
31504
31505
31506
31507
31508
31509
31510
31511
31512
31513
31514
31515
31516
31517
31518
31519
31520
31521
31522
31523
31524
31525
31526
31527
31528
31529
31530
31531
31532
31533
31534
31535
31536
31537
31538
31539
31540
31541
31542
31543
31544
31545
31546
31547
31548
31549
31550
31551
31552
31553
31554
31555
31556
31557
31558
31559
31560
31561
31562
31563
31564
31565
31566
31567
31568
31569
31570
31571
31572
31573
31574
31575
31576
31577
31578
31579
31580
31581
31582
31583
31584
31585
31586
31587
31588
31589
31590
31591
31592
31593
31594
31595
31596
31597
31598
31599
31600
31601
31602
31603
31604
31605
31606
31607
31608
31609
31610
31611
31612
31613
31614
31615
31616
31617
31618
31619
31620
31621
31622
31623
31624
31625
31626
31627
31628
31629
31630
31631
31632
31633
31634
31635
31636
31637
31638
31639
31640
31641
31642
31643
31644
31645
31646
31647
31648
31649
31650
31651
31652
31653
31654
31655
31656
31657
31658
31659
31660
31661
31662
31663
31664
31665
31666
31667
31668
31669
31670
31671
31672
31673
31674
31675
31676
31677
31678
31679
31680
31681
31682
31683
31684
31685
31686
31687
31688
31689
31690
31691
31692
31693
31694
31695
31696
31697
31698
31699
31700
31701
31702
31703
31704
31705
31706
31707
31708
31709
31710
31711
31712
31713
31714
31715
31716
31717
31718
31719
31720
31721
31722
31723
31724
31725
31726
31727
31728
31729
31730
31731
31732
31733
31734
31735
31736
31737
31738
31739
31740
31741
31742
31743
31744
31745
31746
31747
31748
31749
31750
31751
31752
31753
31754
31755
31756
31757
31758
31759
31760
31761
31762
31763
31764
31765
31766
31767
31768
31769
31770
31771
31772
31773
31774
31775
31776
31777
31778
31779
31780
31781
31782
31783
31784
31785
31786
31787
31788
31789
31790
31791
31792
31793
31794
31795
31796
31797
31798
31799
31800
31801
31802
31803
31804
31805
31806
31807
31808
31809
31810
31811
31812
31813
31814
31815
31816
31817
31818
31819
31820
31821
31822
31823
31824
31825
31826
31827
31828
31829
31830
31831
31832
31833
31834
31835
31836
31837
31838
31839
31840
31841
31842
31843
31844
31845
31846
31847
31848
31849
31850
31851
31852
31853
31854
31855
31856
31857
31858
31859
31860
31861
31862
31863
31864
31865
31866
31867
31868
31869
31870
31871
31872
31873
31874
31875
31876
31877
31878
31879
31880
31881
31882
31883
31884
31885
31886
31887
31888
31889
31890
31891
31892
31893
31894
31895
31896
31897
31898
31899
31900
31901
31902
31903
31904
31905
31906
31907
31908
31909
31910
31911
31912
31913
31914
31915
31916
31917
31918
31919
31920
31921
31922
31923
31924
31925
31926
31927
31928
31929
31930
31931
31932
31933
31934
31935
31936
31937
31938
31939
31940
31941
31942
31943
31944
31945
31946
31947
31948
31949
31950
31951
31952
31953
31954
31955
31956
31957
31958
31959
31960
31961
31962
31963
31964
31965
31966
31967
31968
31969
31970
31971
31972
31973
31974
31975
31976
31977
31978
31979
31980
31981
31982
31983
31984
31985
31986
31987
31988
31989
31990
31991
31992
31993
31994
31995
31996
31997
31998
31999
32000
32001
32002
32003
32004
32005
32006
32007
32008
32009
32010
32011
32012
32013
32014
32015
32016
32017
32018
32019
32020
32021
32022
32023
32024
32025
32026
32027
32028
32029
32030
32031
32032
32033
32034
32035
32036
32037
32038
32039
32040
32041
32042
32043
32044
32045
32046
32047
32048
32049
32050
32051
32052
32053
32054
32055
32056
32057
32058
32059
32060
32061
32062
32063
32064
32065
32066
32067
32068
32069
32070
32071
32072
32073
32074
32075
32076
32077
32078
32079
32080
32081
32082
32083
32084
32085
32086
32087
32088
32089
32090
32091
32092
32093
32094
32095
32096
32097
32098
32099
32100
32101
32102
32103
32104
32105
32106
32107
32108
32109
32110
32111
32112
32113
32114
32115
32116
32117
32118
32119
32120
32121
32122
32123
32124
32125
32126
32127
32128
32129
32130
32131
32132
32133
32134
32135
32136
32137
32138
32139
32140
32141
32142
32143
32144
32145
32146
32147
32148
32149
32150
32151
32152
32153
32154
32155
32156
32157
32158
32159
32160
32161
32162
32163
32164
32165
32166
32167
32168
32169
32170
32171
32172
32173
32174
32175
32176
32177
32178
32179
32180
32181
32182
32183
32184
32185
32186
32187
32188
32189
32190
32191
32192
32193
32194
32195
32196
32197
32198
32199
32200
32201
32202
32203
32204
32205
32206
32207
32208
32209
32210
32211
32212
32213
32214
32215
32216
32217
32218
32219
32220
32221
32222
32223
32224
32225
32226
32227
32228
32229
32230
32231
32232
32233
32234
32235
32236
32237
32238
32239
32240
32241
32242
32243
32244
32245
32246
32247
32248
32249
32250
32251
32252
32253
32254
32255
32256
32257
32258
32259
32260
32261
32262
32263
32264
32265
32266
32267
32268
32269
32270
32271
32272
32273
32274
32275
32276
32277
32278
32279
32280
32281
32282
32283
32284
32285
32286
32287
32288
32289
32290
32291
32292
32293
32294
32295
32296
32297
32298
32299
32300
32301
32302
32303
32304
32305
32306
32307
32308
32309
32310
32311
32312
32313
32314
32315
32316
32317
32318
32319
32320
32321
32322
32323
32324
32325
32326
32327
32328
32329
32330
32331
32332
32333
32334
32335
32336
32337
32338
32339
32340
32341
32342
32343
32344
32345
32346
32347
32348
32349
32350
32351
32352
32353
32354
32355
32356
32357
32358
32359
32360
32361
32362
32363
32364
32365
32366
32367
32368
32369
32370
32371
32372
32373
32374
32375
32376
32377
32378
32379
32380
32381
32382
32383
32384
32385
32386
32387
32388
32389
32390
32391
32392
32393
32394
32395
32396
32397
32398
32399
32400
32401
32402
32403
32404
32405
32406
32407
32408
32409
32410
32411
32412
32413
32414
32415
32416
32417
32418
32419
32420
32421
32422
32423
32424
32425
32426
32427
32428
32429
32430
32431
32432
32433
32434
32435
32436
32437
32438
32439
32440
32441
32442
32443
32444
32445
32446
32447
32448
32449
32450
32451
32452
32453
32454
32455
32456
32457
32458
32459
32460
32461
32462
32463
32464
32465
32466
32467
32468
32469
32470
32471
32472
32473
32474
32475
32476
32477
32478
32479
32480
32481
32482
32483
32484
32485
32486
32487
32488
32489
32490
32491
32492
32493
32494
32495
32496
32497
32498
32499
32500
32501
32502
32503
32504
32505
32506
32507
32508
32509
32510
32511
32512
32513
32514
32515
32516
32517
32518
32519
32520
32521
32522
32523
32524
32525
32526
32527
32528
32529
32530
32531
32532
32533
32534
32535
32536
32537
32538
32539
32540
32541
32542
32543
32544
32545
32546
32547
32548
32549
32550
32551
32552
32553
32554
32555
32556
32557
32558
32559
32560
32561
32562
32563
32564
32565
32566
32567
32568
32569
32570
32571
32572
32573
32574
32575
32576
32577
32578
32579
32580
32581
32582
32583
32584
32585
32586
32587
32588
32589
32590
32591
32592
32593
32594
32595
32596
32597
32598
32599
32600
32601
32602
32603
32604
32605
32606
32607
32608
32609
32610
32611
32612
32613
32614
32615
32616
32617
32618
32619
32620
32621
32622
32623
32624
32625
32626
32627
32628
32629
32630
32631
32632
32633
32634
32635
32636
32637
32638
32639
32640
32641
32642
32643
32644
32645
32646
32647
32648
32649
32650
32651
32652
32653
32654
32655
32656
32657
32658
32659
32660
32661
32662
32663
32664
32665
32666
32667
32668
32669
32670
32671
32672
32673
32674
32675
32676
32677
32678
32679
32680
32681
32682
32683
32684
32685
32686
32687
32688
32689
32690
32691
32692
32693
32694
32695
32696
32697
32698
32699
32700
32701
32702
32703
32704
32705
32706
32707
32708
32709
32710
32711
32712
32713
32714
32715
32716
32717
32718
32719
32720
32721
32722
32723
32724
32725
32726
32727
32728
32729
32730
32731
32732
32733
32734
32735
32736
32737
32738
32739
32740
32741
32742
32743
32744
32745
32746
32747
32748
32749
32750
32751
32752
32753
32754
32755
32756
32757
32758
32759
32760
32761
32762
32763
32764
32765
32766
32767
32768
32769
32770
32771
32772
32773
32774
32775
32776
32777
32778
32779
32780
32781
32782
32783
32784
32785
32786
32787
32788
32789
32790
32791
32792
32793
32794
32795
32796
32797
32798
32799
32800
32801
32802
32803
32804
32805
32806
32807
32808
32809
32810
32811
32812
32813
32814
32815
32816
32817
32818
32819
32820
32821
32822
32823
32824
32825
32826
32827
32828
32829
32830
32831
32832
32833
32834
32835
32836
32837
32838
32839
32840
32841
32842
32843
32844
32845
32846
32847
32848
32849
32850
32851
32852
32853
32854
32855
32856
32857
32858
32859
32860
32861
32862
32863
32864
32865
32866
32867
32868
32869
32870
32871
32872
32873
32874
32875
32876
32877
32878
32879
32880
32881
32882
32883
32884
32885
32886
32887
32888
32889
32890
32891
32892
32893
32894
32895
32896
32897
32898
32899
32900
32901
32902
32903
32904
32905
32906
32907
32908
32909
32910
32911
32912
32913
32914
32915
32916
32917
32918
32919
32920
32921
32922
32923
32924
32925
32926
32927
32928
32929
32930
32931
32932
32933
32934
32935
32936
32937
32938
32939
32940
32941
32942
32943
32944
32945
32946
32947
32948
32949
32950
32951
32952
32953
32954
32955
32956
32957
32958
32959
32960
32961
32962
32963
32964
32965
32966
32967
32968
32969
32970
32971
32972
32973
32974
32975
32976
32977
32978
32979
32980
32981
32982
32983
32984
32985
32986
32987
32988
32989
32990
32991
32992
32993
32994
32995
32996
32997
32998
32999
33000
33001
33002
33003
33004
33005
33006
33007
33008
33009
33010
33011
33012
33013
33014
33015
33016
33017
33018
33019
33020
33021
33022
33023
33024
33025
33026
33027
33028
33029
33030
33031
33032
33033
33034
33035
33036
33037
33038
33039
33040
33041
33042
33043
33044
33045
33046
33047
33048
33049
33050
33051
33052
33053
33054
33055
33056
33057
33058
33059
33060
33061
33062
33063
33064
33065
33066
33067
33068
33069
33070
33071
33072
33073
33074
33075
33076
33077
33078
33079
33080
33081
33082
33083
33084
33085
33086
33087
33088
33089
33090
33091
33092
33093
33094
33095
33096
33097
33098
33099
33100
33101
33102
33103
33104
33105
33106
33107
33108
33109
33110
33111
33112
33113
33114
33115
33116
33117
33118
33119
33120
33121
33122
33123
33124
33125
33126
33127
33128
33129
33130
33131
33132
33133
33134
33135
33136
33137
33138
33139
33140
33141
33142
33143
33144
33145
33146
33147
33148
33149
33150
33151
33152
33153
33154
33155
33156
33157
33158
33159
33160
33161
33162
33163
33164
33165
33166
33167
33168
33169
33170
33171
33172
33173
33174
33175
33176
33177
33178
33179
33180
33181
33182
33183
33184
33185
33186
33187
33188
33189
33190
33191
33192
33193
33194
33195
33196
33197
33198
33199
33200
33201
33202
33203
33204
33205
33206
33207
33208
33209
33210
33211
33212
33213
33214
33215
33216
33217
33218
33219
33220
33221
33222
33223
33224
33225
33226
33227
33228
33229
33230
33231
33232
33233
33234
33235
33236
33237
33238
33239
33240
33241
33242
33243
33244
33245
33246
33247
33248
33249
33250
33251
33252
33253
33254
33255
33256
33257
33258
33259
33260
33261
33262
33263
33264
33265
33266
33267
33268
33269
33270
33271
33272
33273
33274
33275
33276
33277
33278
33279
33280
33281
33282
33283
33284
33285
33286
33287
33288
33289
33290
33291
33292
33293
33294
33295
33296
33297
33298
33299
33300
33301
33302
33303
33304
33305
33306
33307
33308
33309
33310
33311
33312
33313
33314
33315
33316
33317
33318
33319
33320
33321
33322
33323
33324
33325
33326
33327
33328
33329
33330
33331
33332
33333
33334
33335
33336
33337
33338
33339
33340
33341
33342
33343
33344
33345
33346
33347
33348
33349
33350
33351
33352
33353
33354
33355
33356
33357
33358
33359
33360
33361
33362
33363
33364
33365
33366
33367
33368
33369
33370
33371
33372
33373
33374
33375
33376
33377
33378
33379
33380
33381
33382
33383
33384
33385
33386
33387
33388
33389
33390
33391
33392
33393
33394
33395
33396
33397
33398
33399
33400
33401
33402
33403
33404
33405
33406
33407
33408
33409
33410
33411
33412
33413
33414
33415
33416
33417
33418
33419
33420
33421
33422
33423
33424
33425
33426
33427
33428
33429
33430
33431
33432
33433
33434
33435
33436
33437
33438
33439
33440
33441
33442
33443
33444
33445
33446
33447
33448
33449
33450
33451
33452
33453
33454
33455
33456
33457
33458
33459
33460
33461
33462
33463
33464
33465
33466
33467
33468
33469
33470
33471
33472
33473
33474
33475
33476
33477
33478
33479
33480
33481
33482
33483
33484
33485
33486
33487
33488
33489
33490
33491
33492
33493
33494
33495
33496
33497
33498
33499
33500
33501
33502
33503
33504
33505
33506
33507
33508
33509
33510
33511
33512
33513
33514
33515
33516
33517
33518
33519
33520
33521
33522
33523
33524
33525
33526
33527
33528
33529
33530
33531
33532
33533
33534
33535
33536
33537
33538
33539
33540
33541
33542
33543
33544
33545
33546
33547
33548
33549
33550
33551
33552
33553
33554
33555
33556
33557
33558
33559
33560
33561
33562
33563
33564
33565
33566
33567
33568
33569
33570
33571
33572
33573
33574
33575
33576
33577
33578
33579
33580
33581
33582
33583
33584
33585
33586
33587
33588
33589
33590
33591
33592
33593
33594
33595
33596
33597
33598
33599
33600
33601
33602
33603
33604
33605
33606
33607
33608
33609
33610
33611
33612
33613
33614
33615
33616
33617
33618
33619
33620
33621
33622
33623
33624
33625
33626
33627
33628
33629
33630
33631
33632
33633
33634
33635
33636
33637
33638
33639
33640
33641
33642
33643
33644
33645
33646
33647
33648
33649
33650
33651
33652
33653
33654
33655
33656
33657
33658
33659
33660
33661
33662
33663
33664
33665
33666
33667
33668
33669
33670
33671
33672
33673
33674
33675
33676
33677
33678
33679
33680
33681
33682
33683
33684
33685
33686
33687
33688
33689
33690
33691
33692
33693
33694
33695
33696
33697
33698
33699
33700
33701
33702
33703
33704
33705
33706
33707
33708
33709
33710
33711
33712
33713
33714
33715
33716
33717
33718
33719
33720
33721
33722
33723
33724
33725
33726
33727
33728
33729
33730
33731
33732
33733
33734
33735
33736
33737
33738
33739
33740
33741
33742
33743
33744
33745
33746
33747
33748
33749
33750
33751
33752
33753
33754
33755
33756
33757
33758
33759
33760
33761
33762
33763
33764
33765
33766
33767
33768
33769
33770
33771
33772
33773
33774
33775
33776
33777
33778
33779
33780
33781
33782
33783
33784
33785
33786
33787
33788
33789
33790
33791
33792
33793
33794
33795
33796
33797
33798
33799
33800
33801
33802
33803
33804
33805
33806
33807
33808
33809
33810
33811
33812
33813
33814
33815
33816
33817
33818
33819
33820
33821
33822
33823
33824
33825
33826
33827
33828
33829
33830
33831
33832
33833
33834
33835
33836
33837
33838
33839
33840
33841
33842
33843
33844
33845
33846
33847
33848
33849
33850
33851
33852
33853
33854
33855
33856
33857
33858
33859
33860
33861
33862
33863
33864
33865
33866
33867
33868
33869
33870
33871
33872
33873
33874
33875
33876
33877
33878
33879
33880
33881
33882
33883
33884
33885
33886
33887
33888
33889
33890
33891
33892
33893
33894
33895
33896
33897
33898
33899
33900
33901
33902
33903
33904
33905
33906
33907
33908
33909
33910
33911
33912
33913
33914
33915
33916
33917
33918
33919
33920
33921
33922
33923
33924
33925
33926
33927
33928
33929
33930
33931
33932
33933
33934
33935
33936
33937
33938
33939
33940
33941
33942
33943
33944
33945
33946
33947
33948
33949
33950
33951
33952
33953
33954
33955
33956
33957
33958
33959
33960
33961
33962
33963
33964
33965
33966
33967
33968
33969
33970
33971
33972
33973
33974
33975
33976
33977
33978
33979
33980
33981
33982
33983
33984
33985
33986
33987
33988
33989
33990
33991
33992
33993
33994
33995
33996
33997
33998
33999
34000
34001
34002
34003
34004
34005
34006
34007
34008
34009
34010
34011
34012
34013
34014
34015
34016
34017
34018
34019
34020
34021
34022
34023
34024
34025
34026
34027
34028
34029
34030
34031
34032
34033
34034
34035
34036
34037
34038
34039
34040
34041
34042
34043
34044
34045
34046
34047
34048
34049
34050
34051
34052
34053
34054
34055
34056
34057
34058
34059
34060
34061
34062
34063
34064
34065
34066
34067
34068
34069
34070
34071
34072
34073
34074
34075
34076
34077
34078
34079
34080
34081
34082
34083
34084
34085
34086
34087
34088
34089
34090
34091
34092
34093
34094
34095
34096
34097
34098
34099
34100
34101
34102
34103
34104
34105
34106
34107
34108
34109
34110
34111
34112
34113
34114
34115
34116
34117
34118
34119
34120
34121
34122
34123
34124
34125
34126
34127
34128
34129
34130
34131
34132
34133
34134
34135
34136
34137
34138
34139
34140
34141
34142
34143
34144
34145
34146
34147
34148
34149
34150
34151
34152
34153
34154
34155
34156
34157
34158
34159
34160
34161
34162
34163
34164
34165
34166
34167
34168
34169
34170
34171
34172
34173
34174
34175
34176
34177
34178
34179
34180
34181
34182
34183
34184
34185
34186
34187
34188
34189
34190
34191
34192
34193
34194
34195
34196
34197
34198
34199
34200
34201
34202
34203
34204
34205
34206
34207
34208
34209
34210
34211
34212
34213
34214
34215
34216
34217
34218
34219
34220
34221
34222
34223
34224
34225
34226
34227
34228
34229
34230
34231
34232
34233
34234
34235
34236
34237
34238
34239
34240
34241
34242
34243
34244
34245
34246
34247
34248
34249
34250
34251
34252
34253
34254
34255
34256
34257
34258
34259
34260
34261
34262
34263
34264
34265
34266
34267
34268
34269
34270
34271
34272
34273
34274
34275
34276
34277
34278
34279
34280
34281
34282
34283
34284
34285
34286
34287
34288
34289
34290
34291
34292
34293
34294
34295
34296
34297
34298
34299
34300
34301
34302
34303
34304
34305
34306
34307
34308
34309
34310
34311
34312
34313
34314
34315
34316
34317
34318
34319
34320
34321
34322
34323
34324
34325
34326
34327
34328
34329
34330
34331
34332
34333
34334
34335
34336
34337
34338
34339
34340
34341
34342
34343
34344
34345
34346
34347
34348
34349
34350
34351
34352
34353
34354
34355
34356
34357
34358
34359
34360
34361
34362
34363
34364
34365
34366
34367
34368
34369
34370
34371
34372
34373
34374
34375
34376
34377
34378
34379
34380
34381
34382
34383
34384
34385
34386
34387
34388
34389
34390
34391
34392
34393
34394
34395
34396
34397
34398
34399
34400
34401
34402
34403
34404
34405
34406
34407
34408
34409
34410
34411
34412
34413
34414
34415
34416
34417
34418
34419
34420
34421
34422
34423
34424
34425
34426
34427
34428
34429
34430
34431
34432
34433
34434
34435
34436
34437
34438
34439
34440
34441
34442
34443
34444
34445
34446
34447
34448
34449
34450
34451
34452
34453
34454
34455
34456
34457
34458
34459
34460
34461
34462
34463
34464
34465
34466
34467
34468
34469
34470
34471
34472
34473
34474
34475
34476
34477
34478
34479
34480
34481
34482
34483
34484
34485
34486
34487
34488
34489
34490
34491
34492
34493
34494
34495
34496
34497
34498
34499
34500
34501
34502
34503
34504
34505
34506
34507
34508
34509
34510
34511
34512
34513
34514
34515
34516
34517
34518
34519
34520
34521
34522
34523
34524
34525
34526
34527
34528
34529
34530
34531
34532
34533
34534
34535
34536
34537
34538
34539
34540
34541
34542
34543
34544
34545
34546
34547
34548
34549
34550
34551
34552
34553
34554
34555
34556
34557
34558
34559
34560
34561
34562
34563
34564
34565
34566
34567
34568
34569
34570
34571
34572
34573
34574
34575
34576
34577
34578
34579
34580
34581
34582
34583
34584
34585
34586
34587
34588
34589
34590
34591
34592
34593
34594
34595
34596
34597
34598
34599
34600
34601
34602
34603
34604
34605
34606
34607
34608
34609
34610
34611
34612
34613
34614
34615
34616
34617
34618
34619
34620
34621
34622
34623
34624
34625
34626
34627
34628
34629
34630
34631
34632
34633
34634
34635
34636
34637
34638
34639
34640
34641
34642
34643
34644
34645
34646
34647
34648
34649
34650
34651
34652
34653
34654
34655
34656
34657
34658
34659
34660
34661
34662
34663
34664
34665
34666
34667
34668
34669
34670
34671
34672
34673
34674
34675
34676
34677
34678
34679
34680
34681
34682
34683
34684
34685
34686
34687
34688
34689
34690
34691
34692
34693
34694
34695
34696
34697
34698
34699
34700
34701
34702
34703
34704
34705
34706
34707
34708
34709
34710
34711
34712
34713
34714
34715
34716
34717
34718
34719
34720
34721
34722
34723
34724
34725
34726
34727
34728
34729
34730
34731
34732
34733
34734
34735
34736
34737
34738
34739
34740
34741
34742
34743
34744
34745
34746
34747
34748
34749
34750
34751
34752
34753
34754
34755
34756
34757
34758
34759
34760
34761
34762
34763
34764
34765
34766
34767
34768
34769
34770
34771
34772
34773
34774
34775
34776
34777
34778
34779
34780
34781
34782
34783
34784
34785
34786
34787
34788
34789
34790
34791
34792
34793
34794
34795
34796
34797
34798
34799
34800
34801
34802
34803
34804
34805
34806
34807
34808
34809
34810
34811
34812
34813
34814
34815
34816
34817
34818
34819
34820
34821
34822
34823
34824
34825
34826
34827
34828
34829
34830
34831
34832
34833
34834
34835
34836
34837
34838
34839
34840
34841
34842
34843
34844
34845
34846
34847
34848
34849
34850
34851
34852
34853
34854
34855
34856
34857
34858
34859
34860
34861
34862
34863
34864
34865
34866
34867
34868
34869
34870
34871
34872
34873
34874
34875
34876
34877
34878
34879
34880
34881
34882
34883
34884
34885
34886
34887
34888
34889
34890
34891
34892
34893
34894
34895
34896
34897
34898
34899
34900
34901
34902
34903
34904
34905
34906
34907
34908
34909
34910
34911
34912
34913
34914
34915
34916
34917
34918
34919
34920
34921
34922
34923
34924
34925
34926
34927
34928
34929
34930
34931
34932
34933
34934
34935
34936
34937
34938
34939
34940
34941
34942
34943
34944
34945
34946
34947
34948
34949
34950
34951
34952
34953
34954
34955
34956
34957
34958
34959
34960
34961
34962
34963
34964
34965
34966
34967
34968
34969
34970
34971
34972
34973
34974
34975
34976
34977
34978
34979
34980
34981
34982
34983
34984
34985
34986
34987
34988
34989
34990
34991
34992
34993
34994
34995
34996
34997
34998
34999
35000
35001
35002
35003
35004
35005
35006
35007
35008
35009
35010
35011
35012
35013
35014
35015
35016
35017
35018
35019
35020
35021
35022
35023
35024
35025
35026
35027
35028
35029
35030
35031
35032
35033
35034
35035
35036
35037
35038
35039
35040
35041
35042
35043
35044
35045
35046
35047
35048
35049
35050
35051
35052
35053
35054
35055
35056
35057
35058
35059
35060
35061
35062
35063
35064
35065
35066
35067
35068
35069
35070
35071
35072
35073
35074
35075
35076
35077
35078
35079
35080
35081
35082
35083
35084
35085
35086
35087
35088
35089
35090
35091
35092
35093
35094
35095
35096
35097
35098
35099
35100
35101
35102
35103
35104
35105
35106
35107
35108
35109
35110
35111
35112
35113
35114
35115
35116
35117
35118
35119
35120
35121
35122
35123
35124
35125
35126
35127
35128
35129
35130
35131
35132
35133
35134
35135
35136
35137
35138
35139
35140
35141
35142
35143
35144
35145
35146
35147
35148
35149
35150
35151
35152
35153
35154
35155
35156
35157
35158
35159
35160
35161
35162
35163
35164
35165
35166
35167
35168
35169
35170
35171
35172
35173
35174
35175
35176
35177
35178
35179
35180
35181
35182
35183
35184
35185
35186
35187
35188
35189
35190
35191
35192
35193
35194
35195
35196
35197
35198
35199
35200
35201
35202
35203
35204
35205
35206
35207
35208
35209
35210
35211
35212
35213
35214
35215
35216
35217
35218
35219
35220
35221
35222
35223
35224
35225
35226
35227
35228
35229
35230
35231
35232
35233
35234
35235
35236
35237
35238
35239
35240
35241
35242
35243
35244
35245
35246
35247
35248
35249
35250
35251
35252
35253
35254
35255
35256
35257
35258
35259
35260
35261
35262
35263
35264
35265
35266
35267
35268
35269
35270
35271
35272
35273
35274
35275
35276
35277
35278
35279
35280
35281
35282
35283
35284
35285
35286
35287
35288
35289
35290
35291
35292
35293
35294
35295
35296
35297
35298
35299
35300
35301
35302
35303
35304
35305
35306
35307
35308
35309
35310
35311
35312
35313
35314
35315
35316
35317
35318
35319
35320
35321
35322
35323
35324
35325
35326
35327
35328
35329
35330
35331
35332
35333
35334
35335
35336
35337
35338
35339
35340
35341
35342
35343
35344
35345
35346
35347
35348
35349
35350
35351
35352
35353
35354
35355
35356
35357
35358
35359
35360
35361
35362
35363
35364
35365
35366
35367
35368
35369
35370
35371
35372
35373
35374
35375
35376
35377
35378
35379
35380
35381
35382
35383
35384
35385
35386
35387
35388
35389
35390
35391
35392
35393
35394
35395
35396
35397
35398
35399
35400
35401
35402
35403
35404
35405
35406
35407
35408
35409
35410
35411
35412
35413
35414
35415
35416
35417
35418
35419
35420
35421
35422
35423
35424
35425
35426
35427
35428
35429
35430
35431
35432
35433
35434
35435
35436
35437
35438
35439
35440
35441
35442
35443
35444
35445
35446
35447
35448
35449
35450
35451
35452
35453
35454
35455
35456
35457
35458
35459
35460
35461
35462
35463
35464
35465
35466
35467
35468
35469
35470
35471
35472
35473
35474
35475
35476
35477
35478
35479
35480
35481
35482
35483
35484
35485
35486
35487
35488
35489
35490
35491
35492
35493
35494

# BEGIN testcases29

# Test parsing of time of day

test clock-29.1 {time parsing} {
    clock scan {2440588 00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H }
} 0
test clock-29.2 {time parsing} {
    clock scan {2440588 00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M }
} 0
test clock-29.3 {time parsing} {
    clock scan {2440588 00:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM }
} 0
test clock-29.4 {time parsing} {
    clock scan {2440588 00:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 0
test clock-29.5 {time parsing} {
    clock scan {2440588 00:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 0
test clock-29.6 {time parsing} {
    clock scan {2440588  0 } \
        -gmt true -locale en_US_roman \
        -format {%J %k }
} 0
test clock-29.7 {time parsing} {
    clock scan {2440588  0:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M }
} 0
test clock-29.8 {time parsing} {
    clock scan {2440588  0:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM }
} 0
test clock-29.9 {time parsing} {
    clock scan {2440588  0:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 0
test clock-29.10 {time parsing} {
    clock scan {2440588  0:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 0
test clock-29.11 {time parsing} {
    clock scan {2440588 ? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH }
} 0
test clock-29.12 {time parsing} {
    clock scan {2440588 ?:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M }
} 0
test clock-29.13 {time parsing} {
    clock scan {2440588 ?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM }
} 0
test clock-29.14 {time parsing} {
    clock scan {2440588 ?:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 0
test clock-29.15 {time parsing} {
    clock scan {2440588 ?:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 0
test clock-29.16 {time parsing} {
    clock scan {2440588 ? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok }
} 0
test clock-29.17 {time parsing} {
    clock scan {2440588 ?:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M }
} 0
test clock-29.18 {time parsing} {
    clock scan {2440588 ?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM }
} 0
test clock-29.19 {time parsing} {
    clock scan {2440588 ?:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 0
test clock-29.20 {time parsing} {
    clock scan {2440588 ?:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 0
test clock-29.21 {time parsing} {
    clock scan {2440588 12 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I %p}
} 0
test clock-29.22 {time parsing} {
    clock scan {2440588 12:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %p}
} 0
test clock-29.23 {time parsing} {
    clock scan {2440588 12:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %p}
} 0
test clock-29.24 {time parsing} {
    clock scan {2440588 12:00:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 0
test clock-29.25 {time parsing} {
    clock scan {2440588 12:?:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 0
test clock-29.26 {time parsing} {
    clock scan {2440588 12 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l %p}
} 0
test clock-29.27 {time parsing} {
    clock scan {2440588 12:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %p}
} 0
test clock-29.28 {time parsing} {
    clock scan {2440588 12:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %p}
} 0
test clock-29.29 {time parsing} {
    clock scan {2440588 12:00:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 0
test clock-29.30 {time parsing} {
    clock scan {2440588 12:?:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 0
test clock-29.31 {time parsing} {
    clock scan {2440588 xii AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI %p}
} 0
test clock-29.32 {time parsing} {
    clock scan {2440588 xii:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %p}
} 0
test clock-29.33 {time parsing} {
    clock scan {2440588 xii:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %p}
} 0
test clock-29.34 {time parsing} {
    clock scan {2440588 xii:00:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 0
test clock-29.35 {time parsing} {
    clock scan {2440588 xii:?:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 0
test clock-29.36 {time parsing} {
    clock scan {2440588 xii AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol %p}
} 0
test clock-29.37 {time parsing} {
    clock scan {2440588 xii:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %p}
} 0
test clock-29.38 {time parsing} {
    clock scan {2440588 xii:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %p}
} 0
test clock-29.39 {time parsing} {
    clock scan {2440588 xii:00:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 0
test clock-29.40 {time parsing} {
    clock scan {2440588 xii:?:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 0
test clock-29.41 {time parsing} {
    clock scan {2440588 12 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I %P}
} 0
test clock-29.42 {time parsing} {
    clock scan {2440588 12:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %P}
} 0
test clock-29.43 {time parsing} {
    clock scan {2440588 12:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %P}
} 0
test clock-29.44 {time parsing} {
    clock scan {2440588 12:00:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 0
test clock-29.45 {time parsing} {
    clock scan {2440588 12:?:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 0
test clock-29.46 {time parsing} {
    clock scan {2440588 12 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l %P}
} 0
test clock-29.47 {time parsing} {
    clock scan {2440588 12:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %P}
} 0
test clock-29.48 {time parsing} {
    clock scan {2440588 12:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %P}
} 0
test clock-29.49 {time parsing} {
    clock scan {2440588 12:00:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 0
test clock-29.50 {time parsing} {
    clock scan {2440588 12:?:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 0
test clock-29.51 {time parsing} {
    clock scan {2440588 xii am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI %P}
} 0
test clock-29.52 {time parsing} {
    clock scan {2440588 xii:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %P}
} 0
test clock-29.53 {time parsing} {
    clock scan {2440588 xii:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %P}
} 0
test clock-29.54 {time parsing} {
    clock scan {2440588 xii:00:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 0
test clock-29.55 {time parsing} {
    clock scan {2440588 xii:?:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 0
test clock-29.56 {time parsing} {
    clock scan {2440588 xii am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol %P}
} 0
test clock-29.57 {time parsing} {
    clock scan {2440588 xii:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %P}
} 0
test clock-29.58 {time parsing} {
    clock scan {2440588 xii:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %P}
} 0
test clock-29.59 {time parsing} {
    clock scan {2440588 xii:00:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 0
test clock-29.60 {time parsing} {
    clock scan {2440588 xii:?:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 0
test clock-29.61 {time parsing} {
    clock scan {2440588 00:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 1
test clock-29.62 {time parsing} {
    clock scan {2440588 00:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 1
test clock-29.63 {time parsing} {
    clock scan {2440588  0:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 1
test clock-29.64 {time parsing} {
    clock scan {2440588  0:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 1
test clock-29.65 {time parsing} {
    clock scan {2440588 ?:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 1
test clock-29.66 {time parsing} {
    clock scan {2440588 ?:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 1
test clock-29.67 {time parsing} {
    clock scan {2440588 ?:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 1
test clock-29.68 {time parsing} {
    clock scan {2440588 ?:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 1
test clock-29.69 {time parsing} {
    clock scan {2440588 12:00:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 1
test clock-29.70 {time parsing} {
    clock scan {2440588 12:?:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 1
test clock-29.71 {time parsing} {
    clock scan {2440588 12:00:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 1
test clock-29.72 {time parsing} {
    clock scan {2440588 12:?:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 1
test clock-29.73 {time parsing} {
    clock scan {2440588 xii:00:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 1
test clock-29.74 {time parsing} {
    clock scan {2440588 xii:?:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 1
test clock-29.75 {time parsing} {
    clock scan {2440588 xii:00:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 1
test clock-29.76 {time parsing} {
    clock scan {2440588 xii:?:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 1
test clock-29.77 {time parsing} {
    clock scan {2440588 12:00:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 1
test clock-29.78 {time parsing} {
    clock scan {2440588 12:?:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 1
test clock-29.79 {time parsing} {
    clock scan {2440588 12:00:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 1
test clock-29.80 {time parsing} {
    clock scan {2440588 12:?:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 1
test clock-29.81 {time parsing} {
    clock scan {2440588 xii:00:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 1
test clock-29.82 {time parsing} {
    clock scan {2440588 xii:?:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 1
test clock-29.83 {time parsing} {
    clock scan {2440588 xii:00:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 1
test clock-29.84 {time parsing} {
    clock scan {2440588 xii:?:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 1
test clock-29.85 {time parsing} {
    clock scan {2440588 00:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 59
test clock-29.86 {time parsing} {
    clock scan {2440588 00:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 59
test clock-29.87 {time parsing} {
    clock scan {2440588  0:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 59
test clock-29.88 {time parsing} {
    clock scan {2440588  0:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 59
test clock-29.89 {time parsing} {
    clock scan {2440588 ?:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 59
test clock-29.90 {time parsing} {
    clock scan {2440588 ?:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 59
test clock-29.91 {time parsing} {
    clock scan {2440588 ?:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 59
test clock-29.92 {time parsing} {
    clock scan {2440588 ?:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 59
test clock-29.93 {time parsing} {
    clock scan {2440588 12:00:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 59
test clock-29.94 {time parsing} {
    clock scan {2440588 12:?:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 59
test clock-29.95 {time parsing} {
    clock scan {2440588 12:00:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 59
test clock-29.96 {time parsing} {
    clock scan {2440588 12:?:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 59
test clock-29.97 {time parsing} {
    clock scan {2440588 xii:00:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 59
test clock-29.98 {time parsing} {
    clock scan {2440588 xii:?:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 59
test clock-29.99 {time parsing} {
    clock scan {2440588 xii:00:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 59
test clock-29.100 {time parsing} {
    clock scan {2440588 xii:?:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 59
test clock-29.101 {time parsing} {
    clock scan {2440588 12:00:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 59
test clock-29.102 {time parsing} {
    clock scan {2440588 12:?:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 59
test clock-29.103 {time parsing} {
    clock scan {2440588 12:00:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 59
test clock-29.104 {time parsing} {
    clock scan {2440588 12:?:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 59
test clock-29.105 {time parsing} {
    clock scan {2440588 xii:00:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 59
test clock-29.106 {time parsing} {
    clock scan {2440588 xii:?:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 59
test clock-29.107 {time parsing} {
    clock scan {2440588 xii:00:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 59
test clock-29.108 {time parsing} {
    clock scan {2440588 xii:?:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 59
test clock-29.109 {time parsing} {
    clock scan {2440588 00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M }
} 60
test clock-29.110 {time parsing} {
    clock scan {2440588 00:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM }
} 60
test clock-29.111 {time parsing} {
    clock scan {2440588 00:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 60
test clock-29.112 {time parsing} {
    clock scan {2440588 00:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 60
test clock-29.113 {time parsing} {
    clock scan {2440588  0:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M }
} 60
test clock-29.114 {time parsing} {
    clock scan {2440588  0:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM }
} 60
test clock-29.115 {time parsing} {
    clock scan {2440588  0:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 60
test clock-29.116 {time parsing} {
    clock scan {2440588  0:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 60
test clock-29.117 {time parsing} {
    clock scan {2440588 ?:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M }
} 60
test clock-29.118 {time parsing} {
    clock scan {2440588 ?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM }
} 60
test clock-29.119 {time parsing} {
    clock scan {2440588 ?:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 60
test clock-29.120 {time parsing} {
    clock scan {2440588 ?:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 60
test clock-29.121 {time parsing} {
    clock scan {2440588 ?:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M }
} 60
test clock-29.122 {time parsing} {
    clock scan {2440588 ?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM }
} 60
test clock-29.123 {time parsing} {
    clock scan {2440588 ?:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 60
test clock-29.124 {time parsing} {
    clock scan {2440588 ?:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 60
test clock-29.125 {time parsing} {
    clock scan {2440588 12:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %p}
} 60
test clock-29.126 {time parsing} {
    clock scan {2440588 12:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %p}
} 60
test clock-29.127 {time parsing} {
    clock scan {2440588 12:01:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 60
test clock-29.128 {time parsing} {
    clock scan {2440588 12:i:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 60
test clock-29.129 {time parsing} {
    clock scan {2440588 12:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %p}
} 60
test clock-29.130 {time parsing} {
    clock scan {2440588 12:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %p}
} 60
test clock-29.131 {time parsing} {
    clock scan {2440588 12:01:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 60
test clock-29.132 {time parsing} {
    clock scan {2440588 12:i:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 60
test clock-29.133 {time parsing} {
    clock scan {2440588 xii:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %p}
} 60
test clock-29.134 {time parsing} {
    clock scan {2440588 xii:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %p}
} 60
test clock-29.135 {time parsing} {
    clock scan {2440588 xii:01:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 60
test clock-29.136 {time parsing} {
    clock scan {2440588 xii:i:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 60
test clock-29.137 {time parsing} {
    clock scan {2440588 xii:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %p}
} 60
test clock-29.138 {time parsing} {
    clock scan {2440588 xii:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %p}
} 60
test clock-29.139 {time parsing} {
    clock scan {2440588 xii:01:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 60
test clock-29.140 {time parsing} {
    clock scan {2440588 xii:i:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 60
test clock-29.141 {time parsing} {
    clock scan {2440588 12:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %P}
} 60
test clock-29.142 {time parsing} {
    clock scan {2440588 12:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %P}
} 60
test clock-29.143 {time parsing} {
    clock scan {2440588 12:01:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 60
test clock-29.144 {time parsing} {
    clock scan {2440588 12:i:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 60
test clock-29.145 {time parsing} {
    clock scan {2440588 12:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %P}
} 60
test clock-29.146 {time parsing} {
    clock scan {2440588 12:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %P}
} 60
test clock-29.147 {time parsing} {
    clock scan {2440588 12:01:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 60
test clock-29.148 {time parsing} {
    clock scan {2440588 12:i:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 60
test clock-29.149 {time parsing} {
    clock scan {2440588 xii:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %P}
} 60
test clock-29.150 {time parsing} {
    clock scan {2440588 xii:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %P}
} 60
test clock-29.151 {time parsing} {
    clock scan {2440588 xii:01:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 60
test clock-29.152 {time parsing} {
    clock scan {2440588 xii:i:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 60
test clock-29.153 {time parsing} {
    clock scan {2440588 xii:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %P}
} 60
test clock-29.154 {time parsing} {
    clock scan {2440588 xii:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %P}
} 60
test clock-29.155 {time parsing} {
    clock scan {2440588 xii:01:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 60
test clock-29.156 {time parsing} {
    clock scan {2440588 xii:i:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 60
test clock-29.157 {time parsing} {
    clock scan {2440588 00:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 61
test clock-29.158 {time parsing} {
    clock scan {2440588 00:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 61
test clock-29.159 {time parsing} {
    clock scan {2440588  0:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 61
test clock-29.160 {time parsing} {
    clock scan {2440588  0:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 61
test clock-29.161 {time parsing} {
    clock scan {2440588 ?:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 61
test clock-29.162 {time parsing} {
    clock scan {2440588 ?:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 61
test clock-29.163 {time parsing} {
    clock scan {2440588 ?:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 61
test clock-29.164 {time parsing} {
    clock scan {2440588 ?:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 61
test clock-29.165 {time parsing} {
    clock scan {2440588 12:01:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 61
test clock-29.166 {time parsing} {
    clock scan {2440588 12:i:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 61
test clock-29.167 {time parsing} {
    clock scan {2440588 12:01:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 61
test clock-29.168 {time parsing} {
    clock scan {2440588 12:i:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 61
test clock-29.169 {time parsing} {
    clock scan {2440588 xii:01:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 61
test clock-29.170 {time parsing} {
    clock scan {2440588 xii:i:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 61
test clock-29.171 {time parsing} {
    clock scan {2440588 xii:01:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 61
test clock-29.172 {time parsing} {
    clock scan {2440588 xii:i:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 61
test clock-29.173 {time parsing} {
    clock scan {2440588 12:01:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 61
test clock-29.174 {time parsing} {
    clock scan {2440588 12:i:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 61
test clock-29.175 {time parsing} {
    clock scan {2440588 12:01:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 61
test clock-29.176 {time parsing} {
    clock scan {2440588 12:i:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 61
test clock-29.177 {time parsing} {
    clock scan {2440588 xii:01:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 61
test clock-29.178 {time parsing} {
    clock scan {2440588 xii:i:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 61
test clock-29.179 {time parsing} {
    clock scan {2440588 xii:01:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 61
test clock-29.180 {time parsing} {
    clock scan {2440588 xii:i:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 61
test clock-29.181 {time parsing} {
    clock scan {2440588 00:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 119
test clock-29.182 {time parsing} {
    clock scan {2440588 00:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 119
test clock-29.183 {time parsing} {
    clock scan {2440588  0:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 119
test clock-29.184 {time parsing} {
    clock scan {2440588  0:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 119
test clock-29.185 {time parsing} {
    clock scan {2440588 ?:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 119
test clock-29.186 {time parsing} {
    clock scan {2440588 ?:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 119
test clock-29.187 {time parsing} {
    clock scan {2440588 ?:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 119
test clock-29.188 {time parsing} {
    clock scan {2440588 ?:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 119
test clock-29.189 {time parsing} {
    clock scan {2440588 12:01:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 119
test clock-29.190 {time parsing} {
    clock scan {2440588 12:i:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 119
test clock-29.191 {time parsing} {
    clock scan {2440588 12:01:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 119
test clock-29.192 {time parsing} {
    clock scan {2440588 12:i:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 119
test clock-29.193 {time parsing} {
    clock scan {2440588 xii:01:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 119
test clock-29.194 {time parsing} {
    clock scan {2440588 xii:i:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 119
test clock-29.195 {time parsing} {
    clock scan {2440588 xii:01:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 119
test clock-29.196 {time parsing} {
    clock scan {2440588 xii:i:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 119
test clock-29.197 {time parsing} {
    clock scan {2440588 12:01:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 119
test clock-29.198 {time parsing} {
    clock scan {2440588 12:i:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 119
test clock-29.199 {time parsing} {
    clock scan {2440588 12:01:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 119
test clock-29.200 {time parsing} {
    clock scan {2440588 12:i:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 119
test clock-29.201 {time parsing} {
    clock scan {2440588 xii:01:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 119
test clock-29.202 {time parsing} {
    clock scan {2440588 xii:i:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 119
test clock-29.203 {time parsing} {
    clock scan {2440588 xii:01:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 119
test clock-29.204 {time parsing} {
    clock scan {2440588 xii:i:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 119
test clock-29.205 {time parsing} {
    clock scan {2440588 00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M }
} 3540
test clock-29.206 {time parsing} {
    clock scan {2440588 00:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM }
} 3540
test clock-29.207 {time parsing} {
    clock scan {2440588 00:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 3540
test clock-29.208 {time parsing} {
    clock scan {2440588 00:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 3540
test clock-29.209 {time parsing} {
    clock scan {2440588  0:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M }
} 3540
test clock-29.210 {time parsing} {
    clock scan {2440588  0:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM }
} 3540
test clock-29.211 {time parsing} {
    clock scan {2440588  0:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 3540
test clock-29.212 {time parsing} {
    clock scan {2440588  0:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 3540
test clock-29.213 {time parsing} {
    clock scan {2440588 ?:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M }
} 3540
test clock-29.214 {time parsing} {
    clock scan {2440588 ?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM }
} 3540
test clock-29.215 {time parsing} {
    clock scan {2440588 ?:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 3540
test clock-29.216 {time parsing} {
    clock scan {2440588 ?:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 3540
test clock-29.217 {time parsing} {
    clock scan {2440588 ?:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M }
} 3540
test clock-29.218 {time parsing} {
    clock scan {2440588 ?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM }
} 3540
test clock-29.219 {time parsing} {
    clock scan {2440588 ?:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 3540
test clock-29.220 {time parsing} {
    clock scan {2440588 ?:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 3540
test clock-29.221 {time parsing} {
    clock scan {2440588 12:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %p}
} 3540
test clock-29.222 {time parsing} {
    clock scan {2440588 12:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %p}
} 3540
test clock-29.223 {time parsing} {
    clock scan {2440588 12:59:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 3540
test clock-29.224 {time parsing} {
    clock scan {2440588 12:lix:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 3540
test clock-29.225 {time parsing} {
    clock scan {2440588 12:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %p}
} 3540
test clock-29.226 {time parsing} {
    clock scan {2440588 12:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %p}
} 3540
test clock-29.227 {time parsing} {
    clock scan {2440588 12:59:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 3540
test clock-29.228 {time parsing} {
    clock scan {2440588 12:lix:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 3540
test clock-29.229 {time parsing} {
    clock scan {2440588 xii:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %p}
} 3540
test clock-29.230 {time parsing} {
    clock scan {2440588 xii:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %p}
} 3540
test clock-29.231 {time parsing} {
    clock scan {2440588 xii:59:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 3540
test clock-29.232 {time parsing} {
    clock scan {2440588 xii:lix:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 3540
test clock-29.233 {time parsing} {
    clock scan {2440588 xii:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %p}
} 3540
test clock-29.234 {time parsing} {
    clock scan {2440588 xii:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %p}
} 3540
test clock-29.235 {time parsing} {
    clock scan {2440588 xii:59:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 3540
test clock-29.236 {time parsing} {
    clock scan {2440588 xii:lix:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 3540
test clock-29.237 {time parsing} {
    clock scan {2440588 12:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %P}
} 3540
test clock-29.238 {time parsing} {
    clock scan {2440588 12:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %P}
} 3540
test clock-29.239 {time parsing} {
    clock scan {2440588 12:59:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 3540
test clock-29.240 {time parsing} {
    clock scan {2440588 12:lix:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 3540
test clock-29.241 {time parsing} {
    clock scan {2440588 12:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %P}
} 3540
test clock-29.242 {time parsing} {
    clock scan {2440588 12:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %P}
} 3540
test clock-29.243 {time parsing} {
    clock scan {2440588 12:59:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 3540
test clock-29.244 {time parsing} {
    clock scan {2440588 12:lix:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 3540
test clock-29.245 {time parsing} {
    clock scan {2440588 xii:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %P}
} 3540
test clock-29.246 {time parsing} {
    clock scan {2440588 xii:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %P}
} 3540
test clock-29.247 {time parsing} {
    clock scan {2440588 xii:59:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 3540
test clock-29.248 {time parsing} {
    clock scan {2440588 xii:lix:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 3540
test clock-29.249 {time parsing} {
    clock scan {2440588 xii:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %P}
} 3540
test clock-29.250 {time parsing} {
    clock scan {2440588 xii:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %P}
} 3540
test clock-29.251 {time parsing} {
    clock scan {2440588 xii:59:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 3540
test clock-29.252 {time parsing} {
    clock scan {2440588 xii:lix:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 3540
test clock-29.253 {time parsing} {
    clock scan {2440588 00:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 3541
test clock-29.254 {time parsing} {
    clock scan {2440588 00:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 3541
test clock-29.255 {time parsing} {
    clock scan {2440588  0:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 3541
test clock-29.256 {time parsing} {
    clock scan {2440588  0:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 3541
test clock-29.257 {time parsing} {
    clock scan {2440588 ?:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 3541
test clock-29.258 {time parsing} {
    clock scan {2440588 ?:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 3541
test clock-29.259 {time parsing} {
    clock scan {2440588 ?:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 3541
test clock-29.260 {time parsing} {
    clock scan {2440588 ?:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 3541
test clock-29.261 {time parsing} {
    clock scan {2440588 12:59:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 3541
test clock-29.262 {time parsing} {
    clock scan {2440588 12:lix:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 3541
test clock-29.263 {time parsing} {
    clock scan {2440588 12:59:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 3541
test clock-29.264 {time parsing} {
    clock scan {2440588 12:lix:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 3541
test clock-29.265 {time parsing} {
    clock scan {2440588 xii:59:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 3541
test clock-29.266 {time parsing} {
    clock scan {2440588 xii:lix:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 3541
test clock-29.267 {time parsing} {
    clock scan {2440588 xii:59:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 3541
test clock-29.268 {time parsing} {
    clock scan {2440588 xii:lix:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 3541
test clock-29.269 {time parsing} {
    clock scan {2440588 12:59:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 3541
test clock-29.270 {time parsing} {
    clock scan {2440588 12:lix:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 3541
test clock-29.271 {time parsing} {
    clock scan {2440588 12:59:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 3541
test clock-29.272 {time parsing} {
    clock scan {2440588 12:lix:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 3541
test clock-29.273 {time parsing} {
    clock scan {2440588 xii:59:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 3541
test clock-29.274 {time parsing} {
    clock scan {2440588 xii:lix:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 3541
test clock-29.275 {time parsing} {
    clock scan {2440588 xii:59:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 3541
test clock-29.276 {time parsing} {
    clock scan {2440588 xii:lix:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 3541
test clock-29.277 {time parsing} {
    clock scan {2440588 00:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 3599
test clock-29.278 {time parsing} {
    clock scan {2440588 00:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 3599
test clock-29.279 {time parsing} {
    clock scan {2440588  0:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 3599
test clock-29.280 {time parsing} {
    clock scan {2440588  0:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 3599
test clock-29.281 {time parsing} {
    clock scan {2440588 ?:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 3599
test clock-29.282 {time parsing} {
    clock scan {2440588 ?:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 3599
test clock-29.283 {time parsing} {
    clock scan {2440588 ?:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 3599
test clock-29.284 {time parsing} {
    clock scan {2440588 ?:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 3599
test clock-29.285 {time parsing} {
    clock scan {2440588 12:59:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 3599
test clock-29.286 {time parsing} {
    clock scan {2440588 12:lix:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 3599
test clock-29.287 {time parsing} {
    clock scan {2440588 12:59:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 3599
test clock-29.288 {time parsing} {
    clock scan {2440588 12:lix:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 3599
test clock-29.289 {time parsing} {
    clock scan {2440588 xii:59:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 3599
test clock-29.290 {time parsing} {
    clock scan {2440588 xii:lix:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 3599
test clock-29.291 {time parsing} {
    clock scan {2440588 xii:59:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 3599
test clock-29.292 {time parsing} {
    clock scan {2440588 xii:lix:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 3599
test clock-29.293 {time parsing} {
    clock scan {2440588 12:59:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 3599
test clock-29.294 {time parsing} {
    clock scan {2440588 12:lix:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 3599
test clock-29.295 {time parsing} {
    clock scan {2440588 12:59:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 3599
test clock-29.296 {time parsing} {
    clock scan {2440588 12:lix:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 3599
test clock-29.297 {time parsing} {
    clock scan {2440588 xii:59:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 3599
test clock-29.298 {time parsing} {
    clock scan {2440588 xii:lix:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 3599
test clock-29.299 {time parsing} {
    clock scan {2440588 xii:59:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 3599
test clock-29.300 {time parsing} {
    clock scan {2440588 xii:lix:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 3599
test clock-29.301 {time parsing} {
    clock scan {2440588 01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H }
} 3600
test clock-29.302 {time parsing} {
    clock scan {2440588 01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M }
} 3600
test clock-29.303 {time parsing} {
    clock scan {2440588 01:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM }
} 3600
test clock-29.304 {time parsing} {
    clock scan {2440588 01:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 3600
test clock-29.305 {time parsing} {
    clock scan {2440588 01:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 3600
test clock-29.306 {time parsing} {
    clock scan {2440588  1 } \
        -gmt true -locale en_US_roman \
        -format {%J %k }
} 3600
test clock-29.307 {time parsing} {
    clock scan {2440588  1:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M }
} 3600
test clock-29.308 {time parsing} {
    clock scan {2440588  1:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM }
} 3600
test clock-29.309 {time parsing} {
    clock scan {2440588  1:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 3600
test clock-29.310 {time parsing} {
    clock scan {2440588  1:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 3600
test clock-29.311 {time parsing} {
    clock scan {2440588 i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH }
} 3600
test clock-29.312 {time parsing} {
    clock scan {2440588 i:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M }
} 3600
test clock-29.313 {time parsing} {
    clock scan {2440588 i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM }
} 3600
test clock-29.314 {time parsing} {
    clock scan {2440588 i:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 3600
test clock-29.315 {time parsing} {
    clock scan {2440588 i:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 3600
test clock-29.316 {time parsing} {
    clock scan {2440588 i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok }
} 3600
test clock-29.317 {time parsing} {
    clock scan {2440588 i:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M }
} 3600
test clock-29.318 {time parsing} {
    clock scan {2440588 i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM }
} 3600
test clock-29.319 {time parsing} {
    clock scan {2440588 i:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 3600
test clock-29.320 {time parsing} {
    clock scan {2440588 i:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 3600
test clock-29.321 {time parsing} {
    clock scan {2440588 01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I %p}
} 3600
test clock-29.322 {time parsing} {
    clock scan {2440588 01:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %p}
} 3600
test clock-29.323 {time parsing} {
    clock scan {2440588 01:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %p}
} 3600
test clock-29.324 {time parsing} {
    clock scan {2440588 01:00:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 3600
test clock-29.325 {time parsing} {
    clock scan {2440588 01:?:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 3600
test clock-29.326 {time parsing} {
    clock scan {2440588  1 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l %p}
} 3600
test clock-29.327 {time parsing} {
    clock scan {2440588  1:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %p}
} 3600
test clock-29.328 {time parsing} {
    clock scan {2440588  1:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %p}
} 3600
test clock-29.329 {time parsing} {
    clock scan {2440588  1:00:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 3600
test clock-29.330 {time parsing} {
    clock scan {2440588  1:?:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 3600
test clock-29.331 {time parsing} {
    clock scan {2440588 i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI %p}
} 3600
test clock-29.332 {time parsing} {
    clock scan {2440588 i:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %p}
} 3600
test clock-29.333 {time parsing} {
    clock scan {2440588 i:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %p}
} 3600
test clock-29.334 {time parsing} {
    clock scan {2440588 i:00:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 3600
test clock-29.335 {time parsing} {
    clock scan {2440588 i:?:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 3600
test clock-29.336 {time parsing} {
    clock scan {2440588 i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol %p}
} 3600
test clock-29.337 {time parsing} {
    clock scan {2440588 i:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %p}
} 3600
test clock-29.338 {time parsing} {
    clock scan {2440588 i:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %p}
} 3600
test clock-29.339 {time parsing} {
    clock scan {2440588 i:00:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 3600
test clock-29.340 {time parsing} {
    clock scan {2440588 i:?:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 3600
test clock-29.341 {time parsing} {
    clock scan {2440588 01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I %P}
} 3600
test clock-29.342 {time parsing} {
    clock scan {2440588 01:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %P}
} 3600
test clock-29.343 {time parsing} {
    clock scan {2440588 01:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %P}
} 3600
test clock-29.344 {time parsing} {
    clock scan {2440588 01:00:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 3600
test clock-29.345 {time parsing} {
    clock scan {2440588 01:?:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 3600
test clock-29.346 {time parsing} {
    clock scan {2440588  1 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l %P}
} 3600
test clock-29.347 {time parsing} {
    clock scan {2440588  1:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %P}
} 3600
test clock-29.348 {time parsing} {
    clock scan {2440588  1:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %P}
} 3600
test clock-29.349 {time parsing} {
    clock scan {2440588  1:00:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 3600
test clock-29.350 {time parsing} {
    clock scan {2440588  1:?:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 3600
test clock-29.351 {time parsing} {
    clock scan {2440588 i am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI %P}
} 3600
test clock-29.352 {time parsing} {
    clock scan {2440588 i:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %P}
} 3600
test clock-29.353 {time parsing} {
    clock scan {2440588 i:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %P}
} 3600
test clock-29.354 {time parsing} {
    clock scan {2440588 i:00:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 3600
test clock-29.355 {time parsing} {
    clock scan {2440588 i:?:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 3600
test clock-29.356 {time parsing} {
    clock scan {2440588 i am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol %P}
} 3600
test clock-29.357 {time parsing} {
    clock scan {2440588 i:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %P}
} 3600
test clock-29.358 {time parsing} {
    clock scan {2440588 i:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %P}
} 3600
test clock-29.359 {time parsing} {
    clock scan {2440588 i:00:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 3600
test clock-29.360 {time parsing} {
    clock scan {2440588 i:?:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 3600
test clock-29.361 {time parsing} {
    clock scan {2440588 01:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 3601
test clock-29.362 {time parsing} {
    clock scan {2440588 01:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 3601
test clock-29.363 {time parsing} {
    clock scan {2440588  1:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 3601
test clock-29.364 {time parsing} {
    clock scan {2440588  1:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 3601
test clock-29.365 {time parsing} {
    clock scan {2440588 i:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 3601
test clock-29.366 {time parsing} {
    clock scan {2440588 i:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 3601
test clock-29.367 {time parsing} {
    clock scan {2440588 i:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 3601
test clock-29.368 {time parsing} {
    clock scan {2440588 i:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 3601
test clock-29.369 {time parsing} {
    clock scan {2440588 01:00:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 3601
test clock-29.370 {time parsing} {
    clock scan {2440588 01:?:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 3601
test clock-29.371 {time parsing} {
    clock scan {2440588  1:00:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 3601
test clock-29.372 {time parsing} {
    clock scan {2440588  1:?:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 3601
test clock-29.373 {time parsing} {
    clock scan {2440588 i:00:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 3601
test clock-29.374 {time parsing} {
    clock scan {2440588 i:?:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 3601
test clock-29.375 {time parsing} {
    clock scan {2440588 i:00:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 3601
test clock-29.376 {time parsing} {
    clock scan {2440588 i:?:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 3601
test clock-29.377 {time parsing} {
    clock scan {2440588 01:00:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 3601
test clock-29.378 {time parsing} {
    clock scan {2440588 01:?:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 3601
test clock-29.379 {time parsing} {
    clock scan {2440588  1:00:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 3601
test clock-29.380 {time parsing} {
    clock scan {2440588  1:?:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 3601
test clock-29.381 {time parsing} {
    clock scan {2440588 i:00:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 3601
test clock-29.382 {time parsing} {
    clock scan {2440588 i:?:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 3601
test clock-29.383 {time parsing} {
    clock scan {2440588 i:00:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 3601
test clock-29.384 {time parsing} {
    clock scan {2440588 i:?:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 3601
test clock-29.385 {time parsing} {
    clock scan {2440588 01:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 3659
test clock-29.386 {time parsing} {
    clock scan {2440588 01:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 3659
test clock-29.387 {time parsing} {
    clock scan {2440588  1:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 3659
test clock-29.388 {time parsing} {
    clock scan {2440588  1:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 3659
test clock-29.389 {time parsing} {
    clock scan {2440588 i:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 3659
test clock-29.390 {time parsing} {
    clock scan {2440588 i:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 3659
test clock-29.391 {time parsing} {
    clock scan {2440588 i:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 3659
test clock-29.392 {time parsing} {
    clock scan {2440588 i:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 3659
test clock-29.393 {time parsing} {
    clock scan {2440588 01:00:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 3659
test clock-29.394 {time parsing} {
    clock scan {2440588 01:?:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 3659
test clock-29.395 {time parsing} {
    clock scan {2440588  1:00:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 3659
test clock-29.396 {time parsing} {
    clock scan {2440588  1:?:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 3659
test clock-29.397 {time parsing} {
    clock scan {2440588 i:00:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 3659
test clock-29.398 {time parsing} {
    clock scan {2440588 i:?:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 3659
test clock-29.399 {time parsing} {
    clock scan {2440588 i:00:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 3659
test clock-29.400 {time parsing} {
    clock scan {2440588 i:?:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 3659
test clock-29.401 {time parsing} {
    clock scan {2440588 01:00:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 3659
test clock-29.402 {time parsing} {
    clock scan {2440588 01:?:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 3659
test clock-29.403 {time parsing} {
    clock scan {2440588  1:00:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 3659
test clock-29.404 {time parsing} {
    clock scan {2440588  1:?:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 3659
test clock-29.405 {time parsing} {
    clock scan {2440588 i:00:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 3659
test clock-29.406 {time parsing} {
    clock scan {2440588 i:?:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 3659
test clock-29.407 {time parsing} {
    clock scan {2440588 i:00:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 3659
test clock-29.408 {time parsing} {
    clock scan {2440588 i:?:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 3659
test clock-29.409 {time parsing} {
    clock scan {2440588 01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M }
} 3660
test clock-29.410 {time parsing} {
    clock scan {2440588 01:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM }
} 3660
test clock-29.411 {time parsing} {
    clock scan {2440588 01:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 3660
test clock-29.412 {time parsing} {
    clock scan {2440588 01:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 3660
test clock-29.413 {time parsing} {
    clock scan {2440588  1:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M }
} 3660
test clock-29.414 {time parsing} {
    clock scan {2440588  1:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM }
} 3660
test clock-29.415 {time parsing} {
    clock scan {2440588  1:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 3660
test clock-29.416 {time parsing} {
    clock scan {2440588  1:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 3660
test clock-29.417 {time parsing} {
    clock scan {2440588 i:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M }
} 3660
test clock-29.418 {time parsing} {
    clock scan {2440588 i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM }
} 3660
test clock-29.419 {time parsing} {
    clock scan {2440588 i:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 3660
test clock-29.420 {time parsing} {
    clock scan {2440588 i:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 3660
test clock-29.421 {time parsing} {
    clock scan {2440588 i:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M }
} 3660
test clock-29.422 {time parsing} {
    clock scan {2440588 i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM }
} 3660
test clock-29.423 {time parsing} {
    clock scan {2440588 i:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 3660
test clock-29.424 {time parsing} {
    clock scan {2440588 i:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 3660
test clock-29.425 {time parsing} {
    clock scan {2440588 01:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %p}
} 3660
test clock-29.426 {time parsing} {
    clock scan {2440588 01:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %p}
} 3660
test clock-29.427 {time parsing} {
    clock scan {2440588 01:01:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 3660
test clock-29.428 {time parsing} {
    clock scan {2440588 01:i:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 3660
test clock-29.429 {time parsing} {
    clock scan {2440588  1:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %p}
} 3660
test clock-29.430 {time parsing} {
    clock scan {2440588  1:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %p}
} 3660
test clock-29.431 {time parsing} {
    clock scan {2440588  1:01:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 3660
test clock-29.432 {time parsing} {
    clock scan {2440588  1:i:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 3660
test clock-29.433 {time parsing} {
    clock scan {2440588 i:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %p}
} 3660
test clock-29.434 {time parsing} {
    clock scan {2440588 i:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %p}
} 3660
test clock-29.435 {time parsing} {
    clock scan {2440588 i:01:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 3660
test clock-29.436 {time parsing} {
    clock scan {2440588 i:i:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 3660
test clock-29.437 {time parsing} {
    clock scan {2440588 i:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %p}
} 3660
test clock-29.438 {time parsing} {
    clock scan {2440588 i:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %p}
} 3660
test clock-29.439 {time parsing} {
    clock scan {2440588 i:01:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 3660
test clock-29.440 {time parsing} {
    clock scan {2440588 i:i:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 3660
test clock-29.441 {time parsing} {
    clock scan {2440588 01:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %P}
} 3660
test clock-29.442 {time parsing} {
    clock scan {2440588 01:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %P}
} 3660
test clock-29.443 {time parsing} {
    clock scan {2440588 01:01:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 3660
test clock-29.444 {time parsing} {
    clock scan {2440588 01:i:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 3660
test clock-29.445 {time parsing} {
    clock scan {2440588  1:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %P}
} 3660
test clock-29.446 {time parsing} {
    clock scan {2440588  1:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %P}
} 3660
test clock-29.447 {time parsing} {
    clock scan {2440588  1:01:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 3660
test clock-29.448 {time parsing} {
    clock scan {2440588  1:i:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 3660
test clock-29.449 {time parsing} {
    clock scan {2440588 i:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %P}
} 3660
test clock-29.450 {time parsing} {
    clock scan {2440588 i:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %P}
} 3660
test clock-29.451 {time parsing} {
    clock scan {2440588 i:01:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 3660
test clock-29.452 {time parsing} {
    clock scan {2440588 i:i:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 3660
test clock-29.453 {time parsing} {
    clock scan {2440588 i:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %P}
} 3660
test clock-29.454 {time parsing} {
    clock scan {2440588 i:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %P}
} 3660
test clock-29.455 {time parsing} {
    clock scan {2440588 i:01:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 3660
test clock-29.456 {time parsing} {
    clock scan {2440588 i:i:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 3660
test clock-29.457 {time parsing} {
    clock scan {2440588 01:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 3661
test clock-29.458 {time parsing} {
    clock scan {2440588 01:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 3661
test clock-29.459 {time parsing} {
    clock scan {2440588  1:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 3661
test clock-29.460 {time parsing} {
    clock scan {2440588  1:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 3661
test clock-29.461 {time parsing} {
    clock scan {2440588 i:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 3661
test clock-29.462 {time parsing} {
    clock scan {2440588 i:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 3661
test clock-29.463 {time parsing} {
    clock scan {2440588 i:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 3661
test clock-29.464 {time parsing} {
    clock scan {2440588 i:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 3661
test clock-29.465 {time parsing} {
    clock scan {2440588 01:01:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 3661
test clock-29.466 {time parsing} {
    clock scan {2440588 01:i:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 3661
test clock-29.467 {time parsing} {
    clock scan {2440588  1:01:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 3661
test clock-29.468 {time parsing} {
    clock scan {2440588  1:i:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 3661
test clock-29.469 {time parsing} {
    clock scan {2440588 i:01:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 3661
test clock-29.470 {time parsing} {
    clock scan {2440588 i:i:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 3661
test clock-29.471 {time parsing} {
    clock scan {2440588 i:01:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 3661
test clock-29.472 {time parsing} {
    clock scan {2440588 i:i:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 3661
test clock-29.473 {time parsing} {
    clock scan {2440588 01:01:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 3661
test clock-29.474 {time parsing} {
    clock scan {2440588 01:i:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 3661
test clock-29.475 {time parsing} {
    clock scan {2440588  1:01:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 3661
test clock-29.476 {time parsing} {
    clock scan {2440588  1:i:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 3661
test clock-29.477 {time parsing} {
    clock scan {2440588 i:01:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 3661
test clock-29.478 {time parsing} {
    clock scan {2440588 i:i:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 3661
test clock-29.479 {time parsing} {
    clock scan {2440588 i:01:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 3661
test clock-29.480 {time parsing} {
    clock scan {2440588 i:i:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 3661
test clock-29.481 {time parsing} {
    clock scan {2440588 01:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 3719
test clock-29.482 {time parsing} {
    clock scan {2440588 01:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 3719
test clock-29.483 {time parsing} {
    clock scan {2440588  1:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 3719
test clock-29.484 {time parsing} {
    clock scan {2440588  1:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 3719
test clock-29.485 {time parsing} {
    clock scan {2440588 i:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 3719
test clock-29.486 {time parsing} {
    clock scan {2440588 i:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 3719
test clock-29.487 {time parsing} {
    clock scan {2440588 i:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 3719
test clock-29.488 {time parsing} {
    clock scan {2440588 i:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 3719
test clock-29.489 {time parsing} {
    clock scan {2440588 01:01:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 3719
test clock-29.490 {time parsing} {
    clock scan {2440588 01:i:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 3719
test clock-29.491 {time parsing} {
    clock scan {2440588  1:01:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 3719
test clock-29.492 {time parsing} {
    clock scan {2440588  1:i:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 3719
test clock-29.493 {time parsing} {
    clock scan {2440588 i:01:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 3719
test clock-29.494 {time parsing} {
    clock scan {2440588 i:i:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 3719
test clock-29.495 {time parsing} {
    clock scan {2440588 i:01:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 3719
test clock-29.496 {time parsing} {
    clock scan {2440588 i:i:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 3719
test clock-29.497 {time parsing} {
    clock scan {2440588 01:01:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 3719
test clock-29.498 {time parsing} {
    clock scan {2440588 01:i:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 3719
test clock-29.499 {time parsing} {
    clock scan {2440588  1:01:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 3719
test clock-29.500 {time parsing} {
    clock scan {2440588  1:i:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 3719
test clock-29.501 {time parsing} {
    clock scan {2440588 i:01:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 3719
test clock-29.502 {time parsing} {
    clock scan {2440588 i:i:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 3719
test clock-29.503 {time parsing} {
    clock scan {2440588 i:01:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 3719
test clock-29.504 {time parsing} {
    clock scan {2440588 i:i:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 3719
test clock-29.505 {time parsing} {
    clock scan {2440588 01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M }
} 7140
test clock-29.506 {time parsing} {
    clock scan {2440588 01:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM }
} 7140
test clock-29.507 {time parsing} {
    clock scan {2440588 01:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 7140
test clock-29.508 {time parsing} {
    clock scan {2440588 01:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 7140
test clock-29.509 {time parsing} {
    clock scan {2440588  1:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M }
} 7140
test clock-29.510 {time parsing} {
    clock scan {2440588  1:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM }
} 7140
test clock-29.511 {time parsing} {
    clock scan {2440588  1:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 7140
test clock-29.512 {time parsing} {
    clock scan {2440588  1:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 7140
test clock-29.513 {time parsing} {
    clock scan {2440588 i:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M }
} 7140
test clock-29.514 {time parsing} {
    clock scan {2440588 i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM }
} 7140
test clock-29.515 {time parsing} {
    clock scan {2440588 i:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 7140
test clock-29.516 {time parsing} {
    clock scan {2440588 i:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 7140
test clock-29.517 {time parsing} {
    clock scan {2440588 i:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M }
} 7140
test clock-29.518 {time parsing} {
    clock scan {2440588 i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM }
} 7140
test clock-29.519 {time parsing} {
    clock scan {2440588 i:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 7140
test clock-29.520 {time parsing} {
    clock scan {2440588 i:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 7140
test clock-29.521 {time parsing} {
    clock scan {2440588 01:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %p}
} 7140
test clock-29.522 {time parsing} {
    clock scan {2440588 01:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %p}
} 7140
test clock-29.523 {time parsing} {
    clock scan {2440588 01:59:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 7140
test clock-29.524 {time parsing} {
    clock scan {2440588 01:lix:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 7140
test clock-29.525 {time parsing} {
    clock scan {2440588  1:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %p}
} 7140
test clock-29.526 {time parsing} {
    clock scan {2440588  1:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %p}
} 7140
test clock-29.527 {time parsing} {
    clock scan {2440588  1:59:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 7140
test clock-29.528 {time parsing} {
    clock scan {2440588  1:lix:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 7140
test clock-29.529 {time parsing} {
    clock scan {2440588 i:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %p}
} 7140
test clock-29.530 {time parsing} {
    clock scan {2440588 i:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %p}
} 7140
test clock-29.531 {time parsing} {
    clock scan {2440588 i:59:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 7140
test clock-29.532 {time parsing} {
    clock scan {2440588 i:lix:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 7140
test clock-29.533 {time parsing} {
    clock scan {2440588 i:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %p}
} 7140
test clock-29.534 {time parsing} {
    clock scan {2440588 i:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %p}
} 7140
test clock-29.535 {time parsing} {
    clock scan {2440588 i:59:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 7140
test clock-29.536 {time parsing} {
    clock scan {2440588 i:lix:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 7140
test clock-29.537 {time parsing} {
    clock scan {2440588 01:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %P}
} 7140
test clock-29.538 {time parsing} {
    clock scan {2440588 01:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %P}
} 7140
test clock-29.539 {time parsing} {
    clock scan {2440588 01:59:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 7140
test clock-29.540 {time parsing} {
    clock scan {2440588 01:lix:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 7140
test clock-29.541 {time parsing} {
    clock scan {2440588  1:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %P}
} 7140
test clock-29.542 {time parsing} {
    clock scan {2440588  1:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %P}
} 7140
test clock-29.543 {time parsing} {
    clock scan {2440588  1:59:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 7140
test clock-29.544 {time parsing} {
    clock scan {2440588  1:lix:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 7140
test clock-29.545 {time parsing} {
    clock scan {2440588 i:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %P}
} 7140
test clock-29.546 {time parsing} {
    clock scan {2440588 i:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %P}
} 7140
test clock-29.547 {time parsing} {
    clock scan {2440588 i:59:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 7140
test clock-29.548 {time parsing} {
    clock scan {2440588 i:lix:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 7140
test clock-29.549 {time parsing} {
    clock scan {2440588 i:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %P}
} 7140
test clock-29.550 {time parsing} {
    clock scan {2440588 i:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %P}
} 7140
test clock-29.551 {time parsing} {
    clock scan {2440588 i:59:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 7140
test clock-29.552 {time parsing} {
    clock scan {2440588 i:lix:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 7140
test clock-29.553 {time parsing} {
    clock scan {2440588 01:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 7141
test clock-29.554 {time parsing} {
    clock scan {2440588 01:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 7141
test clock-29.555 {time parsing} {
    clock scan {2440588  1:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 7141
test clock-29.556 {time parsing} {
    clock scan {2440588  1:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 7141
test clock-29.557 {time parsing} {
    clock scan {2440588 i:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 7141
test clock-29.558 {time parsing} {
    clock scan {2440588 i:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 7141
test clock-29.559 {time parsing} {
    clock scan {2440588 i:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 7141
test clock-29.560 {time parsing} {
    clock scan {2440588 i:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 7141
test clock-29.561 {time parsing} {
    clock scan {2440588 01:59:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 7141
test clock-29.562 {time parsing} {
    clock scan {2440588 01:lix:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 7141
test clock-29.563 {time parsing} {
    clock scan {2440588  1:59:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 7141
test clock-29.564 {time parsing} {
    clock scan {2440588  1:lix:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 7141
test clock-29.565 {time parsing} {
    clock scan {2440588 i:59:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 7141
test clock-29.566 {time parsing} {
    clock scan {2440588 i:lix:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 7141
test clock-29.567 {time parsing} {
    clock scan {2440588 i:59:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 7141
test clock-29.568 {time parsing} {
    clock scan {2440588 i:lix:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 7141
test clock-29.569 {time parsing} {
    clock scan {2440588 01:59:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 7141
test clock-29.570 {time parsing} {
    clock scan {2440588 01:lix:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 7141
test clock-29.571 {time parsing} {
    clock scan {2440588  1:59:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 7141
test clock-29.572 {time parsing} {
    clock scan {2440588  1:lix:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 7141
test clock-29.573 {time parsing} {
    clock scan {2440588 i:59:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 7141
test clock-29.574 {time parsing} {
    clock scan {2440588 i:lix:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 7141
test clock-29.575 {time parsing} {
    clock scan {2440588 i:59:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 7141
test clock-29.576 {time parsing} {
    clock scan {2440588 i:lix:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 7141
test clock-29.577 {time parsing} {
    clock scan {2440588 01:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 7199
test clock-29.578 {time parsing} {
    clock scan {2440588 01:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 7199
test clock-29.579 {time parsing} {
    clock scan {2440588  1:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 7199
test clock-29.580 {time parsing} {
    clock scan {2440588  1:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 7199
test clock-29.581 {time parsing} {
    clock scan {2440588 i:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 7199
test clock-29.582 {time parsing} {
    clock scan {2440588 i:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 7199
test clock-29.583 {time parsing} {
    clock scan {2440588 i:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 7199
test clock-29.584 {time parsing} {
    clock scan {2440588 i:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 7199
test clock-29.585 {time parsing} {
    clock scan {2440588 01:59:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 7199
test clock-29.586 {time parsing} {
    clock scan {2440588 01:lix:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 7199
test clock-29.587 {time parsing} {
    clock scan {2440588  1:59:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 7199
test clock-29.588 {time parsing} {
    clock scan {2440588  1:lix:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 7199
test clock-29.589 {time parsing} {
    clock scan {2440588 i:59:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 7199
test clock-29.590 {time parsing} {
    clock scan {2440588 i:lix:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 7199
test clock-29.591 {time parsing} {
    clock scan {2440588 i:59:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 7199
test clock-29.592 {time parsing} {
    clock scan {2440588 i:lix:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 7199
test clock-29.593 {time parsing} {
    clock scan {2440588 01:59:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 7199
test clock-29.594 {time parsing} {
    clock scan {2440588 01:lix:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 7199
test clock-29.595 {time parsing} {
    clock scan {2440588  1:59:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 7199
test clock-29.596 {time parsing} {
    clock scan {2440588  1:lix:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 7199
test clock-29.597 {time parsing} {
    clock scan {2440588 i:59:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 7199
test clock-29.598 {time parsing} {
    clock scan {2440588 i:lix:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 7199
test clock-29.599 {time parsing} {
    clock scan {2440588 i:59:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 7199
test clock-29.600 {time parsing} {
    clock scan {2440588 i:lix:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 7199
test clock-29.601 {time parsing} {
    clock scan {2440588 11 } \
        -gmt true -locale en_US_roman \
        -format {%J %H }
} 39600
test clock-29.602 {time parsing} {
    clock scan {2440588 11:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M }
} 39600
test clock-29.603 {time parsing} {
    clock scan {2440588 11:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM }
} 39600
test clock-29.604 {time parsing} {
    clock scan {2440588 11:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 39600
test clock-29.605 {time parsing} {
    clock scan {2440588 11:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 39600
test clock-29.606 {time parsing} {
    clock scan {2440588 11 } \
        -gmt true -locale en_US_roman \
        -format {%J %k }
} 39600
test clock-29.607 {time parsing} {
    clock scan {2440588 11:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M }
} 39600
test clock-29.608 {time parsing} {
    clock scan {2440588 11:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM }
} 39600
test clock-29.609 {time parsing} {
    clock scan {2440588 11:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 39600
test clock-29.610 {time parsing} {
    clock scan {2440588 11:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 39600
test clock-29.611 {time parsing} {
    clock scan {2440588 xi } \
        -gmt true -locale en_US_roman \
        -format {%J %OH }
} 39600
test clock-29.612 {time parsing} {
    clock scan {2440588 xi:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M }
} 39600
test clock-29.613 {time parsing} {
    clock scan {2440588 xi:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM }
} 39600
test clock-29.614 {time parsing} {
    clock scan {2440588 xi:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 39600
test clock-29.615 {time parsing} {
    clock scan {2440588 xi:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 39600
test clock-29.616 {time parsing} {
    clock scan {2440588 xi } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok }
} 39600
test clock-29.617 {time parsing} {
    clock scan {2440588 xi:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M }
} 39600
test clock-29.618 {time parsing} {
    clock scan {2440588 xi:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM }
} 39600
test clock-29.619 {time parsing} {
    clock scan {2440588 xi:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 39600
test clock-29.620 {time parsing} {
    clock scan {2440588 xi:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 39600
test clock-29.621 {time parsing} {
    clock scan {2440588 11 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I %p}
} 39600
test clock-29.622 {time parsing} {
    clock scan {2440588 11:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %p}
} 39600
test clock-29.623 {time parsing} {
    clock scan {2440588 11:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %p}
} 39600
test clock-29.624 {time parsing} {
    clock scan {2440588 11:00:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 39600
test clock-29.625 {time parsing} {
    clock scan {2440588 11:?:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 39600
test clock-29.626 {time parsing} {
    clock scan {2440588 11 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l %p}
} 39600
test clock-29.627 {time parsing} {
    clock scan {2440588 11:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %p}
} 39600
test clock-29.628 {time parsing} {
    clock scan {2440588 11:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %p}
} 39600
test clock-29.629 {time parsing} {
    clock scan {2440588 11:00:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 39600
test clock-29.630 {time parsing} {
    clock scan {2440588 11:?:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 39600
test clock-29.631 {time parsing} {
    clock scan {2440588 xi AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI %p}
} 39600
test clock-29.632 {time parsing} {
    clock scan {2440588 xi:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %p}
} 39600
test clock-29.633 {time parsing} {
    clock scan {2440588 xi:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %p}
} 39600
test clock-29.634 {time parsing} {
    clock scan {2440588 xi:00:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 39600
test clock-29.635 {time parsing} {
    clock scan {2440588 xi:?:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 39600
test clock-29.636 {time parsing} {
    clock scan {2440588 xi AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol %p}
} 39600
test clock-29.637 {time parsing} {
    clock scan {2440588 xi:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %p}
} 39600
test clock-29.638 {time parsing} {
    clock scan {2440588 xi:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %p}
} 39600
test clock-29.639 {time parsing} {
    clock scan {2440588 xi:00:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 39600
test clock-29.640 {time parsing} {
    clock scan {2440588 xi:?:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 39600
test clock-29.641 {time parsing} {
    clock scan {2440588 11 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I %P}
} 39600
test clock-29.642 {time parsing} {
    clock scan {2440588 11:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %P}
} 39600
test clock-29.643 {time parsing} {
    clock scan {2440588 11:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %P}
} 39600
test clock-29.644 {time parsing} {
    clock scan {2440588 11:00:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 39600
test clock-29.645 {time parsing} {
    clock scan {2440588 11:?:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 39600
test clock-29.646 {time parsing} {
    clock scan {2440588 11 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l %P}
} 39600
test clock-29.647 {time parsing} {
    clock scan {2440588 11:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %P}
} 39600
test clock-29.648 {time parsing} {
    clock scan {2440588 11:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %P}
} 39600
test clock-29.649 {time parsing} {
    clock scan {2440588 11:00:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 39600
test clock-29.650 {time parsing} {
    clock scan {2440588 11:?:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 39600
test clock-29.651 {time parsing} {
    clock scan {2440588 xi am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI %P}
} 39600
test clock-29.652 {time parsing} {
    clock scan {2440588 xi:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %P}
} 39600
test clock-29.653 {time parsing} {
    clock scan {2440588 xi:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %P}
} 39600
test clock-29.654 {time parsing} {
    clock scan {2440588 xi:00:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 39600
test clock-29.655 {time parsing} {
    clock scan {2440588 xi:?:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 39600
test clock-29.656 {time parsing} {
    clock scan {2440588 xi am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol %P}
} 39600
test clock-29.657 {time parsing} {
    clock scan {2440588 xi:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %P}
} 39600
test clock-29.658 {time parsing} {
    clock scan {2440588 xi:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %P}
} 39600
test clock-29.659 {time parsing} {
    clock scan {2440588 xi:00:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 39600
test clock-29.660 {time parsing} {
    clock scan {2440588 xi:?:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 39600
test clock-29.661 {time parsing} {
    clock scan {2440588 11:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 39601
test clock-29.662 {time parsing} {
    clock scan {2440588 11:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 39601
test clock-29.663 {time parsing} {
    clock scan {2440588 11:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 39601
test clock-29.664 {time parsing} {
    clock scan {2440588 11:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 39601
test clock-29.665 {time parsing} {
    clock scan {2440588 xi:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 39601
test clock-29.666 {time parsing} {
    clock scan {2440588 xi:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 39601
test clock-29.667 {time parsing} {
    clock scan {2440588 xi:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 39601
test clock-29.668 {time parsing} {
    clock scan {2440588 xi:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 39601
test clock-29.669 {time parsing} {
    clock scan {2440588 11:00:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 39601
test clock-29.670 {time parsing} {
    clock scan {2440588 11:?:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 39601
test clock-29.671 {time parsing} {
    clock scan {2440588 11:00:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 39601
test clock-29.672 {time parsing} {
    clock scan {2440588 11:?:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 39601
test clock-29.673 {time parsing} {
    clock scan {2440588 xi:00:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 39601
test clock-29.674 {time parsing} {
    clock scan {2440588 xi:?:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 39601
test clock-29.675 {time parsing} {
    clock scan {2440588 xi:00:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 39601
test clock-29.676 {time parsing} {
    clock scan {2440588 xi:?:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 39601
test clock-29.677 {time parsing} {
    clock scan {2440588 11:00:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 39601
test clock-29.678 {time parsing} {
    clock scan {2440588 11:?:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 39601
test clock-29.679 {time parsing} {
    clock scan {2440588 11:00:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 39601
test clock-29.680 {time parsing} {
    clock scan {2440588 11:?:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 39601
test clock-29.681 {time parsing} {
    clock scan {2440588 xi:00:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 39601
test clock-29.682 {time parsing} {
    clock scan {2440588 xi:?:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 39601
test clock-29.683 {time parsing} {
    clock scan {2440588 xi:00:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 39601
test clock-29.684 {time parsing} {
    clock scan {2440588 xi:?:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 39601
test clock-29.685 {time parsing} {
    clock scan {2440588 11:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 39659
test clock-29.686 {time parsing} {
    clock scan {2440588 11:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 39659
test clock-29.687 {time parsing} {
    clock scan {2440588 11:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 39659
test clock-29.688 {time parsing} {
    clock scan {2440588 11:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 39659
test clock-29.689 {time parsing} {
    clock scan {2440588 xi:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 39659
test clock-29.690 {time parsing} {
    clock scan {2440588 xi:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 39659
test clock-29.691 {time parsing} {
    clock scan {2440588 xi:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 39659
test clock-29.692 {time parsing} {
    clock scan {2440588 xi:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 39659
test clock-29.693 {time parsing} {
    clock scan {2440588 11:00:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 39659
test clock-29.694 {time parsing} {
    clock scan {2440588 11:?:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 39659
test clock-29.695 {time parsing} {
    clock scan {2440588 11:00:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 39659
test clock-29.696 {time parsing} {
    clock scan {2440588 11:?:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 39659
test clock-29.697 {time parsing} {
    clock scan {2440588 xi:00:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 39659
test clock-29.698 {time parsing} {
    clock scan {2440588 xi:?:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 39659
test clock-29.699 {time parsing} {
    clock scan {2440588 xi:00:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 39659
test clock-29.700 {time parsing} {
    clock scan {2440588 xi:?:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 39659
test clock-29.701 {time parsing} {
    clock scan {2440588 11:00:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 39659
test clock-29.702 {time parsing} {
    clock scan {2440588 11:?:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 39659
test clock-29.703 {time parsing} {
    clock scan {2440588 11:00:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 39659
test clock-29.704 {time parsing} {
    clock scan {2440588 11:?:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 39659
test clock-29.705 {time parsing} {
    clock scan {2440588 xi:00:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 39659
test clock-29.706 {time parsing} {
    clock scan {2440588 xi:?:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 39659
test clock-29.707 {time parsing} {
    clock scan {2440588 xi:00:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 39659
test clock-29.708 {time parsing} {
    clock scan {2440588 xi:?:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 39659
test clock-29.709 {time parsing} {
    clock scan {2440588 11:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M }
} 39660
test clock-29.710 {time parsing} {
    clock scan {2440588 11:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM }
} 39660
test clock-29.711 {time parsing} {
    clock scan {2440588 11:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 39660
test clock-29.712 {time parsing} {
    clock scan {2440588 11:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 39660
test clock-29.713 {time parsing} {
    clock scan {2440588 11:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M }
} 39660
test clock-29.714 {time parsing} {
    clock scan {2440588 11:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM }
} 39660
test clock-29.715 {time parsing} {
    clock scan {2440588 11:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 39660
test clock-29.716 {time parsing} {
    clock scan {2440588 11:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 39660
test clock-29.717 {time parsing} {
    clock scan {2440588 xi:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M }
} 39660
test clock-29.718 {time parsing} {
    clock scan {2440588 xi:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM }
} 39660
test clock-29.719 {time parsing} {
    clock scan {2440588 xi:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 39660
test clock-29.720 {time parsing} {
    clock scan {2440588 xi:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 39660
test clock-29.721 {time parsing} {
    clock scan {2440588 xi:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M }
} 39660
test clock-29.722 {time parsing} {
    clock scan {2440588 xi:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM }
} 39660
test clock-29.723 {time parsing} {
    clock scan {2440588 xi:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 39660
test clock-29.724 {time parsing} {
    clock scan {2440588 xi:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 39660
test clock-29.725 {time parsing} {
    clock scan {2440588 11:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %p}
} 39660
test clock-29.726 {time parsing} {
    clock scan {2440588 11:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %p}
} 39660
test clock-29.727 {time parsing} {
    clock scan {2440588 11:01:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 39660
test clock-29.728 {time parsing} {
    clock scan {2440588 11:i:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 39660
test clock-29.729 {time parsing} {
    clock scan {2440588 11:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %p}
} 39660
test clock-29.730 {time parsing} {
    clock scan {2440588 11:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %p}
} 39660
test clock-29.731 {time parsing} {
    clock scan {2440588 11:01:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 39660
test clock-29.732 {time parsing} {
    clock scan {2440588 11:i:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 39660
test clock-29.733 {time parsing} {
    clock scan {2440588 xi:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %p}
} 39660
test clock-29.734 {time parsing} {
    clock scan {2440588 xi:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %p}
} 39660
test clock-29.735 {time parsing} {
    clock scan {2440588 xi:01:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 39660
test clock-29.736 {time parsing} {
    clock scan {2440588 xi:i:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 39660
test clock-29.737 {time parsing} {
    clock scan {2440588 xi:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %p}
} 39660
test clock-29.738 {time parsing} {
    clock scan {2440588 xi:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %p}
} 39660
test clock-29.739 {time parsing} {
    clock scan {2440588 xi:01:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 39660
test clock-29.740 {time parsing} {
    clock scan {2440588 xi:i:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 39660
test clock-29.741 {time parsing} {
    clock scan {2440588 11:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %P}
} 39660
test clock-29.742 {time parsing} {
    clock scan {2440588 11:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %P}
} 39660
test clock-29.743 {time parsing} {
    clock scan {2440588 11:01:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 39660
test clock-29.744 {time parsing} {
    clock scan {2440588 11:i:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 39660
test clock-29.745 {time parsing} {
    clock scan {2440588 11:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %P}
} 39660
test clock-29.746 {time parsing} {
    clock scan {2440588 11:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %P}
} 39660
test clock-29.747 {time parsing} {
    clock scan {2440588 11:01:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 39660
test clock-29.748 {time parsing} {
    clock scan {2440588 11:i:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 39660
test clock-29.749 {time parsing} {
    clock scan {2440588 xi:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %P}
} 39660
test clock-29.750 {time parsing} {
    clock scan {2440588 xi:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %P}
} 39660
test clock-29.751 {time parsing} {
    clock scan {2440588 xi:01:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 39660
test clock-29.752 {time parsing} {
    clock scan {2440588 xi:i:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 39660
test clock-29.753 {time parsing} {
    clock scan {2440588 xi:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %P}
} 39660
test clock-29.754 {time parsing} {
    clock scan {2440588 xi:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %P}
} 39660
test clock-29.755 {time parsing} {
    clock scan {2440588 xi:01:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 39660
test clock-29.756 {time parsing} {
    clock scan {2440588 xi:i:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 39660
test clock-29.757 {time parsing} {
    clock scan {2440588 11:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 39661
test clock-29.758 {time parsing} {
    clock scan {2440588 11:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 39661
test clock-29.759 {time parsing} {
    clock scan {2440588 11:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 39661
test clock-29.760 {time parsing} {
    clock scan {2440588 11:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 39661
test clock-29.761 {time parsing} {
    clock scan {2440588 xi:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 39661
test clock-29.762 {time parsing} {
    clock scan {2440588 xi:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 39661
test clock-29.763 {time parsing} {
    clock scan {2440588 xi:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 39661
test clock-29.764 {time parsing} {
    clock scan {2440588 xi:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 39661
test clock-29.765 {time parsing} {
    clock scan {2440588 11:01:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 39661
test clock-29.766 {time parsing} {
    clock scan {2440588 11:i:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 39661
test clock-29.767 {time parsing} {
    clock scan {2440588 11:01:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 39661
test clock-29.768 {time parsing} {
    clock scan {2440588 11:i:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 39661
test clock-29.769 {time parsing} {
    clock scan {2440588 xi:01:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 39661
test clock-29.770 {time parsing} {
    clock scan {2440588 xi:i:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 39661
test clock-29.771 {time parsing} {
    clock scan {2440588 xi:01:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 39661
test clock-29.772 {time parsing} {
    clock scan {2440588 xi:i:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 39661
test clock-29.773 {time parsing} {
    clock scan {2440588 11:01:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 39661
test clock-29.774 {time parsing} {
    clock scan {2440588 11:i:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 39661
test clock-29.775 {time parsing} {
    clock scan {2440588 11:01:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 39661
test clock-29.776 {time parsing} {
    clock scan {2440588 11:i:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 39661
test clock-29.777 {time parsing} {
    clock scan {2440588 xi:01:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 39661
test clock-29.778 {time parsing} {
    clock scan {2440588 xi:i:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 39661
test clock-29.779 {time parsing} {
    clock scan {2440588 xi:01:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 39661
test clock-29.780 {time parsing} {
    clock scan {2440588 xi:i:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 39661
test clock-29.781 {time parsing} {
    clock scan {2440588 11:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 39719
test clock-29.782 {time parsing} {
    clock scan {2440588 11:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 39719
test clock-29.783 {time parsing} {
    clock scan {2440588 11:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 39719
test clock-29.784 {time parsing} {
    clock scan {2440588 11:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 39719
test clock-29.785 {time parsing} {
    clock scan {2440588 xi:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 39719
test clock-29.786 {time parsing} {
    clock scan {2440588 xi:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 39719
test clock-29.787 {time parsing} {
    clock scan {2440588 xi:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 39719
test clock-29.788 {time parsing} {
    clock scan {2440588 xi:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 39719
test clock-29.789 {time parsing} {
    clock scan {2440588 11:01:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 39719
test clock-29.790 {time parsing} {
    clock scan {2440588 11:i:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 39719
test clock-29.791 {time parsing} {
    clock scan {2440588 11:01:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 39719
test clock-29.792 {time parsing} {
    clock scan {2440588 11:i:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 39719
test clock-29.793 {time parsing} {
    clock scan {2440588 xi:01:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 39719
test clock-29.794 {time parsing} {
    clock scan {2440588 xi:i:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 39719
test clock-29.795 {time parsing} {
    clock scan {2440588 xi:01:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 39719
test clock-29.796 {time parsing} {
    clock scan {2440588 xi:i:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 39719
test clock-29.797 {time parsing} {
    clock scan {2440588 11:01:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 39719
test clock-29.798 {time parsing} {
    clock scan {2440588 11:i:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 39719
test clock-29.799 {time parsing} {
    clock scan {2440588 11:01:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 39719
test clock-29.800 {time parsing} {
    clock scan {2440588 11:i:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 39719
test clock-29.801 {time parsing} {
    clock scan {2440588 xi:01:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 39719
test clock-29.802 {time parsing} {
    clock scan {2440588 xi:i:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 39719
test clock-29.803 {time parsing} {
    clock scan {2440588 xi:01:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 39719
test clock-29.804 {time parsing} {
    clock scan {2440588 xi:i:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 39719
test clock-29.805 {time parsing} {
    clock scan {2440588 11:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M }
} 43140
test clock-29.806 {time parsing} {
    clock scan {2440588 11:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM }
} 43140
test clock-29.807 {time parsing} {
    clock scan {2440588 11:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 43140
test clock-29.808 {time parsing} {
    clock scan {2440588 11:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 43140
test clock-29.809 {time parsing} {
    clock scan {2440588 11:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M }
} 43140
test clock-29.810 {time parsing} {
    clock scan {2440588 11:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM }
} 43140
test clock-29.811 {time parsing} {
    clock scan {2440588 11:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 43140
test clock-29.812 {time parsing} {
    clock scan {2440588 11:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 43140
test clock-29.813 {time parsing} {
    clock scan {2440588 xi:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M }
} 43140
test clock-29.814 {time parsing} {
    clock scan {2440588 xi:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM }
} 43140
test clock-29.815 {time parsing} {
    clock scan {2440588 xi:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 43140
test clock-29.816 {time parsing} {
    clock scan {2440588 xi:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 43140
test clock-29.817 {time parsing} {
    clock scan {2440588 xi:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M }
} 43140
test clock-29.818 {time parsing} {
    clock scan {2440588 xi:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM }
} 43140
test clock-29.819 {time parsing} {
    clock scan {2440588 xi:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 43140
test clock-29.820 {time parsing} {
    clock scan {2440588 xi:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 43140
test clock-29.821 {time parsing} {
    clock scan {2440588 11:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %p}
} 43140
test clock-29.822 {time parsing} {
    clock scan {2440588 11:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %p}
} 43140
test clock-29.823 {time parsing} {
    clock scan {2440588 11:59:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 43140
test clock-29.824 {time parsing} {
    clock scan {2440588 11:lix:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 43140
test clock-29.825 {time parsing} {
    clock scan {2440588 11:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %p}
} 43140
test clock-29.826 {time parsing} {
    clock scan {2440588 11:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %p}
} 43140
test clock-29.827 {time parsing} {
    clock scan {2440588 11:59:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 43140
test clock-29.828 {time parsing} {
    clock scan {2440588 11:lix:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 43140
test clock-29.829 {time parsing} {
    clock scan {2440588 xi:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %p}
} 43140
test clock-29.830 {time parsing} {
    clock scan {2440588 xi:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %p}
} 43140
test clock-29.831 {time parsing} {
    clock scan {2440588 xi:59:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 43140
test clock-29.832 {time parsing} {
    clock scan {2440588 xi:lix:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 43140
test clock-29.833 {time parsing} {
    clock scan {2440588 xi:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %p}
} 43140
test clock-29.834 {time parsing} {
    clock scan {2440588 xi:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %p}
} 43140
test clock-29.835 {time parsing} {
    clock scan {2440588 xi:59:00 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 43140
test clock-29.836 {time parsing} {
    clock scan {2440588 xi:lix:? AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 43140
test clock-29.837 {time parsing} {
    clock scan {2440588 11:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %P}
} 43140
test clock-29.838 {time parsing} {
    clock scan {2440588 11:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %P}
} 43140
test clock-29.839 {time parsing} {
    clock scan {2440588 11:59:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 43140
test clock-29.840 {time parsing} {
    clock scan {2440588 11:lix:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 43140
test clock-29.841 {time parsing} {
    clock scan {2440588 11:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %P}
} 43140
test clock-29.842 {time parsing} {
    clock scan {2440588 11:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %P}
} 43140
test clock-29.843 {time parsing} {
    clock scan {2440588 11:59:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 43140
test clock-29.844 {time parsing} {
    clock scan {2440588 11:lix:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 43140
test clock-29.845 {time parsing} {
    clock scan {2440588 xi:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %P}
} 43140
test clock-29.846 {time parsing} {
    clock scan {2440588 xi:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %P}
} 43140
test clock-29.847 {time parsing} {
    clock scan {2440588 xi:59:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 43140
test clock-29.848 {time parsing} {
    clock scan {2440588 xi:lix:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 43140
test clock-29.849 {time parsing} {
    clock scan {2440588 xi:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %P}
} 43140
test clock-29.850 {time parsing} {
    clock scan {2440588 xi:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %P}
} 43140
test clock-29.851 {time parsing} {
    clock scan {2440588 xi:59:00 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 43140
test clock-29.852 {time parsing} {
    clock scan {2440588 xi:lix:? am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 43140
test clock-29.853 {time parsing} {
    clock scan {2440588 11:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 43141
test clock-29.854 {time parsing} {
    clock scan {2440588 11:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 43141
test clock-29.855 {time parsing} {
    clock scan {2440588 11:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 43141
test clock-29.856 {time parsing} {
    clock scan {2440588 11:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 43141
test clock-29.857 {time parsing} {
    clock scan {2440588 xi:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 43141
test clock-29.858 {time parsing} {
    clock scan {2440588 xi:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 43141
test clock-29.859 {time parsing} {
    clock scan {2440588 xi:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 43141
test clock-29.860 {time parsing} {
    clock scan {2440588 xi:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 43141
test clock-29.861 {time parsing} {
    clock scan {2440588 11:59:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 43141
test clock-29.862 {time parsing} {
    clock scan {2440588 11:lix:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 43141
test clock-29.863 {time parsing} {
    clock scan {2440588 11:59:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 43141
test clock-29.864 {time parsing} {
    clock scan {2440588 11:lix:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 43141
test clock-29.865 {time parsing} {
    clock scan {2440588 xi:59:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 43141
test clock-29.866 {time parsing} {
    clock scan {2440588 xi:lix:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 43141
test clock-29.867 {time parsing} {
    clock scan {2440588 xi:59:01 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 43141
test clock-29.868 {time parsing} {
    clock scan {2440588 xi:lix:i AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 43141
test clock-29.869 {time parsing} {
    clock scan {2440588 11:59:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 43141
test clock-29.870 {time parsing} {
    clock scan {2440588 11:lix:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 43141
test clock-29.871 {time parsing} {
    clock scan {2440588 11:59:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 43141
test clock-29.872 {time parsing} {
    clock scan {2440588 11:lix:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 43141
test clock-29.873 {time parsing} {
    clock scan {2440588 xi:59:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 43141
test clock-29.874 {time parsing} {
    clock scan {2440588 xi:lix:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 43141
test clock-29.875 {time parsing} {
    clock scan {2440588 xi:59:01 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 43141
test clock-29.876 {time parsing} {
    clock scan {2440588 xi:lix:i am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 43141
test clock-29.877 {time parsing} {
    clock scan {2440588 11:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 43199
test clock-29.878 {time parsing} {
    clock scan {2440588 11:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 43199
test clock-29.879 {time parsing} {
    clock scan {2440588 11:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 43199
test clock-29.880 {time parsing} {
    clock scan {2440588 11:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 43199
test clock-29.881 {time parsing} {
    clock scan {2440588 xi:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 43199
test clock-29.882 {time parsing} {
    clock scan {2440588 xi:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 43199
test clock-29.883 {time parsing} {
    clock scan {2440588 xi:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 43199
test clock-29.884 {time parsing} {
    clock scan {2440588 xi:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 43199
test clock-29.885 {time parsing} {
    clock scan {2440588 11:59:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 43199
test clock-29.886 {time parsing} {
    clock scan {2440588 11:lix:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 43199
test clock-29.887 {time parsing} {
    clock scan {2440588 11:59:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 43199
test clock-29.888 {time parsing} {
    clock scan {2440588 11:lix:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 43199
test clock-29.889 {time parsing} {
    clock scan {2440588 xi:59:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 43199
test clock-29.890 {time parsing} {
    clock scan {2440588 xi:lix:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 43199
test clock-29.891 {time parsing} {
    clock scan {2440588 xi:59:59 AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 43199
test clock-29.892 {time parsing} {
    clock scan {2440588 xi:lix:lix AM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 43199
test clock-29.893 {time parsing} {
    clock scan {2440588 11:59:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 43199
test clock-29.894 {time parsing} {
    clock scan {2440588 11:lix:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 43199
test clock-29.895 {time parsing} {
    clock scan {2440588 11:59:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 43199
test clock-29.896 {time parsing} {
    clock scan {2440588 11:lix:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 43199
test clock-29.897 {time parsing} {
    clock scan {2440588 xi:59:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 43199
test clock-29.898 {time parsing} {
    clock scan {2440588 xi:lix:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 43199
test clock-29.899 {time parsing} {
    clock scan {2440588 xi:59:59 am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 43199
test clock-29.900 {time parsing} {
    clock scan {2440588 xi:lix:lix am} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 43199
test clock-29.901 {time parsing} {
    clock scan {2440588 12 } \
        -gmt true -locale en_US_roman \
        -format {%J %H }
} 43200
test clock-29.902 {time parsing} {
    clock scan {2440588 12:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M }
} 43200
test clock-29.903 {time parsing} {
    clock scan {2440588 12:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM }
} 43200
test clock-29.904 {time parsing} {
    clock scan {2440588 12:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 43200
test clock-29.905 {time parsing} {
    clock scan {2440588 12:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 43200
test clock-29.906 {time parsing} {
    clock scan {2440588 12 } \
        -gmt true -locale en_US_roman \
        -format {%J %k }
} 43200
test clock-29.907 {time parsing} {
    clock scan {2440588 12:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M }
} 43200
test clock-29.908 {time parsing} {
    clock scan {2440588 12:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM }
} 43200
test clock-29.909 {time parsing} {
    clock scan {2440588 12:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 43200
test clock-29.910 {time parsing} {
    clock scan {2440588 12:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 43200
test clock-29.911 {time parsing} {
    clock scan {2440588 xii } \
        -gmt true -locale en_US_roman \
        -format {%J %OH }
} 43200
test clock-29.912 {time parsing} {
    clock scan {2440588 xii:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M }
} 43200
test clock-29.913 {time parsing} {
    clock scan {2440588 xii:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM }
} 43200
test clock-29.914 {time parsing} {
    clock scan {2440588 xii:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 43200
test clock-29.915 {time parsing} {
    clock scan {2440588 xii:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 43200
test clock-29.916 {time parsing} {
    clock scan {2440588 xii } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok }
} 43200
test clock-29.917 {time parsing} {
    clock scan {2440588 xii:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M }
} 43200
test clock-29.918 {time parsing} {
    clock scan {2440588 xii:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM }
} 43200
test clock-29.919 {time parsing} {
    clock scan {2440588 xii:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 43200
test clock-29.920 {time parsing} {
    clock scan {2440588 xii:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 43200
test clock-29.921 {time parsing} {
    clock scan {2440588 12 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I %p}
} 43200
test clock-29.922 {time parsing} {
    clock scan {2440588 12:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %p}
} 43200
test clock-29.923 {time parsing} {
    clock scan {2440588 12:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %p}
} 43200
test clock-29.924 {time parsing} {
    clock scan {2440588 12:00:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 43200
test clock-29.925 {time parsing} {
    clock scan {2440588 12:?:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 43200
test clock-29.926 {time parsing} {
    clock scan {2440588 12 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l %p}
} 43200
test clock-29.927 {time parsing} {
    clock scan {2440588 12:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %p}
} 43200
test clock-29.928 {time parsing} {
    clock scan {2440588 12:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %p}
} 43200
test clock-29.929 {time parsing} {
    clock scan {2440588 12:00:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 43200
test clock-29.930 {time parsing} {
    clock scan {2440588 12:?:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 43200
test clock-29.931 {time parsing} {
    clock scan {2440588 xii PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI %p}
} 43200
test clock-29.932 {time parsing} {
    clock scan {2440588 xii:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %p}
} 43200
test clock-29.933 {time parsing} {
    clock scan {2440588 xii:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %p}
} 43200
test clock-29.934 {time parsing} {
    clock scan {2440588 xii:00:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 43200
test clock-29.935 {time parsing} {
    clock scan {2440588 xii:?:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 43200
test clock-29.936 {time parsing} {
    clock scan {2440588 xii PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol %p}
} 43200
test clock-29.937 {time parsing} {
    clock scan {2440588 xii:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %p}
} 43200
test clock-29.938 {time parsing} {
    clock scan {2440588 xii:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %p}
} 43200
test clock-29.939 {time parsing} {
    clock scan {2440588 xii:00:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 43200
test clock-29.940 {time parsing} {
    clock scan {2440588 xii:?:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 43200
test clock-29.941 {time parsing} {
    clock scan {2440588 12 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I %P}
} 43200
test clock-29.942 {time parsing} {
    clock scan {2440588 12:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %P}
} 43200
test clock-29.943 {time parsing} {
    clock scan {2440588 12:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %P}
} 43200
test clock-29.944 {time parsing} {
    clock scan {2440588 12:00:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 43200
test clock-29.945 {time parsing} {
    clock scan {2440588 12:?:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 43200
test clock-29.946 {time parsing} {
    clock scan {2440588 12 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l %P}
} 43200
test clock-29.947 {time parsing} {
    clock scan {2440588 12:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %P}
} 43200
test clock-29.948 {time parsing} {
    clock scan {2440588 12:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %P}
} 43200
test clock-29.949 {time parsing} {
    clock scan {2440588 12:00:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 43200
test clock-29.950 {time parsing} {
    clock scan {2440588 12:?:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 43200
test clock-29.951 {time parsing} {
    clock scan {2440588 xii pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI %P}
} 43200
test clock-29.952 {time parsing} {
    clock scan {2440588 xii:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %P}
} 43200
test clock-29.953 {time parsing} {
    clock scan {2440588 xii:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %P}
} 43200
test clock-29.954 {time parsing} {
    clock scan {2440588 xii:00:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 43200
test clock-29.955 {time parsing} {
    clock scan {2440588 xii:?:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 43200
test clock-29.956 {time parsing} {
    clock scan {2440588 xii pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol %P}
} 43200
test clock-29.957 {time parsing} {
    clock scan {2440588 xii:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %P}
} 43200
test clock-29.958 {time parsing} {
    clock scan {2440588 xii:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %P}
} 43200
test clock-29.959 {time parsing} {
    clock scan {2440588 xii:00:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 43200
test clock-29.960 {time parsing} {
    clock scan {2440588 xii:?:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 43200
test clock-29.961 {time parsing} {
    clock scan {2440588 12:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 43201
test clock-29.962 {time parsing} {
    clock scan {2440588 12:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 43201
test clock-29.963 {time parsing} {
    clock scan {2440588 12:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 43201
test clock-29.964 {time parsing} {
    clock scan {2440588 12:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 43201
test clock-29.965 {time parsing} {
    clock scan {2440588 xii:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 43201
test clock-29.966 {time parsing} {
    clock scan {2440588 xii:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 43201
test clock-29.967 {time parsing} {
    clock scan {2440588 xii:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 43201
test clock-29.968 {time parsing} {
    clock scan {2440588 xii:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 43201
test clock-29.969 {time parsing} {
    clock scan {2440588 12:00:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 43201
test clock-29.970 {time parsing} {
    clock scan {2440588 12:?:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 43201
test clock-29.971 {time parsing} {
    clock scan {2440588 12:00:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 43201
test clock-29.972 {time parsing} {
    clock scan {2440588 12:?:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 43201
test clock-29.973 {time parsing} {
    clock scan {2440588 xii:00:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 43201
test clock-29.974 {time parsing} {
    clock scan {2440588 xii:?:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 43201
test clock-29.975 {time parsing} {
    clock scan {2440588 xii:00:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 43201
test clock-29.976 {time parsing} {
    clock scan {2440588 xii:?:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 43201
test clock-29.977 {time parsing} {
    clock scan {2440588 12:00:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 43201
test clock-29.978 {time parsing} {
    clock scan {2440588 12:?:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 43201
test clock-29.979 {time parsing} {
    clock scan {2440588 12:00:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 43201
test clock-29.980 {time parsing} {
    clock scan {2440588 12:?:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 43201
test clock-29.981 {time parsing} {
    clock scan {2440588 xii:00:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 43201
test clock-29.982 {time parsing} {
    clock scan {2440588 xii:?:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 43201
test clock-29.983 {time parsing} {
    clock scan {2440588 xii:00:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 43201
test clock-29.984 {time parsing} {
    clock scan {2440588 xii:?:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 43201
test clock-29.985 {time parsing} {
    clock scan {2440588 12:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 43259
test clock-29.986 {time parsing} {
    clock scan {2440588 12:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 43259
test clock-29.987 {time parsing} {
    clock scan {2440588 12:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 43259
test clock-29.988 {time parsing} {
    clock scan {2440588 12:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 43259
test clock-29.989 {time parsing} {
    clock scan {2440588 xii:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 43259
test clock-29.990 {time parsing} {
    clock scan {2440588 xii:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 43259
test clock-29.991 {time parsing} {
    clock scan {2440588 xii:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 43259
test clock-29.992 {time parsing} {
    clock scan {2440588 xii:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 43259
test clock-29.993 {time parsing} {
    clock scan {2440588 12:00:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 43259
test clock-29.994 {time parsing} {
    clock scan {2440588 12:?:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 43259
test clock-29.995 {time parsing} {
    clock scan {2440588 12:00:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 43259
test clock-29.996 {time parsing} {
    clock scan {2440588 12:?:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 43259
test clock-29.997 {time parsing} {
    clock scan {2440588 xii:00:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 43259
test clock-29.998 {time parsing} {
    clock scan {2440588 xii:?:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 43259
test clock-29.999 {time parsing} {
    clock scan {2440588 xii:00:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 43259
test clock-29.1000 {time parsing} {
    clock scan {2440588 xii:?:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 43259
test clock-29.1001 {time parsing} {
    clock scan {2440588 12:00:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 43259
test clock-29.1002 {time parsing} {
    clock scan {2440588 12:?:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 43259
test clock-29.1003 {time parsing} {
    clock scan {2440588 12:00:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 43259
test clock-29.1004 {time parsing} {
    clock scan {2440588 12:?:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 43259
test clock-29.1005 {time parsing} {
    clock scan {2440588 xii:00:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 43259
test clock-29.1006 {time parsing} {
    clock scan {2440588 xii:?:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 43259
test clock-29.1007 {time parsing} {
    clock scan {2440588 xii:00:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 43259
test clock-29.1008 {time parsing} {
    clock scan {2440588 xii:?:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 43259
test clock-29.1009 {time parsing} {
    clock scan {2440588 12:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M }
} 43260
test clock-29.1010 {time parsing} {
    clock scan {2440588 12:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM }
} 43260
test clock-29.1011 {time parsing} {
    clock scan {2440588 12:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 43260
test clock-29.1012 {time parsing} {
    clock scan {2440588 12:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 43260
test clock-29.1013 {time parsing} {
    clock scan {2440588 12:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M }
} 43260
test clock-29.1014 {time parsing} {
    clock scan {2440588 12:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM }
} 43260
test clock-29.1015 {time parsing} {
    clock scan {2440588 12:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 43260
test clock-29.1016 {time parsing} {
    clock scan {2440588 12:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 43260
test clock-29.1017 {time parsing} {
    clock scan {2440588 xii:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M }
} 43260
test clock-29.1018 {time parsing} {
    clock scan {2440588 xii:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM }
} 43260
test clock-29.1019 {time parsing} {
    clock scan {2440588 xii:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 43260
test clock-29.1020 {time parsing} {
    clock scan {2440588 xii:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 43260
test clock-29.1021 {time parsing} {
    clock scan {2440588 xii:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M }
} 43260
test clock-29.1022 {time parsing} {
    clock scan {2440588 xii:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM }
} 43260
test clock-29.1023 {time parsing} {
    clock scan {2440588 xii:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 43260
test clock-29.1024 {time parsing} {
    clock scan {2440588 xii:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 43260
test clock-29.1025 {time parsing} {
    clock scan {2440588 12:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %p}
} 43260
test clock-29.1026 {time parsing} {
    clock scan {2440588 12:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %p}
} 43260
test clock-29.1027 {time parsing} {
    clock scan {2440588 12:01:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 43260
test clock-29.1028 {time parsing} {
    clock scan {2440588 12:i:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 43260
test clock-29.1029 {time parsing} {
    clock scan {2440588 12:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %p}
} 43260
test clock-29.1030 {time parsing} {
    clock scan {2440588 12:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %p}
} 43260
test clock-29.1031 {time parsing} {
    clock scan {2440588 12:01:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 43260
test clock-29.1032 {time parsing} {
    clock scan {2440588 12:i:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 43260
test clock-29.1033 {time parsing} {
    clock scan {2440588 xii:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %p}
} 43260
test clock-29.1034 {time parsing} {
    clock scan {2440588 xii:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %p}
} 43260
test clock-29.1035 {time parsing} {
    clock scan {2440588 xii:01:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 43260
test clock-29.1036 {time parsing} {
    clock scan {2440588 xii:i:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 43260
test clock-29.1037 {time parsing} {
    clock scan {2440588 xii:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %p}
} 43260
test clock-29.1038 {time parsing} {
    clock scan {2440588 xii:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %p}
} 43260
test clock-29.1039 {time parsing} {
    clock scan {2440588 xii:01:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 43260
test clock-29.1040 {time parsing} {
    clock scan {2440588 xii:i:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 43260
test clock-29.1041 {time parsing} {
    clock scan {2440588 12:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %P}
} 43260
test clock-29.1042 {time parsing} {
    clock scan {2440588 12:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %P}
} 43260
test clock-29.1043 {time parsing} {
    clock scan {2440588 12:01:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 43260
test clock-29.1044 {time parsing} {
    clock scan {2440588 12:i:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 43260
test clock-29.1045 {time parsing} {
    clock scan {2440588 12:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %P}
} 43260
test clock-29.1046 {time parsing} {
    clock scan {2440588 12:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %P}
} 43260
test clock-29.1047 {time parsing} {
    clock scan {2440588 12:01:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 43260
test clock-29.1048 {time parsing} {
    clock scan {2440588 12:i:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 43260
test clock-29.1049 {time parsing} {
    clock scan {2440588 xii:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %P}
} 43260
test clock-29.1050 {time parsing} {
    clock scan {2440588 xii:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %P}
} 43260
test clock-29.1051 {time parsing} {
    clock scan {2440588 xii:01:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 43260
test clock-29.1052 {time parsing} {
    clock scan {2440588 xii:i:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 43260
test clock-29.1053 {time parsing} {
    clock scan {2440588 xii:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %P}
} 43260
test clock-29.1054 {time parsing} {
    clock scan {2440588 xii:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %P}
} 43260
test clock-29.1055 {time parsing} {
    clock scan {2440588 xii:01:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 43260
test clock-29.1056 {time parsing} {
    clock scan {2440588 xii:i:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 43260
test clock-29.1057 {time parsing} {
    clock scan {2440588 12:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 43261
test clock-29.1058 {time parsing} {
    clock scan {2440588 12:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 43261
test clock-29.1059 {time parsing} {
    clock scan {2440588 12:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 43261
test clock-29.1060 {time parsing} {
    clock scan {2440588 12:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 43261
test clock-29.1061 {time parsing} {
    clock scan {2440588 xii:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 43261
test clock-29.1062 {time parsing} {
    clock scan {2440588 xii:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 43261
test clock-29.1063 {time parsing} {
    clock scan {2440588 xii:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 43261
test clock-29.1064 {time parsing} {
    clock scan {2440588 xii:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 43261
test clock-29.1065 {time parsing} {
    clock scan {2440588 12:01:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 43261
test clock-29.1066 {time parsing} {
    clock scan {2440588 12:i:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 43261
test clock-29.1067 {time parsing} {
    clock scan {2440588 12:01:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 43261
test clock-29.1068 {time parsing} {
    clock scan {2440588 12:i:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 43261
test clock-29.1069 {time parsing} {
    clock scan {2440588 xii:01:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 43261
test clock-29.1070 {time parsing} {
    clock scan {2440588 xii:i:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 43261
test clock-29.1071 {time parsing} {
    clock scan {2440588 xii:01:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 43261
test clock-29.1072 {time parsing} {
    clock scan {2440588 xii:i:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 43261
test clock-29.1073 {time parsing} {
    clock scan {2440588 12:01:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 43261
test clock-29.1074 {time parsing} {
    clock scan {2440588 12:i:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 43261
test clock-29.1075 {time parsing} {
    clock scan {2440588 12:01:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 43261
test clock-29.1076 {time parsing} {
    clock scan {2440588 12:i:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 43261
test clock-29.1077 {time parsing} {
    clock scan {2440588 xii:01:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 43261
test clock-29.1078 {time parsing} {
    clock scan {2440588 xii:i:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 43261
test clock-29.1079 {time parsing} {
    clock scan {2440588 xii:01:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 43261
test clock-29.1080 {time parsing} {
    clock scan {2440588 xii:i:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 43261
test clock-29.1081 {time parsing} {
    clock scan {2440588 12:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 43319
test clock-29.1082 {time parsing} {
    clock scan {2440588 12:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 43319
test clock-29.1083 {time parsing} {
    clock scan {2440588 12:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 43319
test clock-29.1084 {time parsing} {
    clock scan {2440588 12:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 43319
test clock-29.1085 {time parsing} {
    clock scan {2440588 xii:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 43319
test clock-29.1086 {time parsing} {
    clock scan {2440588 xii:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 43319
test clock-29.1087 {time parsing} {
    clock scan {2440588 xii:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 43319
test clock-29.1088 {time parsing} {
    clock scan {2440588 xii:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 43319
test clock-29.1089 {time parsing} {
    clock scan {2440588 12:01:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 43319
test clock-29.1090 {time parsing} {
    clock scan {2440588 12:i:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 43319
test clock-29.1091 {time parsing} {
    clock scan {2440588 12:01:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 43319
test clock-29.1092 {time parsing} {
    clock scan {2440588 12:i:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 43319
test clock-29.1093 {time parsing} {
    clock scan {2440588 xii:01:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 43319
test clock-29.1094 {time parsing} {
    clock scan {2440588 xii:i:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 43319
test clock-29.1095 {time parsing} {
    clock scan {2440588 xii:01:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 43319
test clock-29.1096 {time parsing} {
    clock scan {2440588 xii:i:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 43319
test clock-29.1097 {time parsing} {
    clock scan {2440588 12:01:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 43319
test clock-29.1098 {time parsing} {
    clock scan {2440588 12:i:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 43319
test clock-29.1099 {time parsing} {
    clock scan {2440588 12:01:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 43319
test clock-29.1100 {time parsing} {
    clock scan {2440588 12:i:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 43319
test clock-29.1101 {time parsing} {
    clock scan {2440588 xii:01:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 43319
test clock-29.1102 {time parsing} {
    clock scan {2440588 xii:i:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 43319
test clock-29.1103 {time parsing} {
    clock scan {2440588 xii:01:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 43319
test clock-29.1104 {time parsing} {
    clock scan {2440588 xii:i:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 43319
test clock-29.1105 {time parsing} {
    clock scan {2440588 12:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M }
} 46740
test clock-29.1106 {time parsing} {
    clock scan {2440588 12:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM }
} 46740
test clock-29.1107 {time parsing} {
    clock scan {2440588 12:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 46740
test clock-29.1108 {time parsing} {
    clock scan {2440588 12:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 46740
test clock-29.1109 {time parsing} {
    clock scan {2440588 12:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M }
} 46740
test clock-29.1110 {time parsing} {
    clock scan {2440588 12:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM }
} 46740
test clock-29.1111 {time parsing} {
    clock scan {2440588 12:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 46740
test clock-29.1112 {time parsing} {
    clock scan {2440588 12:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 46740
test clock-29.1113 {time parsing} {
    clock scan {2440588 xii:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M }
} 46740
test clock-29.1114 {time parsing} {
    clock scan {2440588 xii:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM }
} 46740
test clock-29.1115 {time parsing} {
    clock scan {2440588 xii:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 46740
test clock-29.1116 {time parsing} {
    clock scan {2440588 xii:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 46740
test clock-29.1117 {time parsing} {
    clock scan {2440588 xii:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M }
} 46740
test clock-29.1118 {time parsing} {
    clock scan {2440588 xii:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM }
} 46740
test clock-29.1119 {time parsing} {
    clock scan {2440588 xii:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 46740
test clock-29.1120 {time parsing} {
    clock scan {2440588 xii:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 46740
test clock-29.1121 {time parsing} {
    clock scan {2440588 12:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %p}
} 46740
test clock-29.1122 {time parsing} {
    clock scan {2440588 12:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %p}
} 46740
test clock-29.1123 {time parsing} {
    clock scan {2440588 12:59:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 46740
test clock-29.1124 {time parsing} {
    clock scan {2440588 12:lix:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 46740
test clock-29.1125 {time parsing} {
    clock scan {2440588 12:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %p}
} 46740
test clock-29.1126 {time parsing} {
    clock scan {2440588 12:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %p}
} 46740
test clock-29.1127 {time parsing} {
    clock scan {2440588 12:59:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 46740
test clock-29.1128 {time parsing} {
    clock scan {2440588 12:lix:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 46740
test clock-29.1129 {time parsing} {
    clock scan {2440588 xii:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %p}
} 46740
test clock-29.1130 {time parsing} {
    clock scan {2440588 xii:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %p}
} 46740
test clock-29.1131 {time parsing} {
    clock scan {2440588 xii:59:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 46740
test clock-29.1132 {time parsing} {
    clock scan {2440588 xii:lix:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 46740
test clock-29.1133 {time parsing} {
    clock scan {2440588 xii:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %p}
} 46740
test clock-29.1134 {time parsing} {
    clock scan {2440588 xii:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %p}
} 46740
test clock-29.1135 {time parsing} {
    clock scan {2440588 xii:59:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 46740
test clock-29.1136 {time parsing} {
    clock scan {2440588 xii:lix:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 46740
test clock-29.1137 {time parsing} {
    clock scan {2440588 12:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %P}
} 46740
test clock-29.1138 {time parsing} {
    clock scan {2440588 12:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %P}
} 46740
test clock-29.1139 {time parsing} {
    clock scan {2440588 12:59:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 46740
test clock-29.1140 {time parsing} {
    clock scan {2440588 12:lix:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 46740
test clock-29.1141 {time parsing} {
    clock scan {2440588 12:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %P}
} 46740
test clock-29.1142 {time parsing} {
    clock scan {2440588 12:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %P}
} 46740
test clock-29.1143 {time parsing} {
    clock scan {2440588 12:59:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 46740
test clock-29.1144 {time parsing} {
    clock scan {2440588 12:lix:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 46740
test clock-29.1145 {time parsing} {
    clock scan {2440588 xii:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %P}
} 46740
test clock-29.1146 {time parsing} {
    clock scan {2440588 xii:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %P}
} 46740
test clock-29.1147 {time parsing} {
    clock scan {2440588 xii:59:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 46740
test clock-29.1148 {time parsing} {
    clock scan {2440588 xii:lix:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 46740
test clock-29.1149 {time parsing} {
    clock scan {2440588 xii:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %P}
} 46740
test clock-29.1150 {time parsing} {
    clock scan {2440588 xii:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %P}
} 46740
test clock-29.1151 {time parsing} {
    clock scan {2440588 xii:59:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 46740
test clock-29.1152 {time parsing} {
    clock scan {2440588 xii:lix:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 46740
test clock-29.1153 {time parsing} {
    clock scan {2440588 12:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 46741
test clock-29.1154 {time parsing} {
    clock scan {2440588 12:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 46741
test clock-29.1155 {time parsing} {
    clock scan {2440588 12:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 46741
test clock-29.1156 {time parsing} {
    clock scan {2440588 12:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 46741
test clock-29.1157 {time parsing} {
    clock scan {2440588 xii:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 46741
test clock-29.1158 {time parsing} {
    clock scan {2440588 xii:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 46741
test clock-29.1159 {time parsing} {
    clock scan {2440588 xii:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 46741
test clock-29.1160 {time parsing} {
    clock scan {2440588 xii:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 46741
test clock-29.1161 {time parsing} {
    clock scan {2440588 12:59:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 46741
test clock-29.1162 {time parsing} {
    clock scan {2440588 12:lix:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 46741
test clock-29.1163 {time parsing} {
    clock scan {2440588 12:59:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 46741
test clock-29.1164 {time parsing} {
    clock scan {2440588 12:lix:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 46741
test clock-29.1165 {time parsing} {
    clock scan {2440588 xii:59:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 46741
test clock-29.1166 {time parsing} {
    clock scan {2440588 xii:lix:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 46741
test clock-29.1167 {time parsing} {
    clock scan {2440588 xii:59:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 46741
test clock-29.1168 {time parsing} {
    clock scan {2440588 xii:lix:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 46741
test clock-29.1169 {time parsing} {
    clock scan {2440588 12:59:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 46741
test clock-29.1170 {time parsing} {
    clock scan {2440588 12:lix:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 46741
test clock-29.1171 {time parsing} {
    clock scan {2440588 12:59:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 46741
test clock-29.1172 {time parsing} {
    clock scan {2440588 12:lix:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 46741
test clock-29.1173 {time parsing} {
    clock scan {2440588 xii:59:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 46741
test clock-29.1174 {time parsing} {
    clock scan {2440588 xii:lix:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 46741
test clock-29.1175 {time parsing} {
    clock scan {2440588 xii:59:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 46741
test clock-29.1176 {time parsing} {
    clock scan {2440588 xii:lix:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 46741
test clock-29.1177 {time parsing} {
    clock scan {2440588 12:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 46799
test clock-29.1178 {time parsing} {
    clock scan {2440588 12:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 46799
test clock-29.1179 {time parsing} {
    clock scan {2440588 12:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 46799
test clock-29.1180 {time parsing} {
    clock scan {2440588 12:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 46799
test clock-29.1181 {time parsing} {
    clock scan {2440588 xii:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 46799
test clock-29.1182 {time parsing} {
    clock scan {2440588 xii:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 46799
test clock-29.1183 {time parsing} {
    clock scan {2440588 xii:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 46799
test clock-29.1184 {time parsing} {
    clock scan {2440588 xii:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 46799
test clock-29.1185 {time parsing} {
    clock scan {2440588 12:59:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 46799
test clock-29.1186 {time parsing} {
    clock scan {2440588 12:lix:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 46799
test clock-29.1187 {time parsing} {
    clock scan {2440588 12:59:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 46799
test clock-29.1188 {time parsing} {
    clock scan {2440588 12:lix:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 46799
test clock-29.1189 {time parsing} {
    clock scan {2440588 xii:59:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 46799
test clock-29.1190 {time parsing} {
    clock scan {2440588 xii:lix:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 46799
test clock-29.1191 {time parsing} {
    clock scan {2440588 xii:59:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 46799
test clock-29.1192 {time parsing} {
    clock scan {2440588 xii:lix:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 46799
test clock-29.1193 {time parsing} {
    clock scan {2440588 12:59:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 46799
test clock-29.1194 {time parsing} {
    clock scan {2440588 12:lix:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 46799
test clock-29.1195 {time parsing} {
    clock scan {2440588 12:59:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 46799
test clock-29.1196 {time parsing} {
    clock scan {2440588 12:lix:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 46799
test clock-29.1197 {time parsing} {
    clock scan {2440588 xii:59:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 46799
test clock-29.1198 {time parsing} {
    clock scan {2440588 xii:lix:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 46799
test clock-29.1199 {time parsing} {
    clock scan {2440588 xii:59:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 46799
test clock-29.1200 {time parsing} {
    clock scan {2440588 xii:lix:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 46799
test clock-29.1201 {time parsing} {
    clock scan {2440588 13 } \
        -gmt true -locale en_US_roman \
        -format {%J %H }
} 46800
test clock-29.1202 {time parsing} {
    clock scan {2440588 13:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M }
} 46800
test clock-29.1203 {time parsing} {
    clock scan {2440588 13:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM }
} 46800
test clock-29.1204 {time parsing} {
    clock scan {2440588 13:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 46800
test clock-29.1205 {time parsing} {
    clock scan {2440588 13:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 46800
test clock-29.1206 {time parsing} {
    clock scan {2440588 13 } \
        -gmt true -locale en_US_roman \
        -format {%J %k }
} 46800
test clock-29.1207 {time parsing} {
    clock scan {2440588 13:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M }
} 46800
test clock-29.1208 {time parsing} {
    clock scan {2440588 13:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM }
} 46800
test clock-29.1209 {time parsing} {
    clock scan {2440588 13:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 46800
test clock-29.1210 {time parsing} {
    clock scan {2440588 13:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 46800
test clock-29.1211 {time parsing} {
    clock scan {2440588 xiii } \
        -gmt true -locale en_US_roman \
        -format {%J %OH }
} 46800
test clock-29.1212 {time parsing} {
    clock scan {2440588 xiii:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M }
} 46800
test clock-29.1213 {time parsing} {
    clock scan {2440588 xiii:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM }
} 46800
test clock-29.1214 {time parsing} {
    clock scan {2440588 xiii:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 46800
test clock-29.1215 {time parsing} {
    clock scan {2440588 xiii:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 46800
test clock-29.1216 {time parsing} {
    clock scan {2440588 xiii } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok }
} 46800
test clock-29.1217 {time parsing} {
    clock scan {2440588 xiii:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M }
} 46800
test clock-29.1218 {time parsing} {
    clock scan {2440588 xiii:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM }
} 46800
test clock-29.1219 {time parsing} {
    clock scan {2440588 xiii:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 46800
test clock-29.1220 {time parsing} {
    clock scan {2440588 xiii:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 46800
test clock-29.1221 {time parsing} {
    clock scan {2440588 01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I %p}
} 46800
test clock-29.1222 {time parsing} {
    clock scan {2440588 01:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %p}
} 46800
test clock-29.1223 {time parsing} {
    clock scan {2440588 01:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %p}
} 46800
test clock-29.1224 {time parsing} {
    clock scan {2440588 01:00:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 46800
test clock-29.1225 {time parsing} {
    clock scan {2440588 01:?:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 46800
test clock-29.1226 {time parsing} {
    clock scan {2440588  1 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l %p}
} 46800
test clock-29.1227 {time parsing} {
    clock scan {2440588  1:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %p}
} 46800
test clock-29.1228 {time parsing} {
    clock scan {2440588  1:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %p}
} 46800
test clock-29.1229 {time parsing} {
    clock scan {2440588  1:00:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 46800
test clock-29.1230 {time parsing} {
    clock scan {2440588  1:?:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 46800
test clock-29.1231 {time parsing} {
    clock scan {2440588 i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI %p}
} 46800
test clock-29.1232 {time parsing} {
    clock scan {2440588 i:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %p}
} 46800
test clock-29.1233 {time parsing} {
    clock scan {2440588 i:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %p}
} 46800
test clock-29.1234 {time parsing} {
    clock scan {2440588 i:00:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 46800
test clock-29.1235 {time parsing} {
    clock scan {2440588 i:?:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 46800
test clock-29.1236 {time parsing} {
    clock scan {2440588 i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol %p}
} 46800
test clock-29.1237 {time parsing} {
    clock scan {2440588 i:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %p}
} 46800
test clock-29.1238 {time parsing} {
    clock scan {2440588 i:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %p}
} 46800
test clock-29.1239 {time parsing} {
    clock scan {2440588 i:00:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 46800
test clock-29.1240 {time parsing} {
    clock scan {2440588 i:?:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 46800
test clock-29.1241 {time parsing} {
    clock scan {2440588 01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I %P}
} 46800
test clock-29.1242 {time parsing} {
    clock scan {2440588 01:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %P}
} 46800
test clock-29.1243 {time parsing} {
    clock scan {2440588 01:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %P}
} 46800
test clock-29.1244 {time parsing} {
    clock scan {2440588 01:00:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 46800
test clock-29.1245 {time parsing} {
    clock scan {2440588 01:?:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 46800
test clock-29.1246 {time parsing} {
    clock scan {2440588  1 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l %P}
} 46800
test clock-29.1247 {time parsing} {
    clock scan {2440588  1:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %P}
} 46800
test clock-29.1248 {time parsing} {
    clock scan {2440588  1:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %P}
} 46800
test clock-29.1249 {time parsing} {
    clock scan {2440588  1:00:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 46800
test clock-29.1250 {time parsing} {
    clock scan {2440588  1:?:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 46800
test clock-29.1251 {time parsing} {
    clock scan {2440588 i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI %P}
} 46800
test clock-29.1252 {time parsing} {
    clock scan {2440588 i:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %P}
} 46800
test clock-29.1253 {time parsing} {
    clock scan {2440588 i:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %P}
} 46800
test clock-29.1254 {time parsing} {
    clock scan {2440588 i:00:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 46800
test clock-29.1255 {time parsing} {
    clock scan {2440588 i:?:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 46800
test clock-29.1256 {time parsing} {
    clock scan {2440588 i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol %P}
} 46800
test clock-29.1257 {time parsing} {
    clock scan {2440588 i:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %P}
} 46800
test clock-29.1258 {time parsing} {
    clock scan {2440588 i:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %P}
} 46800
test clock-29.1259 {time parsing} {
    clock scan {2440588 i:00:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 46800
test clock-29.1260 {time parsing} {
    clock scan {2440588 i:?:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 46800
test clock-29.1261 {time parsing} {
    clock scan {2440588 13:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 46801
test clock-29.1262 {time parsing} {
    clock scan {2440588 13:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 46801
test clock-29.1263 {time parsing} {
    clock scan {2440588 13:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 46801
test clock-29.1264 {time parsing} {
    clock scan {2440588 13:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 46801
test clock-29.1265 {time parsing} {
    clock scan {2440588 xiii:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 46801
test clock-29.1266 {time parsing} {
    clock scan {2440588 xiii:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 46801
test clock-29.1267 {time parsing} {
    clock scan {2440588 xiii:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 46801
test clock-29.1268 {time parsing} {
    clock scan {2440588 xiii:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 46801
test clock-29.1269 {time parsing} {
    clock scan {2440588 01:00:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 46801
test clock-29.1270 {time parsing} {
    clock scan {2440588 01:?:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 46801
test clock-29.1271 {time parsing} {
    clock scan {2440588  1:00:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 46801
test clock-29.1272 {time parsing} {
    clock scan {2440588  1:?:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 46801
test clock-29.1273 {time parsing} {
    clock scan {2440588 i:00:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 46801
test clock-29.1274 {time parsing} {
    clock scan {2440588 i:?:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 46801
test clock-29.1275 {time parsing} {
    clock scan {2440588 i:00:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 46801
test clock-29.1276 {time parsing} {
    clock scan {2440588 i:?:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 46801
test clock-29.1277 {time parsing} {
    clock scan {2440588 01:00:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 46801
test clock-29.1278 {time parsing} {
    clock scan {2440588 01:?:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 46801
test clock-29.1279 {time parsing} {
    clock scan {2440588  1:00:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 46801
test clock-29.1280 {time parsing} {
    clock scan {2440588  1:?:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 46801
test clock-29.1281 {time parsing} {
    clock scan {2440588 i:00:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 46801
test clock-29.1282 {time parsing} {
    clock scan {2440588 i:?:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 46801
test clock-29.1283 {time parsing} {
    clock scan {2440588 i:00:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 46801
test clock-29.1284 {time parsing} {
    clock scan {2440588 i:?:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 46801
test clock-29.1285 {time parsing} {
    clock scan {2440588 13:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 46859
test clock-29.1286 {time parsing} {
    clock scan {2440588 13:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 46859
test clock-29.1287 {time parsing} {
    clock scan {2440588 13:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 46859
test clock-29.1288 {time parsing} {
    clock scan {2440588 13:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 46859
test clock-29.1289 {time parsing} {
    clock scan {2440588 xiii:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 46859
test clock-29.1290 {time parsing} {
    clock scan {2440588 xiii:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 46859
test clock-29.1291 {time parsing} {
    clock scan {2440588 xiii:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 46859
test clock-29.1292 {time parsing} {
    clock scan {2440588 xiii:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 46859
test clock-29.1293 {time parsing} {
    clock scan {2440588 01:00:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 46859
test clock-29.1294 {time parsing} {
    clock scan {2440588 01:?:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 46859
test clock-29.1295 {time parsing} {
    clock scan {2440588  1:00:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 46859
test clock-29.1296 {time parsing} {
    clock scan {2440588  1:?:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 46859
test clock-29.1297 {time parsing} {
    clock scan {2440588 i:00:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 46859
test clock-29.1298 {time parsing} {
    clock scan {2440588 i:?:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 46859
test clock-29.1299 {time parsing} {
    clock scan {2440588 i:00:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 46859
test clock-29.1300 {time parsing} {
    clock scan {2440588 i:?:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 46859
test clock-29.1301 {time parsing} {
    clock scan {2440588 01:00:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 46859
test clock-29.1302 {time parsing} {
    clock scan {2440588 01:?:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 46859
test clock-29.1303 {time parsing} {
    clock scan {2440588  1:00:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 46859
test clock-29.1304 {time parsing} {
    clock scan {2440588  1:?:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 46859
test clock-29.1305 {time parsing} {
    clock scan {2440588 i:00:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 46859
test clock-29.1306 {time parsing} {
    clock scan {2440588 i:?:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 46859
test clock-29.1307 {time parsing} {
    clock scan {2440588 i:00:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 46859
test clock-29.1308 {time parsing} {
    clock scan {2440588 i:?:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 46859
test clock-29.1309 {time parsing} {
    clock scan {2440588 13:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M }
} 46860
test clock-29.1310 {time parsing} {
    clock scan {2440588 13:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM }
} 46860
test clock-29.1311 {time parsing} {
    clock scan {2440588 13:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 46860
test clock-29.1312 {time parsing} {
    clock scan {2440588 13:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 46860
test clock-29.1313 {time parsing} {
    clock scan {2440588 13:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M }
} 46860
test clock-29.1314 {time parsing} {
    clock scan {2440588 13:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM }
} 46860
test clock-29.1315 {time parsing} {
    clock scan {2440588 13:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 46860
test clock-29.1316 {time parsing} {
    clock scan {2440588 13:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 46860
test clock-29.1317 {time parsing} {
    clock scan {2440588 xiii:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M }
} 46860
test clock-29.1318 {time parsing} {
    clock scan {2440588 xiii:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM }
} 46860
test clock-29.1319 {time parsing} {
    clock scan {2440588 xiii:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 46860
test clock-29.1320 {time parsing} {
    clock scan {2440588 xiii:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 46860
test clock-29.1321 {time parsing} {
    clock scan {2440588 xiii:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M }
} 46860
test clock-29.1322 {time parsing} {
    clock scan {2440588 xiii:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM }
} 46860
test clock-29.1323 {time parsing} {
    clock scan {2440588 xiii:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 46860
test clock-29.1324 {time parsing} {
    clock scan {2440588 xiii:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 46860
test clock-29.1325 {time parsing} {
    clock scan {2440588 01:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %p}
} 46860
test clock-29.1326 {time parsing} {
    clock scan {2440588 01:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %p}
} 46860
test clock-29.1327 {time parsing} {
    clock scan {2440588 01:01:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 46860
test clock-29.1328 {time parsing} {
    clock scan {2440588 01:i:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 46860
test clock-29.1329 {time parsing} {
    clock scan {2440588  1:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %p}
} 46860
test clock-29.1330 {time parsing} {
    clock scan {2440588  1:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %p}
} 46860
test clock-29.1331 {time parsing} {
    clock scan {2440588  1:01:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 46860
test clock-29.1332 {time parsing} {
    clock scan {2440588  1:i:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 46860
test clock-29.1333 {time parsing} {
    clock scan {2440588 i:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %p}
} 46860
test clock-29.1334 {time parsing} {
    clock scan {2440588 i:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %p}
} 46860
test clock-29.1335 {time parsing} {
    clock scan {2440588 i:01:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 46860
test clock-29.1336 {time parsing} {
    clock scan {2440588 i:i:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 46860
test clock-29.1337 {time parsing} {
    clock scan {2440588 i:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %p}
} 46860
test clock-29.1338 {time parsing} {
    clock scan {2440588 i:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %p}
} 46860
test clock-29.1339 {time parsing} {
    clock scan {2440588 i:01:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 46860
test clock-29.1340 {time parsing} {
    clock scan {2440588 i:i:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 46860
test clock-29.1341 {time parsing} {
    clock scan {2440588 01:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %P}
} 46860
test clock-29.1342 {time parsing} {
    clock scan {2440588 01:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %P}
} 46860
test clock-29.1343 {time parsing} {
    clock scan {2440588 01:01:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 46860
test clock-29.1344 {time parsing} {
    clock scan {2440588 01:i:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 46860
test clock-29.1345 {time parsing} {
    clock scan {2440588  1:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %P}
} 46860
test clock-29.1346 {time parsing} {
    clock scan {2440588  1:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %P}
} 46860
test clock-29.1347 {time parsing} {
    clock scan {2440588  1:01:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 46860
test clock-29.1348 {time parsing} {
    clock scan {2440588  1:i:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 46860
test clock-29.1349 {time parsing} {
    clock scan {2440588 i:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %P}
} 46860
test clock-29.1350 {time parsing} {
    clock scan {2440588 i:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %P}
} 46860
test clock-29.1351 {time parsing} {
    clock scan {2440588 i:01:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 46860
test clock-29.1352 {time parsing} {
    clock scan {2440588 i:i:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 46860
test clock-29.1353 {time parsing} {
    clock scan {2440588 i:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %P}
} 46860
test clock-29.1354 {time parsing} {
    clock scan {2440588 i:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %P}
} 46860
test clock-29.1355 {time parsing} {
    clock scan {2440588 i:01:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 46860
test clock-29.1356 {time parsing} {
    clock scan {2440588 i:i:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 46860
test clock-29.1357 {time parsing} {
    clock scan {2440588 13:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 46861
test clock-29.1358 {time parsing} {
    clock scan {2440588 13:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 46861
test clock-29.1359 {time parsing} {
    clock scan {2440588 13:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 46861
test clock-29.1360 {time parsing} {
    clock scan {2440588 13:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 46861
test clock-29.1361 {time parsing} {
    clock scan {2440588 xiii:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 46861
test clock-29.1362 {time parsing} {
    clock scan {2440588 xiii:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 46861
test clock-29.1363 {time parsing} {
    clock scan {2440588 xiii:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 46861
test clock-29.1364 {time parsing} {
    clock scan {2440588 xiii:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 46861
test clock-29.1365 {time parsing} {
    clock scan {2440588 01:01:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 46861
test clock-29.1366 {time parsing} {
    clock scan {2440588 01:i:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 46861
test clock-29.1367 {time parsing} {
    clock scan {2440588  1:01:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 46861
test clock-29.1368 {time parsing} {
    clock scan {2440588  1:i:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 46861
test clock-29.1369 {time parsing} {
    clock scan {2440588 i:01:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 46861
test clock-29.1370 {time parsing} {
    clock scan {2440588 i:i:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 46861
test clock-29.1371 {time parsing} {
    clock scan {2440588 i:01:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 46861
test clock-29.1372 {time parsing} {
    clock scan {2440588 i:i:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 46861
test clock-29.1373 {time parsing} {
    clock scan {2440588 01:01:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 46861
test clock-29.1374 {time parsing} {
    clock scan {2440588 01:i:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 46861
test clock-29.1375 {time parsing} {
    clock scan {2440588  1:01:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 46861
test clock-29.1376 {time parsing} {
    clock scan {2440588  1:i:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 46861
test clock-29.1377 {time parsing} {
    clock scan {2440588 i:01:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 46861
test clock-29.1378 {time parsing} {
    clock scan {2440588 i:i:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 46861
test clock-29.1379 {time parsing} {
    clock scan {2440588 i:01:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 46861
test clock-29.1380 {time parsing} {
    clock scan {2440588 i:i:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 46861
test clock-29.1381 {time parsing} {
    clock scan {2440588 13:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 46919
test clock-29.1382 {time parsing} {
    clock scan {2440588 13:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 46919
test clock-29.1383 {time parsing} {
    clock scan {2440588 13:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 46919
test clock-29.1384 {time parsing} {
    clock scan {2440588 13:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 46919
test clock-29.1385 {time parsing} {
    clock scan {2440588 xiii:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 46919
test clock-29.1386 {time parsing} {
    clock scan {2440588 xiii:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 46919
test clock-29.1387 {time parsing} {
    clock scan {2440588 xiii:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 46919
test clock-29.1388 {time parsing} {
    clock scan {2440588 xiii:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 46919
test clock-29.1389 {time parsing} {
    clock scan {2440588 01:01:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 46919
test clock-29.1390 {time parsing} {
    clock scan {2440588 01:i:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 46919
test clock-29.1391 {time parsing} {
    clock scan {2440588  1:01:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 46919
test clock-29.1392 {time parsing} {
    clock scan {2440588  1:i:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 46919
test clock-29.1393 {time parsing} {
    clock scan {2440588 i:01:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 46919
test clock-29.1394 {time parsing} {
    clock scan {2440588 i:i:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 46919
test clock-29.1395 {time parsing} {
    clock scan {2440588 i:01:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 46919
test clock-29.1396 {time parsing} {
    clock scan {2440588 i:i:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 46919
test clock-29.1397 {time parsing} {
    clock scan {2440588 01:01:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 46919
test clock-29.1398 {time parsing} {
    clock scan {2440588 01:i:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 46919
test clock-29.1399 {time parsing} {
    clock scan {2440588  1:01:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 46919
test clock-29.1400 {time parsing} {
    clock scan {2440588  1:i:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 46919
test clock-29.1401 {time parsing} {
    clock scan {2440588 i:01:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 46919
test clock-29.1402 {time parsing} {
    clock scan {2440588 i:i:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 46919
test clock-29.1403 {time parsing} {
    clock scan {2440588 i:01:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 46919
test clock-29.1404 {time parsing} {
    clock scan {2440588 i:i:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 46919
test clock-29.1405 {time parsing} {
    clock scan {2440588 13:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M }
} 50340
test clock-29.1406 {time parsing} {
    clock scan {2440588 13:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM }
} 50340
test clock-29.1407 {time parsing} {
    clock scan {2440588 13:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 50340
test clock-29.1408 {time parsing} {
    clock scan {2440588 13:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 50340
test clock-29.1409 {time parsing} {
    clock scan {2440588 13:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M }
} 50340
test clock-29.1410 {time parsing} {
    clock scan {2440588 13:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM }
} 50340
test clock-29.1411 {time parsing} {
    clock scan {2440588 13:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 50340
test clock-29.1412 {time parsing} {
    clock scan {2440588 13:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 50340
test clock-29.1413 {time parsing} {
    clock scan {2440588 xiii:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M }
} 50340
test clock-29.1414 {time parsing} {
    clock scan {2440588 xiii:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM }
} 50340
test clock-29.1415 {time parsing} {
    clock scan {2440588 xiii:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 50340
test clock-29.1416 {time parsing} {
    clock scan {2440588 xiii:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 50340
test clock-29.1417 {time parsing} {
    clock scan {2440588 xiii:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M }
} 50340
test clock-29.1418 {time parsing} {
    clock scan {2440588 xiii:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM }
} 50340
test clock-29.1419 {time parsing} {
    clock scan {2440588 xiii:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 50340
test clock-29.1420 {time parsing} {
    clock scan {2440588 xiii:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 50340
test clock-29.1421 {time parsing} {
    clock scan {2440588 01:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %p}
} 50340
test clock-29.1422 {time parsing} {
    clock scan {2440588 01:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %p}
} 50340
test clock-29.1423 {time parsing} {
    clock scan {2440588 01:59:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 50340
test clock-29.1424 {time parsing} {
    clock scan {2440588 01:lix:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 50340
test clock-29.1425 {time parsing} {
    clock scan {2440588  1:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %p}
} 50340
test clock-29.1426 {time parsing} {
    clock scan {2440588  1:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %p}
} 50340
test clock-29.1427 {time parsing} {
    clock scan {2440588  1:59:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 50340
test clock-29.1428 {time parsing} {
    clock scan {2440588  1:lix:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 50340
test clock-29.1429 {time parsing} {
    clock scan {2440588 i:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %p}
} 50340
test clock-29.1430 {time parsing} {
    clock scan {2440588 i:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %p}
} 50340
test clock-29.1431 {time parsing} {
    clock scan {2440588 i:59:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 50340
test clock-29.1432 {time parsing} {
    clock scan {2440588 i:lix:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 50340
test clock-29.1433 {time parsing} {
    clock scan {2440588 i:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %p}
} 50340
test clock-29.1434 {time parsing} {
    clock scan {2440588 i:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %p}
} 50340
test clock-29.1435 {time parsing} {
    clock scan {2440588 i:59:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 50340
test clock-29.1436 {time parsing} {
    clock scan {2440588 i:lix:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 50340
test clock-29.1437 {time parsing} {
    clock scan {2440588 01:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %P}
} 50340
test clock-29.1438 {time parsing} {
    clock scan {2440588 01:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %P}
} 50340
test clock-29.1439 {time parsing} {
    clock scan {2440588 01:59:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 50340
test clock-29.1440 {time parsing} {
    clock scan {2440588 01:lix:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 50340
test clock-29.1441 {time parsing} {
    clock scan {2440588  1:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %P}
} 50340
test clock-29.1442 {time parsing} {
    clock scan {2440588  1:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %P}
} 50340
test clock-29.1443 {time parsing} {
    clock scan {2440588  1:59:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 50340
test clock-29.1444 {time parsing} {
    clock scan {2440588  1:lix:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 50340
test clock-29.1445 {time parsing} {
    clock scan {2440588 i:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %P}
} 50340
test clock-29.1446 {time parsing} {
    clock scan {2440588 i:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %P}
} 50340
test clock-29.1447 {time parsing} {
    clock scan {2440588 i:59:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 50340
test clock-29.1448 {time parsing} {
    clock scan {2440588 i:lix:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 50340
test clock-29.1449 {time parsing} {
    clock scan {2440588 i:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %P}
} 50340
test clock-29.1450 {time parsing} {
    clock scan {2440588 i:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %P}
} 50340
test clock-29.1451 {time parsing} {
    clock scan {2440588 i:59:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 50340
test clock-29.1452 {time parsing} {
    clock scan {2440588 i:lix:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 50340
test clock-29.1453 {time parsing} {
    clock scan {2440588 13:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 50341
test clock-29.1454 {time parsing} {
    clock scan {2440588 13:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 50341
test clock-29.1455 {time parsing} {
    clock scan {2440588 13:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 50341
test clock-29.1456 {time parsing} {
    clock scan {2440588 13:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 50341
test clock-29.1457 {time parsing} {
    clock scan {2440588 xiii:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 50341
test clock-29.1458 {time parsing} {
    clock scan {2440588 xiii:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 50341
test clock-29.1459 {time parsing} {
    clock scan {2440588 xiii:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 50341
test clock-29.1460 {time parsing} {
    clock scan {2440588 xiii:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 50341
test clock-29.1461 {time parsing} {
    clock scan {2440588 01:59:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 50341
test clock-29.1462 {time parsing} {
    clock scan {2440588 01:lix:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 50341
test clock-29.1463 {time parsing} {
    clock scan {2440588  1:59:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 50341
test clock-29.1464 {time parsing} {
    clock scan {2440588  1:lix:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 50341
test clock-29.1465 {time parsing} {
    clock scan {2440588 i:59:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 50341
test clock-29.1466 {time parsing} {
    clock scan {2440588 i:lix:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 50341
test clock-29.1467 {time parsing} {
    clock scan {2440588 i:59:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 50341
test clock-29.1468 {time parsing} {
    clock scan {2440588 i:lix:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 50341
test clock-29.1469 {time parsing} {
    clock scan {2440588 01:59:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 50341
test clock-29.1470 {time parsing} {
    clock scan {2440588 01:lix:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 50341
test clock-29.1471 {time parsing} {
    clock scan {2440588  1:59:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 50341
test clock-29.1472 {time parsing} {
    clock scan {2440588  1:lix:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 50341
test clock-29.1473 {time parsing} {
    clock scan {2440588 i:59:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 50341
test clock-29.1474 {time parsing} {
    clock scan {2440588 i:lix:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 50341
test clock-29.1475 {time parsing} {
    clock scan {2440588 i:59:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 50341
test clock-29.1476 {time parsing} {
    clock scan {2440588 i:lix:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 50341
test clock-29.1477 {time parsing} {
    clock scan {2440588 13:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 50399
test clock-29.1478 {time parsing} {
    clock scan {2440588 13:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 50399
test clock-29.1479 {time parsing} {
    clock scan {2440588 13:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 50399
test clock-29.1480 {time parsing} {
    clock scan {2440588 13:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 50399
test clock-29.1481 {time parsing} {
    clock scan {2440588 xiii:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 50399
test clock-29.1482 {time parsing} {
    clock scan {2440588 xiii:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 50399
test clock-29.1483 {time parsing} {
    clock scan {2440588 xiii:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 50399
test clock-29.1484 {time parsing} {
    clock scan {2440588 xiii:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 50399
test clock-29.1485 {time parsing} {
    clock scan {2440588 01:59:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 50399
test clock-29.1486 {time parsing} {
    clock scan {2440588 01:lix:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 50399
test clock-29.1487 {time parsing} {
    clock scan {2440588  1:59:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 50399
test clock-29.1488 {time parsing} {
    clock scan {2440588  1:lix:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 50399
test clock-29.1489 {time parsing} {
    clock scan {2440588 i:59:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 50399
test clock-29.1490 {time parsing} {
    clock scan {2440588 i:lix:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 50399
test clock-29.1491 {time parsing} {
    clock scan {2440588 i:59:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 50399
test clock-29.1492 {time parsing} {
    clock scan {2440588 i:lix:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 50399
test clock-29.1493 {time parsing} {
    clock scan {2440588 01:59:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 50399
test clock-29.1494 {time parsing} {
    clock scan {2440588 01:lix:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 50399
test clock-29.1495 {time parsing} {
    clock scan {2440588  1:59:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 50399
test clock-29.1496 {time parsing} {
    clock scan {2440588  1:lix:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 50399
test clock-29.1497 {time parsing} {
    clock scan {2440588 i:59:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 50399
test clock-29.1498 {time parsing} {
    clock scan {2440588 i:lix:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 50399
test clock-29.1499 {time parsing} {
    clock scan {2440588 i:59:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 50399
test clock-29.1500 {time parsing} {
    clock scan {2440588 i:lix:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 50399
test clock-29.1501 {time parsing} {
    clock scan {2440588 23 } \
        -gmt true -locale en_US_roman \
        -format {%J %H }
} 82800
test clock-29.1502 {time parsing} {
    clock scan {2440588 23:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M }
} 82800
test clock-29.1503 {time parsing} {
    clock scan {2440588 23:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM }
} 82800
test clock-29.1504 {time parsing} {
    clock scan {2440588 23:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 82800
test clock-29.1505 {time parsing} {
    clock scan {2440588 23:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 82800
test clock-29.1506 {time parsing} {
    clock scan {2440588 23 } \
        -gmt true -locale en_US_roman \
        -format {%J %k }
} 82800
test clock-29.1507 {time parsing} {
    clock scan {2440588 23:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M }
} 82800
test clock-29.1508 {time parsing} {
    clock scan {2440588 23:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM }
} 82800
test clock-29.1509 {time parsing} {
    clock scan {2440588 23:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 82800
test clock-29.1510 {time parsing} {
    clock scan {2440588 23:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 82800
test clock-29.1511 {time parsing} {
    clock scan {2440588 xxiii } \
        -gmt true -locale en_US_roman \
        -format {%J %OH }
} 82800
test clock-29.1512 {time parsing} {
    clock scan {2440588 xxiii:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M }
} 82800
test clock-29.1513 {time parsing} {
    clock scan {2440588 xxiii:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM }
} 82800
test clock-29.1514 {time parsing} {
    clock scan {2440588 xxiii:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 82800
test clock-29.1515 {time parsing} {
    clock scan {2440588 xxiii:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 82800
test clock-29.1516 {time parsing} {
    clock scan {2440588 xxiii } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok }
} 82800
test clock-29.1517 {time parsing} {
    clock scan {2440588 xxiii:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M }
} 82800
test clock-29.1518 {time parsing} {
    clock scan {2440588 xxiii:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM }
} 82800
test clock-29.1519 {time parsing} {
    clock scan {2440588 xxiii:00:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 82800
test clock-29.1520 {time parsing} {
    clock scan {2440588 xxiii:?:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 82800
test clock-29.1521 {time parsing} {
    clock scan {2440588 11 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I %p}
} 82800
test clock-29.1522 {time parsing} {
    clock scan {2440588 11:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %p}
} 82800
test clock-29.1523 {time parsing} {
    clock scan {2440588 11:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %p}
} 82800
test clock-29.1524 {time parsing} {
    clock scan {2440588 11:00:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 82800
test clock-29.1525 {time parsing} {
    clock scan {2440588 11:?:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 82800
test clock-29.1526 {time parsing} {
    clock scan {2440588 11 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l %p}
} 82800
test clock-29.1527 {time parsing} {
    clock scan {2440588 11:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %p}
} 82800
test clock-29.1528 {time parsing} {
    clock scan {2440588 11:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %p}
} 82800
test clock-29.1529 {time parsing} {
    clock scan {2440588 11:00:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 82800
test clock-29.1530 {time parsing} {
    clock scan {2440588 11:?:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 82800
test clock-29.1531 {time parsing} {
    clock scan {2440588 xi PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI %p}
} 82800
test clock-29.1532 {time parsing} {
    clock scan {2440588 xi:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %p}
} 82800
test clock-29.1533 {time parsing} {
    clock scan {2440588 xi:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %p}
} 82800
test clock-29.1534 {time parsing} {
    clock scan {2440588 xi:00:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 82800
test clock-29.1535 {time parsing} {
    clock scan {2440588 xi:?:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 82800
test clock-29.1536 {time parsing} {
    clock scan {2440588 xi PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol %p}
} 82800
test clock-29.1537 {time parsing} {
    clock scan {2440588 xi:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %p}
} 82800
test clock-29.1538 {time parsing} {
    clock scan {2440588 xi:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %p}
} 82800
test clock-29.1539 {time parsing} {
    clock scan {2440588 xi:00:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 82800
test clock-29.1540 {time parsing} {
    clock scan {2440588 xi:?:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 82800
test clock-29.1541 {time parsing} {
    clock scan {2440588 11 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I %P}
} 82800
test clock-29.1542 {time parsing} {
    clock scan {2440588 11:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %P}
} 82800
test clock-29.1543 {time parsing} {
    clock scan {2440588 11:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %P}
} 82800
test clock-29.1544 {time parsing} {
    clock scan {2440588 11:00:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 82800
test clock-29.1545 {time parsing} {
    clock scan {2440588 11:?:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 82800
test clock-29.1546 {time parsing} {
    clock scan {2440588 11 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l %P}
} 82800
test clock-29.1547 {time parsing} {
    clock scan {2440588 11:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %P}
} 82800
test clock-29.1548 {time parsing} {
    clock scan {2440588 11:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %P}
} 82800
test clock-29.1549 {time parsing} {
    clock scan {2440588 11:00:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 82800
test clock-29.1550 {time parsing} {
    clock scan {2440588 11:?:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 82800
test clock-29.1551 {time parsing} {
    clock scan {2440588 xi pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI %P}
} 82800
test clock-29.1552 {time parsing} {
    clock scan {2440588 xi:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %P}
} 82800
test clock-29.1553 {time parsing} {
    clock scan {2440588 xi:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %P}
} 82800
test clock-29.1554 {time parsing} {
    clock scan {2440588 xi:00:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 82800
test clock-29.1555 {time parsing} {
    clock scan {2440588 xi:?:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 82800
test clock-29.1556 {time parsing} {
    clock scan {2440588 xi pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol %P}
} 82800
test clock-29.1557 {time parsing} {
    clock scan {2440588 xi:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %P}
} 82800
test clock-29.1558 {time parsing} {
    clock scan {2440588 xi:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %P}
} 82800
test clock-29.1559 {time parsing} {
    clock scan {2440588 xi:00:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 82800
test clock-29.1560 {time parsing} {
    clock scan {2440588 xi:?:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 82800
test clock-29.1561 {time parsing} {
    clock scan {2440588 23:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 82801
test clock-29.1562 {time parsing} {
    clock scan {2440588 23:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 82801
test clock-29.1563 {time parsing} {
    clock scan {2440588 23:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 82801
test clock-29.1564 {time parsing} {
    clock scan {2440588 23:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 82801
test clock-29.1565 {time parsing} {
    clock scan {2440588 xxiii:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 82801
test clock-29.1566 {time parsing} {
    clock scan {2440588 xxiii:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 82801
test clock-29.1567 {time parsing} {
    clock scan {2440588 xxiii:00:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 82801
test clock-29.1568 {time parsing} {
    clock scan {2440588 xxiii:?:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 82801
test clock-29.1569 {time parsing} {
    clock scan {2440588 11:00:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 82801
test clock-29.1570 {time parsing} {
    clock scan {2440588 11:?:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 82801
test clock-29.1571 {time parsing} {
    clock scan {2440588 11:00:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 82801
test clock-29.1572 {time parsing} {
    clock scan {2440588 11:?:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 82801
test clock-29.1573 {time parsing} {
    clock scan {2440588 xi:00:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 82801
test clock-29.1574 {time parsing} {
    clock scan {2440588 xi:?:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 82801
test clock-29.1575 {time parsing} {
    clock scan {2440588 xi:00:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 82801
test clock-29.1576 {time parsing} {
    clock scan {2440588 xi:?:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 82801
test clock-29.1577 {time parsing} {
    clock scan {2440588 11:00:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 82801
test clock-29.1578 {time parsing} {
    clock scan {2440588 11:?:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 82801
test clock-29.1579 {time parsing} {
    clock scan {2440588 11:00:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 82801
test clock-29.1580 {time parsing} {
    clock scan {2440588 11:?:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 82801
test clock-29.1581 {time parsing} {
    clock scan {2440588 xi:00:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 82801
test clock-29.1582 {time parsing} {
    clock scan {2440588 xi:?:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 82801
test clock-29.1583 {time parsing} {
    clock scan {2440588 xi:00:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 82801
test clock-29.1584 {time parsing} {
    clock scan {2440588 xi:?:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 82801
test clock-29.1585 {time parsing} {
    clock scan {2440588 23:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 82859
test clock-29.1586 {time parsing} {
    clock scan {2440588 23:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 82859
test clock-29.1587 {time parsing} {
    clock scan {2440588 23:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 82859
test clock-29.1588 {time parsing} {
    clock scan {2440588 23:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 82859
test clock-29.1589 {time parsing} {
    clock scan {2440588 xxiii:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 82859
test clock-29.1590 {time parsing} {
    clock scan {2440588 xxiii:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 82859
test clock-29.1591 {time parsing} {
    clock scan {2440588 xxiii:00:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 82859
test clock-29.1592 {time parsing} {
    clock scan {2440588 xxiii:?:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 82859
test clock-29.1593 {time parsing} {
    clock scan {2440588 11:00:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 82859
test clock-29.1594 {time parsing} {
    clock scan {2440588 11:?:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 82859
test clock-29.1595 {time parsing} {
    clock scan {2440588 11:00:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 82859
test clock-29.1596 {time parsing} {
    clock scan {2440588 11:?:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 82859
test clock-29.1597 {time parsing} {
    clock scan {2440588 xi:00:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 82859
test clock-29.1598 {time parsing} {
    clock scan {2440588 xi:?:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 82859
test clock-29.1599 {time parsing} {
    clock scan {2440588 xi:00:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 82859
test clock-29.1600 {time parsing} {
    clock scan {2440588 xi:?:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 82859
test clock-29.1601 {time parsing} {
    clock scan {2440588 11:00:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 82859
test clock-29.1602 {time parsing} {
    clock scan {2440588 11:?:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 82859
test clock-29.1603 {time parsing} {
    clock scan {2440588 11:00:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 82859
test clock-29.1604 {time parsing} {
    clock scan {2440588 11:?:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 82859
test clock-29.1605 {time parsing} {
    clock scan {2440588 xi:00:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 82859
test clock-29.1606 {time parsing} {
    clock scan {2440588 xi:?:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 82859
test clock-29.1607 {time parsing} {
    clock scan {2440588 xi:00:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 82859
test clock-29.1608 {time parsing} {
    clock scan {2440588 xi:?:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 82859
test clock-29.1609 {time parsing} {
    clock scan {2440588 23:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M }
} 82860
test clock-29.1610 {time parsing} {
    clock scan {2440588 23:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM }
} 82860
test clock-29.1611 {time parsing} {
    clock scan {2440588 23:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 82860
test clock-29.1612 {time parsing} {
    clock scan {2440588 23:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 82860
test clock-29.1613 {time parsing} {
    clock scan {2440588 23:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M }
} 82860
test clock-29.1614 {time parsing} {
    clock scan {2440588 23:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM }
} 82860
test clock-29.1615 {time parsing} {
    clock scan {2440588 23:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 82860
test clock-29.1616 {time parsing} {
    clock scan {2440588 23:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 82860
test clock-29.1617 {time parsing} {
    clock scan {2440588 xxiii:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M }
} 82860
test clock-29.1618 {time parsing} {
    clock scan {2440588 xxiii:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM }
} 82860
test clock-29.1619 {time parsing} {
    clock scan {2440588 xxiii:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 82860
test clock-29.1620 {time parsing} {
    clock scan {2440588 xxiii:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 82860
test clock-29.1621 {time parsing} {
    clock scan {2440588 xxiii:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M }
} 82860
test clock-29.1622 {time parsing} {
    clock scan {2440588 xxiii:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM }
} 82860
test clock-29.1623 {time parsing} {
    clock scan {2440588 xxiii:01:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 82860
test clock-29.1624 {time parsing} {
    clock scan {2440588 xxiii:i:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 82860
test clock-29.1625 {time parsing} {
    clock scan {2440588 11:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %p}
} 82860
test clock-29.1626 {time parsing} {
    clock scan {2440588 11:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %p}
} 82860
test clock-29.1627 {time parsing} {
    clock scan {2440588 11:01:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 82860
test clock-29.1628 {time parsing} {
    clock scan {2440588 11:i:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 82860
test clock-29.1629 {time parsing} {
    clock scan {2440588 11:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %p}
} 82860
test clock-29.1630 {time parsing} {
    clock scan {2440588 11:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %p}
} 82860
test clock-29.1631 {time parsing} {
    clock scan {2440588 11:01:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 82860
test clock-29.1632 {time parsing} {
    clock scan {2440588 11:i:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 82860
test clock-29.1633 {time parsing} {
    clock scan {2440588 xi:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %p}
} 82860
test clock-29.1634 {time parsing} {
    clock scan {2440588 xi:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %p}
} 82860
test clock-29.1635 {time parsing} {
    clock scan {2440588 xi:01:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 82860
test clock-29.1636 {time parsing} {
    clock scan {2440588 xi:i:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 82860
test clock-29.1637 {time parsing} {
    clock scan {2440588 xi:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %p}
} 82860
test clock-29.1638 {time parsing} {
    clock scan {2440588 xi:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %p}
} 82860
test clock-29.1639 {time parsing} {
    clock scan {2440588 xi:01:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 82860
test clock-29.1640 {time parsing} {
    clock scan {2440588 xi:i:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 82860
test clock-29.1641 {time parsing} {
    clock scan {2440588 11:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %P}
} 82860
test clock-29.1642 {time parsing} {
    clock scan {2440588 11:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %P}
} 82860
test clock-29.1643 {time parsing} {
    clock scan {2440588 11:01:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 82860
test clock-29.1644 {time parsing} {
    clock scan {2440588 11:i:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 82860
test clock-29.1645 {time parsing} {
    clock scan {2440588 11:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %P}
} 82860
test clock-29.1646 {time parsing} {
    clock scan {2440588 11:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %P}
} 82860
test clock-29.1647 {time parsing} {
    clock scan {2440588 11:01:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 82860
test clock-29.1648 {time parsing} {
    clock scan {2440588 11:i:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 82860
test clock-29.1649 {time parsing} {
    clock scan {2440588 xi:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %P}
} 82860
test clock-29.1650 {time parsing} {
    clock scan {2440588 xi:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %P}
} 82860
test clock-29.1651 {time parsing} {
    clock scan {2440588 xi:01:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 82860
test clock-29.1652 {time parsing} {
    clock scan {2440588 xi:i:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 82860
test clock-29.1653 {time parsing} {
    clock scan {2440588 xi:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %P}
} 82860
test clock-29.1654 {time parsing} {
    clock scan {2440588 xi:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %P}
} 82860
test clock-29.1655 {time parsing} {
    clock scan {2440588 xi:01:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 82860
test clock-29.1656 {time parsing} {
    clock scan {2440588 xi:i:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 82860
test clock-29.1657 {time parsing} {
    clock scan {2440588 23:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 82861
test clock-29.1658 {time parsing} {
    clock scan {2440588 23:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 82861
test clock-29.1659 {time parsing} {
    clock scan {2440588 23:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 82861
test clock-29.1660 {time parsing} {
    clock scan {2440588 23:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 82861
test clock-29.1661 {time parsing} {
    clock scan {2440588 xxiii:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 82861
test clock-29.1662 {time parsing} {
    clock scan {2440588 xxiii:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 82861
test clock-29.1663 {time parsing} {
    clock scan {2440588 xxiii:01:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 82861
test clock-29.1664 {time parsing} {
    clock scan {2440588 xxiii:i:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 82861
test clock-29.1665 {time parsing} {
    clock scan {2440588 11:01:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 82861
test clock-29.1666 {time parsing} {
    clock scan {2440588 11:i:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 82861
test clock-29.1667 {time parsing} {
    clock scan {2440588 11:01:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 82861
test clock-29.1668 {time parsing} {
    clock scan {2440588 11:i:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 82861
test clock-29.1669 {time parsing} {
    clock scan {2440588 xi:01:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 82861
test clock-29.1670 {time parsing} {
    clock scan {2440588 xi:i:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 82861
test clock-29.1671 {time parsing} {
    clock scan {2440588 xi:01:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 82861
test clock-29.1672 {time parsing} {
    clock scan {2440588 xi:i:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 82861
test clock-29.1673 {time parsing} {
    clock scan {2440588 11:01:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 82861
test clock-29.1674 {time parsing} {
    clock scan {2440588 11:i:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 82861
test clock-29.1675 {time parsing} {
    clock scan {2440588 11:01:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 82861
test clock-29.1676 {time parsing} {
    clock scan {2440588 11:i:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 82861
test clock-29.1677 {time parsing} {
    clock scan {2440588 xi:01:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 82861
test clock-29.1678 {time parsing} {
    clock scan {2440588 xi:i:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 82861
test clock-29.1679 {time parsing} {
    clock scan {2440588 xi:01:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 82861
test clock-29.1680 {time parsing} {
    clock scan {2440588 xi:i:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 82861
test clock-29.1681 {time parsing} {
    clock scan {2440588 23:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 82919
test clock-29.1682 {time parsing} {
    clock scan {2440588 23:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 82919
test clock-29.1683 {time parsing} {
    clock scan {2440588 23:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 82919
test clock-29.1684 {time parsing} {
    clock scan {2440588 23:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 82919
test clock-29.1685 {time parsing} {
    clock scan {2440588 xxiii:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 82919
test clock-29.1686 {time parsing} {
    clock scan {2440588 xxiii:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 82919
test clock-29.1687 {time parsing} {
    clock scan {2440588 xxiii:01:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 82919
test clock-29.1688 {time parsing} {
    clock scan {2440588 xxiii:i:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 82919
test clock-29.1689 {time parsing} {
    clock scan {2440588 11:01:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 82919
test clock-29.1690 {time parsing} {
    clock scan {2440588 11:i:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 82919
test clock-29.1691 {time parsing} {
    clock scan {2440588 11:01:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 82919
test clock-29.1692 {time parsing} {
    clock scan {2440588 11:i:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 82919
test clock-29.1693 {time parsing} {
    clock scan {2440588 xi:01:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 82919
test clock-29.1694 {time parsing} {
    clock scan {2440588 xi:i:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 82919
test clock-29.1695 {time parsing} {
    clock scan {2440588 xi:01:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 82919
test clock-29.1696 {time parsing} {
    clock scan {2440588 xi:i:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 82919
test clock-29.1697 {time parsing} {
    clock scan {2440588 11:01:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 82919
test clock-29.1698 {time parsing} {
    clock scan {2440588 11:i:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 82919
test clock-29.1699 {time parsing} {
    clock scan {2440588 11:01:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 82919
test clock-29.1700 {time parsing} {
    clock scan {2440588 11:i:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 82919
test clock-29.1701 {time parsing} {
    clock scan {2440588 xi:01:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 82919
test clock-29.1702 {time parsing} {
    clock scan {2440588 xi:i:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 82919
test clock-29.1703 {time parsing} {
    clock scan {2440588 xi:01:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 82919
test clock-29.1704 {time parsing} {
    clock scan {2440588 xi:i:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 82919
test clock-29.1705 {time parsing} {
    clock scan {2440588 23:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M }
} 86340
test clock-29.1706 {time parsing} {
    clock scan {2440588 23:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM }
} 86340
test clock-29.1707 {time parsing} {
    clock scan {2440588 23:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 86340
test clock-29.1708 {time parsing} {
    clock scan {2440588 23:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 86340
test clock-29.1709 {time parsing} {
    clock scan {2440588 23:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M }
} 86340
test clock-29.1710 {time parsing} {
    clock scan {2440588 23:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM }
} 86340
test clock-29.1711 {time parsing} {
    clock scan {2440588 23:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 86340
test clock-29.1712 {time parsing} {
    clock scan {2440588 23:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 86340
test clock-29.1713 {time parsing} {
    clock scan {2440588 xxiii:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M }
} 86340
test clock-29.1714 {time parsing} {
    clock scan {2440588 xxiii:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM }
} 86340
test clock-29.1715 {time parsing} {
    clock scan {2440588 xxiii:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 86340
test clock-29.1716 {time parsing} {
    clock scan {2440588 xxiii:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 86340
test clock-29.1717 {time parsing} {
    clock scan {2440588 xxiii:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M }
} 86340
test clock-29.1718 {time parsing} {
    clock scan {2440588 xxiii:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM }
} 86340
test clock-29.1719 {time parsing} {
    clock scan {2440588 xxiii:59:00 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 86340
test clock-29.1720 {time parsing} {
    clock scan {2440588 xxiii:lix:? } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 86340
test clock-29.1721 {time parsing} {
    clock scan {2440588 11:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %p}
} 86340
test clock-29.1722 {time parsing} {
    clock scan {2440588 11:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %p}
} 86340
test clock-29.1723 {time parsing} {
    clock scan {2440588 11:59:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 86340
test clock-29.1724 {time parsing} {
    clock scan {2440588 11:lix:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 86340
test clock-29.1725 {time parsing} {
    clock scan {2440588 11:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %p}
} 86340
test clock-29.1726 {time parsing} {
    clock scan {2440588 11:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %p}
} 86340
test clock-29.1727 {time parsing} {
    clock scan {2440588 11:59:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 86340
test clock-29.1728 {time parsing} {
    clock scan {2440588 11:lix:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 86340
test clock-29.1729 {time parsing} {
    clock scan {2440588 xi:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %p}
} 86340
test clock-29.1730 {time parsing} {
    clock scan {2440588 xi:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %p}
} 86340
test clock-29.1731 {time parsing} {
    clock scan {2440588 xi:59:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 86340
test clock-29.1732 {time parsing} {
    clock scan {2440588 xi:lix:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 86340
test clock-29.1733 {time parsing} {
    clock scan {2440588 xi:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %p}
} 86340
test clock-29.1734 {time parsing} {
    clock scan {2440588 xi:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %p}
} 86340
test clock-29.1735 {time parsing} {
    clock scan {2440588 xi:59:00 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 86340
test clock-29.1736 {time parsing} {
    clock scan {2440588 xi:lix:? PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 86340
test clock-29.1737 {time parsing} {
    clock scan {2440588 11:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M %P}
} 86340
test clock-29.1738 {time parsing} {
    clock scan {2440588 11:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM %P}
} 86340
test clock-29.1739 {time parsing} {
    clock scan {2440588 11:59:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 86340
test clock-29.1740 {time parsing} {
    clock scan {2440588 11:lix:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 86340
test clock-29.1741 {time parsing} {
    clock scan {2440588 11:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M %P}
} 86340
test clock-29.1742 {time parsing} {
    clock scan {2440588 11:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM %P}
} 86340
test clock-29.1743 {time parsing} {
    clock scan {2440588 11:59:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 86340
test clock-29.1744 {time parsing} {
    clock scan {2440588 11:lix:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 86340
test clock-29.1745 {time parsing} {
    clock scan {2440588 xi:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M %P}
} 86340
test clock-29.1746 {time parsing} {
    clock scan {2440588 xi:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM %P}
} 86340
test clock-29.1747 {time parsing} {
    clock scan {2440588 xi:59:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 86340
test clock-29.1748 {time parsing} {
    clock scan {2440588 xi:lix:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 86340
test clock-29.1749 {time parsing} {
    clock scan {2440588 xi:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M %P}
} 86340
test clock-29.1750 {time parsing} {
    clock scan {2440588 xi:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM %P}
} 86340
test clock-29.1751 {time parsing} {
    clock scan {2440588 xi:59:00 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 86340
test clock-29.1752 {time parsing} {
    clock scan {2440588 xi:lix:? pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 86340
test clock-29.1753 {time parsing} {
    clock scan {2440588 23:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 86341
test clock-29.1754 {time parsing} {
    clock scan {2440588 23:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 86341
test clock-29.1755 {time parsing} {
    clock scan {2440588 23:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 86341
test clock-29.1756 {time parsing} {
    clock scan {2440588 23:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 86341
test clock-29.1757 {time parsing} {
    clock scan {2440588 xxiii:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 86341
test clock-29.1758 {time parsing} {
    clock scan {2440588 xxiii:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 86341
test clock-29.1759 {time parsing} {
    clock scan {2440588 xxiii:59:01 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 86341
test clock-29.1760 {time parsing} {
    clock scan {2440588 xxiii:lix:i } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 86341
test clock-29.1761 {time parsing} {
    clock scan {2440588 11:59:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 86341
test clock-29.1762 {time parsing} {
    clock scan {2440588 11:lix:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 86341
test clock-29.1763 {time parsing} {
    clock scan {2440588 11:59:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 86341
test clock-29.1764 {time parsing} {
    clock scan {2440588 11:lix:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 86341
test clock-29.1765 {time parsing} {
    clock scan {2440588 xi:59:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 86341
test clock-29.1766 {time parsing} {
    clock scan {2440588 xi:lix:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 86341
test clock-29.1767 {time parsing} {
    clock scan {2440588 xi:59:01 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 86341
test clock-29.1768 {time parsing} {
    clock scan {2440588 xi:lix:i PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 86341
test clock-29.1769 {time parsing} {
    clock scan {2440588 11:59:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 86341
test clock-29.1770 {time parsing} {
    clock scan {2440588 11:lix:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 86341
test clock-29.1771 {time parsing} {
    clock scan {2440588 11:59:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 86341
test clock-29.1772 {time parsing} {
    clock scan {2440588 11:lix:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 86341
test clock-29.1773 {time parsing} {
    clock scan {2440588 xi:59:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 86341
test clock-29.1774 {time parsing} {
    clock scan {2440588 xi:lix:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 86341
test clock-29.1775 {time parsing} {
    clock scan {2440588 xi:59:01 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 86341
test clock-29.1776 {time parsing} {
    clock scan {2440588 xi:lix:i pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 86341
test clock-29.1777 {time parsing} {
    clock scan {2440588 23:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%M:%S }
} 86399
test clock-29.1778 {time parsing} {
    clock scan {2440588 23:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %H:%OM:%OS }
} 86399
test clock-29.1779 {time parsing} {
    clock scan {2440588 23:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%M:%S }
} 86399
test clock-29.1780 {time parsing} {
    clock scan {2440588 23:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %k:%OM:%OS }
} 86399
test clock-29.1781 {time parsing} {
    clock scan {2440588 xxiii:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%M:%S }
} 86399
test clock-29.1782 {time parsing} {
    clock scan {2440588 xxiii:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %OH:%OM:%OS }
} 86399
test clock-29.1783 {time parsing} {
    clock scan {2440588 xxiii:59:59 } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%M:%S }
} 86399
test clock-29.1784 {time parsing} {
    clock scan {2440588 xxiii:lix:lix } \
        -gmt true -locale en_US_roman \
        -format {%J %Ok:%OM:%OS }
} 86399
test clock-29.1785 {time parsing} {
    clock scan {2440588 11:59:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %p}
} 86399
test clock-29.1786 {time parsing} {
    clock scan {2440588 11:lix:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %p}
} 86399
test clock-29.1787 {time parsing} {
    clock scan {2440588 11:59:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %p}
} 86399
test clock-29.1788 {time parsing} {
    clock scan {2440588 11:lix:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %p}
} 86399
test clock-29.1789 {time parsing} {
    clock scan {2440588 xi:59:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %p}
} 86399
test clock-29.1790 {time parsing} {
    clock scan {2440588 xi:lix:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %p}
} 86399
test clock-29.1791 {time parsing} {
    clock scan {2440588 xi:59:59 PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %p}
} 86399
test clock-29.1792 {time parsing} {
    clock scan {2440588 xi:lix:lix PM} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %p}
} 86399
test clock-29.1793 {time parsing} {
    clock scan {2440588 11:59:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%M:%S %P}
} 86399
test clock-29.1794 {time parsing} {
    clock scan {2440588 11:lix:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %I:%OM:%OS %P}
} 86399
test clock-29.1795 {time parsing} {
    clock scan {2440588 11:59:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%M:%S %P}
} 86399
test clock-29.1796 {time parsing} {
    clock scan {2440588 11:lix:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %l:%OM:%OS %P}
} 86399
test clock-29.1797 {time parsing} {
    clock scan {2440588 xi:59:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%M:%S %P}
} 86399
test clock-29.1798 {time parsing} {
    clock scan {2440588 xi:lix:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %OI:%OM:%OS %P}
} 86399
test clock-29.1799 {time parsing} {
    clock scan {2440588 xi:59:59 pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%M:%S %P}
} 86399
test clock-29.1800 {time parsing} {
    clock scan {2440588 xi:lix:lix pm} \
        -gmt true -locale en_US_roman \
        -format {%J %Ol:%OM:%OS %P}
} 86399

test clock-29.1811 {parsing of several localized formats} {
    set res {}
    foreach loc {en de fr} {
	foreach fmt {"%x %X" "%X %x"} {
	    lappend res [clock scan \







|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|



|
|







26484
26485
26486
26487
26488
26489
26490
26491
26492
26493
26494
26495
26496
26497
26498
26499
26500
26501
26502
26503
26504
26505
26506
26507
26508
26509
26510
26511
26512
26513
26514
26515
26516
26517
26518
26519
26520
26521
26522
26523
26524
26525
26526
26527
26528
26529
26530
26531
26532
26533
26534
26535
26536
26537
26538
26539
26540
26541
26542
26543
26544
26545
26546
26547
26548
26549
26550
26551
26552
26553
26554
26555
26556
26557
26558
26559
26560
26561
26562
26563
26564
26565
26566
26567
26568
26569
26570
26571
26572
26573
26574
26575
26576
26577
26578
26579
26580
26581
26582
26583
26584
26585
26586
26587
26588
26589
26590
26591
26592
26593
26594
26595
26596
26597
26598
26599
26600
26601
26602
26603
26604
26605
26606
26607
26608
26609
26610
26611
26612
26613
26614
26615
26616
26617
26618
26619
26620
26621
26622
26623
26624
26625
26626
26627
26628
26629
26630
26631
26632
26633
26634
26635
26636
26637
26638
26639
26640
26641
26642
26643
26644
26645
26646
26647
26648
26649
26650
26651
26652
26653
26654
26655
26656
26657
26658
26659
26660
26661
26662
26663
26664
26665
26666
26667
26668
26669
26670
26671
26672
26673
26674
26675
26676
26677
26678
26679
26680
26681
26682
26683
26684
26685
26686
26687
26688
26689
26690
26691
26692
26693
26694
26695
26696
26697
26698
26699
26700
26701
26702
26703
26704
26705
26706
26707
26708
26709
26710
26711
26712
26713
26714
26715
26716
26717
26718
26719
26720
26721
26722
26723
26724
26725
26726
26727
26728
26729
26730
26731
26732
26733
26734
26735
26736
26737
26738
26739
26740
26741
26742
26743
26744
26745
26746
26747
26748
26749
26750
26751
26752
26753
26754
26755
26756
26757
26758
26759
26760
26761
26762
26763
26764
26765
26766
26767
26768
26769
26770
26771
26772
26773
26774
26775
26776
26777
26778
26779
26780
26781
26782
26783
26784
26785
26786
26787
26788
26789
26790
26791
26792
26793
26794
26795
26796
26797
26798
26799
26800
26801
26802
26803
26804
26805
26806
26807
26808
26809
26810
26811
26812
26813
26814
26815
26816
26817
26818
26819
26820
26821
26822
26823
26824
26825
26826
26827
26828
26829
26830
26831
26832
26833
26834
26835
26836
26837
26838
26839
26840
26841
26842
26843
26844
26845
26846
26847
26848
26849
26850
26851
26852
26853
26854
26855
26856
26857
26858
26859
26860
26861
26862
26863
26864
26865
26866
26867
26868
26869
26870
26871
26872
26873
26874
26875
26876
26877
26878
26879
26880
26881
26882
26883
26884
26885
26886
26887
26888
26889
26890
26891
26892
26893
26894
26895
26896
26897
26898
26899
26900
26901
26902
26903
26904
26905
26906
26907
26908
26909
26910
26911
26912
26913
26914
26915
26916
26917
26918
26919
26920
26921
26922
26923
26924
26925
26926
26927
26928
26929
26930
26931
26932
26933
26934
26935
26936
26937
26938
26939
26940
26941
26942
26943
26944
26945
26946
26947
26948
26949
26950
26951
26952
26953
26954
26955
26956
26957
26958
26959
26960
26961
26962
26963
26964
26965
26966
26967
26968
26969
26970
26971
26972
26973
26974
26975
26976
26977
26978
26979
26980
26981
26982
26983
26984
26985
26986
26987
26988
26989
26990
26991
26992
26993
26994
26995
26996
26997
26998
26999
27000
27001
27002
27003
27004
27005
27006
27007
27008
27009
27010
27011
27012
27013
27014
27015
27016
27017
27018
27019
27020
27021
27022
27023
27024
27025
27026
27027
27028
27029
27030
27031
27032
27033
27034
27035
27036
27037
27038
27039
27040
27041
27042
27043
27044
27045
27046
27047
27048
27049
27050
27051
27052
27053
27054
27055
27056
27057
27058
27059
27060
27061
27062
27063
27064
27065
27066
27067
27068
27069
27070
27071
27072
27073
27074
27075
27076
27077
27078
27079
27080
27081
27082
27083
27084
27085
27086
27087
27088
27089
27090
27091
27092
27093
27094
27095
27096
27097
27098
27099
27100
27101
27102
27103
27104
27105
27106
27107
27108
27109
27110
27111
27112
27113
27114
27115
27116
27117
27118
27119
27120
27121
27122
27123
27124
27125
27126
27127
27128
27129
27130
27131
27132
27133
27134
27135
27136
27137
27138
27139
27140
27141
27142
27143
27144
27145
27146
27147
27148
27149
27150
27151
27152
27153
27154
27155
27156
27157
27158
27159
27160
27161
27162
27163
27164
27165
27166
27167
27168
27169
27170
27171
27172
27173
27174
27175
27176
27177
27178
27179
27180
27181
27182
27183
27184
27185
27186
27187
27188
27189
27190
27191
27192
27193
27194
27195
27196
27197
27198
27199
27200
27201
27202
27203
27204
27205
27206
27207
27208
27209
27210
27211
27212
27213
27214
27215
27216
27217
27218
27219
27220
27221
27222
27223
27224
27225
27226
27227
27228
27229
27230
27231
27232
27233
27234
27235
27236
27237
27238
27239
27240
27241
27242
27243
27244
27245
27246
27247
27248
27249
27250
27251
27252
27253
27254
27255
27256
27257
27258
27259
27260
27261
27262
27263
27264
27265
27266
27267
27268
27269
27270
27271
27272
27273
27274
27275
27276
27277
27278
27279
27280
27281
27282
27283
27284
27285
27286
27287
27288
27289
27290
27291
27292
27293
27294
27295
27296
27297
27298
27299
27300
27301
27302
27303
27304
27305
27306
27307
27308
27309
27310
27311
27312
27313
27314
27315
27316
27317
27318
27319
27320
27321
27322
27323
27324
27325
27326
27327
27328
27329
27330
27331
27332
27333
27334
27335
27336
27337
27338
27339
27340
27341
27342
27343
27344
27345
27346
27347
27348
27349
27350
27351
27352
27353
27354
27355
27356
27357
27358
27359
27360
27361
27362
27363
27364
27365
27366
27367
27368
27369
27370
27371
27372
27373
27374
27375
27376
27377
27378
27379
27380
27381
27382
27383
27384
27385
27386
27387
27388
27389
27390
27391
27392
27393
27394
27395
27396
27397
27398
27399
27400
27401
27402
27403
27404
27405
27406
27407
27408
27409
27410
27411
27412
27413
27414
27415
27416
27417
27418
27419
27420
27421
27422
27423
27424
27425
27426
27427
27428
27429
27430
27431
27432
27433
27434
27435
27436
27437
27438
27439
27440
27441
27442
27443
27444
27445
27446
27447
27448
27449
27450
27451
27452
27453
27454
27455
27456
27457
27458
27459
27460
27461
27462
27463
27464
27465
27466
27467
27468
27469
27470
27471
27472
27473
27474
27475
27476
27477
27478
27479
27480
27481
27482
27483
27484
27485
27486
27487
27488
27489
27490
27491
27492
27493
27494
27495
27496
27497
27498
27499
27500
27501
27502
27503
27504
27505
27506
27507
27508
27509
27510
27511
27512
27513
27514
27515
27516
27517
27518
27519
27520
27521
27522
27523
27524
27525
27526
27527
27528
27529
27530
27531
27532
27533
27534
27535
27536
27537
27538
27539
27540
27541
27542
27543
27544
27545
27546
27547
27548
27549
27550
27551
27552
27553
27554
27555
27556
27557
27558
27559
27560
27561
27562
27563
27564
27565
27566
27567
27568
27569
27570
27571
27572
27573
27574
27575
27576
27577
27578
27579
27580
27581
27582
27583
27584
27585
27586
27587
27588
27589
27590
27591
27592
27593
27594
27595
27596
27597
27598
27599
27600
27601
27602
27603
27604
27605
27606
27607
27608
27609
27610
27611
27612
27613
27614
27615
27616
27617
27618
27619
27620
27621
27622
27623
27624
27625
27626
27627
27628
27629
27630
27631
27632
27633
27634
27635
27636
27637
27638
27639
27640
27641
27642
27643
27644
27645
27646
27647
27648
27649
27650
27651
27652
27653
27654
27655
27656
27657
27658
27659
27660
27661
27662
27663
27664
27665
27666
27667
27668
27669
27670
27671
27672
27673
27674
27675
27676
27677
27678
27679
27680
27681
27682
27683
27684
27685
27686
27687
27688
27689
27690
27691
27692
27693
27694
27695
27696
27697
27698
27699
27700
27701
27702
27703
27704
27705
27706
27707
27708
27709
27710
27711
27712
27713
27714
27715
27716
27717
27718
27719
27720
27721
27722
27723
27724
27725
27726
27727
27728
27729
27730
27731
27732
27733
27734
27735
27736
27737
27738
27739
27740
27741
27742
27743
27744
27745
27746
27747
27748
27749
27750
27751
27752
27753
27754
27755
27756
27757
27758
27759
27760
27761
27762
27763
27764
27765
27766
27767
27768
27769
27770
27771
27772
27773
27774
27775
27776
27777
27778
27779
27780
27781
27782
27783
27784
27785
27786
27787
27788
27789
27790
27791
27792
27793
27794
27795
27796
27797
27798
27799
27800
27801
27802
27803
27804
27805
27806
27807
27808
27809
27810
27811
27812
27813
27814
27815
27816
27817
27818
27819
27820
27821
27822
27823
27824
27825
27826
27827
27828
27829
27830
27831
27832
27833
27834
27835
27836
27837
27838
27839
27840
27841
27842
27843
27844
27845
27846
27847
27848
27849
27850
27851
27852
27853
27854
27855
27856
27857
27858
27859
27860
27861
27862
27863
27864
27865
27866
27867
27868
27869
27870
27871
27872
27873
27874
27875
27876
27877
27878
27879
27880
27881
27882
27883
27884
27885
27886
27887
27888
27889
27890
27891
27892
27893
27894
27895
27896
27897
27898
27899
27900
27901
27902
27903
27904
27905
27906
27907
27908
27909
27910
27911
27912
27913
27914
27915
27916
27917
27918
27919
27920
27921
27922
27923
27924
27925
27926
27927
27928
27929
27930
27931
27932
27933
27934
27935
27936
27937
27938
27939
27940
27941
27942
27943
27944
27945
27946
27947
27948
27949
27950
27951
27952
27953
27954
27955
27956
27957
27958
27959
27960
27961
27962
27963
27964
27965
27966
27967
27968
27969
27970
27971
27972
27973
27974
27975
27976
27977
27978
27979
27980
27981
27982
27983
27984
27985
27986
27987
27988
27989
27990
27991
27992
27993
27994
27995
27996
27997
27998
27999
28000
28001
28002
28003
28004
28005
28006
28007
28008
28009
28010
28011
28012
28013
28014
28015
28016
28017
28018
28019
28020
28021
28022
28023
28024
28025
28026
28027
28028
28029
28030
28031
28032
28033
28034
28035
28036
28037
28038
28039
28040
28041
28042
28043
28044
28045
28046
28047
28048
28049
28050
28051
28052
28053
28054
28055
28056
28057
28058
28059
28060
28061
28062
28063
28064
28065
28066
28067
28068
28069
28070
28071
28072
28073
28074
28075
28076
28077
28078
28079
28080
28081
28082
28083
28084
28085
28086
28087
28088
28089
28090
28091
28092
28093
28094
28095
28096
28097
28098
28099
28100
28101
28102
28103
28104
28105
28106
28107
28108
28109
28110
28111
28112
28113
28114
28115
28116
28117
28118
28119
28120
28121
28122
28123
28124
28125
28126
28127
28128
28129
28130
28131
28132
28133
28134
28135
28136
28137
28138
28139
28140
28141
28142
28143
28144
28145
28146
28147
28148
28149
28150
28151
28152
28153
28154
28155
28156
28157
28158
28159
28160
28161
28162
28163
28164
28165
28166
28167
28168
28169
28170
28171
28172
28173
28174
28175
28176
28177
28178
28179
28180
28181
28182
28183
28184
28185
28186
28187
28188
28189
28190
28191
28192
28193
28194
28195
28196
28197
28198
28199
28200
28201
28202
28203
28204
28205
28206
28207
28208
28209
28210
28211
28212
28213
28214
28215
28216
28217
28218
28219
28220
28221
28222
28223
28224
28225
28226
28227
28228
28229
28230
28231
28232
28233
28234
28235
28236
28237
28238
28239
28240
28241
28242
28243
28244
28245
28246
28247
28248
28249
28250
28251
28252
28253
28254
28255
28256
28257
28258
28259
28260
28261
28262
28263
28264
28265
28266
28267
28268
28269
28270
28271
28272
28273
28274
28275
28276
28277
28278
28279
28280
28281
28282
28283
28284
28285
28286
28287
28288
28289
28290
28291
28292
28293
28294
28295
28296
28297
28298
28299
28300
28301
28302
28303
28304
28305
28306
28307
28308
28309
28310
28311
28312
28313
28314
28315
28316
28317
28318
28319
28320
28321
28322
28323
28324
28325
28326
28327
28328
28329
28330
28331
28332
28333
28334
28335
28336
28337
28338
28339
28340
28341
28342
28343
28344
28345
28346
28347
28348
28349
28350
28351
28352
28353
28354
28355
28356
28357
28358
28359
28360
28361
28362
28363
28364
28365
28366
28367
28368
28369
28370
28371
28372
28373
28374
28375
28376
28377
28378
28379
28380
28381
28382
28383
28384
28385
28386
28387
28388
28389
28390
28391
28392
28393
28394
28395
28396
28397
28398
28399
28400
28401
28402
28403
28404
28405
28406
28407
28408
28409
28410
28411
28412
28413
28414
28415
28416
28417
28418
28419
28420
28421
28422
28423
28424
28425
28426
28427
28428
28429
28430
28431
28432
28433
28434
28435
28436
28437
28438
28439
28440
28441
28442
28443
28444
28445
28446
28447
28448
28449
28450
28451
28452
28453
28454
28455
28456
28457
28458
28459
28460
28461
28462
28463
28464
28465
28466
28467
28468
28469
28470
28471
28472
28473
28474
28475
28476
28477
28478
28479
28480
28481
28482
28483
28484
28485
28486
28487
28488
28489
28490
28491
28492
28493
28494
28495
28496
28497
28498
28499
28500
28501
28502
28503
28504
28505
28506
28507
28508
28509
28510
28511
28512
28513
28514
28515
28516
28517
28518
28519
28520
28521
28522
28523
28524
28525
28526
28527
28528
28529
28530
28531
28532
28533
28534
28535
28536
28537
28538
28539
28540
28541
28542
28543
28544
28545
28546
28547
28548
28549
28550
28551
28552
28553
28554
28555
28556
28557
28558
28559
28560
28561
28562
28563
28564
28565
28566
28567
28568
28569
28570
28571
28572
28573
28574
28575
28576
28577
28578
28579
28580
28581
28582
28583
28584
28585
28586
28587
28588
28589
28590
28591
28592
28593
28594
28595
28596
28597
28598
28599
28600
28601
28602
28603
28604
28605
28606
28607
28608
28609
28610
28611
28612
28613
28614
28615
28616
28617
28618
28619
28620
28621
28622
28623
28624
28625
28626
28627
28628
28629
28630
28631
28632
28633
28634
28635
28636
28637
28638
28639
28640
28641
28642
28643
28644
28645
28646
28647
28648
28649
28650
28651
28652
28653
28654
28655
28656
28657
28658
28659
28660
28661
28662
28663
28664
28665
28666
28667
28668
28669
28670
28671
28672
28673
28674
28675
28676
28677
28678
28679
28680
28681
28682
28683
28684
28685
28686
28687
28688
28689
28690
28691
28692
28693
28694
28695
28696
28697
28698
28699
28700
28701
28702
28703
28704
28705
28706
28707
28708
28709
28710
28711
28712
28713
28714
28715
28716
28717
28718
28719
28720
28721
28722
28723
28724
28725
28726
28727
28728
28729
28730
28731
28732
28733
28734
28735
28736
28737
28738
28739
28740
28741
28742
28743
28744
28745
28746
28747
28748
28749
28750
28751
28752
28753
28754
28755
28756
28757
28758
28759
28760
28761
28762
28763
28764
28765
28766
28767
28768
28769
28770
28771
28772
28773
28774
28775
28776
28777
28778
28779
28780
28781
28782
28783
28784
28785
28786
28787
28788
28789
28790
28791
28792
28793
28794
28795
28796
28797
28798
28799
28800
28801
28802
28803
28804
28805
28806
28807
28808
28809
28810
28811
28812
28813
28814
28815
28816
28817
28818
28819
28820
28821
28822
28823
28824
28825
28826
28827
28828
28829
28830
28831
28832
28833
28834
28835
28836
28837
28838
28839
28840
28841
28842
28843
28844
28845
28846
28847
28848
28849
28850
28851
28852
28853
28854
28855
28856
28857
28858
28859
28860
28861
28862
28863
28864
28865
28866
28867
28868
28869
28870
28871
28872
28873
28874
28875
28876
28877
28878
28879
28880
28881
28882
28883
28884
28885
28886
28887
28888
28889
28890
28891
28892
28893
28894
28895
28896
28897
28898
28899
28900
28901
28902
28903
28904
28905
28906
28907
28908
28909
28910
28911
28912
28913
28914
28915
28916
28917
28918
28919
28920
28921
28922
28923
28924
28925
28926
28927
28928
28929
28930
28931
28932
28933
28934
28935
28936
28937
28938
28939
28940
28941
28942
28943
28944
28945
28946
28947
28948
28949
28950
28951
28952
28953
28954
28955
28956
28957
28958
28959
28960
28961
28962
28963
28964
28965
28966
28967
28968
28969
28970
28971
28972
28973
28974
28975
28976
28977
28978
28979
28980
28981
28982
28983
28984
28985
28986
28987
28988
28989
28990
28991
28992
28993
28994
28995
28996
28997
28998
28999
29000
29001
29002
29003
29004
29005
29006
29007
29008
29009
29010
29011
29012
29013
29014
29015
29016
29017
29018
29019
29020
29021
29022
29023
29024
29025
29026
29027
29028
29029
29030
29031
29032
29033
29034
29035
29036
29037
29038
29039
29040
29041
29042
29043
29044
29045
29046
29047
29048
29049
29050
29051
29052
29053
29054
29055
29056
29057
29058
29059
29060
29061
29062
29063
29064
29065
29066
29067
29068
29069
29070
29071
29072
29073
29074
29075
29076
29077
29078
29079
29080
29081
29082
29083
29084
29085
29086
29087
29088
29089
29090
29091
29092
29093
29094
29095
29096
29097
29098
29099
29100
29101
29102
29103
29104
29105
29106
29107
29108
29109
29110
29111
29112
29113
29114
29115
29116
29117
29118
29119
29120
29121
29122
29123
29124
29125
29126
29127
29128
29129
29130
29131
29132
29133
29134
29135
29136
29137
29138
29139
29140
29141
29142
29143
29144
29145
29146
29147
29148
29149
29150
29151
29152
29153
29154
29155
29156
29157
29158
29159
29160
29161
29162
29163
29164
29165
29166
29167
29168
29169
29170
29171
29172
29173
29174
29175
29176
29177
29178
29179
29180
29181
29182
29183
29184
29185
29186
29187
29188
29189
29190
29191
29192
29193
29194
29195
29196
29197
29198
29199
29200
29201
29202
29203
29204
29205
29206
29207
29208
29209
29210
29211
29212
29213
29214
29215
29216
29217
29218
29219
29220
29221
29222
29223
29224
29225
29226
29227
29228
29229
29230
29231
29232
29233
29234
29235
29236
29237
29238
29239
29240
29241
29242
29243
29244
29245
29246
29247
29248
29249
29250
29251
29252
29253
29254
29255
29256
29257
29258
29259
29260
29261
29262
29263
29264
29265
29266
29267
29268
29269
29270
29271
29272
29273
29274
29275
29276
29277
29278
29279
29280
29281
29282
29283
29284
29285
29286
29287
29288
29289
29290
29291
29292
29293
29294
29295
29296
29297
29298
29299
29300
29301
29302
29303
29304
29305
29306
29307
29308
29309
29310
29311
29312
29313
29314
29315
29316
29317
29318
29319
29320
29321
29322
29323
29324
29325
29326
29327
29328
29329
29330
29331
29332
29333
29334
29335
29336
29337
29338
29339
29340
29341
29342
29343
29344
29345
29346
29347
29348
29349
29350
29351
29352
29353
29354
29355
29356
29357
29358
29359
29360
29361
29362
29363
29364
29365
29366
29367
29368
29369
29370
29371
29372
29373
29374
29375
29376
29377
29378
29379
29380
29381
29382
29383
29384
29385
29386
29387
29388
29389
29390
29391
29392
29393
29394
29395
29396
29397
29398
29399
29400
29401
29402
29403
29404
29405
29406
29407
29408
29409
29410
29411
29412
29413
29414
29415
29416
29417
29418
29419
29420
29421
29422
29423
29424
29425
29426
29427
29428
29429
29430
29431
29432
29433
29434
29435
29436
29437
29438
29439
29440
29441
29442
29443
29444
29445
29446
29447
29448
29449
29450
29451
29452
29453
29454
29455
29456
29457
29458
29459
29460
29461
29462
29463
29464
29465
29466
29467
29468
29469
29470
29471
29472
29473
29474
29475
29476
29477
29478
29479
29480
29481
29482
29483
29484
29485
29486
29487
29488
29489
29490
29491
29492
29493
29494
29495
29496
29497
29498
29499
29500
29501
29502
29503
29504
29505
29506
29507
29508
29509
29510
29511
29512
29513
29514
29515
29516
29517
29518
29519
29520
29521
29522
29523
29524
29525
29526
29527
29528
29529
29530
29531
29532
29533
29534
29535
29536
29537
29538
29539
29540
29541
29542
29543
29544
29545
29546
29547
29548
29549
29550
29551
29552
29553
29554
29555
29556
29557
29558
29559
29560
29561
29562
29563
29564
29565
29566
29567
29568
29569
29570
29571
29572
29573
29574
29575
29576
29577
29578
29579
29580
29581
29582
29583
29584
29585
29586
29587
29588
29589
29590
29591
29592
29593
29594
29595
29596
29597
29598
29599
29600
29601
29602
29603
29604
29605
29606
29607
29608
29609
29610
29611
29612
29613
29614
29615
29616
29617
29618
29619
29620
29621
29622
29623
29624
29625
29626
29627
29628
29629
29630
29631
29632
29633
29634
29635
29636
29637
29638
29639
29640
29641
29642
29643
29644
29645
29646
29647
29648
29649
29650
29651
29652
29653
29654
29655
29656
29657
29658
29659
29660
29661
29662
29663
29664
29665
29666
29667
29668
29669
29670
29671
29672
29673
29674
29675
29676
29677
29678
29679
29680
29681
29682
29683
29684
29685
29686
29687
29688
29689
29690
29691
29692
29693
29694
29695
29696
29697
29698
29699
29700
29701
29702
29703
29704
29705
29706
29707
29708
29709
29710
29711
29712
29713
29714
29715
29716
29717
29718
29719
29720
29721
29722
29723
29724
29725
29726
29727
29728
29729
29730
29731
29732
29733
29734
29735
29736
29737
29738
29739
29740
29741
29742
29743
29744
29745
29746
29747
29748
29749
29750
29751
29752
29753
29754
29755
29756
29757
29758
29759
29760
29761
29762
29763
29764
29765
29766
29767
29768
29769
29770
29771
29772
29773
29774
29775
29776
29777
29778
29779
29780
29781
29782
29783
29784
29785
29786
29787
29788
29789
29790
29791
29792
29793
29794
29795
29796
29797
29798
29799
29800
29801
29802
29803
29804
29805
29806
29807
29808
29809
29810
29811
29812
29813
29814
29815
29816
29817
29818
29819
29820
29821
29822
29823
29824
29825
29826
29827
29828
29829
29830
29831
29832
29833
29834
29835
29836
29837
29838
29839
29840
29841
29842
29843
29844
29845
29846
29847
29848
29849
29850
29851
29852
29853
29854
29855
29856
29857
29858
29859
29860
29861
29862
29863
29864
29865
29866
29867
29868
29869
29870
29871
29872
29873
29874
29875
29876
29877
29878
29879
29880
29881
29882
29883
29884
29885
29886
29887
29888
29889
29890
29891
29892
29893
29894
29895
29896
29897
29898
29899
29900
29901
29902
29903
29904
29905
29906
29907
29908
29909
29910
29911
29912
29913
29914
29915
29916
29917
29918
29919
29920
29921
29922
29923
29924
29925
29926
29927
29928
29929
29930
29931
29932
29933
29934
29935
29936
29937
29938
29939
29940
29941
29942
29943
29944
29945
29946
29947
29948
29949
29950
29951
29952
29953
29954
29955
29956
29957
29958
29959
29960
29961
29962
29963
29964
29965
29966
29967
29968
29969
29970
29971
29972
29973
29974
29975
29976
29977
29978
29979
29980
29981
29982
29983
29984
29985
29986
29987
29988
29989
29990
29991
29992
29993
29994
29995
29996
29997
29998
29999
30000
30001
30002
30003
30004
30005
30006
30007
30008
30009
30010
30011
30012
30013
30014
30015
30016
30017
30018
30019
30020
30021
30022
30023
30024
30025
30026
30027
30028
30029
30030
30031
30032
30033
30034
30035
30036
30037
30038
30039
30040
30041
30042
30043
30044
30045
30046
30047
30048
30049
30050
30051
30052
30053
30054
30055
30056
30057
30058
30059
30060
30061
30062
30063
30064
30065
30066
30067
30068
30069
30070
30071
30072
30073
30074
30075
30076
30077
30078
30079
30080
30081
30082
30083
30084
30085
30086
30087
30088
30089
30090
30091
30092
30093
30094
30095
30096
30097
30098
30099
30100
30101
30102
30103
30104
30105
30106
30107
30108
30109
30110
30111
30112
30113
30114
30115
30116
30117
30118
30119
30120
30121
30122
30123
30124
30125
30126
30127
30128
30129
30130
30131
30132
30133
30134
30135
30136
30137
30138
30139
30140
30141
30142
30143
30144
30145
30146
30147
30148
30149
30150
30151
30152
30153
30154
30155
30156
30157
30158
30159
30160
30161
30162
30163
30164
30165
30166
30167
30168
30169
30170
30171
30172
30173
30174
30175
30176
30177
30178
30179
30180
30181
30182
30183
30184
30185
30186
30187
30188
30189
30190
30191
30192
30193
30194
30195
30196
30197
30198
30199
30200
30201
30202
30203
30204
30205
30206
30207
30208
30209
30210
30211
30212
30213
30214
30215
30216
30217
30218
30219
30220
30221
30222
30223
30224
30225
30226
30227
30228
30229
30230
30231
30232
30233
30234
30235
30236
30237
30238
30239
30240
30241
30242
30243
30244
30245
30246
30247
30248
30249
30250
30251
30252
30253
30254
30255
30256
30257
30258
30259
30260
30261
30262
30263
30264
30265
30266
30267
30268
30269
30270
30271
30272
30273
30274
30275
30276
30277
30278
30279
30280
30281
30282
30283
30284
30285
30286
30287
30288
30289
30290
30291
30292
30293
30294
30295
30296
30297
30298
30299
30300
30301
30302
30303
30304
30305
30306
30307
30308
30309
30310
30311
30312
30313
30314
30315
30316
30317
30318
30319
30320
30321
30322
30323
30324
30325
30326
30327
30328
30329
30330
30331
30332
30333
30334
30335
30336
30337
30338
30339
30340
30341
30342
30343
30344
30345
30346
30347
30348
30349
30350
30351
30352
30353
30354
30355
30356
30357
30358
30359
30360
30361
30362
30363
30364
30365
30366
30367
30368
30369
30370
30371
30372
30373
30374
30375
30376
30377
30378
30379
30380
30381
30382
30383
30384
30385
30386
30387
30388
30389
30390
30391
30392
30393
30394
30395
30396
30397
30398
30399
30400
30401
30402
30403
30404
30405
30406
30407
30408
30409
30410
30411
30412
30413
30414
30415
30416
30417
30418
30419
30420
30421
30422
30423
30424
30425
30426
30427
30428
30429
30430
30431
30432
30433
30434
30435
30436
30437
30438
30439
30440
30441
30442
30443
30444
30445
30446
30447
30448
30449
30450
30451
30452
30453
30454
30455
30456
30457
30458
30459
30460
30461
30462
30463
30464
30465
30466
30467
30468
30469
30470
30471
30472
30473
30474
30475
30476
30477
30478
30479
30480
30481
30482
30483
30484
30485
30486
30487
30488
30489
30490
30491
30492
30493
30494
30495
30496
30497
30498
30499
30500
30501
30502
30503
30504
30505
30506
30507
30508
30509
30510
30511
30512
30513
30514
30515
30516
30517
30518
30519
30520
30521
30522
30523
30524
30525
30526
30527
30528
30529
30530
30531
30532
30533
30534
30535
30536
30537
30538
30539
30540
30541
30542
30543
30544
30545
30546
30547
30548
30549
30550
30551
30552
30553
30554
30555
30556
30557
30558
30559
30560
30561
30562
30563
30564
30565
30566
30567
30568
30569
30570
30571
30572
30573
30574
30575
30576
30577
30578
30579
30580
30581
30582
30583
30584
30585
30586
30587
30588
30589
30590
30591
30592
30593
30594
30595
30596
30597
30598
30599
30600
30601
30602
30603
30604
30605
30606
30607
30608
30609
30610
30611
30612
30613
30614
30615
30616
30617
30618
30619
30620
30621
30622
30623
30624
30625
30626
30627
30628
30629
30630
30631
30632
30633
30634
30635
30636
30637
30638
30639
30640
30641
30642
30643
30644
30645
30646
30647
30648
30649
30650
30651
30652
30653
30654
30655
30656
30657
30658
30659
30660
30661
30662
30663
30664
30665
30666
30667
30668
30669
30670
30671
30672
30673
30674
30675
30676
30677
30678
30679
30680
30681
30682
30683
30684
30685
30686
30687
30688
30689
30690
30691
30692
30693
30694
30695
30696
30697
30698
30699
30700
30701
30702
30703
30704
30705
30706
30707
30708
30709
30710
30711
30712
30713
30714
30715
30716
30717
30718
30719
30720
30721
30722
30723
30724
30725
30726
30727
30728
30729
30730
30731
30732
30733
30734
30735
30736
30737
30738
30739
30740
30741
30742
30743
30744
30745
30746
30747
30748
30749
30750
30751
30752
30753
30754
30755
30756
30757
30758
30759
30760
30761
30762
30763
30764
30765
30766
30767
30768
30769
30770
30771
30772
30773
30774
30775
30776
30777
30778
30779
30780
30781
30782
30783
30784
30785
30786
30787
30788
30789
30790
30791
30792
30793
30794
30795
30796
30797
30798
30799
30800
30801
30802
30803
30804
30805
30806
30807
30808
30809
30810
30811
30812
30813
30814
30815
30816
30817
30818
30819
30820
30821
30822
30823
30824
30825
30826
30827
30828
30829
30830
30831
30832
30833
30834
30835
30836
30837
30838
30839
30840
30841
30842
30843
30844
30845
30846
30847
30848
30849
30850
30851
30852
30853
30854
30855
30856
30857
30858
30859
30860
30861
30862
30863
30864
30865
30866
30867
30868
30869
30870
30871
30872
30873
30874
30875
30876
30877
30878
30879
30880
30881
30882
30883
30884
30885
30886
30887
30888
30889
30890
30891
30892
30893
30894
30895
30896
30897
30898
30899
30900
30901
30902
30903
30904
30905
30906
30907
30908
30909
30910
30911
30912
30913
30914
30915
30916
30917
30918
30919
30920
30921
30922
30923
30924
30925
30926
30927
30928
30929
30930
30931
30932
30933
30934
30935
30936
30937
30938
30939
30940
30941
30942
30943
30944
30945
30946
30947
30948
30949
30950
30951
30952
30953
30954
30955
30956
30957
30958
30959
30960
30961
30962
30963
30964
30965
30966
30967
30968
30969
30970
30971
30972
30973
30974
30975
30976
30977
30978
30979
30980
30981
30982
30983
30984
30985
30986
30987
30988
30989
30990
30991
30992
30993
30994
30995
30996
30997
30998
30999
31000
31001
31002
31003
31004
31005
31006
31007
31008
31009
31010
31011
31012
31013
31014
31015
31016
31017
31018
31019
31020
31021
31022
31023
31024
31025
31026
31027
31028
31029
31030
31031
31032
31033
31034
31035
31036
31037
31038
31039
31040
31041
31042
31043
31044
31045
31046
31047
31048
31049
31050
31051
31052
31053
31054
31055
31056
31057
31058
31059
31060
31061
31062
31063
31064
31065
31066
31067
31068
31069
31070
31071
31072
31073
31074
31075
31076
31077
31078
31079
31080
31081
31082
31083
31084
31085
31086
31087
31088
31089
31090
31091
31092
31093
31094
31095
31096
31097
31098
31099
31100
31101
31102
31103
31104
31105
31106
31107
31108
31109
31110
31111
31112
31113
31114
31115
31116
31117
31118
31119
31120
31121
31122
31123
31124
31125
31126
31127
31128
31129
31130
31131
31132
31133
31134
31135
31136
31137
31138
31139
31140
31141
31142
31143
31144
31145
31146
31147
31148
31149
31150
31151
31152
31153
31154
31155
31156
31157
31158
31159
31160
31161
31162
31163
31164
31165
31166
31167
31168
31169
31170
31171
31172
31173
31174
31175
31176
31177
31178
31179
31180
31181
31182
31183
31184
31185
31186
31187
31188
31189
31190
31191
31192
31193
31194
31195
31196
31197
31198
31199
31200
31201
31202
31203
31204
31205
31206
31207
31208
31209
31210
31211
31212
31213
31214
31215
31216
31217
31218
31219
31220
31221
31222
31223
31224
31225
31226
31227
31228
31229
31230
31231
31232
31233
31234
31235
31236
31237
31238
31239
31240
31241
31242
31243
31244
31245
31246
31247
31248
31249
31250
31251
31252
31253
31254
31255
31256
31257
31258
31259
31260
31261
31262
31263
31264
31265
31266
31267
31268
31269
31270
31271
31272
31273
31274
31275
31276
31277
31278
31279
31280
31281
31282
31283
31284
31285
31286
31287
31288
31289
31290
31291
31292
31293
31294
31295
31296
31297
31298
31299
31300
31301
31302
31303
31304
31305
31306
31307
31308
31309
31310
31311
31312
31313
31314
31315
31316
31317
31318
31319
31320
31321
31322
31323
31324
31325
31326
31327
31328
31329
31330
31331
31332
31333
31334
31335
31336
31337
31338
31339
31340
31341
31342
31343
31344
31345
31346
31347
31348
31349
31350
31351
31352
31353
31354
31355
31356
31357
31358
31359
31360
31361
31362
31363
31364
31365
31366
31367
31368
31369
31370
31371
31372
31373
31374
31375
31376
31377
31378
31379
31380
31381
31382
31383
31384
31385
31386
31387
31388
31389
31390
31391
31392
31393
31394
31395
31396
31397
31398
31399
31400
31401
31402
31403
31404
31405
31406
31407
31408
31409
31410
31411
31412
31413
31414
31415
31416
31417
31418
31419
31420
31421
31422
31423
31424
31425
31426
31427
31428
31429
31430
31431
31432
31433
31434
31435
31436
31437
31438
31439
31440
31441
31442
31443
31444
31445
31446
31447
31448
31449
31450
31451
31452
31453
31454
31455
31456
31457
31458
31459
31460
31461
31462
31463
31464
31465
31466
31467
31468
31469
31470
31471
31472
31473
31474
31475
31476
31477
31478
31479
31480
31481
31482
31483
31484
31485
31486
31487
31488
31489
31490
31491
31492
31493
31494
31495
31496
31497
31498
31499
31500
31501
31502
31503
31504
31505
31506
31507
31508
31509
31510
31511
31512
31513
31514
31515
31516
31517
31518
31519
31520
31521
31522
31523
31524
31525
31526
31527
31528
31529
31530
31531
31532
31533
31534
31535
31536
31537
31538
31539
31540
31541
31542
31543
31544
31545
31546
31547
31548
31549
31550
31551
31552
31553
31554
31555
31556
31557
31558
31559
31560
31561
31562
31563
31564
31565
31566
31567
31568
31569
31570
31571
31572
31573
31574
31575
31576
31577
31578
31579
31580
31581
31582
31583
31584
31585
31586
31587
31588
31589
31590
31591
31592
31593
31594
31595
31596
31597
31598
31599
31600
31601
31602
31603
31604
31605
31606
31607
31608
31609
31610
31611
31612
31613
31614
31615
31616
31617
31618
31619
31620
31621
31622
31623
31624
31625
31626
31627
31628
31629
31630
31631
31632
31633
31634
31635
31636
31637
31638
31639
31640
31641
31642
31643
31644
31645
31646
31647
31648
31649
31650
31651
31652
31653
31654
31655
31656
31657
31658
31659
31660
31661
31662
31663
31664
31665
31666
31667
31668
31669
31670
31671
31672
31673
31674
31675
31676
31677
31678
31679
31680
31681
31682
31683
31684
31685
31686
31687
31688
31689
31690
31691
31692
31693
31694
31695
31696
31697
31698
31699
31700
31701
31702
31703
31704
31705
31706
31707
31708
31709
31710
31711
31712
31713
31714
31715
31716
31717
31718
31719
31720
31721
31722
31723
31724
31725
31726
31727
31728
31729
31730
31731
31732
31733
31734
31735
31736
31737
31738
31739
31740
31741
31742
31743
31744
31745
31746
31747
31748
31749
31750
31751
31752
31753
31754
31755
31756
31757
31758
31759
31760
31761
31762
31763
31764
31765
31766
31767
31768
31769
31770
31771
31772
31773
31774
31775
31776
31777
31778
31779
31780
31781
31782
31783
31784
31785
31786
31787
31788
31789
31790
31791
31792
31793
31794
31795
31796
31797
31798
31799
31800
31801
31802
31803
31804
31805
31806
31807
31808
31809
31810
31811
31812
31813
31814
31815
31816
31817
31818
31819
31820
31821
31822
31823
31824
31825
31826
31827
31828
31829
31830
31831
31832
31833
31834
31835
31836
31837
31838
31839
31840
31841
31842
31843
31844
31845
31846
31847
31848
31849
31850
31851
31852
31853
31854
31855
31856
31857
31858
31859
31860
31861
31862
31863
31864
31865
31866
31867
31868
31869
31870
31871
31872
31873
31874
31875
31876
31877
31878
31879
31880
31881
31882
31883
31884
31885
31886
31887
31888
31889
31890
31891
31892
31893
31894
31895
31896
31897
31898
31899
31900
31901
31902
31903
31904
31905
31906
31907
31908
31909
31910
31911
31912
31913
31914
31915
31916
31917
31918
31919
31920
31921
31922
31923
31924
31925
31926
31927
31928
31929
31930
31931
31932
31933
31934
31935
31936
31937
31938
31939
31940
31941
31942
31943
31944
31945
31946
31947
31948
31949
31950
31951
31952
31953
31954
31955
31956
31957
31958
31959
31960
31961
31962
31963
31964
31965
31966
31967
31968
31969
31970
31971
31972
31973
31974
31975
31976
31977
31978
31979
31980
31981
31982
31983
31984
31985
31986
31987
31988
31989
31990
31991
31992
31993
31994
31995
31996
31997
31998
31999
32000
32001
32002
32003
32004
32005
32006
32007
32008
32009
32010
32011
32012
32013
32014
32015
32016
32017
32018
32019
32020
32021
32022
32023
32024
32025
32026
32027
32028
32029
32030
32031
32032
32033
32034
32035
32036
32037
32038
32039
32040
32041
32042
32043
32044
32045
32046
32047
32048
32049
32050
32051
32052
32053
32054
32055
32056
32057
32058
32059
32060
32061
32062
32063
32064
32065
32066
32067
32068
32069
32070
32071
32072
32073
32074
32075
32076
32077
32078
32079
32080
32081
32082
32083
32084
32085
32086
32087
32088
32089
32090
32091
32092
32093
32094
32095
32096
32097
32098
32099
32100
32101
32102
32103
32104
32105
32106
32107
32108
32109
32110
32111
32112
32113
32114
32115
32116
32117
32118
32119
32120
32121
32122
32123
32124
32125
32126
32127
32128
32129
32130
32131
32132
32133
32134
32135
32136
32137
32138
32139
32140
32141
32142
32143
32144
32145
32146
32147
32148
32149
32150
32151
32152
32153
32154
32155
32156
32157
32158
32159
32160
32161
32162
32163
32164
32165
32166
32167
32168
32169
32170
32171
32172
32173
32174
32175
32176
32177
32178
32179
32180
32181
32182
32183
32184
32185
32186
32187
32188
32189
32190
32191
32192
32193
32194
32195
32196
32197
32198
32199
32200
32201
32202
32203
32204
32205
32206
32207
32208
32209
32210
32211
32212
32213
32214
32215
32216
32217
32218
32219
32220
32221
32222
32223
32224
32225
32226
32227
32228
32229
32230
32231
32232
32233
32234
32235
32236
32237
32238
32239
32240
32241
32242
32243
32244
32245
32246
32247
32248
32249
32250
32251
32252
32253
32254
32255
32256
32257
32258
32259
32260
32261
32262
32263
32264
32265
32266
32267
32268
32269
32270
32271
32272
32273
32274
32275
32276
32277
32278
32279
32280
32281
32282
32283
32284
32285
32286
32287
32288
32289
32290
32291
32292
32293
32294
32295
32296
32297
32298
32299
32300
32301
32302
32303
32304
32305
32306
32307
32308
32309
32310
32311
32312
32313
32314
32315
32316
32317
32318
32319
32320
32321
32322
32323
32324
32325
32326
32327
32328
32329
32330
32331
32332
32333
32334
32335
32336
32337
32338
32339
32340
32341
32342
32343
32344
32345
32346
32347
32348
32349
32350
32351
32352
32353
32354
32355
32356
32357
32358
32359
32360
32361
32362
32363
32364
32365
32366
32367
32368
32369
32370
32371
32372
32373
32374
32375
32376
32377
32378
32379
32380
32381
32382
32383
32384
32385
32386
32387
32388
32389
32390
32391
32392
32393
32394
32395
32396
32397
32398
32399
32400
32401
32402
32403
32404
32405
32406
32407
32408
32409
32410
32411
32412
32413
32414
32415
32416
32417
32418
32419
32420
32421
32422
32423
32424
32425
32426
32427
32428
32429
32430
32431
32432
32433
32434
32435
32436
32437
32438
32439
32440
32441
32442
32443
32444
32445
32446
32447
32448
32449
32450
32451
32452
32453
32454
32455
32456
32457
32458
32459
32460
32461
32462
32463
32464
32465
32466
32467
32468
32469
32470
32471
32472
32473
32474
32475
32476
32477
32478
32479
32480
32481
32482
32483
32484
32485
32486
32487
32488
32489
32490
32491
32492
32493
32494
32495
32496
32497
32498
32499
32500
32501
32502
32503
32504
32505
32506
32507
32508
32509
32510
32511
32512
32513
32514
32515
32516
32517
32518
32519
32520
32521
32522
32523
32524
32525
32526
32527
32528
32529
32530
32531
32532
32533
32534
32535
32536
32537
32538
32539
32540
32541
32542
32543
32544
32545
32546
32547
32548
32549
32550
32551
32552
32553
32554
32555
32556
32557
32558
32559
32560
32561
32562
32563
32564
32565
32566
32567
32568
32569
32570
32571
32572
32573
32574
32575
32576
32577
32578
32579
32580
32581
32582
32583
32584
32585
32586
32587
32588
32589
32590
32591
32592
32593
32594
32595
32596
32597
32598
32599
32600
32601
32602
32603
32604
32605
32606
32607
32608
32609
32610
32611
32612
32613
32614
32615
32616
32617
32618
32619
32620
32621
32622
32623
32624
32625
32626
32627
32628
32629
32630
32631
32632
32633
32634
32635
32636
32637
32638
32639
32640
32641
32642
32643
32644
32645
32646
32647
32648
32649
32650
32651
32652
32653
32654
32655
32656
32657
32658
32659
32660
32661
32662
32663
32664
32665
32666
32667
32668
32669
32670
32671
32672
32673
32674
32675
32676
32677
32678
32679
32680
32681
32682
32683
32684
32685
32686
32687
32688
32689
32690
32691
32692
32693
32694
32695
32696
32697
32698
32699
32700
32701
32702
32703
32704
32705
32706
32707
32708
32709
32710
32711
32712
32713
32714
32715
32716
32717
32718
32719
32720
32721
32722
32723
32724
32725
32726
32727
32728
32729
32730
32731
32732
32733
32734
32735
32736
32737
32738
32739
32740
32741
32742
32743
32744
32745
32746
32747
32748
32749
32750
32751
32752
32753
32754
32755
32756
32757
32758
32759
32760
32761
32762
32763
32764
32765
32766
32767
32768
32769
32770
32771
32772
32773
32774
32775
32776
32777
32778
32779
32780
32781
32782
32783
32784
32785
32786
32787
32788
32789
32790
32791
32792
32793
32794
32795
32796
32797
32798
32799
32800
32801
32802
32803
32804
32805
32806
32807
32808
32809
32810
32811
32812
32813
32814
32815
32816
32817
32818
32819
32820
32821
32822
32823
32824
32825
32826
32827
32828
32829
32830
32831
32832
32833
32834
32835
32836
32837
32838
32839
32840
32841
32842
32843
32844
32845
32846
32847
32848
32849
32850
32851
32852
32853
32854
32855
32856
32857
32858
32859
32860
32861
32862
32863
32864
32865
32866
32867
32868
32869
32870
32871
32872
32873
32874
32875
32876
32877
32878
32879
32880
32881
32882
32883
32884
32885
32886
32887
32888
32889
32890
32891
32892
32893
32894
32895
32896
32897
32898
32899
32900
32901
32902
32903
32904
32905
32906
32907
32908
32909
32910
32911
32912
32913
32914
32915
32916
32917
32918
32919
32920
32921
32922
32923
32924
32925
32926
32927
32928
32929
32930
32931
32932
32933
32934
32935
32936
32937
32938
32939
32940
32941
32942
32943
32944
32945
32946
32947
32948
32949
32950
32951
32952
32953
32954
32955
32956
32957
32958
32959
32960
32961
32962
32963
32964
32965
32966
32967
32968
32969
32970
32971
32972
32973
32974
32975
32976
32977
32978
32979
32980
32981
32982
32983
32984
32985
32986
32987
32988
32989
32990
32991
32992
32993
32994
32995
32996
32997
32998
32999
33000
33001
33002
33003
33004
33005
33006
33007
33008
33009
33010
33011
33012
33013
33014
33015
33016
33017
33018
33019
33020
33021
33022
33023
33024
33025
33026
33027
33028
33029
33030
33031
33032
33033
33034
33035
33036
33037
33038
33039
33040
33041
33042
33043
33044
33045
33046
33047
33048
33049
33050
33051
33052
33053
33054
33055
33056
33057
33058
33059
33060
33061
33062
33063
33064
33065
33066
33067
33068
33069
33070
33071
33072
33073
33074
33075
33076
33077
33078
33079
33080
33081
33082
33083
33084
33085
33086
33087
33088
33089
33090
33091
33092
33093
33094
33095
33096
33097
33098
33099
33100
33101
33102
33103
33104
33105
33106
33107
33108
33109
33110
33111
33112
33113
33114
33115
33116
33117
33118
33119
33120
33121
33122
33123
33124
33125
33126
33127
33128
33129
33130
33131
33132
33133
33134
33135
33136
33137
33138
33139
33140
33141
33142
33143
33144
33145
33146
33147
33148
33149
33150
33151
33152
33153
33154
33155
33156
33157
33158
33159
33160
33161
33162
33163
33164
33165
33166
33167
33168
33169
33170
33171
33172
33173
33174
33175
33176
33177
33178
33179
33180
33181
33182
33183
33184
33185
33186
33187
33188
33189
33190
33191
33192
33193
33194
33195
33196
33197
33198
33199
33200
33201
33202
33203
33204
33205
33206
33207
33208
33209
33210
33211
33212
33213
33214
33215
33216
33217
33218
33219
33220
33221
33222
33223
33224
33225
33226
33227
33228
33229
33230
33231
33232
33233
33234
33235
33236
33237
33238
33239
33240
33241
33242
33243
33244
33245
33246
33247
33248
33249
33250
33251
33252
33253
33254
33255
33256
33257
33258
33259
33260
33261
33262
33263
33264
33265
33266
33267
33268
33269
33270
33271
33272
33273
33274
33275
33276
33277
33278
33279
33280
33281
33282
33283
33284
33285
33286
33287
33288
33289
33290
33291
33292
33293
33294
33295
33296
33297
33298
33299
33300
33301
33302
33303
33304
33305
33306
33307
33308
33309
33310
33311
33312
33313
33314
33315
33316
33317
33318
33319
33320
33321
33322
33323
33324
33325
33326
33327
33328
33329
33330
33331
33332
33333
33334
33335
33336
33337
33338
33339
33340
33341
33342
33343
33344
33345
33346
33347
33348
33349
33350
33351
33352
33353
33354
33355
33356
33357
33358
33359
33360
33361
33362
33363
33364
33365
33366
33367
33368
33369
33370
33371
33372
33373
33374
33375
33376
33377
33378
33379
33380
33381
33382
33383
33384
33385
33386
33387
33388
33389
33390
33391
33392
33393
33394
33395
33396
33397
33398
33399
33400
33401
33402
33403
33404
33405
33406
33407
33408
33409
33410
33411
33412
33413
33414
33415
33416
33417
33418
33419
33420
33421
33422
33423
33424
33425
33426
33427
33428
33429
33430
33431
33432
33433
33434
33435
33436
33437
33438
33439
33440
33441
33442
33443
33444
33445
33446
33447
33448
33449
33450
33451
33452
33453
33454
33455
33456
33457
33458
33459
33460
33461
33462
33463
33464
33465
33466
33467
33468
33469
33470
33471
33472
33473
33474
33475
33476
33477
33478
33479
33480
33481
33482
33483
33484
33485
33486
33487
33488
33489
33490
33491
33492
33493
33494
33495
33496
33497
33498
33499
33500
33501
33502
33503
33504
33505
33506
33507
33508
33509
33510
33511
33512
33513
33514
33515
33516
33517
33518
33519
33520
33521
33522
33523
33524
33525
33526
33527
33528
33529
33530
33531
33532
33533
33534
33535
33536
33537
33538
33539
33540
33541
33542
33543
33544
33545
33546
33547
33548
33549
33550
33551
33552
33553
33554
33555
33556
33557
33558
33559
33560
33561
33562
33563
33564
33565
33566
33567
33568
33569
33570
33571
33572
33573
33574
33575
33576
33577
33578
33579
33580
33581
33582
33583
33584
33585
33586
33587
33588
33589
33590
33591
33592
33593
33594
33595
33596
33597
33598
33599
33600
33601
33602
33603
33604
33605
33606
33607
33608
33609
33610
33611
33612
33613
33614
33615
33616
33617
33618
33619
33620
33621
33622
33623
33624
33625
33626
33627
33628
33629
33630
33631
33632
33633
33634
33635
33636
33637
33638
33639
33640
33641
33642
33643
33644
33645
33646
33647
33648
33649
33650
33651
33652
33653
33654
33655
33656
33657
33658
33659
33660
33661
33662
33663
33664
33665
33666
33667
33668
33669
33670
33671
33672
33673
33674
33675
33676
33677
33678
33679
33680
33681
33682
33683
33684
33685
33686
33687
33688
33689
33690
33691
33692
33693
33694
33695
33696
33697
33698
33699
33700
33701
33702
33703
33704
33705
33706
33707
33708
33709
33710
33711
33712
33713
33714
33715
33716
33717
33718
33719
33720
33721
33722
33723
33724
33725
33726
33727
33728
33729
33730
33731
33732
33733
33734
33735
33736
33737
33738
33739
33740
33741
33742
33743
33744
33745
33746
33747
33748
33749
33750
33751
33752
33753
33754
33755
33756
33757
33758
33759
33760
33761
33762
33763
33764
33765
33766
33767
33768
33769
33770
33771
33772
33773
33774
33775
33776
33777
33778
33779
33780
33781
33782
33783
33784
33785
33786
33787
33788
33789
33790
33791
33792
33793
33794
33795
33796
33797
33798
33799
33800
33801
33802
33803
33804
33805
33806
33807
33808
33809
33810
33811
33812
33813
33814
33815
33816
33817
33818
33819
33820
33821
33822
33823
33824
33825
33826
33827
33828
33829
33830
33831
33832
33833
33834
33835
33836
33837
33838
33839
33840
33841
33842
33843
33844
33845
33846
33847
33848
33849
33850
33851
33852
33853
33854
33855
33856
33857
33858
33859
33860
33861
33862
33863
33864
33865
33866
33867
33868
33869
33870
33871
33872
33873
33874
33875
33876
33877
33878
33879
33880
33881
33882
33883
33884
33885
33886
33887
33888
33889
33890
33891
33892
33893
33894
33895
33896
33897
33898
33899
33900
33901
33902
33903
33904
33905
33906
33907
33908
33909
33910
33911
33912
33913
33914
33915
33916
33917
33918
33919
33920
33921
33922
33923
33924
33925
33926
33927
33928
33929
33930
33931
33932
33933
33934
33935
33936
33937
33938
33939
33940
33941
33942
33943
33944
33945
33946
33947
33948
33949
33950
33951
33952
33953
33954
33955
33956
33957
33958
33959
33960
33961
33962
33963
33964
33965
33966
33967
33968
33969
33970
33971
33972
33973
33974
33975
33976
33977
33978
33979
33980
33981
33982
33983
33984
33985
33986
33987
33988
33989
33990
33991
33992
33993
33994
33995
33996
33997
33998
33999
34000
34001
34002
34003
34004
34005
34006
34007
34008
34009
34010
34011
34012
34013
34014
34015
34016
34017
34018
34019
34020
34021
34022
34023
34024
34025
34026
34027
34028
34029
34030
34031
34032
34033
34034
34035
34036
34037
34038
34039
34040
34041
34042
34043
34044
34045
34046
34047
34048
34049
34050
34051
34052
34053
34054
34055
34056
34057
34058
34059
34060
34061
34062
34063
34064
34065
34066
34067
34068
34069
34070
34071
34072
34073
34074
34075
34076
34077
34078
34079
34080
34081
34082
34083
34084
34085
34086
34087
34088
34089
34090
34091
34092
34093
34094
34095
34096
34097
34098
34099
34100
34101
34102
34103
34104
34105
34106
34107
34108
34109
34110
34111
34112
34113
34114
34115
34116
34117
34118
34119
34120
34121
34122
34123
34124
34125
34126
34127
34128
34129
34130
34131
34132
34133
34134
34135
34136
34137
34138
34139
34140
34141
34142
34143
34144
34145
34146
34147
34148
34149
34150
34151
34152
34153
34154
34155
34156
34157
34158
34159
34160
34161
34162
34163
34164
34165
34166
34167
34168
34169
34170
34171
34172
34173
34174
34175
34176
34177
34178
34179
34180
34181
34182
34183
34184
34185
34186
34187
34188
34189
34190
34191
34192
34193
34194
34195
34196
34197
34198
34199
34200
34201
34202
34203
34204
34205
34206
34207
34208
34209
34210
34211
34212
34213
34214
34215
34216
34217
34218
34219
34220
34221
34222
34223
34224
34225
34226
34227
34228
34229
34230
34231
34232
34233
34234
34235
34236
34237
34238
34239
34240
34241
34242
34243
34244
34245
34246
34247
34248
34249
34250
34251
34252
34253
34254
34255
34256
34257
34258
34259
34260
34261
34262
34263
34264
34265
34266
34267
34268
34269
34270
34271
34272
34273
34274
34275
34276
34277
34278
34279
34280
34281
34282
34283
34284
34285
34286
34287
34288
34289
34290
34291
34292
34293
34294
34295
34296
34297
34298
34299
34300
34301
34302
34303
34304
34305
34306
34307
34308
34309
34310
34311
34312
34313
34314
34315
34316
34317
34318
34319
34320
34321
34322
34323
34324
34325
34326
34327
34328
34329
34330
34331
34332
34333
34334
34335
34336
34337
34338
34339
34340
34341
34342
34343
34344
34345
34346
34347
34348
34349
34350
34351
34352
34353
34354
34355
34356
34357
34358
34359
34360
34361
34362
34363
34364
34365
34366
34367
34368
34369
34370
34371
34372
34373
34374
34375
34376
34377
34378
34379
34380
34381
34382
34383
34384
34385
34386
34387
34388
34389
34390
34391
34392
34393
34394
34395
34396
34397
34398
34399
34400
34401
34402
34403
34404
34405
34406
34407
34408
34409
34410
34411
34412
34413
34414
34415
34416
34417
34418
34419
34420
34421
34422
34423
34424
34425
34426
34427
34428
34429
34430
34431
34432
34433
34434
34435
34436
34437
34438
34439
34440
34441
34442
34443
34444
34445
34446
34447
34448
34449
34450
34451
34452
34453
34454
34455
34456
34457
34458
34459
34460
34461
34462
34463
34464
34465
34466
34467
34468
34469
34470
34471
34472
34473
34474
34475
34476
34477
34478
34479
34480
34481
34482
34483
34484
34485
34486
34487
34488
34489
34490
34491
34492
34493
34494
34495
34496
34497
34498
34499
34500
34501
34502
34503
34504
34505
34506
34507
34508
34509
34510
34511
34512
34513
34514
34515
34516
34517
34518
34519
34520
34521
34522
34523
34524
34525
34526
34527
34528
34529
34530
34531
34532
34533
34534
34535
34536
34537
34538
34539
34540
34541
34542
34543
34544
34545
34546
34547
34548
34549
34550
34551
34552
34553
34554
34555
34556
34557
34558
34559
34560
34561
34562
34563
34564
34565
34566
34567
34568
34569
34570
34571
34572
34573
34574
34575
34576
34577
34578
34579
34580
34581
34582
34583
34584
34585
34586
34587
34588
34589
34590
34591
34592
34593
34594
34595
34596
34597
34598
34599
34600
34601
34602
34603
34604
34605
34606
34607
34608
34609
34610
34611
34612
34613
34614
34615
34616
34617
34618
34619
34620
34621
34622
34623
34624
34625
34626
34627
34628
34629
34630
34631
34632
34633
34634
34635
34636
34637
34638
34639
34640
34641
34642
34643
34644
34645
34646
34647
34648
34649
34650
34651
34652
34653
34654
34655
34656
34657
34658
34659
34660
34661
34662
34663
34664
34665
34666
34667
34668
34669
34670
34671
34672
34673
34674
34675
34676
34677
34678
34679
34680
34681
34682
34683
34684
34685
34686
34687
34688
34689
34690
34691
34692
34693
34694
34695
34696
34697
34698
34699
34700
34701
34702
34703
34704
34705
34706
34707
34708
34709
34710
34711
34712
34713
34714
34715
34716
34717
34718
34719
34720
34721
34722
34723
34724
34725
34726
34727
34728
34729
34730
34731
34732
34733
34734
34735
34736
34737
34738
34739
34740
34741
34742
34743
34744
34745
34746
34747
34748
34749
34750
34751
34752
34753
34754
34755
34756
34757
34758
34759
34760
34761
34762
34763
34764
34765
34766
34767
34768
34769
34770
34771
34772
34773
34774
34775
34776
34777
34778
34779
34780
34781
34782
34783
34784
34785
34786
34787
34788
34789
34790
34791
34792
34793
34794
34795
34796
34797
34798
34799
34800
34801
34802
34803
34804
34805
34806
34807
34808
34809
34810
34811
34812
34813
34814
34815
34816
34817
34818
34819
34820
34821
34822
34823
34824
34825
34826
34827
34828
34829
34830
34831
34832
34833
34834
34835
34836
34837
34838
34839
34840
34841
34842
34843
34844
34845
34846
34847
34848
34849
34850
34851
34852
34853
34854
34855
34856
34857
34858
34859
34860
34861
34862
34863
34864
34865
34866
34867
34868
34869
34870
34871
34872
34873
34874
34875
34876
34877
34878
34879
34880
34881
34882
34883
34884
34885
34886
34887
34888
34889
34890
34891
34892
34893
34894
34895
34896
34897
34898
34899
34900
34901
34902
34903
34904
34905
34906
34907
34908
34909
34910
34911
34912
34913
34914
34915
34916
34917
34918
34919
34920
34921
34922
34923
34924
34925
34926
34927
34928
34929
34930
34931
34932
34933
34934
34935
34936
34937
34938
34939
34940
34941
34942
34943
34944
34945
34946
34947
34948
34949
34950
34951
34952
34953
34954
34955
34956
34957
34958
34959
34960
34961
34962
34963
34964
34965
34966
34967
34968
34969
34970
34971
34972
34973
34974
34975
34976
34977
34978
34979
34980
34981
34982
34983
34984
34985
34986
34987
34988
34989
34990
34991
34992
34993
34994
34995
34996
34997
34998
34999
35000
35001
35002
35003
35004
35005
35006
35007
35008
35009
35010
35011
35012
35013
35014
35015
35016
35017
35018
35019
35020
35021
35022
35023
35024
35025
35026
35027
35028
35029
35030
35031
35032
35033
35034
35035
35036
35037
35038
35039
35040
35041
35042
35043
35044
35045
35046
35047
35048
35049
35050
35051
35052
35053
35054
35055
35056
35057
35058
35059
35060
35061
35062
35063
35064
35065
35066
35067
35068
35069
35070
35071
35072
35073
35074
35075
35076
35077
35078
35079
35080
35081
35082
35083
35084
35085
35086
35087
35088
35089
35090
35091
35092
35093
35094
35095
35096
35097
35098
35099
35100
35101
35102
35103
35104
35105
35106
35107
35108
35109
35110
35111
35112
35113
35114
35115
35116
35117
35118
35119
35120
35121
35122
35123
35124
35125
35126
35127
35128
35129
35130
35131
35132
35133
35134
35135
35136
35137
35138
35139
35140
35141
35142
35143
35144
35145
35146
35147
35148
35149
35150
35151
35152
35153
35154
35155
35156
35157
35158
35159
35160
35161
35162
35163
35164
35165
35166
35167
35168
35169
35170
35171
35172
35173
35174
35175
35176
35177
35178
35179
35180
35181
35182
35183
35184
35185
35186
35187
35188
35189
35190
35191
35192
35193
35194
35195
35196
35197
35198
35199
35200
35201
35202
35203
35204
35205
35206
35207
35208
35209
35210
35211
35212
35213
35214
35215
35216
35217
35218
35219
35220
35221
35222
35223
35224
35225
35226
35227
35228
35229
35230
35231
35232
35233
35234
35235
35236
35237
35238
35239
35240
35241
35242
35243
35244
35245
35246
35247
35248
35249
35250
35251
35252
35253
35254
35255
35256
35257
35258
35259
35260
35261
35262
35263
35264
35265
35266
35267
35268
35269
35270
35271
35272
35273
35274
35275
35276
35277
35278
35279
35280
35281
35282
35283
35284
35285
35286
35287
35288
35289
35290
35291
35292
35293
35294
35295
35296
35297
35298
35299
35300
35301
35302
35303
35304
35305
35306
35307
35308
35309
35310
35311
35312
35313
35314
35315
35316
35317
35318
35319
35320
35321
35322
35323
35324
35325
35326
35327
35328
35329
35330
35331
35332
35333
35334
35335
35336
35337
35338
35339
35340
35341
35342
35343
35344
35345
35346
35347
35348
35349
35350
35351
35352
35353
35354
35355
35356
35357
35358
35359
35360
35361
35362
35363
35364
35365
35366
35367
35368
35369
35370
35371
35372
35373
35374
35375
35376
35377
35378
35379
35380
35381
35382
35383
35384
35385
35386
35387
35388
35389
35390
35391
35392
35393
35394
35395
35396
35397
35398
35399
35400
35401
35402
35403
35404
35405
35406
35407
35408
35409
35410
35411
35412
35413
35414
35415
35416
35417
35418
35419
35420
35421
35422
35423
35424
35425
35426
35427
35428
35429
35430
35431
35432
35433
35434
35435
35436
35437
35438
35439
35440
35441
35442
35443
35444
35445
35446
35447
35448
35449
35450
35451
35452
35453
35454
35455
35456
35457
35458
35459
35460
35461
35462
35463
35464
35465
35466
35467
35468
35469
35470
35471
35472
35473
35474
35475
35476
35477
35478
35479
35480
35481
35482
35483
35484
35485
35486
35487
35488
35489
35490
35491
35492
35493
35494

# BEGIN testcases29

# Test parsing of time of day

test clock-29.1 {time parsing} {
    clock scan {2440588 00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H }
} 0
test clock-29.2 {time parsing} {
    clock scan {2440588 00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M }
} 0
test clock-29.3 {time parsing} {
    clock scan {2440588 00:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM }
} 0
test clock-29.4 {time parsing} {
    clock scan {2440588 00:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 0
test clock-29.5 {time parsing} {
    clock scan {2440588 00:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 0
test clock-29.6 {time parsing} {
    clock scan {2440588  0 } \
	-gmt true -locale en_US_roman \
	-format {%J %k }
} 0
test clock-29.7 {time parsing} {
    clock scan {2440588  0:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M }
} 0
test clock-29.8 {time parsing} {
    clock scan {2440588  0:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM }
} 0
test clock-29.9 {time parsing} {
    clock scan {2440588  0:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 0
test clock-29.10 {time parsing} {
    clock scan {2440588  0:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 0
test clock-29.11 {time parsing} {
    clock scan {2440588 ? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH }
} 0
test clock-29.12 {time parsing} {
    clock scan {2440588 ?:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M }
} 0
test clock-29.13 {time parsing} {
    clock scan {2440588 ?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM }
} 0
test clock-29.14 {time parsing} {
    clock scan {2440588 ?:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 0
test clock-29.15 {time parsing} {
    clock scan {2440588 ?:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 0
test clock-29.16 {time parsing} {
    clock scan {2440588 ? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok }
} 0
test clock-29.17 {time parsing} {
    clock scan {2440588 ?:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M }
} 0
test clock-29.18 {time parsing} {
    clock scan {2440588 ?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM }
} 0
test clock-29.19 {time parsing} {
    clock scan {2440588 ?:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 0
test clock-29.20 {time parsing} {
    clock scan {2440588 ?:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 0
test clock-29.21 {time parsing} {
    clock scan {2440588 12 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I %p}
} 0
test clock-29.22 {time parsing} {
    clock scan {2440588 12:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %p}
} 0
test clock-29.23 {time parsing} {
    clock scan {2440588 12:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %p}
} 0
test clock-29.24 {time parsing} {
    clock scan {2440588 12:00:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 0
test clock-29.25 {time parsing} {
    clock scan {2440588 12:?:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 0
test clock-29.26 {time parsing} {
    clock scan {2440588 12 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l %p}
} 0
test clock-29.27 {time parsing} {
    clock scan {2440588 12:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %p}
} 0
test clock-29.28 {time parsing} {
    clock scan {2440588 12:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %p}
} 0
test clock-29.29 {time parsing} {
    clock scan {2440588 12:00:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 0
test clock-29.30 {time parsing} {
    clock scan {2440588 12:?:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 0
test clock-29.31 {time parsing} {
    clock scan {2440588 xii AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI %p}
} 0
test clock-29.32 {time parsing} {
    clock scan {2440588 xii:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %p}
} 0
test clock-29.33 {time parsing} {
    clock scan {2440588 xii:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %p}
} 0
test clock-29.34 {time parsing} {
    clock scan {2440588 xii:00:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 0
test clock-29.35 {time parsing} {
    clock scan {2440588 xii:?:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 0
test clock-29.36 {time parsing} {
    clock scan {2440588 xii AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol %p}
} 0
test clock-29.37 {time parsing} {
    clock scan {2440588 xii:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %p}
} 0
test clock-29.38 {time parsing} {
    clock scan {2440588 xii:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %p}
} 0
test clock-29.39 {time parsing} {
    clock scan {2440588 xii:00:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 0
test clock-29.40 {time parsing} {
    clock scan {2440588 xii:?:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 0
test clock-29.41 {time parsing} {
    clock scan {2440588 12 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I %P}
} 0
test clock-29.42 {time parsing} {
    clock scan {2440588 12:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %P}
} 0
test clock-29.43 {time parsing} {
    clock scan {2440588 12:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %P}
} 0
test clock-29.44 {time parsing} {
    clock scan {2440588 12:00:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 0
test clock-29.45 {time parsing} {
    clock scan {2440588 12:?:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 0
test clock-29.46 {time parsing} {
    clock scan {2440588 12 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l %P}
} 0
test clock-29.47 {time parsing} {
    clock scan {2440588 12:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %P}
} 0
test clock-29.48 {time parsing} {
    clock scan {2440588 12:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %P}
} 0
test clock-29.49 {time parsing} {
    clock scan {2440588 12:00:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 0
test clock-29.50 {time parsing} {
    clock scan {2440588 12:?:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 0
test clock-29.51 {time parsing} {
    clock scan {2440588 xii am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI %P}
} 0
test clock-29.52 {time parsing} {
    clock scan {2440588 xii:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %P}
} 0
test clock-29.53 {time parsing} {
    clock scan {2440588 xii:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %P}
} 0
test clock-29.54 {time parsing} {
    clock scan {2440588 xii:00:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 0
test clock-29.55 {time parsing} {
    clock scan {2440588 xii:?:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 0
test clock-29.56 {time parsing} {
    clock scan {2440588 xii am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol %P}
} 0
test clock-29.57 {time parsing} {
    clock scan {2440588 xii:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %P}
} 0
test clock-29.58 {time parsing} {
    clock scan {2440588 xii:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %P}
} 0
test clock-29.59 {time parsing} {
    clock scan {2440588 xii:00:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 0
test clock-29.60 {time parsing} {
    clock scan {2440588 xii:?:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 0
test clock-29.61 {time parsing} {
    clock scan {2440588 00:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 1
test clock-29.62 {time parsing} {
    clock scan {2440588 00:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 1
test clock-29.63 {time parsing} {
    clock scan {2440588  0:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 1
test clock-29.64 {time parsing} {
    clock scan {2440588  0:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 1
test clock-29.65 {time parsing} {
    clock scan {2440588 ?:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 1
test clock-29.66 {time parsing} {
    clock scan {2440588 ?:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 1
test clock-29.67 {time parsing} {
    clock scan {2440588 ?:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 1
test clock-29.68 {time parsing} {
    clock scan {2440588 ?:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 1
test clock-29.69 {time parsing} {
    clock scan {2440588 12:00:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 1
test clock-29.70 {time parsing} {
    clock scan {2440588 12:?:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 1
test clock-29.71 {time parsing} {
    clock scan {2440588 12:00:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 1
test clock-29.72 {time parsing} {
    clock scan {2440588 12:?:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 1
test clock-29.73 {time parsing} {
    clock scan {2440588 xii:00:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 1
test clock-29.74 {time parsing} {
    clock scan {2440588 xii:?:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 1
test clock-29.75 {time parsing} {
    clock scan {2440588 xii:00:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 1
test clock-29.76 {time parsing} {
    clock scan {2440588 xii:?:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 1
test clock-29.77 {time parsing} {
    clock scan {2440588 12:00:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 1
test clock-29.78 {time parsing} {
    clock scan {2440588 12:?:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 1
test clock-29.79 {time parsing} {
    clock scan {2440588 12:00:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 1
test clock-29.80 {time parsing} {
    clock scan {2440588 12:?:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 1
test clock-29.81 {time parsing} {
    clock scan {2440588 xii:00:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 1
test clock-29.82 {time parsing} {
    clock scan {2440588 xii:?:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 1
test clock-29.83 {time parsing} {
    clock scan {2440588 xii:00:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 1
test clock-29.84 {time parsing} {
    clock scan {2440588 xii:?:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 1
test clock-29.85 {time parsing} {
    clock scan {2440588 00:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 59
test clock-29.86 {time parsing} {
    clock scan {2440588 00:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 59
test clock-29.87 {time parsing} {
    clock scan {2440588  0:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 59
test clock-29.88 {time parsing} {
    clock scan {2440588  0:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 59
test clock-29.89 {time parsing} {
    clock scan {2440588 ?:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 59
test clock-29.90 {time parsing} {
    clock scan {2440588 ?:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 59
test clock-29.91 {time parsing} {
    clock scan {2440588 ?:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 59
test clock-29.92 {time parsing} {
    clock scan {2440588 ?:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 59
test clock-29.93 {time parsing} {
    clock scan {2440588 12:00:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 59
test clock-29.94 {time parsing} {
    clock scan {2440588 12:?:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 59
test clock-29.95 {time parsing} {
    clock scan {2440588 12:00:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 59
test clock-29.96 {time parsing} {
    clock scan {2440588 12:?:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 59
test clock-29.97 {time parsing} {
    clock scan {2440588 xii:00:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 59
test clock-29.98 {time parsing} {
    clock scan {2440588 xii:?:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 59
test clock-29.99 {time parsing} {
    clock scan {2440588 xii:00:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 59
test clock-29.100 {time parsing} {
    clock scan {2440588 xii:?:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 59
test clock-29.101 {time parsing} {
    clock scan {2440588 12:00:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 59
test clock-29.102 {time parsing} {
    clock scan {2440588 12:?:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 59
test clock-29.103 {time parsing} {
    clock scan {2440588 12:00:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 59
test clock-29.104 {time parsing} {
    clock scan {2440588 12:?:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 59
test clock-29.105 {time parsing} {
    clock scan {2440588 xii:00:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 59
test clock-29.106 {time parsing} {
    clock scan {2440588 xii:?:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 59
test clock-29.107 {time parsing} {
    clock scan {2440588 xii:00:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 59
test clock-29.108 {time parsing} {
    clock scan {2440588 xii:?:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 59
test clock-29.109 {time parsing} {
    clock scan {2440588 00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M }
} 60
test clock-29.110 {time parsing} {
    clock scan {2440588 00:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM }
} 60
test clock-29.111 {time parsing} {
    clock scan {2440588 00:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 60
test clock-29.112 {time parsing} {
    clock scan {2440588 00:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 60
test clock-29.113 {time parsing} {
    clock scan {2440588  0:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M }
} 60
test clock-29.114 {time parsing} {
    clock scan {2440588  0:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM }
} 60
test clock-29.115 {time parsing} {
    clock scan {2440588  0:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 60
test clock-29.116 {time parsing} {
    clock scan {2440588  0:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 60
test clock-29.117 {time parsing} {
    clock scan {2440588 ?:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M }
} 60
test clock-29.118 {time parsing} {
    clock scan {2440588 ?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM }
} 60
test clock-29.119 {time parsing} {
    clock scan {2440588 ?:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 60
test clock-29.120 {time parsing} {
    clock scan {2440588 ?:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 60
test clock-29.121 {time parsing} {
    clock scan {2440588 ?:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M }
} 60
test clock-29.122 {time parsing} {
    clock scan {2440588 ?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM }
} 60
test clock-29.123 {time parsing} {
    clock scan {2440588 ?:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 60
test clock-29.124 {time parsing} {
    clock scan {2440588 ?:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 60
test clock-29.125 {time parsing} {
    clock scan {2440588 12:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %p}
} 60
test clock-29.126 {time parsing} {
    clock scan {2440588 12:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %p}
} 60
test clock-29.127 {time parsing} {
    clock scan {2440588 12:01:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 60
test clock-29.128 {time parsing} {
    clock scan {2440588 12:i:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 60
test clock-29.129 {time parsing} {
    clock scan {2440588 12:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %p}
} 60
test clock-29.130 {time parsing} {
    clock scan {2440588 12:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %p}
} 60
test clock-29.131 {time parsing} {
    clock scan {2440588 12:01:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 60
test clock-29.132 {time parsing} {
    clock scan {2440588 12:i:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 60
test clock-29.133 {time parsing} {
    clock scan {2440588 xii:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %p}
} 60
test clock-29.134 {time parsing} {
    clock scan {2440588 xii:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %p}
} 60
test clock-29.135 {time parsing} {
    clock scan {2440588 xii:01:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 60
test clock-29.136 {time parsing} {
    clock scan {2440588 xii:i:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 60
test clock-29.137 {time parsing} {
    clock scan {2440588 xii:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %p}
} 60
test clock-29.138 {time parsing} {
    clock scan {2440588 xii:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %p}
} 60
test clock-29.139 {time parsing} {
    clock scan {2440588 xii:01:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 60
test clock-29.140 {time parsing} {
    clock scan {2440588 xii:i:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 60
test clock-29.141 {time parsing} {
    clock scan {2440588 12:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %P}
} 60
test clock-29.142 {time parsing} {
    clock scan {2440588 12:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %P}
} 60
test clock-29.143 {time parsing} {
    clock scan {2440588 12:01:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 60
test clock-29.144 {time parsing} {
    clock scan {2440588 12:i:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 60
test clock-29.145 {time parsing} {
    clock scan {2440588 12:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %P}
} 60
test clock-29.146 {time parsing} {
    clock scan {2440588 12:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %P}
} 60
test clock-29.147 {time parsing} {
    clock scan {2440588 12:01:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 60
test clock-29.148 {time parsing} {
    clock scan {2440588 12:i:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 60
test clock-29.149 {time parsing} {
    clock scan {2440588 xii:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %P}
} 60
test clock-29.150 {time parsing} {
    clock scan {2440588 xii:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %P}
} 60
test clock-29.151 {time parsing} {
    clock scan {2440588 xii:01:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 60
test clock-29.152 {time parsing} {
    clock scan {2440588 xii:i:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 60
test clock-29.153 {time parsing} {
    clock scan {2440588 xii:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %P}
} 60
test clock-29.154 {time parsing} {
    clock scan {2440588 xii:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %P}
} 60
test clock-29.155 {time parsing} {
    clock scan {2440588 xii:01:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 60
test clock-29.156 {time parsing} {
    clock scan {2440588 xii:i:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 60
test clock-29.157 {time parsing} {
    clock scan {2440588 00:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 61
test clock-29.158 {time parsing} {
    clock scan {2440588 00:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 61
test clock-29.159 {time parsing} {
    clock scan {2440588  0:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 61
test clock-29.160 {time parsing} {
    clock scan {2440588  0:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 61
test clock-29.161 {time parsing} {
    clock scan {2440588 ?:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 61
test clock-29.162 {time parsing} {
    clock scan {2440588 ?:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 61
test clock-29.163 {time parsing} {
    clock scan {2440588 ?:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 61
test clock-29.164 {time parsing} {
    clock scan {2440588 ?:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 61
test clock-29.165 {time parsing} {
    clock scan {2440588 12:01:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 61
test clock-29.166 {time parsing} {
    clock scan {2440588 12:i:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 61
test clock-29.167 {time parsing} {
    clock scan {2440588 12:01:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 61
test clock-29.168 {time parsing} {
    clock scan {2440588 12:i:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 61
test clock-29.169 {time parsing} {
    clock scan {2440588 xii:01:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 61
test clock-29.170 {time parsing} {
    clock scan {2440588 xii:i:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 61
test clock-29.171 {time parsing} {
    clock scan {2440588 xii:01:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 61
test clock-29.172 {time parsing} {
    clock scan {2440588 xii:i:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 61
test clock-29.173 {time parsing} {
    clock scan {2440588 12:01:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 61
test clock-29.174 {time parsing} {
    clock scan {2440588 12:i:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 61
test clock-29.175 {time parsing} {
    clock scan {2440588 12:01:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 61
test clock-29.176 {time parsing} {
    clock scan {2440588 12:i:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 61
test clock-29.177 {time parsing} {
    clock scan {2440588 xii:01:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 61
test clock-29.178 {time parsing} {
    clock scan {2440588 xii:i:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 61
test clock-29.179 {time parsing} {
    clock scan {2440588 xii:01:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 61
test clock-29.180 {time parsing} {
    clock scan {2440588 xii:i:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 61
test clock-29.181 {time parsing} {
    clock scan {2440588 00:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 119
test clock-29.182 {time parsing} {
    clock scan {2440588 00:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 119
test clock-29.183 {time parsing} {
    clock scan {2440588  0:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 119
test clock-29.184 {time parsing} {
    clock scan {2440588  0:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 119
test clock-29.185 {time parsing} {
    clock scan {2440588 ?:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 119
test clock-29.186 {time parsing} {
    clock scan {2440588 ?:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 119
test clock-29.187 {time parsing} {
    clock scan {2440588 ?:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 119
test clock-29.188 {time parsing} {
    clock scan {2440588 ?:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 119
test clock-29.189 {time parsing} {
    clock scan {2440588 12:01:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 119
test clock-29.190 {time parsing} {
    clock scan {2440588 12:i:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 119
test clock-29.191 {time parsing} {
    clock scan {2440588 12:01:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 119
test clock-29.192 {time parsing} {
    clock scan {2440588 12:i:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 119
test clock-29.193 {time parsing} {
    clock scan {2440588 xii:01:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 119
test clock-29.194 {time parsing} {
    clock scan {2440588 xii:i:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 119
test clock-29.195 {time parsing} {
    clock scan {2440588 xii:01:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 119
test clock-29.196 {time parsing} {
    clock scan {2440588 xii:i:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 119
test clock-29.197 {time parsing} {
    clock scan {2440588 12:01:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 119
test clock-29.198 {time parsing} {
    clock scan {2440588 12:i:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 119
test clock-29.199 {time parsing} {
    clock scan {2440588 12:01:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 119
test clock-29.200 {time parsing} {
    clock scan {2440588 12:i:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 119
test clock-29.201 {time parsing} {
    clock scan {2440588 xii:01:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 119
test clock-29.202 {time parsing} {
    clock scan {2440588 xii:i:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 119
test clock-29.203 {time parsing} {
    clock scan {2440588 xii:01:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 119
test clock-29.204 {time parsing} {
    clock scan {2440588 xii:i:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 119
test clock-29.205 {time parsing} {
    clock scan {2440588 00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M }
} 3540
test clock-29.206 {time parsing} {
    clock scan {2440588 00:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM }
} 3540
test clock-29.207 {time parsing} {
    clock scan {2440588 00:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 3540
test clock-29.208 {time parsing} {
    clock scan {2440588 00:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 3540
test clock-29.209 {time parsing} {
    clock scan {2440588  0:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M }
} 3540
test clock-29.210 {time parsing} {
    clock scan {2440588  0:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM }
} 3540
test clock-29.211 {time parsing} {
    clock scan {2440588  0:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 3540
test clock-29.212 {time parsing} {
    clock scan {2440588  0:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 3540
test clock-29.213 {time parsing} {
    clock scan {2440588 ?:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M }
} 3540
test clock-29.214 {time parsing} {
    clock scan {2440588 ?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM }
} 3540
test clock-29.215 {time parsing} {
    clock scan {2440588 ?:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 3540
test clock-29.216 {time parsing} {
    clock scan {2440588 ?:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 3540
test clock-29.217 {time parsing} {
    clock scan {2440588 ?:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M }
} 3540
test clock-29.218 {time parsing} {
    clock scan {2440588 ?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM }
} 3540
test clock-29.219 {time parsing} {
    clock scan {2440588 ?:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 3540
test clock-29.220 {time parsing} {
    clock scan {2440588 ?:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 3540
test clock-29.221 {time parsing} {
    clock scan {2440588 12:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %p}
} 3540
test clock-29.222 {time parsing} {
    clock scan {2440588 12:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %p}
} 3540
test clock-29.223 {time parsing} {
    clock scan {2440588 12:59:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 3540
test clock-29.224 {time parsing} {
    clock scan {2440588 12:lix:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 3540
test clock-29.225 {time parsing} {
    clock scan {2440588 12:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %p}
} 3540
test clock-29.226 {time parsing} {
    clock scan {2440588 12:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %p}
} 3540
test clock-29.227 {time parsing} {
    clock scan {2440588 12:59:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 3540
test clock-29.228 {time parsing} {
    clock scan {2440588 12:lix:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 3540
test clock-29.229 {time parsing} {
    clock scan {2440588 xii:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %p}
} 3540
test clock-29.230 {time parsing} {
    clock scan {2440588 xii:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %p}
} 3540
test clock-29.231 {time parsing} {
    clock scan {2440588 xii:59:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 3540
test clock-29.232 {time parsing} {
    clock scan {2440588 xii:lix:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 3540
test clock-29.233 {time parsing} {
    clock scan {2440588 xii:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %p}
} 3540
test clock-29.234 {time parsing} {
    clock scan {2440588 xii:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %p}
} 3540
test clock-29.235 {time parsing} {
    clock scan {2440588 xii:59:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 3540
test clock-29.236 {time parsing} {
    clock scan {2440588 xii:lix:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 3540
test clock-29.237 {time parsing} {
    clock scan {2440588 12:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %P}
} 3540
test clock-29.238 {time parsing} {
    clock scan {2440588 12:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %P}
} 3540
test clock-29.239 {time parsing} {
    clock scan {2440588 12:59:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 3540
test clock-29.240 {time parsing} {
    clock scan {2440588 12:lix:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 3540
test clock-29.241 {time parsing} {
    clock scan {2440588 12:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %P}
} 3540
test clock-29.242 {time parsing} {
    clock scan {2440588 12:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %P}
} 3540
test clock-29.243 {time parsing} {
    clock scan {2440588 12:59:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 3540
test clock-29.244 {time parsing} {
    clock scan {2440588 12:lix:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 3540
test clock-29.245 {time parsing} {
    clock scan {2440588 xii:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %P}
} 3540
test clock-29.246 {time parsing} {
    clock scan {2440588 xii:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %P}
} 3540
test clock-29.247 {time parsing} {
    clock scan {2440588 xii:59:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 3540
test clock-29.248 {time parsing} {
    clock scan {2440588 xii:lix:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 3540
test clock-29.249 {time parsing} {
    clock scan {2440588 xii:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %P}
} 3540
test clock-29.250 {time parsing} {
    clock scan {2440588 xii:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %P}
} 3540
test clock-29.251 {time parsing} {
    clock scan {2440588 xii:59:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 3540
test clock-29.252 {time parsing} {
    clock scan {2440588 xii:lix:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 3540
test clock-29.253 {time parsing} {
    clock scan {2440588 00:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 3541
test clock-29.254 {time parsing} {
    clock scan {2440588 00:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 3541
test clock-29.255 {time parsing} {
    clock scan {2440588  0:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 3541
test clock-29.256 {time parsing} {
    clock scan {2440588  0:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 3541
test clock-29.257 {time parsing} {
    clock scan {2440588 ?:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 3541
test clock-29.258 {time parsing} {
    clock scan {2440588 ?:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 3541
test clock-29.259 {time parsing} {
    clock scan {2440588 ?:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 3541
test clock-29.260 {time parsing} {
    clock scan {2440588 ?:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 3541
test clock-29.261 {time parsing} {
    clock scan {2440588 12:59:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 3541
test clock-29.262 {time parsing} {
    clock scan {2440588 12:lix:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 3541
test clock-29.263 {time parsing} {
    clock scan {2440588 12:59:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 3541
test clock-29.264 {time parsing} {
    clock scan {2440588 12:lix:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 3541
test clock-29.265 {time parsing} {
    clock scan {2440588 xii:59:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 3541
test clock-29.266 {time parsing} {
    clock scan {2440588 xii:lix:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 3541
test clock-29.267 {time parsing} {
    clock scan {2440588 xii:59:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 3541
test clock-29.268 {time parsing} {
    clock scan {2440588 xii:lix:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 3541
test clock-29.269 {time parsing} {
    clock scan {2440588 12:59:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 3541
test clock-29.270 {time parsing} {
    clock scan {2440588 12:lix:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 3541
test clock-29.271 {time parsing} {
    clock scan {2440588 12:59:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 3541
test clock-29.272 {time parsing} {
    clock scan {2440588 12:lix:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 3541
test clock-29.273 {time parsing} {
    clock scan {2440588 xii:59:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 3541
test clock-29.274 {time parsing} {
    clock scan {2440588 xii:lix:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 3541
test clock-29.275 {time parsing} {
    clock scan {2440588 xii:59:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 3541
test clock-29.276 {time parsing} {
    clock scan {2440588 xii:lix:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 3541
test clock-29.277 {time parsing} {
    clock scan {2440588 00:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 3599
test clock-29.278 {time parsing} {
    clock scan {2440588 00:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 3599
test clock-29.279 {time parsing} {
    clock scan {2440588  0:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 3599
test clock-29.280 {time parsing} {
    clock scan {2440588  0:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 3599
test clock-29.281 {time parsing} {
    clock scan {2440588 ?:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 3599
test clock-29.282 {time parsing} {
    clock scan {2440588 ?:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 3599
test clock-29.283 {time parsing} {
    clock scan {2440588 ?:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 3599
test clock-29.284 {time parsing} {
    clock scan {2440588 ?:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 3599
test clock-29.285 {time parsing} {
    clock scan {2440588 12:59:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 3599
test clock-29.286 {time parsing} {
    clock scan {2440588 12:lix:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 3599
test clock-29.287 {time parsing} {
    clock scan {2440588 12:59:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 3599
test clock-29.288 {time parsing} {
    clock scan {2440588 12:lix:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 3599
test clock-29.289 {time parsing} {
    clock scan {2440588 xii:59:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 3599
test clock-29.290 {time parsing} {
    clock scan {2440588 xii:lix:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 3599
test clock-29.291 {time parsing} {
    clock scan {2440588 xii:59:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 3599
test clock-29.292 {time parsing} {
    clock scan {2440588 xii:lix:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 3599
test clock-29.293 {time parsing} {
    clock scan {2440588 12:59:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 3599
test clock-29.294 {time parsing} {
    clock scan {2440588 12:lix:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 3599
test clock-29.295 {time parsing} {
    clock scan {2440588 12:59:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 3599
test clock-29.296 {time parsing} {
    clock scan {2440588 12:lix:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 3599
test clock-29.297 {time parsing} {
    clock scan {2440588 xii:59:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 3599
test clock-29.298 {time parsing} {
    clock scan {2440588 xii:lix:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 3599
test clock-29.299 {time parsing} {
    clock scan {2440588 xii:59:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 3599
test clock-29.300 {time parsing} {
    clock scan {2440588 xii:lix:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 3599
test clock-29.301 {time parsing} {
    clock scan {2440588 01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H }
} 3600
test clock-29.302 {time parsing} {
    clock scan {2440588 01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M }
} 3600
test clock-29.303 {time parsing} {
    clock scan {2440588 01:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM }
} 3600
test clock-29.304 {time parsing} {
    clock scan {2440588 01:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 3600
test clock-29.305 {time parsing} {
    clock scan {2440588 01:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 3600
test clock-29.306 {time parsing} {
    clock scan {2440588  1 } \
	-gmt true -locale en_US_roman \
	-format {%J %k }
} 3600
test clock-29.307 {time parsing} {
    clock scan {2440588  1:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M }
} 3600
test clock-29.308 {time parsing} {
    clock scan {2440588  1:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM }
} 3600
test clock-29.309 {time parsing} {
    clock scan {2440588  1:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 3600
test clock-29.310 {time parsing} {
    clock scan {2440588  1:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 3600
test clock-29.311 {time parsing} {
    clock scan {2440588 i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH }
} 3600
test clock-29.312 {time parsing} {
    clock scan {2440588 i:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M }
} 3600
test clock-29.313 {time parsing} {
    clock scan {2440588 i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM }
} 3600
test clock-29.314 {time parsing} {
    clock scan {2440588 i:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 3600
test clock-29.315 {time parsing} {
    clock scan {2440588 i:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 3600
test clock-29.316 {time parsing} {
    clock scan {2440588 i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok }
} 3600
test clock-29.317 {time parsing} {
    clock scan {2440588 i:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M }
} 3600
test clock-29.318 {time parsing} {
    clock scan {2440588 i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM }
} 3600
test clock-29.319 {time parsing} {
    clock scan {2440588 i:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 3600
test clock-29.320 {time parsing} {
    clock scan {2440588 i:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 3600
test clock-29.321 {time parsing} {
    clock scan {2440588 01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I %p}
} 3600
test clock-29.322 {time parsing} {
    clock scan {2440588 01:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %p}
} 3600
test clock-29.323 {time parsing} {
    clock scan {2440588 01:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %p}
} 3600
test clock-29.324 {time parsing} {
    clock scan {2440588 01:00:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 3600
test clock-29.325 {time parsing} {
    clock scan {2440588 01:?:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 3600
test clock-29.326 {time parsing} {
    clock scan {2440588  1 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l %p}
} 3600
test clock-29.327 {time parsing} {
    clock scan {2440588  1:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %p}
} 3600
test clock-29.328 {time parsing} {
    clock scan {2440588  1:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %p}
} 3600
test clock-29.329 {time parsing} {
    clock scan {2440588  1:00:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 3600
test clock-29.330 {time parsing} {
    clock scan {2440588  1:?:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 3600
test clock-29.331 {time parsing} {
    clock scan {2440588 i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI %p}
} 3600
test clock-29.332 {time parsing} {
    clock scan {2440588 i:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %p}
} 3600
test clock-29.333 {time parsing} {
    clock scan {2440588 i:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %p}
} 3600
test clock-29.334 {time parsing} {
    clock scan {2440588 i:00:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 3600
test clock-29.335 {time parsing} {
    clock scan {2440588 i:?:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 3600
test clock-29.336 {time parsing} {
    clock scan {2440588 i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol %p}
} 3600
test clock-29.337 {time parsing} {
    clock scan {2440588 i:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %p}
} 3600
test clock-29.338 {time parsing} {
    clock scan {2440588 i:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %p}
} 3600
test clock-29.339 {time parsing} {
    clock scan {2440588 i:00:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 3600
test clock-29.340 {time parsing} {
    clock scan {2440588 i:?:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 3600
test clock-29.341 {time parsing} {
    clock scan {2440588 01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I %P}
} 3600
test clock-29.342 {time parsing} {
    clock scan {2440588 01:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %P}
} 3600
test clock-29.343 {time parsing} {
    clock scan {2440588 01:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %P}
} 3600
test clock-29.344 {time parsing} {
    clock scan {2440588 01:00:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 3600
test clock-29.345 {time parsing} {
    clock scan {2440588 01:?:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 3600
test clock-29.346 {time parsing} {
    clock scan {2440588  1 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l %P}
} 3600
test clock-29.347 {time parsing} {
    clock scan {2440588  1:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %P}
} 3600
test clock-29.348 {time parsing} {
    clock scan {2440588  1:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %P}
} 3600
test clock-29.349 {time parsing} {
    clock scan {2440588  1:00:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 3600
test clock-29.350 {time parsing} {
    clock scan {2440588  1:?:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 3600
test clock-29.351 {time parsing} {
    clock scan {2440588 i am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI %P}
} 3600
test clock-29.352 {time parsing} {
    clock scan {2440588 i:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %P}
} 3600
test clock-29.353 {time parsing} {
    clock scan {2440588 i:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %P}
} 3600
test clock-29.354 {time parsing} {
    clock scan {2440588 i:00:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 3600
test clock-29.355 {time parsing} {
    clock scan {2440588 i:?:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 3600
test clock-29.356 {time parsing} {
    clock scan {2440588 i am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol %P}
} 3600
test clock-29.357 {time parsing} {
    clock scan {2440588 i:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %P}
} 3600
test clock-29.358 {time parsing} {
    clock scan {2440588 i:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %P}
} 3600
test clock-29.359 {time parsing} {
    clock scan {2440588 i:00:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 3600
test clock-29.360 {time parsing} {
    clock scan {2440588 i:?:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 3600
test clock-29.361 {time parsing} {
    clock scan {2440588 01:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 3601
test clock-29.362 {time parsing} {
    clock scan {2440588 01:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 3601
test clock-29.363 {time parsing} {
    clock scan {2440588  1:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 3601
test clock-29.364 {time parsing} {
    clock scan {2440588  1:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 3601
test clock-29.365 {time parsing} {
    clock scan {2440588 i:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 3601
test clock-29.366 {time parsing} {
    clock scan {2440588 i:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 3601
test clock-29.367 {time parsing} {
    clock scan {2440588 i:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 3601
test clock-29.368 {time parsing} {
    clock scan {2440588 i:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 3601
test clock-29.369 {time parsing} {
    clock scan {2440588 01:00:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 3601
test clock-29.370 {time parsing} {
    clock scan {2440588 01:?:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 3601
test clock-29.371 {time parsing} {
    clock scan {2440588  1:00:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 3601
test clock-29.372 {time parsing} {
    clock scan {2440588  1:?:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 3601
test clock-29.373 {time parsing} {
    clock scan {2440588 i:00:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 3601
test clock-29.374 {time parsing} {
    clock scan {2440588 i:?:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 3601
test clock-29.375 {time parsing} {
    clock scan {2440588 i:00:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 3601
test clock-29.376 {time parsing} {
    clock scan {2440588 i:?:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 3601
test clock-29.377 {time parsing} {
    clock scan {2440588 01:00:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 3601
test clock-29.378 {time parsing} {
    clock scan {2440588 01:?:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 3601
test clock-29.379 {time parsing} {
    clock scan {2440588  1:00:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 3601
test clock-29.380 {time parsing} {
    clock scan {2440588  1:?:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 3601
test clock-29.381 {time parsing} {
    clock scan {2440588 i:00:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 3601
test clock-29.382 {time parsing} {
    clock scan {2440588 i:?:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 3601
test clock-29.383 {time parsing} {
    clock scan {2440588 i:00:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 3601
test clock-29.384 {time parsing} {
    clock scan {2440588 i:?:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 3601
test clock-29.385 {time parsing} {
    clock scan {2440588 01:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 3659
test clock-29.386 {time parsing} {
    clock scan {2440588 01:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 3659
test clock-29.387 {time parsing} {
    clock scan {2440588  1:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 3659
test clock-29.388 {time parsing} {
    clock scan {2440588  1:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 3659
test clock-29.389 {time parsing} {
    clock scan {2440588 i:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 3659
test clock-29.390 {time parsing} {
    clock scan {2440588 i:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 3659
test clock-29.391 {time parsing} {
    clock scan {2440588 i:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 3659
test clock-29.392 {time parsing} {
    clock scan {2440588 i:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 3659
test clock-29.393 {time parsing} {
    clock scan {2440588 01:00:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 3659
test clock-29.394 {time parsing} {
    clock scan {2440588 01:?:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 3659
test clock-29.395 {time parsing} {
    clock scan {2440588  1:00:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 3659
test clock-29.396 {time parsing} {
    clock scan {2440588  1:?:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 3659
test clock-29.397 {time parsing} {
    clock scan {2440588 i:00:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 3659
test clock-29.398 {time parsing} {
    clock scan {2440588 i:?:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 3659
test clock-29.399 {time parsing} {
    clock scan {2440588 i:00:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 3659
test clock-29.400 {time parsing} {
    clock scan {2440588 i:?:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 3659
test clock-29.401 {time parsing} {
    clock scan {2440588 01:00:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 3659
test clock-29.402 {time parsing} {
    clock scan {2440588 01:?:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 3659
test clock-29.403 {time parsing} {
    clock scan {2440588  1:00:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 3659
test clock-29.404 {time parsing} {
    clock scan {2440588  1:?:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 3659
test clock-29.405 {time parsing} {
    clock scan {2440588 i:00:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 3659
test clock-29.406 {time parsing} {
    clock scan {2440588 i:?:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 3659
test clock-29.407 {time parsing} {
    clock scan {2440588 i:00:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 3659
test clock-29.408 {time parsing} {
    clock scan {2440588 i:?:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 3659
test clock-29.409 {time parsing} {
    clock scan {2440588 01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M }
} 3660
test clock-29.410 {time parsing} {
    clock scan {2440588 01:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM }
} 3660
test clock-29.411 {time parsing} {
    clock scan {2440588 01:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 3660
test clock-29.412 {time parsing} {
    clock scan {2440588 01:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 3660
test clock-29.413 {time parsing} {
    clock scan {2440588  1:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M }
} 3660
test clock-29.414 {time parsing} {
    clock scan {2440588  1:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM }
} 3660
test clock-29.415 {time parsing} {
    clock scan {2440588  1:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 3660
test clock-29.416 {time parsing} {
    clock scan {2440588  1:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 3660
test clock-29.417 {time parsing} {
    clock scan {2440588 i:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M }
} 3660
test clock-29.418 {time parsing} {
    clock scan {2440588 i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM }
} 3660
test clock-29.419 {time parsing} {
    clock scan {2440588 i:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 3660
test clock-29.420 {time parsing} {
    clock scan {2440588 i:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 3660
test clock-29.421 {time parsing} {
    clock scan {2440588 i:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M }
} 3660
test clock-29.422 {time parsing} {
    clock scan {2440588 i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM }
} 3660
test clock-29.423 {time parsing} {
    clock scan {2440588 i:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 3660
test clock-29.424 {time parsing} {
    clock scan {2440588 i:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 3660
test clock-29.425 {time parsing} {
    clock scan {2440588 01:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %p}
} 3660
test clock-29.426 {time parsing} {
    clock scan {2440588 01:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %p}
} 3660
test clock-29.427 {time parsing} {
    clock scan {2440588 01:01:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 3660
test clock-29.428 {time parsing} {
    clock scan {2440588 01:i:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 3660
test clock-29.429 {time parsing} {
    clock scan {2440588  1:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %p}
} 3660
test clock-29.430 {time parsing} {
    clock scan {2440588  1:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %p}
} 3660
test clock-29.431 {time parsing} {
    clock scan {2440588  1:01:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 3660
test clock-29.432 {time parsing} {
    clock scan {2440588  1:i:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 3660
test clock-29.433 {time parsing} {
    clock scan {2440588 i:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %p}
} 3660
test clock-29.434 {time parsing} {
    clock scan {2440588 i:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %p}
} 3660
test clock-29.435 {time parsing} {
    clock scan {2440588 i:01:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 3660
test clock-29.436 {time parsing} {
    clock scan {2440588 i:i:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 3660
test clock-29.437 {time parsing} {
    clock scan {2440588 i:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %p}
} 3660
test clock-29.438 {time parsing} {
    clock scan {2440588 i:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %p}
} 3660
test clock-29.439 {time parsing} {
    clock scan {2440588 i:01:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 3660
test clock-29.440 {time parsing} {
    clock scan {2440588 i:i:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 3660
test clock-29.441 {time parsing} {
    clock scan {2440588 01:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %P}
} 3660
test clock-29.442 {time parsing} {
    clock scan {2440588 01:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %P}
} 3660
test clock-29.443 {time parsing} {
    clock scan {2440588 01:01:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 3660
test clock-29.444 {time parsing} {
    clock scan {2440588 01:i:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 3660
test clock-29.445 {time parsing} {
    clock scan {2440588  1:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %P}
} 3660
test clock-29.446 {time parsing} {
    clock scan {2440588  1:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %P}
} 3660
test clock-29.447 {time parsing} {
    clock scan {2440588  1:01:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 3660
test clock-29.448 {time parsing} {
    clock scan {2440588  1:i:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 3660
test clock-29.449 {time parsing} {
    clock scan {2440588 i:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %P}
} 3660
test clock-29.450 {time parsing} {
    clock scan {2440588 i:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %P}
} 3660
test clock-29.451 {time parsing} {
    clock scan {2440588 i:01:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 3660
test clock-29.452 {time parsing} {
    clock scan {2440588 i:i:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 3660
test clock-29.453 {time parsing} {
    clock scan {2440588 i:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %P}
} 3660
test clock-29.454 {time parsing} {
    clock scan {2440588 i:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %P}
} 3660
test clock-29.455 {time parsing} {
    clock scan {2440588 i:01:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 3660
test clock-29.456 {time parsing} {
    clock scan {2440588 i:i:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 3660
test clock-29.457 {time parsing} {
    clock scan {2440588 01:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 3661
test clock-29.458 {time parsing} {
    clock scan {2440588 01:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 3661
test clock-29.459 {time parsing} {
    clock scan {2440588  1:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 3661
test clock-29.460 {time parsing} {
    clock scan {2440588  1:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 3661
test clock-29.461 {time parsing} {
    clock scan {2440588 i:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 3661
test clock-29.462 {time parsing} {
    clock scan {2440588 i:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 3661
test clock-29.463 {time parsing} {
    clock scan {2440588 i:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 3661
test clock-29.464 {time parsing} {
    clock scan {2440588 i:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 3661
test clock-29.465 {time parsing} {
    clock scan {2440588 01:01:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 3661
test clock-29.466 {time parsing} {
    clock scan {2440588 01:i:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 3661
test clock-29.467 {time parsing} {
    clock scan {2440588  1:01:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 3661
test clock-29.468 {time parsing} {
    clock scan {2440588  1:i:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 3661
test clock-29.469 {time parsing} {
    clock scan {2440588 i:01:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 3661
test clock-29.470 {time parsing} {
    clock scan {2440588 i:i:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 3661
test clock-29.471 {time parsing} {
    clock scan {2440588 i:01:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 3661
test clock-29.472 {time parsing} {
    clock scan {2440588 i:i:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 3661
test clock-29.473 {time parsing} {
    clock scan {2440588 01:01:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 3661
test clock-29.474 {time parsing} {
    clock scan {2440588 01:i:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 3661
test clock-29.475 {time parsing} {
    clock scan {2440588  1:01:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 3661
test clock-29.476 {time parsing} {
    clock scan {2440588  1:i:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 3661
test clock-29.477 {time parsing} {
    clock scan {2440588 i:01:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 3661
test clock-29.478 {time parsing} {
    clock scan {2440588 i:i:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 3661
test clock-29.479 {time parsing} {
    clock scan {2440588 i:01:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 3661
test clock-29.480 {time parsing} {
    clock scan {2440588 i:i:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 3661
test clock-29.481 {time parsing} {
    clock scan {2440588 01:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 3719
test clock-29.482 {time parsing} {
    clock scan {2440588 01:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 3719
test clock-29.483 {time parsing} {
    clock scan {2440588  1:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 3719
test clock-29.484 {time parsing} {
    clock scan {2440588  1:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 3719
test clock-29.485 {time parsing} {
    clock scan {2440588 i:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 3719
test clock-29.486 {time parsing} {
    clock scan {2440588 i:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 3719
test clock-29.487 {time parsing} {
    clock scan {2440588 i:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 3719
test clock-29.488 {time parsing} {
    clock scan {2440588 i:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 3719
test clock-29.489 {time parsing} {
    clock scan {2440588 01:01:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 3719
test clock-29.490 {time parsing} {
    clock scan {2440588 01:i:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 3719
test clock-29.491 {time parsing} {
    clock scan {2440588  1:01:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 3719
test clock-29.492 {time parsing} {
    clock scan {2440588  1:i:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 3719
test clock-29.493 {time parsing} {
    clock scan {2440588 i:01:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 3719
test clock-29.494 {time parsing} {
    clock scan {2440588 i:i:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 3719
test clock-29.495 {time parsing} {
    clock scan {2440588 i:01:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 3719
test clock-29.496 {time parsing} {
    clock scan {2440588 i:i:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 3719
test clock-29.497 {time parsing} {
    clock scan {2440588 01:01:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 3719
test clock-29.498 {time parsing} {
    clock scan {2440588 01:i:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 3719
test clock-29.499 {time parsing} {
    clock scan {2440588  1:01:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 3719
test clock-29.500 {time parsing} {
    clock scan {2440588  1:i:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 3719
test clock-29.501 {time parsing} {
    clock scan {2440588 i:01:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 3719
test clock-29.502 {time parsing} {
    clock scan {2440588 i:i:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 3719
test clock-29.503 {time parsing} {
    clock scan {2440588 i:01:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 3719
test clock-29.504 {time parsing} {
    clock scan {2440588 i:i:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 3719
test clock-29.505 {time parsing} {
    clock scan {2440588 01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M }
} 7140
test clock-29.506 {time parsing} {
    clock scan {2440588 01:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM }
} 7140
test clock-29.507 {time parsing} {
    clock scan {2440588 01:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 7140
test clock-29.508 {time parsing} {
    clock scan {2440588 01:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 7140
test clock-29.509 {time parsing} {
    clock scan {2440588  1:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M }
} 7140
test clock-29.510 {time parsing} {
    clock scan {2440588  1:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM }
} 7140
test clock-29.511 {time parsing} {
    clock scan {2440588  1:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 7140
test clock-29.512 {time parsing} {
    clock scan {2440588  1:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 7140
test clock-29.513 {time parsing} {
    clock scan {2440588 i:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M }
} 7140
test clock-29.514 {time parsing} {
    clock scan {2440588 i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM }
} 7140
test clock-29.515 {time parsing} {
    clock scan {2440588 i:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 7140
test clock-29.516 {time parsing} {
    clock scan {2440588 i:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 7140
test clock-29.517 {time parsing} {
    clock scan {2440588 i:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M }
} 7140
test clock-29.518 {time parsing} {
    clock scan {2440588 i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM }
} 7140
test clock-29.519 {time parsing} {
    clock scan {2440588 i:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 7140
test clock-29.520 {time parsing} {
    clock scan {2440588 i:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 7140
test clock-29.521 {time parsing} {
    clock scan {2440588 01:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %p}
} 7140
test clock-29.522 {time parsing} {
    clock scan {2440588 01:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %p}
} 7140
test clock-29.523 {time parsing} {
    clock scan {2440588 01:59:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 7140
test clock-29.524 {time parsing} {
    clock scan {2440588 01:lix:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 7140
test clock-29.525 {time parsing} {
    clock scan {2440588  1:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %p}
} 7140
test clock-29.526 {time parsing} {
    clock scan {2440588  1:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %p}
} 7140
test clock-29.527 {time parsing} {
    clock scan {2440588  1:59:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 7140
test clock-29.528 {time parsing} {
    clock scan {2440588  1:lix:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 7140
test clock-29.529 {time parsing} {
    clock scan {2440588 i:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %p}
} 7140
test clock-29.530 {time parsing} {
    clock scan {2440588 i:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %p}
} 7140
test clock-29.531 {time parsing} {
    clock scan {2440588 i:59:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 7140
test clock-29.532 {time parsing} {
    clock scan {2440588 i:lix:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 7140
test clock-29.533 {time parsing} {
    clock scan {2440588 i:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %p}
} 7140
test clock-29.534 {time parsing} {
    clock scan {2440588 i:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %p}
} 7140
test clock-29.535 {time parsing} {
    clock scan {2440588 i:59:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 7140
test clock-29.536 {time parsing} {
    clock scan {2440588 i:lix:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 7140
test clock-29.537 {time parsing} {
    clock scan {2440588 01:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %P}
} 7140
test clock-29.538 {time parsing} {
    clock scan {2440588 01:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %P}
} 7140
test clock-29.539 {time parsing} {
    clock scan {2440588 01:59:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 7140
test clock-29.540 {time parsing} {
    clock scan {2440588 01:lix:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 7140
test clock-29.541 {time parsing} {
    clock scan {2440588  1:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %P}
} 7140
test clock-29.542 {time parsing} {
    clock scan {2440588  1:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %P}
} 7140
test clock-29.543 {time parsing} {
    clock scan {2440588  1:59:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 7140
test clock-29.544 {time parsing} {
    clock scan {2440588  1:lix:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 7140
test clock-29.545 {time parsing} {
    clock scan {2440588 i:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %P}
} 7140
test clock-29.546 {time parsing} {
    clock scan {2440588 i:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %P}
} 7140
test clock-29.547 {time parsing} {
    clock scan {2440588 i:59:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 7140
test clock-29.548 {time parsing} {
    clock scan {2440588 i:lix:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 7140
test clock-29.549 {time parsing} {
    clock scan {2440588 i:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %P}
} 7140
test clock-29.550 {time parsing} {
    clock scan {2440588 i:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %P}
} 7140
test clock-29.551 {time parsing} {
    clock scan {2440588 i:59:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 7140
test clock-29.552 {time parsing} {
    clock scan {2440588 i:lix:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 7140
test clock-29.553 {time parsing} {
    clock scan {2440588 01:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 7141
test clock-29.554 {time parsing} {
    clock scan {2440588 01:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 7141
test clock-29.555 {time parsing} {
    clock scan {2440588  1:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 7141
test clock-29.556 {time parsing} {
    clock scan {2440588  1:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 7141
test clock-29.557 {time parsing} {
    clock scan {2440588 i:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 7141
test clock-29.558 {time parsing} {
    clock scan {2440588 i:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 7141
test clock-29.559 {time parsing} {
    clock scan {2440588 i:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 7141
test clock-29.560 {time parsing} {
    clock scan {2440588 i:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 7141
test clock-29.561 {time parsing} {
    clock scan {2440588 01:59:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 7141
test clock-29.562 {time parsing} {
    clock scan {2440588 01:lix:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 7141
test clock-29.563 {time parsing} {
    clock scan {2440588  1:59:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 7141
test clock-29.564 {time parsing} {
    clock scan {2440588  1:lix:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 7141
test clock-29.565 {time parsing} {
    clock scan {2440588 i:59:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 7141
test clock-29.566 {time parsing} {
    clock scan {2440588 i:lix:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 7141
test clock-29.567 {time parsing} {
    clock scan {2440588 i:59:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 7141
test clock-29.568 {time parsing} {
    clock scan {2440588 i:lix:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 7141
test clock-29.569 {time parsing} {
    clock scan {2440588 01:59:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 7141
test clock-29.570 {time parsing} {
    clock scan {2440588 01:lix:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 7141
test clock-29.571 {time parsing} {
    clock scan {2440588  1:59:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 7141
test clock-29.572 {time parsing} {
    clock scan {2440588  1:lix:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 7141
test clock-29.573 {time parsing} {
    clock scan {2440588 i:59:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 7141
test clock-29.574 {time parsing} {
    clock scan {2440588 i:lix:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 7141
test clock-29.575 {time parsing} {
    clock scan {2440588 i:59:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 7141
test clock-29.576 {time parsing} {
    clock scan {2440588 i:lix:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 7141
test clock-29.577 {time parsing} {
    clock scan {2440588 01:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 7199
test clock-29.578 {time parsing} {
    clock scan {2440588 01:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 7199
test clock-29.579 {time parsing} {
    clock scan {2440588  1:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 7199
test clock-29.580 {time parsing} {
    clock scan {2440588  1:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 7199
test clock-29.581 {time parsing} {
    clock scan {2440588 i:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 7199
test clock-29.582 {time parsing} {
    clock scan {2440588 i:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 7199
test clock-29.583 {time parsing} {
    clock scan {2440588 i:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 7199
test clock-29.584 {time parsing} {
    clock scan {2440588 i:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 7199
test clock-29.585 {time parsing} {
    clock scan {2440588 01:59:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 7199
test clock-29.586 {time parsing} {
    clock scan {2440588 01:lix:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 7199
test clock-29.587 {time parsing} {
    clock scan {2440588  1:59:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 7199
test clock-29.588 {time parsing} {
    clock scan {2440588  1:lix:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 7199
test clock-29.589 {time parsing} {
    clock scan {2440588 i:59:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 7199
test clock-29.590 {time parsing} {
    clock scan {2440588 i:lix:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 7199
test clock-29.591 {time parsing} {
    clock scan {2440588 i:59:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 7199
test clock-29.592 {time parsing} {
    clock scan {2440588 i:lix:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 7199
test clock-29.593 {time parsing} {
    clock scan {2440588 01:59:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 7199
test clock-29.594 {time parsing} {
    clock scan {2440588 01:lix:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 7199
test clock-29.595 {time parsing} {
    clock scan {2440588  1:59:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 7199
test clock-29.596 {time parsing} {
    clock scan {2440588  1:lix:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 7199
test clock-29.597 {time parsing} {
    clock scan {2440588 i:59:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 7199
test clock-29.598 {time parsing} {
    clock scan {2440588 i:lix:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 7199
test clock-29.599 {time parsing} {
    clock scan {2440588 i:59:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 7199
test clock-29.600 {time parsing} {
    clock scan {2440588 i:lix:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 7199
test clock-29.601 {time parsing} {
    clock scan {2440588 11 } \
	-gmt true -locale en_US_roman \
	-format {%J %H }
} 39600
test clock-29.602 {time parsing} {
    clock scan {2440588 11:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M }
} 39600
test clock-29.603 {time parsing} {
    clock scan {2440588 11:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM }
} 39600
test clock-29.604 {time parsing} {
    clock scan {2440588 11:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 39600
test clock-29.605 {time parsing} {
    clock scan {2440588 11:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 39600
test clock-29.606 {time parsing} {
    clock scan {2440588 11 } \
	-gmt true -locale en_US_roman \
	-format {%J %k }
} 39600
test clock-29.607 {time parsing} {
    clock scan {2440588 11:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M }
} 39600
test clock-29.608 {time parsing} {
    clock scan {2440588 11:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM }
} 39600
test clock-29.609 {time parsing} {
    clock scan {2440588 11:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 39600
test clock-29.610 {time parsing} {
    clock scan {2440588 11:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 39600
test clock-29.611 {time parsing} {
    clock scan {2440588 xi } \
	-gmt true -locale en_US_roman \
	-format {%J %OH }
} 39600
test clock-29.612 {time parsing} {
    clock scan {2440588 xi:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M }
} 39600
test clock-29.613 {time parsing} {
    clock scan {2440588 xi:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM }
} 39600
test clock-29.614 {time parsing} {
    clock scan {2440588 xi:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 39600
test clock-29.615 {time parsing} {
    clock scan {2440588 xi:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 39600
test clock-29.616 {time parsing} {
    clock scan {2440588 xi } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok }
} 39600
test clock-29.617 {time parsing} {
    clock scan {2440588 xi:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M }
} 39600
test clock-29.618 {time parsing} {
    clock scan {2440588 xi:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM }
} 39600
test clock-29.619 {time parsing} {
    clock scan {2440588 xi:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 39600
test clock-29.620 {time parsing} {
    clock scan {2440588 xi:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 39600
test clock-29.621 {time parsing} {
    clock scan {2440588 11 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I %p}
} 39600
test clock-29.622 {time parsing} {
    clock scan {2440588 11:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %p}
} 39600
test clock-29.623 {time parsing} {
    clock scan {2440588 11:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %p}
} 39600
test clock-29.624 {time parsing} {
    clock scan {2440588 11:00:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 39600
test clock-29.625 {time parsing} {
    clock scan {2440588 11:?:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 39600
test clock-29.626 {time parsing} {
    clock scan {2440588 11 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l %p}
} 39600
test clock-29.627 {time parsing} {
    clock scan {2440588 11:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %p}
} 39600
test clock-29.628 {time parsing} {
    clock scan {2440588 11:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %p}
} 39600
test clock-29.629 {time parsing} {
    clock scan {2440588 11:00:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 39600
test clock-29.630 {time parsing} {
    clock scan {2440588 11:?:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 39600
test clock-29.631 {time parsing} {
    clock scan {2440588 xi AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI %p}
} 39600
test clock-29.632 {time parsing} {
    clock scan {2440588 xi:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %p}
} 39600
test clock-29.633 {time parsing} {
    clock scan {2440588 xi:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %p}
} 39600
test clock-29.634 {time parsing} {
    clock scan {2440588 xi:00:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 39600
test clock-29.635 {time parsing} {
    clock scan {2440588 xi:?:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 39600
test clock-29.636 {time parsing} {
    clock scan {2440588 xi AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol %p}
} 39600
test clock-29.637 {time parsing} {
    clock scan {2440588 xi:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %p}
} 39600
test clock-29.638 {time parsing} {
    clock scan {2440588 xi:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %p}
} 39600
test clock-29.639 {time parsing} {
    clock scan {2440588 xi:00:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 39600
test clock-29.640 {time parsing} {
    clock scan {2440588 xi:?:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 39600
test clock-29.641 {time parsing} {
    clock scan {2440588 11 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I %P}
} 39600
test clock-29.642 {time parsing} {
    clock scan {2440588 11:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %P}
} 39600
test clock-29.643 {time parsing} {
    clock scan {2440588 11:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %P}
} 39600
test clock-29.644 {time parsing} {
    clock scan {2440588 11:00:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 39600
test clock-29.645 {time parsing} {
    clock scan {2440588 11:?:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 39600
test clock-29.646 {time parsing} {
    clock scan {2440588 11 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l %P}
} 39600
test clock-29.647 {time parsing} {
    clock scan {2440588 11:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %P}
} 39600
test clock-29.648 {time parsing} {
    clock scan {2440588 11:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %P}
} 39600
test clock-29.649 {time parsing} {
    clock scan {2440588 11:00:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 39600
test clock-29.650 {time parsing} {
    clock scan {2440588 11:?:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 39600
test clock-29.651 {time parsing} {
    clock scan {2440588 xi am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI %P}
} 39600
test clock-29.652 {time parsing} {
    clock scan {2440588 xi:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %P}
} 39600
test clock-29.653 {time parsing} {
    clock scan {2440588 xi:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %P}
} 39600
test clock-29.654 {time parsing} {
    clock scan {2440588 xi:00:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 39600
test clock-29.655 {time parsing} {
    clock scan {2440588 xi:?:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 39600
test clock-29.656 {time parsing} {
    clock scan {2440588 xi am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol %P}
} 39600
test clock-29.657 {time parsing} {
    clock scan {2440588 xi:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %P}
} 39600
test clock-29.658 {time parsing} {
    clock scan {2440588 xi:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %P}
} 39600
test clock-29.659 {time parsing} {
    clock scan {2440588 xi:00:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 39600
test clock-29.660 {time parsing} {
    clock scan {2440588 xi:?:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 39600
test clock-29.661 {time parsing} {
    clock scan {2440588 11:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 39601
test clock-29.662 {time parsing} {
    clock scan {2440588 11:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 39601
test clock-29.663 {time parsing} {
    clock scan {2440588 11:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 39601
test clock-29.664 {time parsing} {
    clock scan {2440588 11:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 39601
test clock-29.665 {time parsing} {
    clock scan {2440588 xi:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 39601
test clock-29.666 {time parsing} {
    clock scan {2440588 xi:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 39601
test clock-29.667 {time parsing} {
    clock scan {2440588 xi:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 39601
test clock-29.668 {time parsing} {
    clock scan {2440588 xi:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 39601
test clock-29.669 {time parsing} {
    clock scan {2440588 11:00:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 39601
test clock-29.670 {time parsing} {
    clock scan {2440588 11:?:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 39601
test clock-29.671 {time parsing} {
    clock scan {2440588 11:00:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 39601
test clock-29.672 {time parsing} {
    clock scan {2440588 11:?:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 39601
test clock-29.673 {time parsing} {
    clock scan {2440588 xi:00:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 39601
test clock-29.674 {time parsing} {
    clock scan {2440588 xi:?:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 39601
test clock-29.675 {time parsing} {
    clock scan {2440588 xi:00:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 39601
test clock-29.676 {time parsing} {
    clock scan {2440588 xi:?:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 39601
test clock-29.677 {time parsing} {
    clock scan {2440588 11:00:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 39601
test clock-29.678 {time parsing} {
    clock scan {2440588 11:?:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 39601
test clock-29.679 {time parsing} {
    clock scan {2440588 11:00:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 39601
test clock-29.680 {time parsing} {
    clock scan {2440588 11:?:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 39601
test clock-29.681 {time parsing} {
    clock scan {2440588 xi:00:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 39601
test clock-29.682 {time parsing} {
    clock scan {2440588 xi:?:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 39601
test clock-29.683 {time parsing} {
    clock scan {2440588 xi:00:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 39601
test clock-29.684 {time parsing} {
    clock scan {2440588 xi:?:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 39601
test clock-29.685 {time parsing} {
    clock scan {2440588 11:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 39659
test clock-29.686 {time parsing} {
    clock scan {2440588 11:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 39659
test clock-29.687 {time parsing} {
    clock scan {2440588 11:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 39659
test clock-29.688 {time parsing} {
    clock scan {2440588 11:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 39659
test clock-29.689 {time parsing} {
    clock scan {2440588 xi:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 39659
test clock-29.690 {time parsing} {
    clock scan {2440588 xi:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 39659
test clock-29.691 {time parsing} {
    clock scan {2440588 xi:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 39659
test clock-29.692 {time parsing} {
    clock scan {2440588 xi:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 39659
test clock-29.693 {time parsing} {
    clock scan {2440588 11:00:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 39659
test clock-29.694 {time parsing} {
    clock scan {2440588 11:?:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 39659
test clock-29.695 {time parsing} {
    clock scan {2440588 11:00:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 39659
test clock-29.696 {time parsing} {
    clock scan {2440588 11:?:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 39659
test clock-29.697 {time parsing} {
    clock scan {2440588 xi:00:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 39659
test clock-29.698 {time parsing} {
    clock scan {2440588 xi:?:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 39659
test clock-29.699 {time parsing} {
    clock scan {2440588 xi:00:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 39659
test clock-29.700 {time parsing} {
    clock scan {2440588 xi:?:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 39659
test clock-29.701 {time parsing} {
    clock scan {2440588 11:00:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 39659
test clock-29.702 {time parsing} {
    clock scan {2440588 11:?:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 39659
test clock-29.703 {time parsing} {
    clock scan {2440588 11:00:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 39659
test clock-29.704 {time parsing} {
    clock scan {2440588 11:?:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 39659
test clock-29.705 {time parsing} {
    clock scan {2440588 xi:00:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 39659
test clock-29.706 {time parsing} {
    clock scan {2440588 xi:?:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 39659
test clock-29.707 {time parsing} {
    clock scan {2440588 xi:00:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 39659
test clock-29.708 {time parsing} {
    clock scan {2440588 xi:?:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 39659
test clock-29.709 {time parsing} {
    clock scan {2440588 11:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M }
} 39660
test clock-29.710 {time parsing} {
    clock scan {2440588 11:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM }
} 39660
test clock-29.711 {time parsing} {
    clock scan {2440588 11:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 39660
test clock-29.712 {time parsing} {
    clock scan {2440588 11:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 39660
test clock-29.713 {time parsing} {
    clock scan {2440588 11:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M }
} 39660
test clock-29.714 {time parsing} {
    clock scan {2440588 11:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM }
} 39660
test clock-29.715 {time parsing} {
    clock scan {2440588 11:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 39660
test clock-29.716 {time parsing} {
    clock scan {2440588 11:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 39660
test clock-29.717 {time parsing} {
    clock scan {2440588 xi:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M }
} 39660
test clock-29.718 {time parsing} {
    clock scan {2440588 xi:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM }
} 39660
test clock-29.719 {time parsing} {
    clock scan {2440588 xi:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 39660
test clock-29.720 {time parsing} {
    clock scan {2440588 xi:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 39660
test clock-29.721 {time parsing} {
    clock scan {2440588 xi:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M }
} 39660
test clock-29.722 {time parsing} {
    clock scan {2440588 xi:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM }
} 39660
test clock-29.723 {time parsing} {
    clock scan {2440588 xi:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 39660
test clock-29.724 {time parsing} {
    clock scan {2440588 xi:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 39660
test clock-29.725 {time parsing} {
    clock scan {2440588 11:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %p}
} 39660
test clock-29.726 {time parsing} {
    clock scan {2440588 11:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %p}
} 39660
test clock-29.727 {time parsing} {
    clock scan {2440588 11:01:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 39660
test clock-29.728 {time parsing} {
    clock scan {2440588 11:i:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 39660
test clock-29.729 {time parsing} {
    clock scan {2440588 11:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %p}
} 39660
test clock-29.730 {time parsing} {
    clock scan {2440588 11:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %p}
} 39660
test clock-29.731 {time parsing} {
    clock scan {2440588 11:01:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 39660
test clock-29.732 {time parsing} {
    clock scan {2440588 11:i:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 39660
test clock-29.733 {time parsing} {
    clock scan {2440588 xi:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %p}
} 39660
test clock-29.734 {time parsing} {
    clock scan {2440588 xi:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %p}
} 39660
test clock-29.735 {time parsing} {
    clock scan {2440588 xi:01:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 39660
test clock-29.736 {time parsing} {
    clock scan {2440588 xi:i:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 39660
test clock-29.737 {time parsing} {
    clock scan {2440588 xi:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %p}
} 39660
test clock-29.738 {time parsing} {
    clock scan {2440588 xi:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %p}
} 39660
test clock-29.739 {time parsing} {
    clock scan {2440588 xi:01:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 39660
test clock-29.740 {time parsing} {
    clock scan {2440588 xi:i:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 39660
test clock-29.741 {time parsing} {
    clock scan {2440588 11:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %P}
} 39660
test clock-29.742 {time parsing} {
    clock scan {2440588 11:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %P}
} 39660
test clock-29.743 {time parsing} {
    clock scan {2440588 11:01:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 39660
test clock-29.744 {time parsing} {
    clock scan {2440588 11:i:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 39660
test clock-29.745 {time parsing} {
    clock scan {2440588 11:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %P}
} 39660
test clock-29.746 {time parsing} {
    clock scan {2440588 11:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %P}
} 39660
test clock-29.747 {time parsing} {
    clock scan {2440588 11:01:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 39660
test clock-29.748 {time parsing} {
    clock scan {2440588 11:i:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 39660
test clock-29.749 {time parsing} {
    clock scan {2440588 xi:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %P}
} 39660
test clock-29.750 {time parsing} {
    clock scan {2440588 xi:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %P}
} 39660
test clock-29.751 {time parsing} {
    clock scan {2440588 xi:01:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 39660
test clock-29.752 {time parsing} {
    clock scan {2440588 xi:i:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 39660
test clock-29.753 {time parsing} {
    clock scan {2440588 xi:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %P}
} 39660
test clock-29.754 {time parsing} {
    clock scan {2440588 xi:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %P}
} 39660
test clock-29.755 {time parsing} {
    clock scan {2440588 xi:01:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 39660
test clock-29.756 {time parsing} {
    clock scan {2440588 xi:i:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 39660
test clock-29.757 {time parsing} {
    clock scan {2440588 11:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 39661
test clock-29.758 {time parsing} {
    clock scan {2440588 11:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 39661
test clock-29.759 {time parsing} {
    clock scan {2440588 11:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 39661
test clock-29.760 {time parsing} {
    clock scan {2440588 11:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 39661
test clock-29.761 {time parsing} {
    clock scan {2440588 xi:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 39661
test clock-29.762 {time parsing} {
    clock scan {2440588 xi:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 39661
test clock-29.763 {time parsing} {
    clock scan {2440588 xi:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 39661
test clock-29.764 {time parsing} {
    clock scan {2440588 xi:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 39661
test clock-29.765 {time parsing} {
    clock scan {2440588 11:01:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 39661
test clock-29.766 {time parsing} {
    clock scan {2440588 11:i:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 39661
test clock-29.767 {time parsing} {
    clock scan {2440588 11:01:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 39661
test clock-29.768 {time parsing} {
    clock scan {2440588 11:i:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 39661
test clock-29.769 {time parsing} {
    clock scan {2440588 xi:01:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 39661
test clock-29.770 {time parsing} {
    clock scan {2440588 xi:i:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 39661
test clock-29.771 {time parsing} {
    clock scan {2440588 xi:01:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 39661
test clock-29.772 {time parsing} {
    clock scan {2440588 xi:i:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 39661
test clock-29.773 {time parsing} {
    clock scan {2440588 11:01:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 39661
test clock-29.774 {time parsing} {
    clock scan {2440588 11:i:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 39661
test clock-29.775 {time parsing} {
    clock scan {2440588 11:01:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 39661
test clock-29.776 {time parsing} {
    clock scan {2440588 11:i:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 39661
test clock-29.777 {time parsing} {
    clock scan {2440588 xi:01:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 39661
test clock-29.778 {time parsing} {
    clock scan {2440588 xi:i:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 39661
test clock-29.779 {time parsing} {
    clock scan {2440588 xi:01:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 39661
test clock-29.780 {time parsing} {
    clock scan {2440588 xi:i:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 39661
test clock-29.781 {time parsing} {
    clock scan {2440588 11:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 39719
test clock-29.782 {time parsing} {
    clock scan {2440588 11:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 39719
test clock-29.783 {time parsing} {
    clock scan {2440588 11:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 39719
test clock-29.784 {time parsing} {
    clock scan {2440588 11:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 39719
test clock-29.785 {time parsing} {
    clock scan {2440588 xi:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 39719
test clock-29.786 {time parsing} {
    clock scan {2440588 xi:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 39719
test clock-29.787 {time parsing} {
    clock scan {2440588 xi:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 39719
test clock-29.788 {time parsing} {
    clock scan {2440588 xi:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 39719
test clock-29.789 {time parsing} {
    clock scan {2440588 11:01:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 39719
test clock-29.790 {time parsing} {
    clock scan {2440588 11:i:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 39719
test clock-29.791 {time parsing} {
    clock scan {2440588 11:01:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 39719
test clock-29.792 {time parsing} {
    clock scan {2440588 11:i:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 39719
test clock-29.793 {time parsing} {
    clock scan {2440588 xi:01:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 39719
test clock-29.794 {time parsing} {
    clock scan {2440588 xi:i:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 39719
test clock-29.795 {time parsing} {
    clock scan {2440588 xi:01:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 39719
test clock-29.796 {time parsing} {
    clock scan {2440588 xi:i:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 39719
test clock-29.797 {time parsing} {
    clock scan {2440588 11:01:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 39719
test clock-29.798 {time parsing} {
    clock scan {2440588 11:i:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 39719
test clock-29.799 {time parsing} {
    clock scan {2440588 11:01:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 39719
test clock-29.800 {time parsing} {
    clock scan {2440588 11:i:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 39719
test clock-29.801 {time parsing} {
    clock scan {2440588 xi:01:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 39719
test clock-29.802 {time parsing} {
    clock scan {2440588 xi:i:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 39719
test clock-29.803 {time parsing} {
    clock scan {2440588 xi:01:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 39719
test clock-29.804 {time parsing} {
    clock scan {2440588 xi:i:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 39719
test clock-29.805 {time parsing} {
    clock scan {2440588 11:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M }
} 43140
test clock-29.806 {time parsing} {
    clock scan {2440588 11:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM }
} 43140
test clock-29.807 {time parsing} {
    clock scan {2440588 11:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 43140
test clock-29.808 {time parsing} {
    clock scan {2440588 11:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 43140
test clock-29.809 {time parsing} {
    clock scan {2440588 11:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M }
} 43140
test clock-29.810 {time parsing} {
    clock scan {2440588 11:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM }
} 43140
test clock-29.811 {time parsing} {
    clock scan {2440588 11:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 43140
test clock-29.812 {time parsing} {
    clock scan {2440588 11:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 43140
test clock-29.813 {time parsing} {
    clock scan {2440588 xi:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M }
} 43140
test clock-29.814 {time parsing} {
    clock scan {2440588 xi:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM }
} 43140
test clock-29.815 {time parsing} {
    clock scan {2440588 xi:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 43140
test clock-29.816 {time parsing} {
    clock scan {2440588 xi:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 43140
test clock-29.817 {time parsing} {
    clock scan {2440588 xi:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M }
} 43140
test clock-29.818 {time parsing} {
    clock scan {2440588 xi:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM }
} 43140
test clock-29.819 {time parsing} {
    clock scan {2440588 xi:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 43140
test clock-29.820 {time parsing} {
    clock scan {2440588 xi:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 43140
test clock-29.821 {time parsing} {
    clock scan {2440588 11:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %p}
} 43140
test clock-29.822 {time parsing} {
    clock scan {2440588 11:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %p}
} 43140
test clock-29.823 {time parsing} {
    clock scan {2440588 11:59:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 43140
test clock-29.824 {time parsing} {
    clock scan {2440588 11:lix:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 43140
test clock-29.825 {time parsing} {
    clock scan {2440588 11:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %p}
} 43140
test clock-29.826 {time parsing} {
    clock scan {2440588 11:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %p}
} 43140
test clock-29.827 {time parsing} {
    clock scan {2440588 11:59:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 43140
test clock-29.828 {time parsing} {
    clock scan {2440588 11:lix:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 43140
test clock-29.829 {time parsing} {
    clock scan {2440588 xi:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %p}
} 43140
test clock-29.830 {time parsing} {
    clock scan {2440588 xi:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %p}
} 43140
test clock-29.831 {time parsing} {
    clock scan {2440588 xi:59:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 43140
test clock-29.832 {time parsing} {
    clock scan {2440588 xi:lix:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 43140
test clock-29.833 {time parsing} {
    clock scan {2440588 xi:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %p}
} 43140
test clock-29.834 {time parsing} {
    clock scan {2440588 xi:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %p}
} 43140
test clock-29.835 {time parsing} {
    clock scan {2440588 xi:59:00 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 43140
test clock-29.836 {time parsing} {
    clock scan {2440588 xi:lix:? AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 43140
test clock-29.837 {time parsing} {
    clock scan {2440588 11:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %P}
} 43140
test clock-29.838 {time parsing} {
    clock scan {2440588 11:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %P}
} 43140
test clock-29.839 {time parsing} {
    clock scan {2440588 11:59:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 43140
test clock-29.840 {time parsing} {
    clock scan {2440588 11:lix:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 43140
test clock-29.841 {time parsing} {
    clock scan {2440588 11:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %P}
} 43140
test clock-29.842 {time parsing} {
    clock scan {2440588 11:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %P}
} 43140
test clock-29.843 {time parsing} {
    clock scan {2440588 11:59:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 43140
test clock-29.844 {time parsing} {
    clock scan {2440588 11:lix:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 43140
test clock-29.845 {time parsing} {
    clock scan {2440588 xi:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %P}
} 43140
test clock-29.846 {time parsing} {
    clock scan {2440588 xi:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %P}
} 43140
test clock-29.847 {time parsing} {
    clock scan {2440588 xi:59:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 43140
test clock-29.848 {time parsing} {
    clock scan {2440588 xi:lix:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 43140
test clock-29.849 {time parsing} {
    clock scan {2440588 xi:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %P}
} 43140
test clock-29.850 {time parsing} {
    clock scan {2440588 xi:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %P}
} 43140
test clock-29.851 {time parsing} {
    clock scan {2440588 xi:59:00 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 43140
test clock-29.852 {time parsing} {
    clock scan {2440588 xi:lix:? am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 43140
test clock-29.853 {time parsing} {
    clock scan {2440588 11:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 43141
test clock-29.854 {time parsing} {
    clock scan {2440588 11:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 43141
test clock-29.855 {time parsing} {
    clock scan {2440588 11:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 43141
test clock-29.856 {time parsing} {
    clock scan {2440588 11:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 43141
test clock-29.857 {time parsing} {
    clock scan {2440588 xi:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 43141
test clock-29.858 {time parsing} {
    clock scan {2440588 xi:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 43141
test clock-29.859 {time parsing} {
    clock scan {2440588 xi:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 43141
test clock-29.860 {time parsing} {
    clock scan {2440588 xi:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 43141
test clock-29.861 {time parsing} {
    clock scan {2440588 11:59:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 43141
test clock-29.862 {time parsing} {
    clock scan {2440588 11:lix:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 43141
test clock-29.863 {time parsing} {
    clock scan {2440588 11:59:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 43141
test clock-29.864 {time parsing} {
    clock scan {2440588 11:lix:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 43141
test clock-29.865 {time parsing} {
    clock scan {2440588 xi:59:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 43141
test clock-29.866 {time parsing} {
    clock scan {2440588 xi:lix:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 43141
test clock-29.867 {time parsing} {
    clock scan {2440588 xi:59:01 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 43141
test clock-29.868 {time parsing} {
    clock scan {2440588 xi:lix:i AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 43141
test clock-29.869 {time parsing} {
    clock scan {2440588 11:59:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 43141
test clock-29.870 {time parsing} {
    clock scan {2440588 11:lix:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 43141
test clock-29.871 {time parsing} {
    clock scan {2440588 11:59:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 43141
test clock-29.872 {time parsing} {
    clock scan {2440588 11:lix:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 43141
test clock-29.873 {time parsing} {
    clock scan {2440588 xi:59:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 43141
test clock-29.874 {time parsing} {
    clock scan {2440588 xi:lix:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 43141
test clock-29.875 {time parsing} {
    clock scan {2440588 xi:59:01 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 43141
test clock-29.876 {time parsing} {
    clock scan {2440588 xi:lix:i am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 43141
test clock-29.877 {time parsing} {
    clock scan {2440588 11:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 43199
test clock-29.878 {time parsing} {
    clock scan {2440588 11:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 43199
test clock-29.879 {time parsing} {
    clock scan {2440588 11:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 43199
test clock-29.880 {time parsing} {
    clock scan {2440588 11:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 43199
test clock-29.881 {time parsing} {
    clock scan {2440588 xi:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 43199
test clock-29.882 {time parsing} {
    clock scan {2440588 xi:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 43199
test clock-29.883 {time parsing} {
    clock scan {2440588 xi:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 43199
test clock-29.884 {time parsing} {
    clock scan {2440588 xi:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 43199
test clock-29.885 {time parsing} {
    clock scan {2440588 11:59:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 43199
test clock-29.886 {time parsing} {
    clock scan {2440588 11:lix:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 43199
test clock-29.887 {time parsing} {
    clock scan {2440588 11:59:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 43199
test clock-29.888 {time parsing} {
    clock scan {2440588 11:lix:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 43199
test clock-29.889 {time parsing} {
    clock scan {2440588 xi:59:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 43199
test clock-29.890 {time parsing} {
    clock scan {2440588 xi:lix:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 43199
test clock-29.891 {time parsing} {
    clock scan {2440588 xi:59:59 AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 43199
test clock-29.892 {time parsing} {
    clock scan {2440588 xi:lix:lix AM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 43199
test clock-29.893 {time parsing} {
    clock scan {2440588 11:59:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 43199
test clock-29.894 {time parsing} {
    clock scan {2440588 11:lix:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 43199
test clock-29.895 {time parsing} {
    clock scan {2440588 11:59:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 43199
test clock-29.896 {time parsing} {
    clock scan {2440588 11:lix:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 43199
test clock-29.897 {time parsing} {
    clock scan {2440588 xi:59:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 43199
test clock-29.898 {time parsing} {
    clock scan {2440588 xi:lix:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 43199
test clock-29.899 {time parsing} {
    clock scan {2440588 xi:59:59 am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 43199
test clock-29.900 {time parsing} {
    clock scan {2440588 xi:lix:lix am} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 43199
test clock-29.901 {time parsing} {
    clock scan {2440588 12 } \
	-gmt true -locale en_US_roman \
	-format {%J %H }
} 43200
test clock-29.902 {time parsing} {
    clock scan {2440588 12:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M }
} 43200
test clock-29.903 {time parsing} {
    clock scan {2440588 12:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM }
} 43200
test clock-29.904 {time parsing} {
    clock scan {2440588 12:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 43200
test clock-29.905 {time parsing} {
    clock scan {2440588 12:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 43200
test clock-29.906 {time parsing} {
    clock scan {2440588 12 } \
	-gmt true -locale en_US_roman \
	-format {%J %k }
} 43200
test clock-29.907 {time parsing} {
    clock scan {2440588 12:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M }
} 43200
test clock-29.908 {time parsing} {
    clock scan {2440588 12:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM }
} 43200
test clock-29.909 {time parsing} {
    clock scan {2440588 12:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 43200
test clock-29.910 {time parsing} {
    clock scan {2440588 12:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 43200
test clock-29.911 {time parsing} {
    clock scan {2440588 xii } \
	-gmt true -locale en_US_roman \
	-format {%J %OH }
} 43200
test clock-29.912 {time parsing} {
    clock scan {2440588 xii:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M }
} 43200
test clock-29.913 {time parsing} {
    clock scan {2440588 xii:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM }
} 43200
test clock-29.914 {time parsing} {
    clock scan {2440588 xii:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 43200
test clock-29.915 {time parsing} {
    clock scan {2440588 xii:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 43200
test clock-29.916 {time parsing} {
    clock scan {2440588 xii } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok }
} 43200
test clock-29.917 {time parsing} {
    clock scan {2440588 xii:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M }
} 43200
test clock-29.918 {time parsing} {
    clock scan {2440588 xii:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM }
} 43200
test clock-29.919 {time parsing} {
    clock scan {2440588 xii:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 43200
test clock-29.920 {time parsing} {
    clock scan {2440588 xii:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 43200
test clock-29.921 {time parsing} {
    clock scan {2440588 12 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I %p}
} 43200
test clock-29.922 {time parsing} {
    clock scan {2440588 12:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %p}
} 43200
test clock-29.923 {time parsing} {
    clock scan {2440588 12:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %p}
} 43200
test clock-29.924 {time parsing} {
    clock scan {2440588 12:00:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 43200
test clock-29.925 {time parsing} {
    clock scan {2440588 12:?:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 43200
test clock-29.926 {time parsing} {
    clock scan {2440588 12 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l %p}
} 43200
test clock-29.927 {time parsing} {
    clock scan {2440588 12:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %p}
} 43200
test clock-29.928 {time parsing} {
    clock scan {2440588 12:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %p}
} 43200
test clock-29.929 {time parsing} {
    clock scan {2440588 12:00:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 43200
test clock-29.930 {time parsing} {
    clock scan {2440588 12:?:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 43200
test clock-29.931 {time parsing} {
    clock scan {2440588 xii PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI %p}
} 43200
test clock-29.932 {time parsing} {
    clock scan {2440588 xii:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %p}
} 43200
test clock-29.933 {time parsing} {
    clock scan {2440588 xii:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %p}
} 43200
test clock-29.934 {time parsing} {
    clock scan {2440588 xii:00:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 43200
test clock-29.935 {time parsing} {
    clock scan {2440588 xii:?:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 43200
test clock-29.936 {time parsing} {
    clock scan {2440588 xii PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol %p}
} 43200
test clock-29.937 {time parsing} {
    clock scan {2440588 xii:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %p}
} 43200
test clock-29.938 {time parsing} {
    clock scan {2440588 xii:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %p}
} 43200
test clock-29.939 {time parsing} {
    clock scan {2440588 xii:00:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 43200
test clock-29.940 {time parsing} {
    clock scan {2440588 xii:?:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 43200
test clock-29.941 {time parsing} {
    clock scan {2440588 12 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I %P}
} 43200
test clock-29.942 {time parsing} {
    clock scan {2440588 12:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %P}
} 43200
test clock-29.943 {time parsing} {
    clock scan {2440588 12:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %P}
} 43200
test clock-29.944 {time parsing} {
    clock scan {2440588 12:00:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 43200
test clock-29.945 {time parsing} {
    clock scan {2440588 12:?:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 43200
test clock-29.946 {time parsing} {
    clock scan {2440588 12 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l %P}
} 43200
test clock-29.947 {time parsing} {
    clock scan {2440588 12:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %P}
} 43200
test clock-29.948 {time parsing} {
    clock scan {2440588 12:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %P}
} 43200
test clock-29.949 {time parsing} {
    clock scan {2440588 12:00:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 43200
test clock-29.950 {time parsing} {
    clock scan {2440588 12:?:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 43200
test clock-29.951 {time parsing} {
    clock scan {2440588 xii pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI %P}
} 43200
test clock-29.952 {time parsing} {
    clock scan {2440588 xii:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %P}
} 43200
test clock-29.953 {time parsing} {
    clock scan {2440588 xii:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %P}
} 43200
test clock-29.954 {time parsing} {
    clock scan {2440588 xii:00:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 43200
test clock-29.955 {time parsing} {
    clock scan {2440588 xii:?:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 43200
test clock-29.956 {time parsing} {
    clock scan {2440588 xii pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol %P}
} 43200
test clock-29.957 {time parsing} {
    clock scan {2440588 xii:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %P}
} 43200
test clock-29.958 {time parsing} {
    clock scan {2440588 xii:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %P}
} 43200
test clock-29.959 {time parsing} {
    clock scan {2440588 xii:00:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 43200
test clock-29.960 {time parsing} {
    clock scan {2440588 xii:?:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 43200
test clock-29.961 {time parsing} {
    clock scan {2440588 12:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 43201
test clock-29.962 {time parsing} {
    clock scan {2440588 12:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 43201
test clock-29.963 {time parsing} {
    clock scan {2440588 12:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 43201
test clock-29.964 {time parsing} {
    clock scan {2440588 12:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 43201
test clock-29.965 {time parsing} {
    clock scan {2440588 xii:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 43201
test clock-29.966 {time parsing} {
    clock scan {2440588 xii:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 43201
test clock-29.967 {time parsing} {
    clock scan {2440588 xii:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 43201
test clock-29.968 {time parsing} {
    clock scan {2440588 xii:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 43201
test clock-29.969 {time parsing} {
    clock scan {2440588 12:00:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 43201
test clock-29.970 {time parsing} {
    clock scan {2440588 12:?:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 43201
test clock-29.971 {time parsing} {
    clock scan {2440588 12:00:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 43201
test clock-29.972 {time parsing} {
    clock scan {2440588 12:?:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 43201
test clock-29.973 {time parsing} {
    clock scan {2440588 xii:00:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 43201
test clock-29.974 {time parsing} {
    clock scan {2440588 xii:?:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 43201
test clock-29.975 {time parsing} {
    clock scan {2440588 xii:00:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 43201
test clock-29.976 {time parsing} {
    clock scan {2440588 xii:?:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 43201
test clock-29.977 {time parsing} {
    clock scan {2440588 12:00:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 43201
test clock-29.978 {time parsing} {
    clock scan {2440588 12:?:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 43201
test clock-29.979 {time parsing} {
    clock scan {2440588 12:00:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 43201
test clock-29.980 {time parsing} {
    clock scan {2440588 12:?:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 43201
test clock-29.981 {time parsing} {
    clock scan {2440588 xii:00:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 43201
test clock-29.982 {time parsing} {
    clock scan {2440588 xii:?:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 43201
test clock-29.983 {time parsing} {
    clock scan {2440588 xii:00:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 43201
test clock-29.984 {time parsing} {
    clock scan {2440588 xii:?:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 43201
test clock-29.985 {time parsing} {
    clock scan {2440588 12:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 43259
test clock-29.986 {time parsing} {
    clock scan {2440588 12:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 43259
test clock-29.987 {time parsing} {
    clock scan {2440588 12:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 43259
test clock-29.988 {time parsing} {
    clock scan {2440588 12:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 43259
test clock-29.989 {time parsing} {
    clock scan {2440588 xii:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 43259
test clock-29.990 {time parsing} {
    clock scan {2440588 xii:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 43259
test clock-29.991 {time parsing} {
    clock scan {2440588 xii:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 43259
test clock-29.992 {time parsing} {
    clock scan {2440588 xii:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 43259
test clock-29.993 {time parsing} {
    clock scan {2440588 12:00:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 43259
test clock-29.994 {time parsing} {
    clock scan {2440588 12:?:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 43259
test clock-29.995 {time parsing} {
    clock scan {2440588 12:00:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 43259
test clock-29.996 {time parsing} {
    clock scan {2440588 12:?:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 43259
test clock-29.997 {time parsing} {
    clock scan {2440588 xii:00:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 43259
test clock-29.998 {time parsing} {
    clock scan {2440588 xii:?:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 43259
test clock-29.999 {time parsing} {
    clock scan {2440588 xii:00:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 43259
test clock-29.1000 {time parsing} {
    clock scan {2440588 xii:?:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 43259
test clock-29.1001 {time parsing} {
    clock scan {2440588 12:00:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 43259
test clock-29.1002 {time parsing} {
    clock scan {2440588 12:?:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 43259
test clock-29.1003 {time parsing} {
    clock scan {2440588 12:00:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 43259
test clock-29.1004 {time parsing} {
    clock scan {2440588 12:?:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 43259
test clock-29.1005 {time parsing} {
    clock scan {2440588 xii:00:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 43259
test clock-29.1006 {time parsing} {
    clock scan {2440588 xii:?:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 43259
test clock-29.1007 {time parsing} {
    clock scan {2440588 xii:00:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 43259
test clock-29.1008 {time parsing} {
    clock scan {2440588 xii:?:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 43259
test clock-29.1009 {time parsing} {
    clock scan {2440588 12:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M }
} 43260
test clock-29.1010 {time parsing} {
    clock scan {2440588 12:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM }
} 43260
test clock-29.1011 {time parsing} {
    clock scan {2440588 12:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 43260
test clock-29.1012 {time parsing} {
    clock scan {2440588 12:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 43260
test clock-29.1013 {time parsing} {
    clock scan {2440588 12:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M }
} 43260
test clock-29.1014 {time parsing} {
    clock scan {2440588 12:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM }
} 43260
test clock-29.1015 {time parsing} {
    clock scan {2440588 12:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 43260
test clock-29.1016 {time parsing} {
    clock scan {2440588 12:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 43260
test clock-29.1017 {time parsing} {
    clock scan {2440588 xii:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M }
} 43260
test clock-29.1018 {time parsing} {
    clock scan {2440588 xii:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM }
} 43260
test clock-29.1019 {time parsing} {
    clock scan {2440588 xii:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 43260
test clock-29.1020 {time parsing} {
    clock scan {2440588 xii:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 43260
test clock-29.1021 {time parsing} {
    clock scan {2440588 xii:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M }
} 43260
test clock-29.1022 {time parsing} {
    clock scan {2440588 xii:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM }
} 43260
test clock-29.1023 {time parsing} {
    clock scan {2440588 xii:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 43260
test clock-29.1024 {time parsing} {
    clock scan {2440588 xii:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 43260
test clock-29.1025 {time parsing} {
    clock scan {2440588 12:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %p}
} 43260
test clock-29.1026 {time parsing} {
    clock scan {2440588 12:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %p}
} 43260
test clock-29.1027 {time parsing} {
    clock scan {2440588 12:01:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 43260
test clock-29.1028 {time parsing} {
    clock scan {2440588 12:i:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 43260
test clock-29.1029 {time parsing} {
    clock scan {2440588 12:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %p}
} 43260
test clock-29.1030 {time parsing} {
    clock scan {2440588 12:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %p}
} 43260
test clock-29.1031 {time parsing} {
    clock scan {2440588 12:01:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 43260
test clock-29.1032 {time parsing} {
    clock scan {2440588 12:i:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 43260
test clock-29.1033 {time parsing} {
    clock scan {2440588 xii:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %p}
} 43260
test clock-29.1034 {time parsing} {
    clock scan {2440588 xii:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %p}
} 43260
test clock-29.1035 {time parsing} {
    clock scan {2440588 xii:01:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 43260
test clock-29.1036 {time parsing} {
    clock scan {2440588 xii:i:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 43260
test clock-29.1037 {time parsing} {
    clock scan {2440588 xii:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %p}
} 43260
test clock-29.1038 {time parsing} {
    clock scan {2440588 xii:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %p}
} 43260
test clock-29.1039 {time parsing} {
    clock scan {2440588 xii:01:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 43260
test clock-29.1040 {time parsing} {
    clock scan {2440588 xii:i:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 43260
test clock-29.1041 {time parsing} {
    clock scan {2440588 12:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %P}
} 43260
test clock-29.1042 {time parsing} {
    clock scan {2440588 12:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %P}
} 43260
test clock-29.1043 {time parsing} {
    clock scan {2440588 12:01:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 43260
test clock-29.1044 {time parsing} {
    clock scan {2440588 12:i:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 43260
test clock-29.1045 {time parsing} {
    clock scan {2440588 12:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %P}
} 43260
test clock-29.1046 {time parsing} {
    clock scan {2440588 12:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %P}
} 43260
test clock-29.1047 {time parsing} {
    clock scan {2440588 12:01:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 43260
test clock-29.1048 {time parsing} {
    clock scan {2440588 12:i:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 43260
test clock-29.1049 {time parsing} {
    clock scan {2440588 xii:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %P}
} 43260
test clock-29.1050 {time parsing} {
    clock scan {2440588 xii:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %P}
} 43260
test clock-29.1051 {time parsing} {
    clock scan {2440588 xii:01:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 43260
test clock-29.1052 {time parsing} {
    clock scan {2440588 xii:i:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 43260
test clock-29.1053 {time parsing} {
    clock scan {2440588 xii:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %P}
} 43260
test clock-29.1054 {time parsing} {
    clock scan {2440588 xii:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %P}
} 43260
test clock-29.1055 {time parsing} {
    clock scan {2440588 xii:01:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 43260
test clock-29.1056 {time parsing} {
    clock scan {2440588 xii:i:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 43260
test clock-29.1057 {time parsing} {
    clock scan {2440588 12:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 43261
test clock-29.1058 {time parsing} {
    clock scan {2440588 12:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 43261
test clock-29.1059 {time parsing} {
    clock scan {2440588 12:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 43261
test clock-29.1060 {time parsing} {
    clock scan {2440588 12:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 43261
test clock-29.1061 {time parsing} {
    clock scan {2440588 xii:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 43261
test clock-29.1062 {time parsing} {
    clock scan {2440588 xii:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 43261
test clock-29.1063 {time parsing} {
    clock scan {2440588 xii:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 43261
test clock-29.1064 {time parsing} {
    clock scan {2440588 xii:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 43261
test clock-29.1065 {time parsing} {
    clock scan {2440588 12:01:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 43261
test clock-29.1066 {time parsing} {
    clock scan {2440588 12:i:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 43261
test clock-29.1067 {time parsing} {
    clock scan {2440588 12:01:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 43261
test clock-29.1068 {time parsing} {
    clock scan {2440588 12:i:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 43261
test clock-29.1069 {time parsing} {
    clock scan {2440588 xii:01:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 43261
test clock-29.1070 {time parsing} {
    clock scan {2440588 xii:i:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 43261
test clock-29.1071 {time parsing} {
    clock scan {2440588 xii:01:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 43261
test clock-29.1072 {time parsing} {
    clock scan {2440588 xii:i:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 43261
test clock-29.1073 {time parsing} {
    clock scan {2440588 12:01:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 43261
test clock-29.1074 {time parsing} {
    clock scan {2440588 12:i:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 43261
test clock-29.1075 {time parsing} {
    clock scan {2440588 12:01:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 43261
test clock-29.1076 {time parsing} {
    clock scan {2440588 12:i:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 43261
test clock-29.1077 {time parsing} {
    clock scan {2440588 xii:01:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 43261
test clock-29.1078 {time parsing} {
    clock scan {2440588 xii:i:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 43261
test clock-29.1079 {time parsing} {
    clock scan {2440588 xii:01:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 43261
test clock-29.1080 {time parsing} {
    clock scan {2440588 xii:i:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 43261
test clock-29.1081 {time parsing} {
    clock scan {2440588 12:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 43319
test clock-29.1082 {time parsing} {
    clock scan {2440588 12:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 43319
test clock-29.1083 {time parsing} {
    clock scan {2440588 12:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 43319
test clock-29.1084 {time parsing} {
    clock scan {2440588 12:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 43319
test clock-29.1085 {time parsing} {
    clock scan {2440588 xii:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 43319
test clock-29.1086 {time parsing} {
    clock scan {2440588 xii:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 43319
test clock-29.1087 {time parsing} {
    clock scan {2440588 xii:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 43319
test clock-29.1088 {time parsing} {
    clock scan {2440588 xii:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 43319
test clock-29.1089 {time parsing} {
    clock scan {2440588 12:01:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 43319
test clock-29.1090 {time parsing} {
    clock scan {2440588 12:i:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 43319
test clock-29.1091 {time parsing} {
    clock scan {2440588 12:01:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 43319
test clock-29.1092 {time parsing} {
    clock scan {2440588 12:i:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 43319
test clock-29.1093 {time parsing} {
    clock scan {2440588 xii:01:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 43319
test clock-29.1094 {time parsing} {
    clock scan {2440588 xii:i:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 43319
test clock-29.1095 {time parsing} {
    clock scan {2440588 xii:01:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 43319
test clock-29.1096 {time parsing} {
    clock scan {2440588 xii:i:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 43319
test clock-29.1097 {time parsing} {
    clock scan {2440588 12:01:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 43319
test clock-29.1098 {time parsing} {
    clock scan {2440588 12:i:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 43319
test clock-29.1099 {time parsing} {
    clock scan {2440588 12:01:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 43319
test clock-29.1100 {time parsing} {
    clock scan {2440588 12:i:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 43319
test clock-29.1101 {time parsing} {
    clock scan {2440588 xii:01:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 43319
test clock-29.1102 {time parsing} {
    clock scan {2440588 xii:i:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 43319
test clock-29.1103 {time parsing} {
    clock scan {2440588 xii:01:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 43319
test clock-29.1104 {time parsing} {
    clock scan {2440588 xii:i:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 43319
test clock-29.1105 {time parsing} {
    clock scan {2440588 12:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M }
} 46740
test clock-29.1106 {time parsing} {
    clock scan {2440588 12:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM }
} 46740
test clock-29.1107 {time parsing} {
    clock scan {2440588 12:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 46740
test clock-29.1108 {time parsing} {
    clock scan {2440588 12:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 46740
test clock-29.1109 {time parsing} {
    clock scan {2440588 12:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M }
} 46740
test clock-29.1110 {time parsing} {
    clock scan {2440588 12:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM }
} 46740
test clock-29.1111 {time parsing} {
    clock scan {2440588 12:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 46740
test clock-29.1112 {time parsing} {
    clock scan {2440588 12:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 46740
test clock-29.1113 {time parsing} {
    clock scan {2440588 xii:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M }
} 46740
test clock-29.1114 {time parsing} {
    clock scan {2440588 xii:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM }
} 46740
test clock-29.1115 {time parsing} {
    clock scan {2440588 xii:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 46740
test clock-29.1116 {time parsing} {
    clock scan {2440588 xii:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 46740
test clock-29.1117 {time parsing} {
    clock scan {2440588 xii:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M }
} 46740
test clock-29.1118 {time parsing} {
    clock scan {2440588 xii:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM }
} 46740
test clock-29.1119 {time parsing} {
    clock scan {2440588 xii:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 46740
test clock-29.1120 {time parsing} {
    clock scan {2440588 xii:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 46740
test clock-29.1121 {time parsing} {
    clock scan {2440588 12:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %p}
} 46740
test clock-29.1122 {time parsing} {
    clock scan {2440588 12:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %p}
} 46740
test clock-29.1123 {time parsing} {
    clock scan {2440588 12:59:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 46740
test clock-29.1124 {time parsing} {
    clock scan {2440588 12:lix:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 46740
test clock-29.1125 {time parsing} {
    clock scan {2440588 12:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %p}
} 46740
test clock-29.1126 {time parsing} {
    clock scan {2440588 12:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %p}
} 46740
test clock-29.1127 {time parsing} {
    clock scan {2440588 12:59:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 46740
test clock-29.1128 {time parsing} {
    clock scan {2440588 12:lix:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 46740
test clock-29.1129 {time parsing} {
    clock scan {2440588 xii:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %p}
} 46740
test clock-29.1130 {time parsing} {
    clock scan {2440588 xii:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %p}
} 46740
test clock-29.1131 {time parsing} {
    clock scan {2440588 xii:59:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 46740
test clock-29.1132 {time parsing} {
    clock scan {2440588 xii:lix:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 46740
test clock-29.1133 {time parsing} {
    clock scan {2440588 xii:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %p}
} 46740
test clock-29.1134 {time parsing} {
    clock scan {2440588 xii:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %p}
} 46740
test clock-29.1135 {time parsing} {
    clock scan {2440588 xii:59:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 46740
test clock-29.1136 {time parsing} {
    clock scan {2440588 xii:lix:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 46740
test clock-29.1137 {time parsing} {
    clock scan {2440588 12:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %P}
} 46740
test clock-29.1138 {time parsing} {
    clock scan {2440588 12:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %P}
} 46740
test clock-29.1139 {time parsing} {
    clock scan {2440588 12:59:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 46740
test clock-29.1140 {time parsing} {
    clock scan {2440588 12:lix:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 46740
test clock-29.1141 {time parsing} {
    clock scan {2440588 12:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %P}
} 46740
test clock-29.1142 {time parsing} {
    clock scan {2440588 12:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %P}
} 46740
test clock-29.1143 {time parsing} {
    clock scan {2440588 12:59:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 46740
test clock-29.1144 {time parsing} {
    clock scan {2440588 12:lix:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 46740
test clock-29.1145 {time parsing} {
    clock scan {2440588 xii:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %P}
} 46740
test clock-29.1146 {time parsing} {
    clock scan {2440588 xii:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %P}
} 46740
test clock-29.1147 {time parsing} {
    clock scan {2440588 xii:59:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 46740
test clock-29.1148 {time parsing} {
    clock scan {2440588 xii:lix:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 46740
test clock-29.1149 {time parsing} {
    clock scan {2440588 xii:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %P}
} 46740
test clock-29.1150 {time parsing} {
    clock scan {2440588 xii:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %P}
} 46740
test clock-29.1151 {time parsing} {
    clock scan {2440588 xii:59:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 46740
test clock-29.1152 {time parsing} {
    clock scan {2440588 xii:lix:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 46740
test clock-29.1153 {time parsing} {
    clock scan {2440588 12:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 46741
test clock-29.1154 {time parsing} {
    clock scan {2440588 12:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 46741
test clock-29.1155 {time parsing} {
    clock scan {2440588 12:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 46741
test clock-29.1156 {time parsing} {
    clock scan {2440588 12:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 46741
test clock-29.1157 {time parsing} {
    clock scan {2440588 xii:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 46741
test clock-29.1158 {time parsing} {
    clock scan {2440588 xii:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 46741
test clock-29.1159 {time parsing} {
    clock scan {2440588 xii:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 46741
test clock-29.1160 {time parsing} {
    clock scan {2440588 xii:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 46741
test clock-29.1161 {time parsing} {
    clock scan {2440588 12:59:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 46741
test clock-29.1162 {time parsing} {
    clock scan {2440588 12:lix:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 46741
test clock-29.1163 {time parsing} {
    clock scan {2440588 12:59:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 46741
test clock-29.1164 {time parsing} {
    clock scan {2440588 12:lix:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 46741
test clock-29.1165 {time parsing} {
    clock scan {2440588 xii:59:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 46741
test clock-29.1166 {time parsing} {
    clock scan {2440588 xii:lix:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 46741
test clock-29.1167 {time parsing} {
    clock scan {2440588 xii:59:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 46741
test clock-29.1168 {time parsing} {
    clock scan {2440588 xii:lix:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 46741
test clock-29.1169 {time parsing} {
    clock scan {2440588 12:59:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 46741
test clock-29.1170 {time parsing} {
    clock scan {2440588 12:lix:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 46741
test clock-29.1171 {time parsing} {
    clock scan {2440588 12:59:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 46741
test clock-29.1172 {time parsing} {
    clock scan {2440588 12:lix:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 46741
test clock-29.1173 {time parsing} {
    clock scan {2440588 xii:59:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 46741
test clock-29.1174 {time parsing} {
    clock scan {2440588 xii:lix:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 46741
test clock-29.1175 {time parsing} {
    clock scan {2440588 xii:59:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 46741
test clock-29.1176 {time parsing} {
    clock scan {2440588 xii:lix:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 46741
test clock-29.1177 {time parsing} {
    clock scan {2440588 12:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 46799
test clock-29.1178 {time parsing} {
    clock scan {2440588 12:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 46799
test clock-29.1179 {time parsing} {
    clock scan {2440588 12:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 46799
test clock-29.1180 {time parsing} {
    clock scan {2440588 12:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 46799
test clock-29.1181 {time parsing} {
    clock scan {2440588 xii:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 46799
test clock-29.1182 {time parsing} {
    clock scan {2440588 xii:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 46799
test clock-29.1183 {time parsing} {
    clock scan {2440588 xii:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 46799
test clock-29.1184 {time parsing} {
    clock scan {2440588 xii:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 46799
test clock-29.1185 {time parsing} {
    clock scan {2440588 12:59:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 46799
test clock-29.1186 {time parsing} {
    clock scan {2440588 12:lix:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 46799
test clock-29.1187 {time parsing} {
    clock scan {2440588 12:59:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 46799
test clock-29.1188 {time parsing} {
    clock scan {2440588 12:lix:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 46799
test clock-29.1189 {time parsing} {
    clock scan {2440588 xii:59:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 46799
test clock-29.1190 {time parsing} {
    clock scan {2440588 xii:lix:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 46799
test clock-29.1191 {time parsing} {
    clock scan {2440588 xii:59:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 46799
test clock-29.1192 {time parsing} {
    clock scan {2440588 xii:lix:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 46799
test clock-29.1193 {time parsing} {
    clock scan {2440588 12:59:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 46799
test clock-29.1194 {time parsing} {
    clock scan {2440588 12:lix:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 46799
test clock-29.1195 {time parsing} {
    clock scan {2440588 12:59:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 46799
test clock-29.1196 {time parsing} {
    clock scan {2440588 12:lix:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 46799
test clock-29.1197 {time parsing} {
    clock scan {2440588 xii:59:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 46799
test clock-29.1198 {time parsing} {
    clock scan {2440588 xii:lix:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 46799
test clock-29.1199 {time parsing} {
    clock scan {2440588 xii:59:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 46799
test clock-29.1200 {time parsing} {
    clock scan {2440588 xii:lix:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 46799
test clock-29.1201 {time parsing} {
    clock scan {2440588 13 } \
	-gmt true -locale en_US_roman \
	-format {%J %H }
} 46800
test clock-29.1202 {time parsing} {
    clock scan {2440588 13:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M }
} 46800
test clock-29.1203 {time parsing} {
    clock scan {2440588 13:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM }
} 46800
test clock-29.1204 {time parsing} {
    clock scan {2440588 13:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 46800
test clock-29.1205 {time parsing} {
    clock scan {2440588 13:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 46800
test clock-29.1206 {time parsing} {
    clock scan {2440588 13 } \
	-gmt true -locale en_US_roman \
	-format {%J %k }
} 46800
test clock-29.1207 {time parsing} {
    clock scan {2440588 13:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M }
} 46800
test clock-29.1208 {time parsing} {
    clock scan {2440588 13:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM }
} 46800
test clock-29.1209 {time parsing} {
    clock scan {2440588 13:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 46800
test clock-29.1210 {time parsing} {
    clock scan {2440588 13:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 46800
test clock-29.1211 {time parsing} {
    clock scan {2440588 xiii } \
	-gmt true -locale en_US_roman \
	-format {%J %OH }
} 46800
test clock-29.1212 {time parsing} {
    clock scan {2440588 xiii:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M }
} 46800
test clock-29.1213 {time parsing} {
    clock scan {2440588 xiii:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM }
} 46800
test clock-29.1214 {time parsing} {
    clock scan {2440588 xiii:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 46800
test clock-29.1215 {time parsing} {
    clock scan {2440588 xiii:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 46800
test clock-29.1216 {time parsing} {
    clock scan {2440588 xiii } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok }
} 46800
test clock-29.1217 {time parsing} {
    clock scan {2440588 xiii:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M }
} 46800
test clock-29.1218 {time parsing} {
    clock scan {2440588 xiii:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM }
} 46800
test clock-29.1219 {time parsing} {
    clock scan {2440588 xiii:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 46800
test clock-29.1220 {time parsing} {
    clock scan {2440588 xiii:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 46800
test clock-29.1221 {time parsing} {
    clock scan {2440588 01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I %p}
} 46800
test clock-29.1222 {time parsing} {
    clock scan {2440588 01:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %p}
} 46800
test clock-29.1223 {time parsing} {
    clock scan {2440588 01:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %p}
} 46800
test clock-29.1224 {time parsing} {
    clock scan {2440588 01:00:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 46800
test clock-29.1225 {time parsing} {
    clock scan {2440588 01:?:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 46800
test clock-29.1226 {time parsing} {
    clock scan {2440588  1 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l %p}
} 46800
test clock-29.1227 {time parsing} {
    clock scan {2440588  1:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %p}
} 46800
test clock-29.1228 {time parsing} {
    clock scan {2440588  1:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %p}
} 46800
test clock-29.1229 {time parsing} {
    clock scan {2440588  1:00:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 46800
test clock-29.1230 {time parsing} {
    clock scan {2440588  1:?:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 46800
test clock-29.1231 {time parsing} {
    clock scan {2440588 i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI %p}
} 46800
test clock-29.1232 {time parsing} {
    clock scan {2440588 i:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %p}
} 46800
test clock-29.1233 {time parsing} {
    clock scan {2440588 i:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %p}
} 46800
test clock-29.1234 {time parsing} {
    clock scan {2440588 i:00:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 46800
test clock-29.1235 {time parsing} {
    clock scan {2440588 i:?:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 46800
test clock-29.1236 {time parsing} {
    clock scan {2440588 i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol %p}
} 46800
test clock-29.1237 {time parsing} {
    clock scan {2440588 i:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %p}
} 46800
test clock-29.1238 {time parsing} {
    clock scan {2440588 i:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %p}
} 46800
test clock-29.1239 {time parsing} {
    clock scan {2440588 i:00:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 46800
test clock-29.1240 {time parsing} {
    clock scan {2440588 i:?:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 46800
test clock-29.1241 {time parsing} {
    clock scan {2440588 01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I %P}
} 46800
test clock-29.1242 {time parsing} {
    clock scan {2440588 01:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %P}
} 46800
test clock-29.1243 {time parsing} {
    clock scan {2440588 01:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %P}
} 46800
test clock-29.1244 {time parsing} {
    clock scan {2440588 01:00:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 46800
test clock-29.1245 {time parsing} {
    clock scan {2440588 01:?:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 46800
test clock-29.1246 {time parsing} {
    clock scan {2440588  1 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l %P}
} 46800
test clock-29.1247 {time parsing} {
    clock scan {2440588  1:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %P}
} 46800
test clock-29.1248 {time parsing} {
    clock scan {2440588  1:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %P}
} 46800
test clock-29.1249 {time parsing} {
    clock scan {2440588  1:00:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 46800
test clock-29.1250 {time parsing} {
    clock scan {2440588  1:?:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 46800
test clock-29.1251 {time parsing} {
    clock scan {2440588 i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI %P}
} 46800
test clock-29.1252 {time parsing} {
    clock scan {2440588 i:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %P}
} 46800
test clock-29.1253 {time parsing} {
    clock scan {2440588 i:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %P}
} 46800
test clock-29.1254 {time parsing} {
    clock scan {2440588 i:00:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 46800
test clock-29.1255 {time parsing} {
    clock scan {2440588 i:?:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 46800
test clock-29.1256 {time parsing} {
    clock scan {2440588 i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol %P}
} 46800
test clock-29.1257 {time parsing} {
    clock scan {2440588 i:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %P}
} 46800
test clock-29.1258 {time parsing} {
    clock scan {2440588 i:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %P}
} 46800
test clock-29.1259 {time parsing} {
    clock scan {2440588 i:00:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 46800
test clock-29.1260 {time parsing} {
    clock scan {2440588 i:?:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 46800
test clock-29.1261 {time parsing} {
    clock scan {2440588 13:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 46801
test clock-29.1262 {time parsing} {
    clock scan {2440588 13:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 46801
test clock-29.1263 {time parsing} {
    clock scan {2440588 13:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 46801
test clock-29.1264 {time parsing} {
    clock scan {2440588 13:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 46801
test clock-29.1265 {time parsing} {
    clock scan {2440588 xiii:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 46801
test clock-29.1266 {time parsing} {
    clock scan {2440588 xiii:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 46801
test clock-29.1267 {time parsing} {
    clock scan {2440588 xiii:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 46801
test clock-29.1268 {time parsing} {
    clock scan {2440588 xiii:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 46801
test clock-29.1269 {time parsing} {
    clock scan {2440588 01:00:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 46801
test clock-29.1270 {time parsing} {
    clock scan {2440588 01:?:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 46801
test clock-29.1271 {time parsing} {
    clock scan {2440588  1:00:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 46801
test clock-29.1272 {time parsing} {
    clock scan {2440588  1:?:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 46801
test clock-29.1273 {time parsing} {
    clock scan {2440588 i:00:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 46801
test clock-29.1274 {time parsing} {
    clock scan {2440588 i:?:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 46801
test clock-29.1275 {time parsing} {
    clock scan {2440588 i:00:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 46801
test clock-29.1276 {time parsing} {
    clock scan {2440588 i:?:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 46801
test clock-29.1277 {time parsing} {
    clock scan {2440588 01:00:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 46801
test clock-29.1278 {time parsing} {
    clock scan {2440588 01:?:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 46801
test clock-29.1279 {time parsing} {
    clock scan {2440588  1:00:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 46801
test clock-29.1280 {time parsing} {
    clock scan {2440588  1:?:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 46801
test clock-29.1281 {time parsing} {
    clock scan {2440588 i:00:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 46801
test clock-29.1282 {time parsing} {
    clock scan {2440588 i:?:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 46801
test clock-29.1283 {time parsing} {
    clock scan {2440588 i:00:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 46801
test clock-29.1284 {time parsing} {
    clock scan {2440588 i:?:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 46801
test clock-29.1285 {time parsing} {
    clock scan {2440588 13:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 46859
test clock-29.1286 {time parsing} {
    clock scan {2440588 13:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 46859
test clock-29.1287 {time parsing} {
    clock scan {2440588 13:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 46859
test clock-29.1288 {time parsing} {
    clock scan {2440588 13:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 46859
test clock-29.1289 {time parsing} {
    clock scan {2440588 xiii:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 46859
test clock-29.1290 {time parsing} {
    clock scan {2440588 xiii:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 46859
test clock-29.1291 {time parsing} {
    clock scan {2440588 xiii:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 46859
test clock-29.1292 {time parsing} {
    clock scan {2440588 xiii:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 46859
test clock-29.1293 {time parsing} {
    clock scan {2440588 01:00:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 46859
test clock-29.1294 {time parsing} {
    clock scan {2440588 01:?:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 46859
test clock-29.1295 {time parsing} {
    clock scan {2440588  1:00:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 46859
test clock-29.1296 {time parsing} {
    clock scan {2440588  1:?:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 46859
test clock-29.1297 {time parsing} {
    clock scan {2440588 i:00:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 46859
test clock-29.1298 {time parsing} {
    clock scan {2440588 i:?:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 46859
test clock-29.1299 {time parsing} {
    clock scan {2440588 i:00:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 46859
test clock-29.1300 {time parsing} {
    clock scan {2440588 i:?:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 46859
test clock-29.1301 {time parsing} {
    clock scan {2440588 01:00:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 46859
test clock-29.1302 {time parsing} {
    clock scan {2440588 01:?:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 46859
test clock-29.1303 {time parsing} {
    clock scan {2440588  1:00:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 46859
test clock-29.1304 {time parsing} {
    clock scan {2440588  1:?:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 46859
test clock-29.1305 {time parsing} {
    clock scan {2440588 i:00:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 46859
test clock-29.1306 {time parsing} {
    clock scan {2440588 i:?:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 46859
test clock-29.1307 {time parsing} {
    clock scan {2440588 i:00:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 46859
test clock-29.1308 {time parsing} {
    clock scan {2440588 i:?:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 46859
test clock-29.1309 {time parsing} {
    clock scan {2440588 13:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M }
} 46860
test clock-29.1310 {time parsing} {
    clock scan {2440588 13:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM }
} 46860
test clock-29.1311 {time parsing} {
    clock scan {2440588 13:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 46860
test clock-29.1312 {time parsing} {
    clock scan {2440588 13:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 46860
test clock-29.1313 {time parsing} {
    clock scan {2440588 13:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M }
} 46860
test clock-29.1314 {time parsing} {
    clock scan {2440588 13:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM }
} 46860
test clock-29.1315 {time parsing} {
    clock scan {2440588 13:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 46860
test clock-29.1316 {time parsing} {
    clock scan {2440588 13:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 46860
test clock-29.1317 {time parsing} {
    clock scan {2440588 xiii:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M }
} 46860
test clock-29.1318 {time parsing} {
    clock scan {2440588 xiii:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM }
} 46860
test clock-29.1319 {time parsing} {
    clock scan {2440588 xiii:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 46860
test clock-29.1320 {time parsing} {
    clock scan {2440588 xiii:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 46860
test clock-29.1321 {time parsing} {
    clock scan {2440588 xiii:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M }
} 46860
test clock-29.1322 {time parsing} {
    clock scan {2440588 xiii:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM }
} 46860
test clock-29.1323 {time parsing} {
    clock scan {2440588 xiii:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 46860
test clock-29.1324 {time parsing} {
    clock scan {2440588 xiii:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 46860
test clock-29.1325 {time parsing} {
    clock scan {2440588 01:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %p}
} 46860
test clock-29.1326 {time parsing} {
    clock scan {2440588 01:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %p}
} 46860
test clock-29.1327 {time parsing} {
    clock scan {2440588 01:01:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 46860
test clock-29.1328 {time parsing} {
    clock scan {2440588 01:i:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 46860
test clock-29.1329 {time parsing} {
    clock scan {2440588  1:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %p}
} 46860
test clock-29.1330 {time parsing} {
    clock scan {2440588  1:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %p}
} 46860
test clock-29.1331 {time parsing} {
    clock scan {2440588  1:01:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 46860
test clock-29.1332 {time parsing} {
    clock scan {2440588  1:i:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 46860
test clock-29.1333 {time parsing} {
    clock scan {2440588 i:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %p}
} 46860
test clock-29.1334 {time parsing} {
    clock scan {2440588 i:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %p}
} 46860
test clock-29.1335 {time parsing} {
    clock scan {2440588 i:01:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 46860
test clock-29.1336 {time parsing} {
    clock scan {2440588 i:i:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 46860
test clock-29.1337 {time parsing} {
    clock scan {2440588 i:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %p}
} 46860
test clock-29.1338 {time parsing} {
    clock scan {2440588 i:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %p}
} 46860
test clock-29.1339 {time parsing} {
    clock scan {2440588 i:01:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 46860
test clock-29.1340 {time parsing} {
    clock scan {2440588 i:i:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 46860
test clock-29.1341 {time parsing} {
    clock scan {2440588 01:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %P}
} 46860
test clock-29.1342 {time parsing} {
    clock scan {2440588 01:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %P}
} 46860
test clock-29.1343 {time parsing} {
    clock scan {2440588 01:01:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 46860
test clock-29.1344 {time parsing} {
    clock scan {2440588 01:i:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 46860
test clock-29.1345 {time parsing} {
    clock scan {2440588  1:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %P}
} 46860
test clock-29.1346 {time parsing} {
    clock scan {2440588  1:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %P}
} 46860
test clock-29.1347 {time parsing} {
    clock scan {2440588  1:01:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 46860
test clock-29.1348 {time parsing} {
    clock scan {2440588  1:i:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 46860
test clock-29.1349 {time parsing} {
    clock scan {2440588 i:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %P}
} 46860
test clock-29.1350 {time parsing} {
    clock scan {2440588 i:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %P}
} 46860
test clock-29.1351 {time parsing} {
    clock scan {2440588 i:01:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 46860
test clock-29.1352 {time parsing} {
    clock scan {2440588 i:i:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 46860
test clock-29.1353 {time parsing} {
    clock scan {2440588 i:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %P}
} 46860
test clock-29.1354 {time parsing} {
    clock scan {2440588 i:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %P}
} 46860
test clock-29.1355 {time parsing} {
    clock scan {2440588 i:01:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 46860
test clock-29.1356 {time parsing} {
    clock scan {2440588 i:i:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 46860
test clock-29.1357 {time parsing} {
    clock scan {2440588 13:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 46861
test clock-29.1358 {time parsing} {
    clock scan {2440588 13:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 46861
test clock-29.1359 {time parsing} {
    clock scan {2440588 13:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 46861
test clock-29.1360 {time parsing} {
    clock scan {2440588 13:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 46861
test clock-29.1361 {time parsing} {
    clock scan {2440588 xiii:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 46861
test clock-29.1362 {time parsing} {
    clock scan {2440588 xiii:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 46861
test clock-29.1363 {time parsing} {
    clock scan {2440588 xiii:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 46861
test clock-29.1364 {time parsing} {
    clock scan {2440588 xiii:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 46861
test clock-29.1365 {time parsing} {
    clock scan {2440588 01:01:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 46861
test clock-29.1366 {time parsing} {
    clock scan {2440588 01:i:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 46861
test clock-29.1367 {time parsing} {
    clock scan {2440588  1:01:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 46861
test clock-29.1368 {time parsing} {
    clock scan {2440588  1:i:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 46861
test clock-29.1369 {time parsing} {
    clock scan {2440588 i:01:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 46861
test clock-29.1370 {time parsing} {
    clock scan {2440588 i:i:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 46861
test clock-29.1371 {time parsing} {
    clock scan {2440588 i:01:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 46861
test clock-29.1372 {time parsing} {
    clock scan {2440588 i:i:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 46861
test clock-29.1373 {time parsing} {
    clock scan {2440588 01:01:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 46861
test clock-29.1374 {time parsing} {
    clock scan {2440588 01:i:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 46861
test clock-29.1375 {time parsing} {
    clock scan {2440588  1:01:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 46861
test clock-29.1376 {time parsing} {
    clock scan {2440588  1:i:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 46861
test clock-29.1377 {time parsing} {
    clock scan {2440588 i:01:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 46861
test clock-29.1378 {time parsing} {
    clock scan {2440588 i:i:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 46861
test clock-29.1379 {time parsing} {
    clock scan {2440588 i:01:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 46861
test clock-29.1380 {time parsing} {
    clock scan {2440588 i:i:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 46861
test clock-29.1381 {time parsing} {
    clock scan {2440588 13:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 46919
test clock-29.1382 {time parsing} {
    clock scan {2440588 13:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 46919
test clock-29.1383 {time parsing} {
    clock scan {2440588 13:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 46919
test clock-29.1384 {time parsing} {
    clock scan {2440588 13:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 46919
test clock-29.1385 {time parsing} {
    clock scan {2440588 xiii:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 46919
test clock-29.1386 {time parsing} {
    clock scan {2440588 xiii:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 46919
test clock-29.1387 {time parsing} {
    clock scan {2440588 xiii:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 46919
test clock-29.1388 {time parsing} {
    clock scan {2440588 xiii:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 46919
test clock-29.1389 {time parsing} {
    clock scan {2440588 01:01:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 46919
test clock-29.1390 {time parsing} {
    clock scan {2440588 01:i:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 46919
test clock-29.1391 {time parsing} {
    clock scan {2440588  1:01:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 46919
test clock-29.1392 {time parsing} {
    clock scan {2440588  1:i:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 46919
test clock-29.1393 {time parsing} {
    clock scan {2440588 i:01:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 46919
test clock-29.1394 {time parsing} {
    clock scan {2440588 i:i:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 46919
test clock-29.1395 {time parsing} {
    clock scan {2440588 i:01:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 46919
test clock-29.1396 {time parsing} {
    clock scan {2440588 i:i:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 46919
test clock-29.1397 {time parsing} {
    clock scan {2440588 01:01:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 46919
test clock-29.1398 {time parsing} {
    clock scan {2440588 01:i:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 46919
test clock-29.1399 {time parsing} {
    clock scan {2440588  1:01:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 46919
test clock-29.1400 {time parsing} {
    clock scan {2440588  1:i:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 46919
test clock-29.1401 {time parsing} {
    clock scan {2440588 i:01:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 46919
test clock-29.1402 {time parsing} {
    clock scan {2440588 i:i:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 46919
test clock-29.1403 {time parsing} {
    clock scan {2440588 i:01:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 46919
test clock-29.1404 {time parsing} {
    clock scan {2440588 i:i:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 46919
test clock-29.1405 {time parsing} {
    clock scan {2440588 13:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M }
} 50340
test clock-29.1406 {time parsing} {
    clock scan {2440588 13:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM }
} 50340
test clock-29.1407 {time parsing} {
    clock scan {2440588 13:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 50340
test clock-29.1408 {time parsing} {
    clock scan {2440588 13:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 50340
test clock-29.1409 {time parsing} {
    clock scan {2440588 13:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M }
} 50340
test clock-29.1410 {time parsing} {
    clock scan {2440588 13:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM }
} 50340
test clock-29.1411 {time parsing} {
    clock scan {2440588 13:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 50340
test clock-29.1412 {time parsing} {
    clock scan {2440588 13:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 50340
test clock-29.1413 {time parsing} {
    clock scan {2440588 xiii:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M }
} 50340
test clock-29.1414 {time parsing} {
    clock scan {2440588 xiii:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM }
} 50340
test clock-29.1415 {time parsing} {
    clock scan {2440588 xiii:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 50340
test clock-29.1416 {time parsing} {
    clock scan {2440588 xiii:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 50340
test clock-29.1417 {time parsing} {
    clock scan {2440588 xiii:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M }
} 50340
test clock-29.1418 {time parsing} {
    clock scan {2440588 xiii:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM }
} 50340
test clock-29.1419 {time parsing} {
    clock scan {2440588 xiii:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 50340
test clock-29.1420 {time parsing} {
    clock scan {2440588 xiii:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 50340
test clock-29.1421 {time parsing} {
    clock scan {2440588 01:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %p}
} 50340
test clock-29.1422 {time parsing} {
    clock scan {2440588 01:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %p}
} 50340
test clock-29.1423 {time parsing} {
    clock scan {2440588 01:59:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 50340
test clock-29.1424 {time parsing} {
    clock scan {2440588 01:lix:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 50340
test clock-29.1425 {time parsing} {
    clock scan {2440588  1:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %p}
} 50340
test clock-29.1426 {time parsing} {
    clock scan {2440588  1:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %p}
} 50340
test clock-29.1427 {time parsing} {
    clock scan {2440588  1:59:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 50340
test clock-29.1428 {time parsing} {
    clock scan {2440588  1:lix:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 50340
test clock-29.1429 {time parsing} {
    clock scan {2440588 i:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %p}
} 50340
test clock-29.1430 {time parsing} {
    clock scan {2440588 i:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %p}
} 50340
test clock-29.1431 {time parsing} {
    clock scan {2440588 i:59:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 50340
test clock-29.1432 {time parsing} {
    clock scan {2440588 i:lix:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 50340
test clock-29.1433 {time parsing} {
    clock scan {2440588 i:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %p}
} 50340
test clock-29.1434 {time parsing} {
    clock scan {2440588 i:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %p}
} 50340
test clock-29.1435 {time parsing} {
    clock scan {2440588 i:59:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 50340
test clock-29.1436 {time parsing} {
    clock scan {2440588 i:lix:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 50340
test clock-29.1437 {time parsing} {
    clock scan {2440588 01:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %P}
} 50340
test clock-29.1438 {time parsing} {
    clock scan {2440588 01:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %P}
} 50340
test clock-29.1439 {time parsing} {
    clock scan {2440588 01:59:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 50340
test clock-29.1440 {time parsing} {
    clock scan {2440588 01:lix:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 50340
test clock-29.1441 {time parsing} {
    clock scan {2440588  1:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %P}
} 50340
test clock-29.1442 {time parsing} {
    clock scan {2440588  1:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %P}
} 50340
test clock-29.1443 {time parsing} {
    clock scan {2440588  1:59:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 50340
test clock-29.1444 {time parsing} {
    clock scan {2440588  1:lix:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 50340
test clock-29.1445 {time parsing} {
    clock scan {2440588 i:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %P}
} 50340
test clock-29.1446 {time parsing} {
    clock scan {2440588 i:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %P}
} 50340
test clock-29.1447 {time parsing} {
    clock scan {2440588 i:59:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 50340
test clock-29.1448 {time parsing} {
    clock scan {2440588 i:lix:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 50340
test clock-29.1449 {time parsing} {
    clock scan {2440588 i:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %P}
} 50340
test clock-29.1450 {time parsing} {
    clock scan {2440588 i:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %P}
} 50340
test clock-29.1451 {time parsing} {
    clock scan {2440588 i:59:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 50340
test clock-29.1452 {time parsing} {
    clock scan {2440588 i:lix:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 50340
test clock-29.1453 {time parsing} {
    clock scan {2440588 13:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 50341
test clock-29.1454 {time parsing} {
    clock scan {2440588 13:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 50341
test clock-29.1455 {time parsing} {
    clock scan {2440588 13:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 50341
test clock-29.1456 {time parsing} {
    clock scan {2440588 13:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 50341
test clock-29.1457 {time parsing} {
    clock scan {2440588 xiii:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 50341
test clock-29.1458 {time parsing} {
    clock scan {2440588 xiii:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 50341
test clock-29.1459 {time parsing} {
    clock scan {2440588 xiii:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 50341
test clock-29.1460 {time parsing} {
    clock scan {2440588 xiii:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 50341
test clock-29.1461 {time parsing} {
    clock scan {2440588 01:59:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 50341
test clock-29.1462 {time parsing} {
    clock scan {2440588 01:lix:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 50341
test clock-29.1463 {time parsing} {
    clock scan {2440588  1:59:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 50341
test clock-29.1464 {time parsing} {
    clock scan {2440588  1:lix:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 50341
test clock-29.1465 {time parsing} {
    clock scan {2440588 i:59:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 50341
test clock-29.1466 {time parsing} {
    clock scan {2440588 i:lix:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 50341
test clock-29.1467 {time parsing} {
    clock scan {2440588 i:59:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 50341
test clock-29.1468 {time parsing} {
    clock scan {2440588 i:lix:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 50341
test clock-29.1469 {time parsing} {
    clock scan {2440588 01:59:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 50341
test clock-29.1470 {time parsing} {
    clock scan {2440588 01:lix:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 50341
test clock-29.1471 {time parsing} {
    clock scan {2440588  1:59:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 50341
test clock-29.1472 {time parsing} {
    clock scan {2440588  1:lix:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 50341
test clock-29.1473 {time parsing} {
    clock scan {2440588 i:59:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 50341
test clock-29.1474 {time parsing} {
    clock scan {2440588 i:lix:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 50341
test clock-29.1475 {time parsing} {
    clock scan {2440588 i:59:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 50341
test clock-29.1476 {time parsing} {
    clock scan {2440588 i:lix:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 50341
test clock-29.1477 {time parsing} {
    clock scan {2440588 13:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 50399
test clock-29.1478 {time parsing} {
    clock scan {2440588 13:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 50399
test clock-29.1479 {time parsing} {
    clock scan {2440588 13:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 50399
test clock-29.1480 {time parsing} {
    clock scan {2440588 13:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 50399
test clock-29.1481 {time parsing} {
    clock scan {2440588 xiii:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 50399
test clock-29.1482 {time parsing} {
    clock scan {2440588 xiii:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 50399
test clock-29.1483 {time parsing} {
    clock scan {2440588 xiii:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 50399
test clock-29.1484 {time parsing} {
    clock scan {2440588 xiii:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 50399
test clock-29.1485 {time parsing} {
    clock scan {2440588 01:59:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 50399
test clock-29.1486 {time parsing} {
    clock scan {2440588 01:lix:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 50399
test clock-29.1487 {time parsing} {
    clock scan {2440588  1:59:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 50399
test clock-29.1488 {time parsing} {
    clock scan {2440588  1:lix:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 50399
test clock-29.1489 {time parsing} {
    clock scan {2440588 i:59:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 50399
test clock-29.1490 {time parsing} {
    clock scan {2440588 i:lix:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 50399
test clock-29.1491 {time parsing} {
    clock scan {2440588 i:59:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 50399
test clock-29.1492 {time parsing} {
    clock scan {2440588 i:lix:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 50399
test clock-29.1493 {time parsing} {
    clock scan {2440588 01:59:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 50399
test clock-29.1494 {time parsing} {
    clock scan {2440588 01:lix:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 50399
test clock-29.1495 {time parsing} {
    clock scan {2440588  1:59:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 50399
test clock-29.1496 {time parsing} {
    clock scan {2440588  1:lix:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 50399
test clock-29.1497 {time parsing} {
    clock scan {2440588 i:59:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 50399
test clock-29.1498 {time parsing} {
    clock scan {2440588 i:lix:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 50399
test clock-29.1499 {time parsing} {
    clock scan {2440588 i:59:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 50399
test clock-29.1500 {time parsing} {
    clock scan {2440588 i:lix:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 50399
test clock-29.1501 {time parsing} {
    clock scan {2440588 23 } \
	-gmt true -locale en_US_roman \
	-format {%J %H }
} 82800
test clock-29.1502 {time parsing} {
    clock scan {2440588 23:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M }
} 82800
test clock-29.1503 {time parsing} {
    clock scan {2440588 23:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM }
} 82800
test clock-29.1504 {time parsing} {
    clock scan {2440588 23:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 82800
test clock-29.1505 {time parsing} {
    clock scan {2440588 23:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 82800
test clock-29.1506 {time parsing} {
    clock scan {2440588 23 } \
	-gmt true -locale en_US_roman \
	-format {%J %k }
} 82800
test clock-29.1507 {time parsing} {
    clock scan {2440588 23:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M }
} 82800
test clock-29.1508 {time parsing} {
    clock scan {2440588 23:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM }
} 82800
test clock-29.1509 {time parsing} {
    clock scan {2440588 23:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 82800
test clock-29.1510 {time parsing} {
    clock scan {2440588 23:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 82800
test clock-29.1511 {time parsing} {
    clock scan {2440588 xxiii } \
	-gmt true -locale en_US_roman \
	-format {%J %OH }
} 82800
test clock-29.1512 {time parsing} {
    clock scan {2440588 xxiii:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M }
} 82800
test clock-29.1513 {time parsing} {
    clock scan {2440588 xxiii:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM }
} 82800
test clock-29.1514 {time parsing} {
    clock scan {2440588 xxiii:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 82800
test clock-29.1515 {time parsing} {
    clock scan {2440588 xxiii:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 82800
test clock-29.1516 {time parsing} {
    clock scan {2440588 xxiii } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok }
} 82800
test clock-29.1517 {time parsing} {
    clock scan {2440588 xxiii:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M }
} 82800
test clock-29.1518 {time parsing} {
    clock scan {2440588 xxiii:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM }
} 82800
test clock-29.1519 {time parsing} {
    clock scan {2440588 xxiii:00:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 82800
test clock-29.1520 {time parsing} {
    clock scan {2440588 xxiii:?:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 82800
test clock-29.1521 {time parsing} {
    clock scan {2440588 11 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I %p}
} 82800
test clock-29.1522 {time parsing} {
    clock scan {2440588 11:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %p}
} 82800
test clock-29.1523 {time parsing} {
    clock scan {2440588 11:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %p}
} 82800
test clock-29.1524 {time parsing} {
    clock scan {2440588 11:00:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 82800
test clock-29.1525 {time parsing} {
    clock scan {2440588 11:?:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 82800
test clock-29.1526 {time parsing} {
    clock scan {2440588 11 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l %p}
} 82800
test clock-29.1527 {time parsing} {
    clock scan {2440588 11:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %p}
} 82800
test clock-29.1528 {time parsing} {
    clock scan {2440588 11:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %p}
} 82800
test clock-29.1529 {time parsing} {
    clock scan {2440588 11:00:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 82800
test clock-29.1530 {time parsing} {
    clock scan {2440588 11:?:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 82800
test clock-29.1531 {time parsing} {
    clock scan {2440588 xi PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI %p}
} 82800
test clock-29.1532 {time parsing} {
    clock scan {2440588 xi:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %p}
} 82800
test clock-29.1533 {time parsing} {
    clock scan {2440588 xi:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %p}
} 82800
test clock-29.1534 {time parsing} {
    clock scan {2440588 xi:00:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 82800
test clock-29.1535 {time parsing} {
    clock scan {2440588 xi:?:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 82800
test clock-29.1536 {time parsing} {
    clock scan {2440588 xi PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol %p}
} 82800
test clock-29.1537 {time parsing} {
    clock scan {2440588 xi:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %p}
} 82800
test clock-29.1538 {time parsing} {
    clock scan {2440588 xi:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %p}
} 82800
test clock-29.1539 {time parsing} {
    clock scan {2440588 xi:00:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 82800
test clock-29.1540 {time parsing} {
    clock scan {2440588 xi:?:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 82800
test clock-29.1541 {time parsing} {
    clock scan {2440588 11 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I %P}
} 82800
test clock-29.1542 {time parsing} {
    clock scan {2440588 11:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %P}
} 82800
test clock-29.1543 {time parsing} {
    clock scan {2440588 11:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %P}
} 82800
test clock-29.1544 {time parsing} {
    clock scan {2440588 11:00:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 82800
test clock-29.1545 {time parsing} {
    clock scan {2440588 11:?:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 82800
test clock-29.1546 {time parsing} {
    clock scan {2440588 11 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l %P}
} 82800
test clock-29.1547 {time parsing} {
    clock scan {2440588 11:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %P}
} 82800
test clock-29.1548 {time parsing} {
    clock scan {2440588 11:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %P}
} 82800
test clock-29.1549 {time parsing} {
    clock scan {2440588 11:00:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 82800
test clock-29.1550 {time parsing} {
    clock scan {2440588 11:?:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 82800
test clock-29.1551 {time parsing} {
    clock scan {2440588 xi pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI %P}
} 82800
test clock-29.1552 {time parsing} {
    clock scan {2440588 xi:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %P}
} 82800
test clock-29.1553 {time parsing} {
    clock scan {2440588 xi:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %P}
} 82800
test clock-29.1554 {time parsing} {
    clock scan {2440588 xi:00:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 82800
test clock-29.1555 {time parsing} {
    clock scan {2440588 xi:?:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 82800
test clock-29.1556 {time parsing} {
    clock scan {2440588 xi pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol %P}
} 82800
test clock-29.1557 {time parsing} {
    clock scan {2440588 xi:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %P}
} 82800
test clock-29.1558 {time parsing} {
    clock scan {2440588 xi:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %P}
} 82800
test clock-29.1559 {time parsing} {
    clock scan {2440588 xi:00:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 82800
test clock-29.1560 {time parsing} {
    clock scan {2440588 xi:?:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 82800
test clock-29.1561 {time parsing} {
    clock scan {2440588 23:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 82801
test clock-29.1562 {time parsing} {
    clock scan {2440588 23:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 82801
test clock-29.1563 {time parsing} {
    clock scan {2440588 23:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 82801
test clock-29.1564 {time parsing} {
    clock scan {2440588 23:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 82801
test clock-29.1565 {time parsing} {
    clock scan {2440588 xxiii:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 82801
test clock-29.1566 {time parsing} {
    clock scan {2440588 xxiii:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 82801
test clock-29.1567 {time parsing} {
    clock scan {2440588 xxiii:00:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 82801
test clock-29.1568 {time parsing} {
    clock scan {2440588 xxiii:?:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 82801
test clock-29.1569 {time parsing} {
    clock scan {2440588 11:00:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 82801
test clock-29.1570 {time parsing} {
    clock scan {2440588 11:?:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 82801
test clock-29.1571 {time parsing} {
    clock scan {2440588 11:00:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 82801
test clock-29.1572 {time parsing} {
    clock scan {2440588 11:?:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 82801
test clock-29.1573 {time parsing} {
    clock scan {2440588 xi:00:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 82801
test clock-29.1574 {time parsing} {
    clock scan {2440588 xi:?:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 82801
test clock-29.1575 {time parsing} {
    clock scan {2440588 xi:00:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 82801
test clock-29.1576 {time parsing} {
    clock scan {2440588 xi:?:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 82801
test clock-29.1577 {time parsing} {
    clock scan {2440588 11:00:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 82801
test clock-29.1578 {time parsing} {
    clock scan {2440588 11:?:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 82801
test clock-29.1579 {time parsing} {
    clock scan {2440588 11:00:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 82801
test clock-29.1580 {time parsing} {
    clock scan {2440588 11:?:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 82801
test clock-29.1581 {time parsing} {
    clock scan {2440588 xi:00:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 82801
test clock-29.1582 {time parsing} {
    clock scan {2440588 xi:?:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 82801
test clock-29.1583 {time parsing} {
    clock scan {2440588 xi:00:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 82801
test clock-29.1584 {time parsing} {
    clock scan {2440588 xi:?:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 82801
test clock-29.1585 {time parsing} {
    clock scan {2440588 23:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 82859
test clock-29.1586 {time parsing} {
    clock scan {2440588 23:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 82859
test clock-29.1587 {time parsing} {
    clock scan {2440588 23:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 82859
test clock-29.1588 {time parsing} {
    clock scan {2440588 23:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 82859
test clock-29.1589 {time parsing} {
    clock scan {2440588 xxiii:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 82859
test clock-29.1590 {time parsing} {
    clock scan {2440588 xxiii:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 82859
test clock-29.1591 {time parsing} {
    clock scan {2440588 xxiii:00:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 82859
test clock-29.1592 {time parsing} {
    clock scan {2440588 xxiii:?:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 82859
test clock-29.1593 {time parsing} {
    clock scan {2440588 11:00:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 82859
test clock-29.1594 {time parsing} {
    clock scan {2440588 11:?:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 82859
test clock-29.1595 {time parsing} {
    clock scan {2440588 11:00:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 82859
test clock-29.1596 {time parsing} {
    clock scan {2440588 11:?:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 82859
test clock-29.1597 {time parsing} {
    clock scan {2440588 xi:00:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 82859
test clock-29.1598 {time parsing} {
    clock scan {2440588 xi:?:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 82859
test clock-29.1599 {time parsing} {
    clock scan {2440588 xi:00:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 82859
test clock-29.1600 {time parsing} {
    clock scan {2440588 xi:?:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 82859
test clock-29.1601 {time parsing} {
    clock scan {2440588 11:00:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 82859
test clock-29.1602 {time parsing} {
    clock scan {2440588 11:?:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 82859
test clock-29.1603 {time parsing} {
    clock scan {2440588 11:00:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 82859
test clock-29.1604 {time parsing} {
    clock scan {2440588 11:?:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 82859
test clock-29.1605 {time parsing} {
    clock scan {2440588 xi:00:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 82859
test clock-29.1606 {time parsing} {
    clock scan {2440588 xi:?:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 82859
test clock-29.1607 {time parsing} {
    clock scan {2440588 xi:00:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 82859
test clock-29.1608 {time parsing} {
    clock scan {2440588 xi:?:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 82859
test clock-29.1609 {time parsing} {
    clock scan {2440588 23:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M }
} 82860
test clock-29.1610 {time parsing} {
    clock scan {2440588 23:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM }
} 82860
test clock-29.1611 {time parsing} {
    clock scan {2440588 23:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 82860
test clock-29.1612 {time parsing} {
    clock scan {2440588 23:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 82860
test clock-29.1613 {time parsing} {
    clock scan {2440588 23:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M }
} 82860
test clock-29.1614 {time parsing} {
    clock scan {2440588 23:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM }
} 82860
test clock-29.1615 {time parsing} {
    clock scan {2440588 23:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 82860
test clock-29.1616 {time parsing} {
    clock scan {2440588 23:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 82860
test clock-29.1617 {time parsing} {
    clock scan {2440588 xxiii:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M }
} 82860
test clock-29.1618 {time parsing} {
    clock scan {2440588 xxiii:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM }
} 82860
test clock-29.1619 {time parsing} {
    clock scan {2440588 xxiii:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 82860
test clock-29.1620 {time parsing} {
    clock scan {2440588 xxiii:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 82860
test clock-29.1621 {time parsing} {
    clock scan {2440588 xxiii:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M }
} 82860
test clock-29.1622 {time parsing} {
    clock scan {2440588 xxiii:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM }
} 82860
test clock-29.1623 {time parsing} {
    clock scan {2440588 xxiii:01:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 82860
test clock-29.1624 {time parsing} {
    clock scan {2440588 xxiii:i:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 82860
test clock-29.1625 {time parsing} {
    clock scan {2440588 11:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %p}
} 82860
test clock-29.1626 {time parsing} {
    clock scan {2440588 11:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %p}
} 82860
test clock-29.1627 {time parsing} {
    clock scan {2440588 11:01:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 82860
test clock-29.1628 {time parsing} {
    clock scan {2440588 11:i:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 82860
test clock-29.1629 {time parsing} {
    clock scan {2440588 11:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %p}
} 82860
test clock-29.1630 {time parsing} {
    clock scan {2440588 11:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %p}
} 82860
test clock-29.1631 {time parsing} {
    clock scan {2440588 11:01:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 82860
test clock-29.1632 {time parsing} {
    clock scan {2440588 11:i:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 82860
test clock-29.1633 {time parsing} {
    clock scan {2440588 xi:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %p}
} 82860
test clock-29.1634 {time parsing} {
    clock scan {2440588 xi:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %p}
} 82860
test clock-29.1635 {time parsing} {
    clock scan {2440588 xi:01:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 82860
test clock-29.1636 {time parsing} {
    clock scan {2440588 xi:i:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 82860
test clock-29.1637 {time parsing} {
    clock scan {2440588 xi:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %p}
} 82860
test clock-29.1638 {time parsing} {
    clock scan {2440588 xi:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %p}
} 82860
test clock-29.1639 {time parsing} {
    clock scan {2440588 xi:01:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 82860
test clock-29.1640 {time parsing} {
    clock scan {2440588 xi:i:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 82860
test clock-29.1641 {time parsing} {
    clock scan {2440588 11:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %P}
} 82860
test clock-29.1642 {time parsing} {
    clock scan {2440588 11:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %P}
} 82860
test clock-29.1643 {time parsing} {
    clock scan {2440588 11:01:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 82860
test clock-29.1644 {time parsing} {
    clock scan {2440588 11:i:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 82860
test clock-29.1645 {time parsing} {
    clock scan {2440588 11:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %P}
} 82860
test clock-29.1646 {time parsing} {
    clock scan {2440588 11:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %P}
} 82860
test clock-29.1647 {time parsing} {
    clock scan {2440588 11:01:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 82860
test clock-29.1648 {time parsing} {
    clock scan {2440588 11:i:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 82860
test clock-29.1649 {time parsing} {
    clock scan {2440588 xi:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %P}
} 82860
test clock-29.1650 {time parsing} {
    clock scan {2440588 xi:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %P}
} 82860
test clock-29.1651 {time parsing} {
    clock scan {2440588 xi:01:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 82860
test clock-29.1652 {time parsing} {
    clock scan {2440588 xi:i:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 82860
test clock-29.1653 {time parsing} {
    clock scan {2440588 xi:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %P}
} 82860
test clock-29.1654 {time parsing} {
    clock scan {2440588 xi:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %P}
} 82860
test clock-29.1655 {time parsing} {
    clock scan {2440588 xi:01:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 82860
test clock-29.1656 {time parsing} {
    clock scan {2440588 xi:i:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 82860
test clock-29.1657 {time parsing} {
    clock scan {2440588 23:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 82861
test clock-29.1658 {time parsing} {
    clock scan {2440588 23:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 82861
test clock-29.1659 {time parsing} {
    clock scan {2440588 23:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 82861
test clock-29.1660 {time parsing} {
    clock scan {2440588 23:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 82861
test clock-29.1661 {time parsing} {
    clock scan {2440588 xxiii:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 82861
test clock-29.1662 {time parsing} {
    clock scan {2440588 xxiii:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 82861
test clock-29.1663 {time parsing} {
    clock scan {2440588 xxiii:01:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 82861
test clock-29.1664 {time parsing} {
    clock scan {2440588 xxiii:i:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 82861
test clock-29.1665 {time parsing} {
    clock scan {2440588 11:01:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 82861
test clock-29.1666 {time parsing} {
    clock scan {2440588 11:i:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 82861
test clock-29.1667 {time parsing} {
    clock scan {2440588 11:01:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 82861
test clock-29.1668 {time parsing} {
    clock scan {2440588 11:i:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 82861
test clock-29.1669 {time parsing} {
    clock scan {2440588 xi:01:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 82861
test clock-29.1670 {time parsing} {
    clock scan {2440588 xi:i:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 82861
test clock-29.1671 {time parsing} {
    clock scan {2440588 xi:01:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 82861
test clock-29.1672 {time parsing} {
    clock scan {2440588 xi:i:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 82861
test clock-29.1673 {time parsing} {
    clock scan {2440588 11:01:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 82861
test clock-29.1674 {time parsing} {
    clock scan {2440588 11:i:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 82861
test clock-29.1675 {time parsing} {
    clock scan {2440588 11:01:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 82861
test clock-29.1676 {time parsing} {
    clock scan {2440588 11:i:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 82861
test clock-29.1677 {time parsing} {
    clock scan {2440588 xi:01:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 82861
test clock-29.1678 {time parsing} {
    clock scan {2440588 xi:i:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 82861
test clock-29.1679 {time parsing} {
    clock scan {2440588 xi:01:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 82861
test clock-29.1680 {time parsing} {
    clock scan {2440588 xi:i:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 82861
test clock-29.1681 {time parsing} {
    clock scan {2440588 23:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 82919
test clock-29.1682 {time parsing} {
    clock scan {2440588 23:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 82919
test clock-29.1683 {time parsing} {
    clock scan {2440588 23:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 82919
test clock-29.1684 {time parsing} {
    clock scan {2440588 23:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 82919
test clock-29.1685 {time parsing} {
    clock scan {2440588 xxiii:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 82919
test clock-29.1686 {time parsing} {
    clock scan {2440588 xxiii:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 82919
test clock-29.1687 {time parsing} {
    clock scan {2440588 xxiii:01:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 82919
test clock-29.1688 {time parsing} {
    clock scan {2440588 xxiii:i:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 82919
test clock-29.1689 {time parsing} {
    clock scan {2440588 11:01:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 82919
test clock-29.1690 {time parsing} {
    clock scan {2440588 11:i:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 82919
test clock-29.1691 {time parsing} {
    clock scan {2440588 11:01:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 82919
test clock-29.1692 {time parsing} {
    clock scan {2440588 11:i:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 82919
test clock-29.1693 {time parsing} {
    clock scan {2440588 xi:01:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 82919
test clock-29.1694 {time parsing} {
    clock scan {2440588 xi:i:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 82919
test clock-29.1695 {time parsing} {
    clock scan {2440588 xi:01:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 82919
test clock-29.1696 {time parsing} {
    clock scan {2440588 xi:i:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 82919
test clock-29.1697 {time parsing} {
    clock scan {2440588 11:01:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 82919
test clock-29.1698 {time parsing} {
    clock scan {2440588 11:i:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 82919
test clock-29.1699 {time parsing} {
    clock scan {2440588 11:01:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 82919
test clock-29.1700 {time parsing} {
    clock scan {2440588 11:i:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 82919
test clock-29.1701 {time parsing} {
    clock scan {2440588 xi:01:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 82919
test clock-29.1702 {time parsing} {
    clock scan {2440588 xi:i:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 82919
test clock-29.1703 {time parsing} {
    clock scan {2440588 xi:01:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 82919
test clock-29.1704 {time parsing} {
    clock scan {2440588 xi:i:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 82919
test clock-29.1705 {time parsing} {
    clock scan {2440588 23:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M }
} 86340
test clock-29.1706 {time parsing} {
    clock scan {2440588 23:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM }
} 86340
test clock-29.1707 {time parsing} {
    clock scan {2440588 23:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 86340
test clock-29.1708 {time parsing} {
    clock scan {2440588 23:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 86340
test clock-29.1709 {time parsing} {
    clock scan {2440588 23:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M }
} 86340
test clock-29.1710 {time parsing} {
    clock scan {2440588 23:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM }
} 86340
test clock-29.1711 {time parsing} {
    clock scan {2440588 23:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 86340
test clock-29.1712 {time parsing} {
    clock scan {2440588 23:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 86340
test clock-29.1713 {time parsing} {
    clock scan {2440588 xxiii:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M }
} 86340
test clock-29.1714 {time parsing} {
    clock scan {2440588 xxiii:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM }
} 86340
test clock-29.1715 {time parsing} {
    clock scan {2440588 xxiii:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 86340
test clock-29.1716 {time parsing} {
    clock scan {2440588 xxiii:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 86340
test clock-29.1717 {time parsing} {
    clock scan {2440588 xxiii:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M }
} 86340
test clock-29.1718 {time parsing} {
    clock scan {2440588 xxiii:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM }
} 86340
test clock-29.1719 {time parsing} {
    clock scan {2440588 xxiii:59:00 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 86340
test clock-29.1720 {time parsing} {
    clock scan {2440588 xxiii:lix:? } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 86340
test clock-29.1721 {time parsing} {
    clock scan {2440588 11:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %p}
} 86340
test clock-29.1722 {time parsing} {
    clock scan {2440588 11:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %p}
} 86340
test clock-29.1723 {time parsing} {
    clock scan {2440588 11:59:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 86340
test clock-29.1724 {time parsing} {
    clock scan {2440588 11:lix:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 86340
test clock-29.1725 {time parsing} {
    clock scan {2440588 11:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %p}
} 86340
test clock-29.1726 {time parsing} {
    clock scan {2440588 11:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %p}
} 86340
test clock-29.1727 {time parsing} {
    clock scan {2440588 11:59:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 86340
test clock-29.1728 {time parsing} {
    clock scan {2440588 11:lix:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 86340
test clock-29.1729 {time parsing} {
    clock scan {2440588 xi:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %p}
} 86340
test clock-29.1730 {time parsing} {
    clock scan {2440588 xi:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %p}
} 86340
test clock-29.1731 {time parsing} {
    clock scan {2440588 xi:59:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 86340
test clock-29.1732 {time parsing} {
    clock scan {2440588 xi:lix:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 86340
test clock-29.1733 {time parsing} {
    clock scan {2440588 xi:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %p}
} 86340
test clock-29.1734 {time parsing} {
    clock scan {2440588 xi:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %p}
} 86340
test clock-29.1735 {time parsing} {
    clock scan {2440588 xi:59:00 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 86340
test clock-29.1736 {time parsing} {
    clock scan {2440588 xi:lix:? PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 86340
test clock-29.1737 {time parsing} {
    clock scan {2440588 11:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M %P}
} 86340
test clock-29.1738 {time parsing} {
    clock scan {2440588 11:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM %P}
} 86340
test clock-29.1739 {time parsing} {
    clock scan {2440588 11:59:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 86340
test clock-29.1740 {time parsing} {
    clock scan {2440588 11:lix:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 86340
test clock-29.1741 {time parsing} {
    clock scan {2440588 11:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M %P}
} 86340
test clock-29.1742 {time parsing} {
    clock scan {2440588 11:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM %P}
} 86340
test clock-29.1743 {time parsing} {
    clock scan {2440588 11:59:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 86340
test clock-29.1744 {time parsing} {
    clock scan {2440588 11:lix:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 86340
test clock-29.1745 {time parsing} {
    clock scan {2440588 xi:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M %P}
} 86340
test clock-29.1746 {time parsing} {
    clock scan {2440588 xi:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM %P}
} 86340
test clock-29.1747 {time parsing} {
    clock scan {2440588 xi:59:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 86340
test clock-29.1748 {time parsing} {
    clock scan {2440588 xi:lix:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 86340
test clock-29.1749 {time parsing} {
    clock scan {2440588 xi:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M %P}
} 86340
test clock-29.1750 {time parsing} {
    clock scan {2440588 xi:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM %P}
} 86340
test clock-29.1751 {time parsing} {
    clock scan {2440588 xi:59:00 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 86340
test clock-29.1752 {time parsing} {
    clock scan {2440588 xi:lix:? pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 86340
test clock-29.1753 {time parsing} {
    clock scan {2440588 23:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 86341
test clock-29.1754 {time parsing} {
    clock scan {2440588 23:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 86341
test clock-29.1755 {time parsing} {
    clock scan {2440588 23:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 86341
test clock-29.1756 {time parsing} {
    clock scan {2440588 23:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 86341
test clock-29.1757 {time parsing} {
    clock scan {2440588 xxiii:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 86341
test clock-29.1758 {time parsing} {
    clock scan {2440588 xxiii:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 86341
test clock-29.1759 {time parsing} {
    clock scan {2440588 xxiii:59:01 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 86341
test clock-29.1760 {time parsing} {
    clock scan {2440588 xxiii:lix:i } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 86341
test clock-29.1761 {time parsing} {
    clock scan {2440588 11:59:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 86341
test clock-29.1762 {time parsing} {
    clock scan {2440588 11:lix:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 86341
test clock-29.1763 {time parsing} {
    clock scan {2440588 11:59:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 86341
test clock-29.1764 {time parsing} {
    clock scan {2440588 11:lix:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 86341
test clock-29.1765 {time parsing} {
    clock scan {2440588 xi:59:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 86341
test clock-29.1766 {time parsing} {
    clock scan {2440588 xi:lix:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 86341
test clock-29.1767 {time parsing} {
    clock scan {2440588 xi:59:01 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 86341
test clock-29.1768 {time parsing} {
    clock scan {2440588 xi:lix:i PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 86341
test clock-29.1769 {time parsing} {
    clock scan {2440588 11:59:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 86341
test clock-29.1770 {time parsing} {
    clock scan {2440588 11:lix:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 86341
test clock-29.1771 {time parsing} {
    clock scan {2440588 11:59:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 86341
test clock-29.1772 {time parsing} {
    clock scan {2440588 11:lix:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 86341
test clock-29.1773 {time parsing} {
    clock scan {2440588 xi:59:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 86341
test clock-29.1774 {time parsing} {
    clock scan {2440588 xi:lix:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 86341
test clock-29.1775 {time parsing} {
    clock scan {2440588 xi:59:01 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 86341
test clock-29.1776 {time parsing} {
    clock scan {2440588 xi:lix:i pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 86341
test clock-29.1777 {time parsing} {
    clock scan {2440588 23:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%M:%S }
} 86399
test clock-29.1778 {time parsing} {
    clock scan {2440588 23:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %H:%OM:%OS }
} 86399
test clock-29.1779 {time parsing} {
    clock scan {2440588 23:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%M:%S }
} 86399
test clock-29.1780 {time parsing} {
    clock scan {2440588 23:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %k:%OM:%OS }
} 86399
test clock-29.1781 {time parsing} {
    clock scan {2440588 xxiii:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%M:%S }
} 86399
test clock-29.1782 {time parsing} {
    clock scan {2440588 xxiii:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %OH:%OM:%OS }
} 86399
test clock-29.1783 {time parsing} {
    clock scan {2440588 xxiii:59:59 } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%M:%S }
} 86399
test clock-29.1784 {time parsing} {
    clock scan {2440588 xxiii:lix:lix } \
	-gmt true -locale en_US_roman \
	-format {%J %Ok:%OM:%OS }
} 86399
test clock-29.1785 {time parsing} {
    clock scan {2440588 11:59:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %p}
} 86399
test clock-29.1786 {time parsing} {
    clock scan {2440588 11:lix:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %p}
} 86399
test clock-29.1787 {time parsing} {
    clock scan {2440588 11:59:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %p}
} 86399
test clock-29.1788 {time parsing} {
    clock scan {2440588 11:lix:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %p}
} 86399
test clock-29.1789 {time parsing} {
    clock scan {2440588 xi:59:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %p}
} 86399
test clock-29.1790 {time parsing} {
    clock scan {2440588 xi:lix:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %p}
} 86399
test clock-29.1791 {time parsing} {
    clock scan {2440588 xi:59:59 PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %p}
} 86399
test clock-29.1792 {time parsing} {
    clock scan {2440588 xi:lix:lix PM} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %p}
} 86399
test clock-29.1793 {time parsing} {
    clock scan {2440588 11:59:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%M:%S %P}
} 86399
test clock-29.1794 {time parsing} {
    clock scan {2440588 11:lix:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %I:%OM:%OS %P}
} 86399
test clock-29.1795 {time parsing} {
    clock scan {2440588 11:59:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%M:%S %P}
} 86399
test clock-29.1796 {time parsing} {
    clock scan {2440588 11:lix:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %l:%OM:%OS %P}
} 86399
test clock-29.1797 {time parsing} {
    clock scan {2440588 xi:59:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%M:%S %P}
} 86399
test clock-29.1798 {time parsing} {
    clock scan {2440588 xi:lix:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %OI:%OM:%OS %P}
} 86399
test clock-29.1799 {time parsing} {
    clock scan {2440588 xi:59:59 pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%M:%S %P}
} 86399
test clock-29.1800 {time parsing} {
    clock scan {2440588 xi:lix:lix pm} \
	-gmt true -locale en_US_roman \
	-format {%J %Ol:%OM:%OS %P}
} 86399

test clock-29.1811 {parsing of several localized formats} {
    set res {}
    foreach loc {en de fr} {
	foreach fmt {"%x %X" "%X %x"} {
	    lappend res [clock scan \
35779
35780
35781
35782
35783
35784
35785
35786
35787
35788
35789
35790
35791
35792
35793
35794
35795
35796
35797
35798
35799
35800
35801
35802
35803
35804
35805
35806
35807
35808
35809
35810
35811
35812
35813
    set f1 [clock add $t 0 weekdays]
    set x1 [clock format $f1 -format {%Y-%m-%d}]
} {2016-02-27}
test clock-30.30 {clock add weekdays and back} -body {
    set n [clock seconds]
    # we start on each day of the week
    for {set i 0} {$i < 7} {incr i} {
        set start  [clock add $n $i days]
        set startu [clock format $start -format %u]
        # add 0 - 100 weekdays
        for {set j 0} {$j < 100} {incr j} {
            set forth [clock add $start $j weekdays]
            set back  [clock add $forth -$j weekdays]
            # If $s was a weekday or $j was 0, $b must be the same day.
            # Otherwise, $b must be the immediately preceeding Friday
            set fail 0
            if {$j == 0 || $startu < 6} {
                if {$start != $back} { set fail 1}
            } else {
                set friday [clock add $start -[expr {$startu % 5}] days]
                if {$friday != $back} { set fail 1 }
            }
            if {$fail} {
                set sdate [clock format $start -format {%Y-%m-%d}]
                set bdate [clock format $back  -format {%Y-%m-%d}]
                return "$sdate + $j - $j := $bdate"
            }
        }
    }
    return "OK"
} -result {OK}
test clock-30.31 {regression test - add no int overflow} {
    list \
      [list \
	[clock add 0 1600000000 seconds 24856 days -gmt 1] \







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







35779
35780
35781
35782
35783
35784
35785
35786
35787
35788
35789
35790
35791
35792
35793
35794
35795
35796
35797
35798
35799
35800
35801
35802
35803
35804
35805
35806
35807
35808
35809
35810
35811
35812
35813
    set f1 [clock add $t 0 weekdays]
    set x1 [clock format $f1 -format {%Y-%m-%d}]
} {2016-02-27}
test clock-30.30 {clock add weekdays and back} -body {
    set n [clock seconds]
    # we start on each day of the week
    for {set i 0} {$i < 7} {incr i} {
	set start  [clock add $n $i days]
	set startu [clock format $start -format %u]
	# add 0 - 100 weekdays
	for {set j 0} {$j < 100} {incr j} {
	    set forth [clock add $start $j weekdays]
	    set back  [clock add $forth -$j weekdays]
	    # If $s was a weekday or $j was 0, $b must be the same day.
	    # Otherwise, $b must be the immediately preceeding Friday
	    set fail 0
	    if {$j == 0 || $startu < 6} {
		if {$start != $back} { set fail 1}
	    } else {
		set friday [clock add $start -[expr {$startu % 5}] days]
		if {$friday != $back} { set fail 1 }
	    }
	    if {$fail} {
		set sdate [clock format $start -format {%Y-%m-%d}]
		set bdate [clock format $back  -format {%Y-%m-%d}]
		return "$sdate + $j - $j := $bdate"
	    }
	}
    }
    return "OK"
} -result {OK}
test clock-30.31 {regression test - add no int overflow} {
    list \
      [list \
	[clock add 0 1600000000 seconds 24856 days -gmt 1] \
36032
36033
36034
36035
36036
36037
36038
36039
36040
36041
36042
36043
36044
36045
36046
test clock-32.1 {scan/format across the Gregorian change} {
    set problems {}
    set t [expr { wide(-6857395200) }]
    foreach d {       1  2 14 15 16
	       17 18 19 20 21 22 23
	       24 25 26 27 28 29 30 } \
	j {         245 246 258 259 260
            261 262 263 264 265 266 267
	    268 269 270 271 272 273 274 } {
	set u [format 1752-09-%02d $d]
	set s [clock format $t -format %Y-%m-%d \
		   -locale en_US_roman -timezone :UTC]
	if { $s ne $u } {
	    append problems "formatting $t: $s should be $u\n"
	}







|







36032
36033
36034
36035
36036
36037
36038
36039
36040
36041
36042
36043
36044
36045
36046
test clock-32.1 {scan/format across the Gregorian change} {
    set problems {}
    set t [expr { wide(-6857395200) }]
    foreach d {       1  2 14 15 16
	       17 18 19 20 21 22 23
	       24 25 26 27 28 29 30 } \
	j {         245 246 258 259 260
	    261 262 263 264 265 266 267
	    268 269 270 271 272 273 274 } {
	set u [format 1752-09-%02d $d]
	set s [clock format $t -format %Y-%m-%d \
		   -locale en_US_roman -timezone :UTC]
	if { $s ne $u } {
	    append problems "formatting $t: $s should be $u\n"
	}
36555
36556
36557
36558
36559
36560
36561
36562
36563
36564
36565
36566
36567
36568
36569
36570
36571
36572
36573
36574
36575
36576
36577
36578
36579
36580
36581
36582
36583
    clock format [clock scan "next thursday" -base [clock scan 20000112]] \
	    -format {%b %d, %Y}
} "Jan 20, 2000"
test clock-34.40.1 {clock scan, ordinal month after relative date} {
    # This will fail without the bug fix (clock.tcl), as still missing
    # month/julian day conversion before ordinal month increment
    clock format [ \
        clock scan "5 years 18 months 387 days" -base 0 -gmt 1
    ] -format {%a, %b %d, %Y} -gmt 1 -locale en_US_roman
} "Sat, Jul 23, 1977"
test clock-34.40.2 {clock scan, ordinal month after relative date} {
    # This will fail without the bug fix (clock.tcl), as still missing
    # month/julian day conversion before ordinal month increment
    clock format [ \
        clock scan "5 years 18 months 387 days next Jan" -base 0 -gmt 1
    ] -format {%a, %b %d, %Y} -gmt 1 -locale en_US_roman
} "Mon, Jan 23, 1978"
test clock-34.40.3 {clock scan, day of week after ordinal date} {
    # This will fail without the bug fix (clock.tcl), because the relative
    # week day should be applied after whole date conversion
    clock format [ \
        clock scan "5 years 18 months 387 days next January Fri" -base 0 -gmt 1
    ] -format {%a, %b %d, %Y} -gmt 1 -locale en_US_roman
} "Fri, Jan 27, 1978"

# weekday specification and base.
test clock-34.41 {2nd monday in november} {
    set res {}
    foreach i {91 92 93 94 95 96} {







|






|






|







36555
36556
36557
36558
36559
36560
36561
36562
36563
36564
36565
36566
36567
36568
36569
36570
36571
36572
36573
36574
36575
36576
36577
36578
36579
36580
36581
36582
36583
    clock format [clock scan "next thursday" -base [clock scan 20000112]] \
	    -format {%b %d, %Y}
} "Jan 20, 2000"
test clock-34.40.1 {clock scan, ordinal month after relative date} {
    # This will fail without the bug fix (clock.tcl), as still missing
    # month/julian day conversion before ordinal month increment
    clock format [ \
	clock scan "5 years 18 months 387 days" -base 0 -gmt 1
    ] -format {%a, %b %d, %Y} -gmt 1 -locale en_US_roman
} "Sat, Jul 23, 1977"
test clock-34.40.2 {clock scan, ordinal month after relative date} {
    # This will fail without the bug fix (clock.tcl), as still missing
    # month/julian day conversion before ordinal month increment
    clock format [ \
	clock scan "5 years 18 months 387 days next Jan" -base 0 -gmt 1
    ] -format {%a, %b %d, %Y} -gmt 1 -locale en_US_roman
} "Mon, Jan 23, 1978"
test clock-34.40.3 {clock scan, day of week after ordinal date} {
    # This will fail without the bug fix (clock.tcl), because the relative
    # week day should be applied after whole date conversion
    clock format [ \
	clock scan "5 years 18 months 387 days next January Fri" -base 0 -gmt 1
    ] -format {%a, %b %d, %Y} -gmt 1 -locale en_US_roman
} "Fri, Jan 27, 1978"

# weekday specification and base.
test clock-34.41 {2nd monday in november} {
    set res {}
    foreach i {91 92 93 94 95 96} {
36760
36761
36762
36763
36764
36765
36766
36767
36768
36769
36770
36771
36772
36773
36774
36775
36776
36777
36778
36779
36780
36781
36782
36783
36784
36785
36786
36787
36788
36789
36790
36791
36792
36793
36794
36795
36796
36797
36798
36799
36800
36801
36802
36803
36804
36805
36806
36807
36808
36809
36810
} {{2016-03-27 01:00:00 CET} {2016-03-27 03:00:00 CEST}}

test clock-34.70.1 {check date in DST-hole: daylight switch CET -> CEST} {
    set res {}
    # forwards
    set base 1459033200
    for {set i 0} {$i <= 3} {incr i} {
    	set d [clock scan "+$i hour" -base $base -timezone CET]
    	lappend res "$d = [clock format $d -timezone CET -format {%Y-%m-%d %H:%M:%S %Z}]"
    }
    lappend res "#--"
    # backwards
    set base 1459044000
    for {set i 0} {$i <= 3} {incr i} {
    	set d [clock scan "-$i hour" -base $base -timezone CET]
    	lappend res "$d = [clock format $d -timezone CET -format {%Y-%m-%d %H:%M:%S %Z}]"
    }
    set res
} [split [regsub -all {^\n|\n$} {
1459033200 = 2016-03-27 00:00:00 CET
1459036800 = 2016-03-27 01:00:00 CET
1459040400 = 2016-03-27 03:00:00 CEST
1459044000 = 2016-03-27 04:00:00 CEST
#--
1459044000 = 2016-03-27 04:00:00 CEST
1459040400 = 2016-03-27 03:00:00 CEST
1459036800 = 2016-03-27 01:00:00 CET
1459033200 = 2016-03-27 00:00:00 CET
} {}] \n]

test clock-34.70.2 {check date in DST-hole: daylight switch CEST -> CET} {
    set res {}
    # forwards
    set base 1477782000
    for {set i 0} {$i <= 3} {incr i} {
    	set d [clock scan "+$i hour" -base $base -timezone CET]
    	lappend res "$d = [clock format $d -timezone CET -format {%Y-%m-%d %H:%M:%S %Z}]"
    }
    lappend res "#--"
    # backwards
    set base 1477792800
    for {set i 0} {$i <= 3} {incr i} {
    	set d [clock scan "-$i hour" -base $base -timezone CET]
    	lappend res "$d = [clock format $d -timezone CET -format {%Y-%m-%d %H:%M:%S %Z}]"
    }
    set res
} [split [regsub -all {^\n|\n$} {
1477782000 = 2016-10-30 01:00:00 CEST
1477785600 = 2016-10-30 02:00:00 CEST
1477789200 = 2016-10-30 02:00:00 CET
1477792800 = 2016-10-30 03:00:00 CET







|
|





|
|



















|
|





|
|







36760
36761
36762
36763
36764
36765
36766
36767
36768
36769
36770
36771
36772
36773
36774
36775
36776
36777
36778
36779
36780
36781
36782
36783
36784
36785
36786
36787
36788
36789
36790
36791
36792
36793
36794
36795
36796
36797
36798
36799
36800
36801
36802
36803
36804
36805
36806
36807
36808
36809
36810
} {{2016-03-27 01:00:00 CET} {2016-03-27 03:00:00 CEST}}

test clock-34.70.1 {check date in DST-hole: daylight switch CET -> CEST} {
    set res {}
    # forwards
    set base 1459033200
    for {set i 0} {$i <= 3} {incr i} {
	set d [clock scan "+$i hour" -base $base -timezone CET]
	lappend res "$d = [clock format $d -timezone CET -format {%Y-%m-%d %H:%M:%S %Z}]"
    }
    lappend res "#--"
    # backwards
    set base 1459044000
    for {set i 0} {$i <= 3} {incr i} {
	set d [clock scan "-$i hour" -base $base -timezone CET]
	lappend res "$d = [clock format $d -timezone CET -format {%Y-%m-%d %H:%M:%S %Z}]"
    }
    set res
} [split [regsub -all {^\n|\n$} {
1459033200 = 2016-03-27 00:00:00 CET
1459036800 = 2016-03-27 01:00:00 CET
1459040400 = 2016-03-27 03:00:00 CEST
1459044000 = 2016-03-27 04:00:00 CEST
#--
1459044000 = 2016-03-27 04:00:00 CEST
1459040400 = 2016-03-27 03:00:00 CEST
1459036800 = 2016-03-27 01:00:00 CET
1459033200 = 2016-03-27 00:00:00 CET
} {}] \n]

test clock-34.70.2 {check date in DST-hole: daylight switch CEST -> CET} {
    set res {}
    # forwards
    set base 1477782000
    for {set i 0} {$i <= 3} {incr i} {
	set d [clock scan "+$i hour" -base $base -timezone CET]
	lappend res "$d = [clock format $d -timezone CET -format {%Y-%m-%d %H:%M:%S %Z}]"
    }
    lappend res "#--"
    # backwards
    set base 1477792800
    for {set i 0} {$i <= 3} {incr i} {
	set d [clock scan "-$i hour" -base $base -timezone CET]
	lappend res "$d = [clock format $d -timezone CET -format {%Y-%m-%d %H:%M:%S %Z}]"
    }
    set res
} [split [regsub -all {^\n|\n$} {
1477782000 = 2016-10-30 01:00:00 CEST
1477785600 = 2016-10-30 02:00:00 CEST
1477789200 = 2016-10-30 02:00:00 CET
1477792800 = 2016-10-30 03:00:00 CET
36893
36894
36895
36896
36897
36898
36899
36900
36901
36902
36903
36904
36905
36906
36907
36908
36909
36910
36911
36912
36913
36914
36915
36916
36917
36918
36919
36920
36921
36922
36923
36924
36925
36926
36927
36928
36929
36930
36931
36932
36933
36934
36935
36936
36937
36938
36939
36940
36941
36942
36943
36944
    } \
    -result {01:00:00}

test clock-38.2 {make sure TZ is not cached after unset} \
    -setup {
	if { [info exists env(TZ)] } {
	    set oldTZ $env(TZ)
            unset env(TZ)
	}
	if { [info exists env(TCL_TZ)] } {
	    set oldTCLTZ $env(TCL_TZ)
            unset env(TCL_TZ)
	}
    } \
    -body {
        set t1 [clock format 0]
        # a time zone that is unlikely to anywhere
        set env(TZ) "+04:20"
        set t2 [clock format 0]
        unset env(TZ)
        set t3 [clock format 0]
        expr {$t1 eq $t3 && $t1 ne $t2}
    } \
    -cleanup {
        if { [info exists oldTZ] } {
            set env(TZ) $oldTZ
            unset oldTZ
        }
        if { [info exists oldTclTZ] } {
            set env(TCL_TZ) $oldTclTZ
            unset oldTclTZ
        }
    } \
    -result 1

test clock-38.3sc {ensure cache of base is correct for :localtime if TZ-env changing / scan} \
    -setup {
	if { [info exists env(TZ)] } {
	    set oldTZ $env(TZ)
	}
    } \
    -body {
	set res {}
	foreach env(TZ) {GMT-11:30 GMT-07:30 GMT-03:30 GMT} \
	        i {{07:30:00} {03:30:00} {23:30:00} {20:00:00}} \
	{
	    lappend res [clock scan $i -format "%H:%M:%S" -base [expr {20*60*60}] -timezone :localtime]
	}
	set res
    } \
    -cleanup {
	if { [info exists oldTZ] } {







|



|



|
|
|
|
|
|
|


|
|
|
|
|
|
|
|












|







36893
36894
36895
36896
36897
36898
36899
36900
36901
36902
36903
36904
36905
36906
36907
36908
36909
36910
36911
36912
36913
36914
36915
36916
36917
36918
36919
36920
36921
36922
36923
36924
36925
36926
36927
36928
36929
36930
36931
36932
36933
36934
36935
36936
36937
36938
36939
36940
36941
36942
36943
36944
    } \
    -result {01:00:00}

test clock-38.2 {make sure TZ is not cached after unset} \
    -setup {
	if { [info exists env(TZ)] } {
	    set oldTZ $env(TZ)
	    unset env(TZ)
	}
	if { [info exists env(TCL_TZ)] } {
	    set oldTCLTZ $env(TCL_TZ)
	    unset env(TCL_TZ)
	}
    } \
    -body {
	set t1 [clock format 0]
	# a time zone that is unlikely to anywhere
	set env(TZ) "+04:20"
	set t2 [clock format 0]
	unset env(TZ)
	set t3 [clock format 0]
	expr {$t1 eq $t3 && $t1 ne $t2}
    } \
    -cleanup {
	if { [info exists oldTZ] } {
	    set env(TZ) $oldTZ
	    unset oldTZ
	}
	if { [info exists oldTclTZ] } {
	    set env(TCL_TZ) $oldTclTZ
	    unset oldTclTZ
	}
    } \
    -result 1

test clock-38.3sc {ensure cache of base is correct for :localtime if TZ-env changing / scan} \
    -setup {
	if { [info exists env(TZ)] } {
	    set oldTZ $env(TZ)
	}
    } \
    -body {
	set res {}
	foreach env(TZ) {GMT-11:30 GMT-07:30 GMT-03:30 GMT} \
		i {{07:30:00} {03:30:00} {23:30:00} {20:00:00}} \
	{
	    lappend res [clock scan $i -format "%H:%M:%S" -base [expr {20*60*60}] -timezone :localtime]
	}
	set res
    } \
    -cleanup {
	if { [info exists oldTZ] } {
37554
37555
37556
37557
37558
37559
37560
37561
37562
37563
37564
37565
37566
37567
37568
37569
37570
37571
37572
37573
37574
37575
37576
37577
37578
37579
37580
37581
37582
37583
37584
37585
37586
37587
37588
37589
37590
} {01:59:59 01:59:59 03:00:00 03:00:00}

test clock-52.2 {correct conversion of times in Europe} {
   # [Bug 2207436]
   set result {}
   foreach t [list 1206838799 1206838800 1224982799 1224982800] {
       lappend result [clock format $t -format %H:%M:%S \
                           -timezone MET-1METDST]
       lappend result [clock format $t -format %H:%M:%S \
                           -timezone MET0METDST]
   }
   set result
} {01:59:59 00:59:59 03:00:00 02:00:00 02:59:59 01:59:59 02:00:00 01:00:00}

test clock-52.3 {correct conversion of times in Russia} {
   # [Bug 2207436]
   set result {}
   foreach t [list 1206799199 1206799200 1224943199 1224943200] {
       lappend result [clock format $t -format %H:%M:%S \
                           -timezone WST-12WSTDST]
   }
   set result
} {01:59:59 03:00:00 02:59:59 02:00:00}

test clock-52.4 {correct conversion of times in USA} {
   # [Bug 2207436]
   set result {}
   foreach t [list 1268549999 1268550000 1257055199 1257055200] {
       lappend result [clock format $t -format %H:%M:%S \
                           -timezone EST5EDT]
   }
   set result
} {01:59:59 03:00:00 01:59:59 01:00:00}

# Regression test for Bug # 1505383

test clock-53.1 {%EC %Ey} {







|

|









|









|







37554
37555
37556
37557
37558
37559
37560
37561
37562
37563
37564
37565
37566
37567
37568
37569
37570
37571
37572
37573
37574
37575
37576
37577
37578
37579
37580
37581
37582
37583
37584
37585
37586
37587
37588
37589
37590
} {01:59:59 01:59:59 03:00:00 03:00:00}

test clock-52.2 {correct conversion of times in Europe} {
   # [Bug 2207436]
   set result {}
   foreach t [list 1206838799 1206838800 1224982799 1224982800] {
       lappend result [clock format $t -format %H:%M:%S \
			   -timezone MET-1METDST]
       lappend result [clock format $t -format %H:%M:%S \
			   -timezone MET0METDST]
   }
   set result
} {01:59:59 00:59:59 03:00:00 02:00:00 02:59:59 01:59:59 02:00:00 01:00:00}

test clock-52.3 {correct conversion of times in Russia} {
   # [Bug 2207436]
   set result {}
   foreach t [list 1206799199 1206799200 1224943199 1224943200] {
       lappend result [clock format $t -format %H:%M:%S \
			   -timezone WST-12WSTDST]
   }
   set result
} {01:59:59 03:00:00 02:59:59 02:00:00}

test clock-52.4 {correct conversion of times in USA} {
   # [Bug 2207436]
   set result {}
   foreach t [list 1268549999 1268550000 1257055199 1257055200] {
       lappend result [clock format $t -format %H:%M:%S \
			   -timezone EST5EDT]
   }
   set result
} {01:59:59 03:00:00 01:59:59 01:00:00}

# Regression test for Bug # 1505383

test clock-53.1 {%EC %Ey} {
37748
37749
37750
37751
37752
37753
37754
37755
37756
37757
37758
37759
37760
37761
37762
37763
37764
37765
37766
37767
37768
37769
37770
37771
37772
37773
37774
37775
37776
37777
37778
37779
37780
37781
37782
37783
37784
37785
37786
37787
37788
37789
37790
37791
37792
37793
37794
37795
37796
37797
37798
37799
37800
37801
37802
37803
37804
37805
37806
37807
37808
37809
37810
37811
37812
37813
37814
37815
37816
37817
37818
37819
37820
37821
37822
37823
37824
37825
37826
37827
37828
37829
37830
37831
37832
37833
37834
37835
37836
37837
37838
37839
37840
37841
37842
37843
37844
37845
37846
37847
37848
37849
37850
37851
37852
37853
37854
37855
37856
37857
37858
37859
37860
37861
37862
37863
37864
37865
37866
37867
37868
37869
37870
37871
37872
37873
37874
37875
37876
37877
37878
37879
37880
37881
37882
37883
37884
37885
37886
37887
37888
37889
37890
37891
37892
37893
37894
37895
37896
37897
37898
37899
37900
37901
37902
37903
37904
37905
37906
37907
37908
37909
37910
37911
37912
37913
37914
37915
37916
37917
37918
37919
37920
37921
37922
37923
37924
37925
37926
37927
37928
37929
37930
37931
37932
37933
37934
37935
37936
37937
37938
37939
37940
37941
37942
    -setup {
	clock format [clock seconds]
	set tzdir [makeDirectory zoneinfo]
	set tzdir2 [makeDirectory Test $tzdir]
	set tzfile [makeFile {} TijuanaTwo $tzdir2]
	set f [open $tzfile wb]
	puts -nonewline $f [binary format c* {
            0x54 0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
            0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x06 0x00 0x00
            0x00 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x95 0x00 0x00 0x00
            0x06 0x00 0x00 0x00 0x18 0xa5 0xb6 0xf6 0x80 0xa9 0x79 0x4f 0x70
            0xaf 0xf2 0x7c 0xf0 0xb6 0x66 0x64 0x70 0xb7 0x1b 0x10 0x00 0xb8
            0x0a 0xf2 0xf0 0xcb 0xea 0x8d 0x80 0xd2 0x23 0xf4 0x70 0xd2 0x99
            0xba 0x70 0xd7 0x1b 0x59 0x00 0xd8 0x91 0xb4 0xf0 0xe2 0x7e 0x59
            0xa0 0xe3 0x49 0x52 0x90 0xe4 0x5e 0x3b 0xa0 0xe5 0x29 0x34 0x90
            0xe6 0x47 0x58 0x20 0xe7 0x12 0x51 0x10 0xe8 0x27 0x3a 0x20 0xe8
            0xf2 0x33 0x10 0xea 0x07 0x1c 0x20 0xea 0xd2 0x15 0x10 0xeb 0xe6
            0xfe 0x20 0xec 0xb1 0xf7 0x10 0xed 0xc6 0xe0 0x20 0xee 0x91 0xd9
            0x10 0x0b 0xe0 0xaf 0xa0 0x0c 0xd9 0xcd 0x10 0x0d 0xc0 0x91 0xa0
            0x0e 0xb9 0xaf 0x10 0x0f 0xa9 0xae 0x20 0x10 0x99 0x91 0x10 0x11
            0x89 0x90 0x20 0x12 0x79 0x73 0x10 0x13 0x69 0x72 0x20 0x14 0x59
            0x55 0x10 0x15 0x49 0x54 0x20 0x16 0x39 0x37 0x10 0x17 0x29 0x36
            0x20 0x18 0x22 0x53 0x90 0x19 0x09 0x18 0x20 0x1a 0x02 0x35 0x90
            0x1a 0xf2 0x34 0xa0 0x1b 0xe2 0x17 0x90 0x1c 0xd2 0x16 0xa0 0x1d
            0xc1 0xf9 0x90 0x1e 0xb1 0xf8 0xa0 0x1f 0xa1 0xdb 0x90 0x20 0x76
            0x2b 0x20 0x21 0x81 0xbd 0x90 0x22 0x56 0x0d 0x20 0x23 0x6a 0xda
            0x10 0x24 0x35 0xef 0x20 0x25 0x4a 0xbc 0x10 0x26 0x15 0xd1 0x20
            0x27 0x2a 0x9e 0x10 0x27 0xfe 0xed 0xa0 0x29 0x0a 0x80 0x10 0x29
            0xde 0xcf 0xa0 0x2a 0xea 0x62 0x10 0x2b 0xbe 0xb1 0xa0 0x2c 0xd3
            0x7e 0x90 0x2d 0x9e 0x93 0xa0 0x2e 0xb3 0x60 0x90 0x2f 0x7e 0x75
            0xa0 0x30 0x93 0x42 0x90 0x31 0x67 0x92 0x20 0x32 0x73 0x24 0x90
            0x33 0x47 0x74 0x20 0x34 0x53 0x06 0x90 0x35 0x27 0x56 0x20 0x36
            0x32 0xe8 0x90 0x37 0x07 0x38 0x20 0x38 0x1c 0x05 0x10 0x38 0xe7
            0x1a 0x20 0x39 0xfb 0xe7 0x10 0x3a 0xc6 0xfc 0x20 0x3b 0xdb 0xc9
            0x10 0x3c 0xb0 0x18 0xa0 0x3d 0xbb 0xab 0x10 0x3e 0x8f 0xfa 0xa0
            0x3f 0x9b 0x8d 0x10 0x40 0x6f 0xdc 0xa0 0x41 0x84 0xa9 0x90 0x42
            0x4f 0xbe 0xa0 0x43 0x64 0x8b 0x90 0x44 0x2f 0xa0 0xa0 0x45 0x44
            0x6d 0x90 0x46 0x0f 0x82 0xa0 0x47 0x24 0x4f 0x90 0x47 0xf8 0x9f
            0x20 0x49 0x04 0x31 0x90 0x49 0xd8 0x81 0x20 0x4a 0xe4 0x13 0x90
            0x4b 0xb8 0x63 0x20 0x4c 0xcd 0x30 0x10 0x4d 0x98 0x45 0x20 0x4e
            0xad 0x12 0x10 0x4f 0x78 0x27 0x20 0x50 0x8c 0xf4 0x10 0x51 0x61
            0x43 0xa0 0x52 0x6c 0xd6 0x10 0x53 0x41 0x25 0xa0 0x54 0x4c 0xb8
            0x10 0x55 0x21 0x07 0xa0 0x56 0x2c 0x9a 0x10 0x57 0x00 0xe9 0xa0
            0x58 0x15 0xb6 0x90 0x58 0xe0 0xcb 0xa0 0x59 0xf5 0x98 0x90 0x5a
            0xc0 0xad 0xa0 0x5b 0xd5 0x7a 0x90 0x5c 0xa9 0xca 0x20 0x5d 0xb5
            0x5c 0x90 0x5e 0x89 0xac 0x20 0x5f 0x95 0x3e 0x90 0x60 0x69 0x8e
            0x20 0x61 0x7e 0x5b 0x10 0x62 0x49 0x70 0x20 0x63 0x5e 0x3d 0x10
            0x64 0x29 0x52 0x20 0x65 0x3e 0x1f 0x10 0x66 0x12 0x6e 0xa0 0x67
            0x1e 0x01 0x10 0x67 0xf2 0x50 0xa0 0x68 0xfd 0xe3 0x10 0x69 0xd2
            0x32 0xa0 0x6a 0xdd 0xc5 0x10 0x6b 0xb2 0x14 0xa0 0x6c 0xc6 0xe1
            0x90 0x6d 0x91 0xf6 0xa0 0x6e 0xa6 0xc3 0x90 0x6f 0x71 0xd8 0xa0
            0x70 0x86 0xa5 0x90 0x71 0x5a 0xf5 0x20 0x72 0x66 0x87 0x90 0x73
            0x3a 0xd7 0x20 0x74 0x46 0x69 0x90 0x75 0x1a 0xb9 0x20 0x76 0x2f
            0x86 0x10 0x76 0xfa 0x9b 0x20 0x78 0x0f 0x68 0x10 0x78 0xda 0x7d
            0x20 0x79 0xef 0x4a 0x10 0x7a 0xba 0x5f 0x20 0x7b 0xcf 0x2c 0x10
            0x7c 0xa3 0x7b 0xa0 0x7d 0xaf 0x0e 0x10 0x7e 0x83 0x5d 0xa0 0x7f
            0x8e 0xf0 0x10 0x01 0x02 0x01 0x02 0x03 0x02 0x04 0x05 0x02 0x03
            0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
            0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
            0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
            0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
            0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
            0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
            0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
            0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
            0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
            0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
            0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0xff 0xff 0x92 0x4c
            0x00 0x00 0xff 0xff 0x9d 0x90 0x00 0x04 0xff 0xff 0x8f 0x80 0x00
            0x08 0xff 0xff 0x9d 0x90 0x01 0x0c 0xff 0xff 0x9d 0x90 0x01 0x10
            0xff 0xff 0x9d 0x90 0x01 0x14 0x4c 0x4d 0x54 0x00 0x4d 0x53 0x54
            0x00 0x50 0x53 0x54 0x00 0x50 0x44 0x54 0x00 0x50 0x57 0x54 0x00
            0x50 0x50 0x54 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x00 0x00 0x00
            0x00 0x00 0x01 0x54 0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00
            0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
            0x06 0x00 0x00 0x00 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x95
            0x00 0x00 0x00 0x06 0x00 0x00 0x00 0x18 0xff 0xff 0xff 0xff 0xa5
            0xb6 0xf6 0x80 0xff 0xff 0xff 0xff 0xa9 0x79 0x4f 0x70 0xff 0xff
            0xff 0xff 0xaf 0xf2 0x7c 0xf0 0xff 0xff 0xff 0xff 0xb6 0x66 0x64
            0x70 0xff 0xff 0xff 0xff 0xb7 0x1b 0x10 0x00 0xff 0xff 0xff 0xff
            0xb8 0x0a 0xf2 0xf0 0xff 0xff 0xff 0xff 0xcb 0xea 0x8d 0x80 0xff
            0xff 0xff 0xff 0xd2 0x23 0xf4 0x70 0xff 0xff 0xff 0xff 0xd2 0x99
            0xba 0x70 0xff 0xff 0xff 0xff 0xd7 0x1b 0x59 0x00 0xff 0xff 0xff
            0xff 0xd8 0x91 0xb4 0xf0 0xff 0xff 0xff 0xff 0xe2 0x7e 0x59 0xa0
            0xff 0xff 0xff 0xff 0xe3 0x49 0x52 0x90 0xff 0xff 0xff 0xff 0xe4
            0x5e 0x3b 0xa0 0xff 0xff 0xff 0xff 0xe5 0x29 0x34 0x90 0xff 0xff
            0xff 0xff 0xe6 0x47 0x58 0x20 0xff 0xff 0xff 0xff 0xe7 0x12 0x51
            0x10 0xff 0xff 0xff 0xff 0xe8 0x27 0x3a 0x20 0xff 0xff 0xff 0xff
            0xe8 0xf2 0x33 0x10 0xff 0xff 0xff 0xff 0xea 0x07 0x1c 0x20 0xff
            0xff 0xff 0xff 0xea 0xd2 0x15 0x10 0xff 0xff 0xff 0xff 0xeb 0xe6
            0xfe 0x20 0xff 0xff 0xff 0xff 0xec 0xb1 0xf7 0x10 0xff 0xff 0xff
            0xff 0xed 0xc6 0xe0 0x20 0xff 0xff 0xff 0xff 0xee 0x91 0xd9 0x10
            0x00 0x00 0x00 0x00 0x0b 0xe0 0xaf 0xa0 0x00 0x00 0x00 0x00 0x0c
            0xd9 0xcd 0x10 0x00 0x00 0x00 0x00 0x0d 0xc0 0x91 0xa0 0x00 0x00
            0x00 0x00 0x0e 0xb9 0xaf 0x10 0x00 0x00 0x00 0x00 0x0f 0xa9 0xae
            0x20 0x00 0x00 0x00 0x00 0x10 0x99 0x91 0x10 0x00 0x00 0x00 0x00
            0x11 0x89 0x90 0x20 0x00 0x00 0x00 0x00 0x12 0x79 0x73 0x10 0x00
            0x00 0x00 0x00 0x13 0x69 0x72 0x20 0x00 0x00 0x00 0x00 0x14 0x59
            0x55 0x10 0x00 0x00 0x00 0x00 0x15 0x49 0x54 0x20 0x00 0x00 0x00
            0x00 0x16 0x39 0x37 0x10 0x00 0x00 0x00 0x00 0x17 0x29 0x36 0x20
            0x00 0x00 0x00 0x00 0x18 0x22 0x53 0x90 0x00 0x00 0x00 0x00 0x19
            0x09 0x18 0x20 0x00 0x00 0x00 0x00 0x1a 0x02 0x35 0x90 0x00 0x00
            0x00 0x00 0x1a 0xf2 0x34 0xa0 0x00 0x00 0x00 0x00 0x1b 0xe2 0x17
            0x90 0x00 0x00 0x00 0x00 0x1c 0xd2 0x16 0xa0 0x00 0x00 0x00 0x00
            0x1d 0xc1 0xf9 0x90 0x00 0x00 0x00 0x00 0x1e 0xb1 0xf8 0xa0 0x00
            0x00 0x00 0x00 0x1f 0xa1 0xdb 0x90 0x00 0x00 0x00 0x00 0x20 0x76
            0x2b 0x20 0x00 0x00 0x00 0x00 0x21 0x81 0xbd 0x90 0x00 0x00 0x00
            0x00 0x22 0x56 0x0d 0x20 0x00 0x00 0x00 0x00 0x23 0x6a 0xda 0x10
            0x00 0x00 0x00 0x00 0x24 0x35 0xef 0x20 0x00 0x00 0x00 0x00 0x25
            0x4a 0xbc 0x10 0x00 0x00 0x00 0x00 0x26 0x15 0xd1 0x20 0x00 0x00
            0x00 0x00 0x27 0x2a 0x9e 0x10 0x00 0x00 0x00 0x00 0x27 0xfe 0xed
            0xa0 0x00 0x00 0x00 0x00 0x29 0x0a 0x80 0x10 0x00 0x00 0x00 0x00
            0x29 0xde 0xcf 0xa0 0x00 0x00 0x00 0x00 0x2a 0xea 0x62 0x10 0x00
            0x00 0x00 0x00 0x2b 0xbe 0xb1 0xa0 0x00 0x00 0x00 0x00 0x2c 0xd3
            0x7e 0x90 0x00 0x00 0x00 0x00 0x2d 0x9e 0x93 0xa0 0x00 0x00 0x00
            0x00 0x2e 0xb3 0x60 0x90 0x00 0x00 0x00 0x00 0x2f 0x7e 0x75 0xa0
            0x00 0x00 0x00 0x00 0x30 0x93 0x42 0x90 0x00 0x00 0x00 0x00 0x31
            0x67 0x92 0x20 0x00 0x00 0x00 0x00 0x32 0x73 0x24 0x90 0x00 0x00
            0x00 0x00 0x33 0x47 0x74 0x20 0x00 0x00 0x00 0x00 0x34 0x53 0x06
            0x90 0x00 0x00 0x00 0x00 0x35 0x27 0x56 0x20 0x00 0x00 0x00 0x00
            0x36 0x32 0xe8 0x90 0x00 0x00 0x00 0x00 0x37 0x07 0x38 0x20 0x00
            0x00 0x00 0x00 0x38 0x1c 0x05 0x10 0x00 0x00 0x00 0x00 0x38 0xe7
            0x1a 0x20 0x00 0x00 0x00 0x00 0x39 0xfb 0xe7 0x10 0x00 0x00 0x00
            0x00 0x3a 0xc6 0xfc 0x20 0x00 0x00 0x00 0x00 0x3b 0xdb 0xc9 0x10
            0x00 0x00 0x00 0x00 0x3c 0xb0 0x18 0xa0 0x00 0x00 0x00 0x00 0x3d
            0xbb 0xab 0x10 0x00 0x00 0x00 0x00 0x3e 0x8f 0xfa 0xa0 0x00 0x00
            0x00 0x00 0x3f 0x9b 0x8d 0x10 0x00 0x00 0x00 0x00 0x40 0x6f 0xdc
            0xa0 0x00 0x00 0x00 0x00 0x41 0x84 0xa9 0x90 0x00 0x00 0x00 0x00
            0x42 0x4f 0xbe 0xa0 0x00 0x00 0x00 0x00 0x43 0x64 0x8b 0x90 0x00
            0x00 0x00 0x00 0x44 0x2f 0xa0 0xa0 0x00 0x00 0x00 0x00 0x45 0x44
            0x6d 0x90 0x00 0x00 0x00 0x00 0x46 0x0f 0x82 0xa0 0x00 0x00 0x00
            0x00 0x47 0x24 0x4f 0x90 0x00 0x00 0x00 0x00 0x47 0xf8 0x9f 0x20
            0x00 0x00 0x00 0x00 0x49 0x04 0x31 0x90 0x00 0x00 0x00 0x00 0x49
            0xd8 0x81 0x20 0x00 0x00 0x00 0x00 0x4a 0xe4 0x13 0x90 0x00 0x00
            0x00 0x00 0x4b 0xb8 0x63 0x20 0x00 0x00 0x00 0x00 0x4c 0xcd 0x30
            0x10 0x00 0x00 0x00 0x00 0x4d 0x98 0x45 0x20 0x00 0x00 0x00 0x00
            0x4e 0xad 0x12 0x10 0x00 0x00 0x00 0x00 0x4f 0x78 0x27 0x20 0x00
            0x00 0x00 0x00 0x50 0x8c 0xf4 0x10 0x00 0x00 0x00 0x00 0x51 0x61
            0x43 0xa0 0x00 0x00 0x00 0x00 0x52 0x6c 0xd6 0x10 0x00 0x00 0x00
            0x00 0x53 0x41 0x25 0xa0 0x00 0x00 0x00 0x00 0x54 0x4c 0xb8 0x10
            0x00 0x00 0x00 0x00 0x55 0x21 0x07 0xa0 0x00 0x00 0x00 0x00 0x56
            0x2c 0x9a 0x10 0x00 0x00 0x00 0x00 0x57 0x00 0xe9 0xa0 0x00 0x00
            0x00 0x00 0x58 0x15 0xb6 0x90 0x00 0x00 0x00 0x00 0x58 0xe0 0xcb
            0xa0 0x00 0x00 0x00 0x00 0x59 0xf5 0x98 0x90 0x00 0x00 0x00 0x00
            0x5a 0xc0 0xad 0xa0 0x00 0x00 0x00 0x00 0x5b 0xd5 0x7a 0x90 0x00
            0x00 0x00 0x00 0x5c 0xa9 0xca 0x20 0x00 0x00 0x00 0x00 0x5d 0xb5
            0x5c 0x90 0x00 0x00 0x00 0x00 0x5e 0x89 0xac 0x20 0x00 0x00 0x00
            0x00 0x5f 0x95 0x3e 0x90 0x00 0x00 0x00 0x00 0x60 0x69 0x8e 0x20
            0x00 0x00 0x00 0x00 0x61 0x7e 0x5b 0x10 0x00 0x00 0x00 0x00 0x62
            0x49 0x70 0x20 0x00 0x00 0x00 0x00 0x63 0x5e 0x3d 0x10 0x00 0x00
            0x00 0x00 0x64 0x29 0x52 0x20 0x00 0x00 0x00 0x00 0x65 0x3e 0x1f
            0x10 0x00 0x00 0x00 0x00 0x66 0x12 0x6e 0xa0 0x00 0x00 0x00 0x00
            0x67 0x1e 0x01 0x10 0x00 0x00 0x00 0x00 0x67 0xf2 0x50 0xa0 0x00
            0x00 0x00 0x00 0x68 0xfd 0xe3 0x10 0x00 0x00 0x00 0x00 0x69 0xd2
            0x32 0xa0 0x00 0x00 0x00 0x00 0x6a 0xdd 0xc5 0x10 0x00 0x00 0x00
            0x00 0x6b 0xb2 0x14 0xa0 0x00 0x00 0x00 0x00 0x6c 0xc6 0xe1 0x90
            0x00 0x00 0x00 0x00 0x6d 0x91 0xf6 0xa0 0x00 0x00 0x00 0x00 0x6e
            0xa6 0xc3 0x90 0x00 0x00 0x00 0x00 0x6f 0x71 0xd8 0xa0 0x00 0x00
            0x00 0x00 0x70 0x86 0xa5 0x90 0x00 0x00 0x00 0x00 0x71 0x5a 0xf5
            0x20 0x00 0x00 0x00 0x00 0x72 0x66 0x87 0x90 0x00 0x00 0x00 0x00
            0x73 0x3a 0xd7 0x20 0x00 0x00 0x00 0x00 0x74 0x46 0x69 0x90 0x00
            0x00 0x00 0x00 0x75 0x1a 0xb9 0x20 0x00 0x00 0x00 0x00 0x76 0x2f
            0x86 0x10 0x00 0x00 0x00 0x00 0x76 0xfa 0x9b 0x20 0x00 0x00 0x00
            0x00 0x78 0x0f 0x68 0x10 0x00 0x00 0x00 0x00 0x78 0xda 0x7d 0x20
            0x00 0x00 0x00 0x00 0x79 0xef 0x4a 0x10 0x00 0x00 0x00 0x00 0x7a
            0xba 0x5f 0x20 0x00 0x00 0x00 0x00 0x7b 0xcf 0x2c 0x10 0x00 0x00
            0x00 0x00 0x7c 0xa3 0x7b 0xa0 0x00 0x00 0x00 0x00 0x7d 0xaf 0x0e
            0x10 0x00 0x00 0x00 0x00 0x7e 0x83 0x5d 0xa0 0x00 0x00 0x00 0x00
            0x7f 0x8e 0xf0 0x10 0x01 0x02 0x01 0x02 0x03 0x02 0x04 0x05 0x02
            0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
            0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
            0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
            0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
            0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
            0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
            0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
            0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
            0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
            0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
            0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0xff 0xff 0x92
            0x4c 0x00 0x00 0xff 0xff 0x9d 0x90 0x00 0x04 0xff 0xff 0x8f 0x80
            0x00 0x08 0xff 0xff 0x9d 0x90 0x01 0x0c 0xff 0xff 0x9d 0x90 0x01
            0x10 0xff 0xff 0x9d 0x90 0x01 0x14 0x4c 0x4d 0x54 0x00 0x4d 0x53
            0x54 0x00 0x50 0x53 0x54 0x00 0x50 0x44 0x54 0x00 0x50 0x57 0x54
            0x00 0x50 0x50 0x54 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x00 0x00
            0x00 0x00 0x00 0x01 0x0a 0x50 0x53 0x54 0x38 0x50 0x44 0x54 0x2c
            0x4d 0x34 0x2e 0x31 0x2e 0x30 0x2c 0x4d 0x31 0x30 0x2e 0x35 0x2e
            0x30 0x0a
	}]
	close $f
	set ::tcl::clock::ZoneinfoPaths \
	    [linsert $::tcl::clock::ZoneinfoPaths 0 $tzdir]
	::tcl::clock::ClearCaches
    }
    -cleanup {







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







37748
37749
37750
37751
37752
37753
37754
37755
37756
37757
37758
37759
37760
37761
37762
37763
37764
37765
37766
37767
37768
37769
37770
37771
37772
37773
37774
37775
37776
37777
37778
37779
37780
37781
37782
37783
37784
37785
37786
37787
37788
37789
37790
37791
37792
37793
37794
37795
37796
37797
37798
37799
37800
37801
37802
37803
37804
37805
37806
37807
37808
37809
37810
37811
37812
37813
37814
37815
37816
37817
37818
37819
37820
37821
37822
37823
37824
37825
37826
37827
37828
37829
37830
37831
37832
37833
37834
37835
37836
37837
37838
37839
37840
37841
37842
37843
37844
37845
37846
37847
37848
37849
37850
37851
37852
37853
37854
37855
37856
37857
37858
37859
37860
37861
37862
37863
37864
37865
37866
37867
37868
37869
37870
37871
37872
37873
37874
37875
37876
37877
37878
37879
37880
37881
37882
37883
37884
37885
37886
37887
37888
37889
37890
37891
37892
37893
37894
37895
37896
37897
37898
37899
37900
37901
37902
37903
37904
37905
37906
37907
37908
37909
37910
37911
37912
37913
37914
37915
37916
37917
37918
37919
37920
37921
37922
37923
37924
37925
37926
37927
37928
37929
37930
37931
37932
37933
37934
37935
37936
37937
37938
37939
37940
37941
37942
    -setup {
	clock format [clock seconds]
	set tzdir [makeDirectory zoneinfo]
	set tzdir2 [makeDirectory Test $tzdir]
	set tzfile [makeFile {} TijuanaTwo $tzdir2]
	set f [open $tzfile wb]
	puts -nonewline $f [binary format c* {
	    0x54 0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
	    0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x06 0x00 0x00
	    0x00 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x95 0x00 0x00 0x00
	    0x06 0x00 0x00 0x00 0x18 0xa5 0xb6 0xf6 0x80 0xa9 0x79 0x4f 0x70
	    0xaf 0xf2 0x7c 0xf0 0xb6 0x66 0x64 0x70 0xb7 0x1b 0x10 0x00 0xb8
	    0x0a 0xf2 0xf0 0xcb 0xea 0x8d 0x80 0xd2 0x23 0xf4 0x70 0xd2 0x99
	    0xba 0x70 0xd7 0x1b 0x59 0x00 0xd8 0x91 0xb4 0xf0 0xe2 0x7e 0x59
	    0xa0 0xe3 0x49 0x52 0x90 0xe4 0x5e 0x3b 0xa0 0xe5 0x29 0x34 0x90
	    0xe6 0x47 0x58 0x20 0xe7 0x12 0x51 0x10 0xe8 0x27 0x3a 0x20 0xe8
	    0xf2 0x33 0x10 0xea 0x07 0x1c 0x20 0xea 0xd2 0x15 0x10 0xeb 0xe6
	    0xfe 0x20 0xec 0xb1 0xf7 0x10 0xed 0xc6 0xe0 0x20 0xee 0x91 0xd9
	    0x10 0x0b 0xe0 0xaf 0xa0 0x0c 0xd9 0xcd 0x10 0x0d 0xc0 0x91 0xa0
	    0x0e 0xb9 0xaf 0x10 0x0f 0xa9 0xae 0x20 0x10 0x99 0x91 0x10 0x11
	    0x89 0x90 0x20 0x12 0x79 0x73 0x10 0x13 0x69 0x72 0x20 0x14 0x59
	    0x55 0x10 0x15 0x49 0x54 0x20 0x16 0x39 0x37 0x10 0x17 0x29 0x36
	    0x20 0x18 0x22 0x53 0x90 0x19 0x09 0x18 0x20 0x1a 0x02 0x35 0x90
	    0x1a 0xf2 0x34 0xa0 0x1b 0xe2 0x17 0x90 0x1c 0xd2 0x16 0xa0 0x1d
	    0xc1 0xf9 0x90 0x1e 0xb1 0xf8 0xa0 0x1f 0xa1 0xdb 0x90 0x20 0x76
	    0x2b 0x20 0x21 0x81 0xbd 0x90 0x22 0x56 0x0d 0x20 0x23 0x6a 0xda
	    0x10 0x24 0x35 0xef 0x20 0x25 0x4a 0xbc 0x10 0x26 0x15 0xd1 0x20
	    0x27 0x2a 0x9e 0x10 0x27 0xfe 0xed 0xa0 0x29 0x0a 0x80 0x10 0x29
	    0xde 0xcf 0xa0 0x2a 0xea 0x62 0x10 0x2b 0xbe 0xb1 0xa0 0x2c 0xd3
	    0x7e 0x90 0x2d 0x9e 0x93 0xa0 0x2e 0xb3 0x60 0x90 0x2f 0x7e 0x75
	    0xa0 0x30 0x93 0x42 0x90 0x31 0x67 0x92 0x20 0x32 0x73 0x24 0x90
	    0x33 0x47 0x74 0x20 0x34 0x53 0x06 0x90 0x35 0x27 0x56 0x20 0x36
	    0x32 0xe8 0x90 0x37 0x07 0x38 0x20 0x38 0x1c 0x05 0x10 0x38 0xe7
	    0x1a 0x20 0x39 0xfb 0xe7 0x10 0x3a 0xc6 0xfc 0x20 0x3b 0xdb 0xc9
	    0x10 0x3c 0xb0 0x18 0xa0 0x3d 0xbb 0xab 0x10 0x3e 0x8f 0xfa 0xa0
	    0x3f 0x9b 0x8d 0x10 0x40 0x6f 0xdc 0xa0 0x41 0x84 0xa9 0x90 0x42
	    0x4f 0xbe 0xa0 0x43 0x64 0x8b 0x90 0x44 0x2f 0xa0 0xa0 0x45 0x44
	    0x6d 0x90 0x46 0x0f 0x82 0xa0 0x47 0x24 0x4f 0x90 0x47 0xf8 0x9f
	    0x20 0x49 0x04 0x31 0x90 0x49 0xd8 0x81 0x20 0x4a 0xe4 0x13 0x90
	    0x4b 0xb8 0x63 0x20 0x4c 0xcd 0x30 0x10 0x4d 0x98 0x45 0x20 0x4e
	    0xad 0x12 0x10 0x4f 0x78 0x27 0x20 0x50 0x8c 0xf4 0x10 0x51 0x61
	    0x43 0xa0 0x52 0x6c 0xd6 0x10 0x53 0x41 0x25 0xa0 0x54 0x4c 0xb8
	    0x10 0x55 0x21 0x07 0xa0 0x56 0x2c 0x9a 0x10 0x57 0x00 0xe9 0xa0
	    0x58 0x15 0xb6 0x90 0x58 0xe0 0xcb 0xa0 0x59 0xf5 0x98 0x90 0x5a
	    0xc0 0xad 0xa0 0x5b 0xd5 0x7a 0x90 0x5c 0xa9 0xca 0x20 0x5d 0xb5
	    0x5c 0x90 0x5e 0x89 0xac 0x20 0x5f 0x95 0x3e 0x90 0x60 0x69 0x8e
	    0x20 0x61 0x7e 0x5b 0x10 0x62 0x49 0x70 0x20 0x63 0x5e 0x3d 0x10
	    0x64 0x29 0x52 0x20 0x65 0x3e 0x1f 0x10 0x66 0x12 0x6e 0xa0 0x67
	    0x1e 0x01 0x10 0x67 0xf2 0x50 0xa0 0x68 0xfd 0xe3 0x10 0x69 0xd2
	    0x32 0xa0 0x6a 0xdd 0xc5 0x10 0x6b 0xb2 0x14 0xa0 0x6c 0xc6 0xe1
	    0x90 0x6d 0x91 0xf6 0xa0 0x6e 0xa6 0xc3 0x90 0x6f 0x71 0xd8 0xa0
	    0x70 0x86 0xa5 0x90 0x71 0x5a 0xf5 0x20 0x72 0x66 0x87 0x90 0x73
	    0x3a 0xd7 0x20 0x74 0x46 0x69 0x90 0x75 0x1a 0xb9 0x20 0x76 0x2f
	    0x86 0x10 0x76 0xfa 0x9b 0x20 0x78 0x0f 0x68 0x10 0x78 0xda 0x7d
	    0x20 0x79 0xef 0x4a 0x10 0x7a 0xba 0x5f 0x20 0x7b 0xcf 0x2c 0x10
	    0x7c 0xa3 0x7b 0xa0 0x7d 0xaf 0x0e 0x10 0x7e 0x83 0x5d 0xa0 0x7f
	    0x8e 0xf0 0x10 0x01 0x02 0x01 0x02 0x03 0x02 0x04 0x05 0x02 0x03
	    0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
	    0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
	    0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
	    0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
	    0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
	    0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
	    0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
	    0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
	    0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
	    0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
	    0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0xff 0xff 0x92 0x4c
	    0x00 0x00 0xff 0xff 0x9d 0x90 0x00 0x04 0xff 0xff 0x8f 0x80 0x00
	    0x08 0xff 0xff 0x9d 0x90 0x01 0x0c 0xff 0xff 0x9d 0x90 0x01 0x10
	    0xff 0xff 0x9d 0x90 0x01 0x14 0x4c 0x4d 0x54 0x00 0x4d 0x53 0x54
	    0x00 0x50 0x53 0x54 0x00 0x50 0x44 0x54 0x00 0x50 0x57 0x54 0x00
	    0x50 0x50 0x54 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x00 0x00 0x00
	    0x00 0x00 0x01 0x54 0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00
	    0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
	    0x06 0x00 0x00 0x00 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x95
	    0x00 0x00 0x00 0x06 0x00 0x00 0x00 0x18 0xff 0xff 0xff 0xff 0xa5
	    0xb6 0xf6 0x80 0xff 0xff 0xff 0xff 0xa9 0x79 0x4f 0x70 0xff 0xff
	    0xff 0xff 0xaf 0xf2 0x7c 0xf0 0xff 0xff 0xff 0xff 0xb6 0x66 0x64
	    0x70 0xff 0xff 0xff 0xff 0xb7 0x1b 0x10 0x00 0xff 0xff 0xff 0xff
	    0xb8 0x0a 0xf2 0xf0 0xff 0xff 0xff 0xff 0xcb 0xea 0x8d 0x80 0xff
	    0xff 0xff 0xff 0xd2 0x23 0xf4 0x70 0xff 0xff 0xff 0xff 0xd2 0x99
	    0xba 0x70 0xff 0xff 0xff 0xff 0xd7 0x1b 0x59 0x00 0xff 0xff 0xff
	    0xff 0xd8 0x91 0xb4 0xf0 0xff 0xff 0xff 0xff 0xe2 0x7e 0x59 0xa0
	    0xff 0xff 0xff 0xff 0xe3 0x49 0x52 0x90 0xff 0xff 0xff 0xff 0xe4
	    0x5e 0x3b 0xa0 0xff 0xff 0xff 0xff 0xe5 0x29 0x34 0x90 0xff 0xff
	    0xff 0xff 0xe6 0x47 0x58 0x20 0xff 0xff 0xff 0xff 0xe7 0x12 0x51
	    0x10 0xff 0xff 0xff 0xff 0xe8 0x27 0x3a 0x20 0xff 0xff 0xff 0xff
	    0xe8 0xf2 0x33 0x10 0xff 0xff 0xff 0xff 0xea 0x07 0x1c 0x20 0xff
	    0xff 0xff 0xff 0xea 0xd2 0x15 0x10 0xff 0xff 0xff 0xff 0xeb 0xe6
	    0xfe 0x20 0xff 0xff 0xff 0xff 0xec 0xb1 0xf7 0x10 0xff 0xff 0xff
	    0xff 0xed 0xc6 0xe0 0x20 0xff 0xff 0xff 0xff 0xee 0x91 0xd9 0x10
	    0x00 0x00 0x00 0x00 0x0b 0xe0 0xaf 0xa0 0x00 0x00 0x00 0x00 0x0c
	    0xd9 0xcd 0x10 0x00 0x00 0x00 0x00 0x0d 0xc0 0x91 0xa0 0x00 0x00
	    0x00 0x00 0x0e 0xb9 0xaf 0x10 0x00 0x00 0x00 0x00 0x0f 0xa9 0xae
	    0x20 0x00 0x00 0x00 0x00 0x10 0x99 0x91 0x10 0x00 0x00 0x00 0x00
	    0x11 0x89 0x90 0x20 0x00 0x00 0x00 0x00 0x12 0x79 0x73 0x10 0x00
	    0x00 0x00 0x00 0x13 0x69 0x72 0x20 0x00 0x00 0x00 0x00 0x14 0x59
	    0x55 0x10 0x00 0x00 0x00 0x00 0x15 0x49 0x54 0x20 0x00 0x00 0x00
	    0x00 0x16 0x39 0x37 0x10 0x00 0x00 0x00 0x00 0x17 0x29 0x36 0x20
	    0x00 0x00 0x00 0x00 0x18 0x22 0x53 0x90 0x00 0x00 0x00 0x00 0x19
	    0x09 0x18 0x20 0x00 0x00 0x00 0x00 0x1a 0x02 0x35 0x90 0x00 0x00
	    0x00 0x00 0x1a 0xf2 0x34 0xa0 0x00 0x00 0x00 0x00 0x1b 0xe2 0x17
	    0x90 0x00 0x00 0x00 0x00 0x1c 0xd2 0x16 0xa0 0x00 0x00 0x00 0x00
	    0x1d 0xc1 0xf9 0x90 0x00 0x00 0x00 0x00 0x1e 0xb1 0xf8 0xa0 0x00
	    0x00 0x00 0x00 0x1f 0xa1 0xdb 0x90 0x00 0x00 0x00 0x00 0x20 0x76
	    0x2b 0x20 0x00 0x00 0x00 0x00 0x21 0x81 0xbd 0x90 0x00 0x00 0x00
	    0x00 0x22 0x56 0x0d 0x20 0x00 0x00 0x00 0x00 0x23 0x6a 0xda 0x10
	    0x00 0x00 0x00 0x00 0x24 0x35 0xef 0x20 0x00 0x00 0x00 0x00 0x25
	    0x4a 0xbc 0x10 0x00 0x00 0x00 0x00 0x26 0x15 0xd1 0x20 0x00 0x00
	    0x00 0x00 0x27 0x2a 0x9e 0x10 0x00 0x00 0x00 0x00 0x27 0xfe 0xed
	    0xa0 0x00 0x00 0x00 0x00 0x29 0x0a 0x80 0x10 0x00 0x00 0x00 0x00
	    0x29 0xde 0xcf 0xa0 0x00 0x00 0x00 0x00 0x2a 0xea 0x62 0x10 0x00
	    0x00 0x00 0x00 0x2b 0xbe 0xb1 0xa0 0x00 0x00 0x00 0x00 0x2c 0xd3
	    0x7e 0x90 0x00 0x00 0x00 0x00 0x2d 0x9e 0x93 0xa0 0x00 0x00 0x00
	    0x00 0x2e 0xb3 0x60 0x90 0x00 0x00 0x00 0x00 0x2f 0x7e 0x75 0xa0
	    0x00 0x00 0x00 0x00 0x30 0x93 0x42 0x90 0x00 0x00 0x00 0x00 0x31
	    0x67 0x92 0x20 0x00 0x00 0x00 0x00 0x32 0x73 0x24 0x90 0x00 0x00
	    0x00 0x00 0x33 0x47 0x74 0x20 0x00 0x00 0x00 0x00 0x34 0x53 0x06
	    0x90 0x00 0x00 0x00 0x00 0x35 0x27 0x56 0x20 0x00 0x00 0x00 0x00
	    0x36 0x32 0xe8 0x90 0x00 0x00 0x00 0x00 0x37 0x07 0x38 0x20 0x00
	    0x00 0x00 0x00 0x38 0x1c 0x05 0x10 0x00 0x00 0x00 0x00 0x38 0xe7
	    0x1a 0x20 0x00 0x00 0x00 0x00 0x39 0xfb 0xe7 0x10 0x00 0x00 0x00
	    0x00 0x3a 0xc6 0xfc 0x20 0x00 0x00 0x00 0x00 0x3b 0xdb 0xc9 0x10
	    0x00 0x00 0x00 0x00 0x3c 0xb0 0x18 0xa0 0x00 0x00 0x00 0x00 0x3d
	    0xbb 0xab 0x10 0x00 0x00 0x00 0x00 0x3e 0x8f 0xfa 0xa0 0x00 0x00
	    0x00 0x00 0x3f 0x9b 0x8d 0x10 0x00 0x00 0x00 0x00 0x40 0x6f 0xdc
	    0xa0 0x00 0x00 0x00 0x00 0x41 0x84 0xa9 0x90 0x00 0x00 0x00 0x00
	    0x42 0x4f 0xbe 0xa0 0x00 0x00 0x00 0x00 0x43 0x64 0x8b 0x90 0x00
	    0x00 0x00 0x00 0x44 0x2f 0xa0 0xa0 0x00 0x00 0x00 0x00 0x45 0x44
	    0x6d 0x90 0x00 0x00 0x00 0x00 0x46 0x0f 0x82 0xa0 0x00 0x00 0x00
	    0x00 0x47 0x24 0x4f 0x90 0x00 0x00 0x00 0x00 0x47 0xf8 0x9f 0x20
	    0x00 0x00 0x00 0x00 0x49 0x04 0x31 0x90 0x00 0x00 0x00 0x00 0x49
	    0xd8 0x81 0x20 0x00 0x00 0x00 0x00 0x4a 0xe4 0x13 0x90 0x00 0x00
	    0x00 0x00 0x4b 0xb8 0x63 0x20 0x00 0x00 0x00 0x00 0x4c 0xcd 0x30
	    0x10 0x00 0x00 0x00 0x00 0x4d 0x98 0x45 0x20 0x00 0x00 0x00 0x00
	    0x4e 0xad 0x12 0x10 0x00 0x00 0x00 0x00 0x4f 0x78 0x27 0x20 0x00
	    0x00 0x00 0x00 0x50 0x8c 0xf4 0x10 0x00 0x00 0x00 0x00 0x51 0x61
	    0x43 0xa0 0x00 0x00 0x00 0x00 0x52 0x6c 0xd6 0x10 0x00 0x00 0x00
	    0x00 0x53 0x41 0x25 0xa0 0x00 0x00 0x00 0x00 0x54 0x4c 0xb8 0x10
	    0x00 0x00 0x00 0x00 0x55 0x21 0x07 0xa0 0x00 0x00 0x00 0x00 0x56
	    0x2c 0x9a 0x10 0x00 0x00 0x00 0x00 0x57 0x00 0xe9 0xa0 0x00 0x00
	    0x00 0x00 0x58 0x15 0xb6 0x90 0x00 0x00 0x00 0x00 0x58 0xe0 0xcb
	    0xa0 0x00 0x00 0x00 0x00 0x59 0xf5 0x98 0x90 0x00 0x00 0x00 0x00
	    0x5a 0xc0 0xad 0xa0 0x00 0x00 0x00 0x00 0x5b 0xd5 0x7a 0x90 0x00
	    0x00 0x00 0x00 0x5c 0xa9 0xca 0x20 0x00 0x00 0x00 0x00 0x5d 0xb5
	    0x5c 0x90 0x00 0x00 0x00 0x00 0x5e 0x89 0xac 0x20 0x00 0x00 0x00
	    0x00 0x5f 0x95 0x3e 0x90 0x00 0x00 0x00 0x00 0x60 0x69 0x8e 0x20
	    0x00 0x00 0x00 0x00 0x61 0x7e 0x5b 0x10 0x00 0x00 0x00 0x00 0x62
	    0x49 0x70 0x20 0x00 0x00 0x00 0x00 0x63 0x5e 0x3d 0x10 0x00 0x00
	    0x00 0x00 0x64 0x29 0x52 0x20 0x00 0x00 0x00 0x00 0x65 0x3e 0x1f
	    0x10 0x00 0x00 0x00 0x00 0x66 0x12 0x6e 0xa0 0x00 0x00 0x00 0x00
	    0x67 0x1e 0x01 0x10 0x00 0x00 0x00 0x00 0x67 0xf2 0x50 0xa0 0x00
	    0x00 0x00 0x00 0x68 0xfd 0xe3 0x10 0x00 0x00 0x00 0x00 0x69 0xd2
	    0x32 0xa0 0x00 0x00 0x00 0x00 0x6a 0xdd 0xc5 0x10 0x00 0x00 0x00
	    0x00 0x6b 0xb2 0x14 0xa0 0x00 0x00 0x00 0x00 0x6c 0xc6 0xe1 0x90
	    0x00 0x00 0x00 0x00 0x6d 0x91 0xf6 0xa0 0x00 0x00 0x00 0x00 0x6e
	    0xa6 0xc3 0x90 0x00 0x00 0x00 0x00 0x6f 0x71 0xd8 0xa0 0x00 0x00
	    0x00 0x00 0x70 0x86 0xa5 0x90 0x00 0x00 0x00 0x00 0x71 0x5a 0xf5
	    0x20 0x00 0x00 0x00 0x00 0x72 0x66 0x87 0x90 0x00 0x00 0x00 0x00
	    0x73 0x3a 0xd7 0x20 0x00 0x00 0x00 0x00 0x74 0x46 0x69 0x90 0x00
	    0x00 0x00 0x00 0x75 0x1a 0xb9 0x20 0x00 0x00 0x00 0x00 0x76 0x2f
	    0x86 0x10 0x00 0x00 0x00 0x00 0x76 0xfa 0x9b 0x20 0x00 0x00 0x00
	    0x00 0x78 0x0f 0x68 0x10 0x00 0x00 0x00 0x00 0x78 0xda 0x7d 0x20
	    0x00 0x00 0x00 0x00 0x79 0xef 0x4a 0x10 0x00 0x00 0x00 0x00 0x7a
	    0xba 0x5f 0x20 0x00 0x00 0x00 0x00 0x7b 0xcf 0x2c 0x10 0x00 0x00
	    0x00 0x00 0x7c 0xa3 0x7b 0xa0 0x00 0x00 0x00 0x00 0x7d 0xaf 0x0e
	    0x10 0x00 0x00 0x00 0x00 0x7e 0x83 0x5d 0xa0 0x00 0x00 0x00 0x00
	    0x7f 0x8e 0xf0 0x10 0x01 0x02 0x01 0x02 0x03 0x02 0x04 0x05 0x02
	    0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
	    0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
	    0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
	    0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
	    0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
	    0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
	    0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
	    0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
	    0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
	    0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
	    0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0xff 0xff 0x92
	    0x4c 0x00 0x00 0xff 0xff 0x9d 0x90 0x00 0x04 0xff 0xff 0x8f 0x80
	    0x00 0x08 0xff 0xff 0x9d 0x90 0x01 0x0c 0xff 0xff 0x9d 0x90 0x01
	    0x10 0xff 0xff 0x9d 0x90 0x01 0x14 0x4c 0x4d 0x54 0x00 0x4d 0x53
	    0x54 0x00 0x50 0x53 0x54 0x00 0x50 0x44 0x54 0x00 0x50 0x57 0x54
	    0x00 0x50 0x50 0x54 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x00 0x00
	    0x00 0x00 0x00 0x01 0x0a 0x50 0x53 0x54 0x38 0x50 0x44 0x54 0x2c
	    0x4d 0x34 0x2e 0x31 0x2e 0x30 0x2c 0x4d 0x31 0x30 0x2e 0x35 0x2e
	    0x30 0x0a
	}]
	close $f
	set ::tcl::clock::ZoneinfoPaths \
	    [linsert $::tcl::clock::ZoneinfoPaths 0 $tzdir]
	::tcl::clock::ClearCaches
    }
    -cleanup {
37958
37959
37960
37961
37962
37963
37964
37965
37966
37967
37968
37969
37970
37971
37972
37973
37974
37975
37976
37977
37978
37979
37980
37981
37982
37983
37984
37985
37986
37987
37988
37989
37990
37991
37992
37993
37994
37995
37996
37997
37998
37999
38000
38001
38002
38003
38004
38005
38006
38007
38008
38009
38010
38011
38012
38013
38014
38015
38016
38017
38018
38019
38020
38021
38022
38023
38024
38025
38026
38027
38028
38029
38030
38031
38032
38033
38034
38035
38036
38037
38038
38039
38040
38041
38042
38043
38044
38045
38046
38047
38048
38049
38050
38051
38052
38053
38054
38055
38056
38057
38058
38059
38060
38061
38062
38063
38064
38065
38066
38067
38068
38069
38070
38071
38072
38073
38074
38075
38076
38077
38078
38079
38080
38081
38082
38083
38084
38085
38086
38087
38088
38089
38090
38091
    -setup {
	clock format [clock seconds]
	set tzdir [makeDirectory zoneinfo]
	set tzdir2 [makeDirectory Test $tzdir]
	set tzfile [makeFile {} Windhoek $tzdir2]
	set f [open $tzfile wb]
	puts -nonewline $f [binary format c* {
            0x54 0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
            0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x06 0x00 0x00
            0x00 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x5c 0x00 0x00 0x00
            0x06 0x00 0x00 0x00 0x13 0x82 0x46 0xcf 0x68 0xcc 0xae 0x8c 0x80
            0xcd 0x9e 0x6f 0x70 0x26 0x06 0xa7 0xe0 0x2d 0x9d 0xea 0xe0 0x2e
            0x69 0x1c 0x10 0x2f 0x7d 0xe9 0x00 0x30 0x48 0xfe 0x10 0x31 0x67
            0x05 0x80 0x32 0x28 0xe0 0x10 0x33 0x46 0xe7 0x80 0x34 0x11 0xfc
            0x90 0x35 0x26 0xc9 0x80 0x35 0xf1 0xde 0x90 0x37 0x06 0xab 0x80
            0x37 0xd1 0xc0 0x90 0x38 0xe6 0x8d 0x80 0x39 0xb1 0xa2 0x90 0x3a
            0xc6 0x6f 0x80 0x3b 0x91 0x84 0x90 0x3c 0xaf 0x8c 0x00 0x3d 0x71
            0x66 0x90 0x3e 0x8f 0x6e 0x00 0x3f 0x5a 0x83 0x10 0x40 0x6f 0x50
            0x00 0x41 0x3a 0x65 0x10 0x42 0x4f 0x32 0x00 0x43 0x1a 0x47 0x10
            0x44 0x2f 0x14 0x00 0x44 0xfa 0x29 0x10 0x46 0x0e 0xf6 0x00 0x46
            0xda 0x0b 0x10 0x47 0xf8 0x12 0x80 0x48 0xc3 0x27 0x90 0x49 0xd7
            0xf4 0x80 0x4a 0xa3 0x09 0x90 0x4b 0xb7 0xd6 0x80 0x4c 0x82 0xeb
            0x90 0x4d 0x97 0xb8 0x80 0x4e 0x62 0xcd 0x90 0x4f 0x77 0x9a 0x80
            0x50 0x42 0xaf 0x90 0x51 0x60 0xb7 0x00 0x52 0x22 0x91 0x90 0x53
            0x40 0x99 0x00 0x54 0x0b 0xae 0x10 0x55 0x20 0x7b 0x00 0x55 0xeb
            0x90 0x10 0x57 0x00 0x5d 0x00 0x57 0xcb 0x72 0x10 0x58 0xe0 0x3f
            0x00 0x59 0xab 0x54 0x10 0x5a 0xc0 0x21 0x00 0x5b 0x8b 0x36 0x10
            0x5c 0xa9 0x3d 0x80 0x5d 0x6b 0x18 0x10 0x5e 0x89 0x1f 0x80 0x5f
            0x54 0x34 0x90 0x60 0x69 0x01 0x80 0x61 0x34 0x16 0x90 0x62 0x48
            0xe3 0x80 0x63 0x13 0xf8 0x90 0x64 0x28 0xc5 0x80 0x64 0xf3 0xda
            0x90 0x66 0x11 0xe2 0x00 0x66 0xd3 0xbc 0x90 0x67 0xf1 0xc4 0x00
            0x68 0xbc 0xd9 0x10 0x69 0xd1 0xa6 0x00 0x6a 0x9c 0xbb 0x10 0x6b
            0xb1 0x88 0x00 0x6c 0x7c 0x9d 0x10 0x6d 0x91 0x6a 0x00 0x6e 0x5c
            0x7f 0x10 0x6f 0x71 0x4c 0x00 0x70 0x3c 0x61 0x10 0x71 0x5a 0x68
            0x80 0x72 0x1c 0x43 0x10 0x73 0x3a 0x4a 0x80 0x74 0x05 0x5f 0x90
            0x75 0x1a 0x2c 0x80 0x75 0xe5 0x41 0x90 0x76 0xfa 0x0e 0x80 0x77
            0xc5 0x23 0x90 0x78 0xd9 0xf0 0x80 0x79 0xa5 0x05 0x90 0x7a 0xb9
            0xd2 0x80 0x7b 0x84 0xe7 0x90 0x7c 0xa2 0xef 0x00 0x7d 0x6e 0x04
            0x10 0x7e 0x82 0xd1 0x00 0x7f 0x4d 0xe6 0x10 0x01 0x02 0x01 0x03
            0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05
            0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04
            0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05
            0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04
            0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05
            0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04
            0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x00 0x00 0x15
            0x18 0x00 0x00 0x00 0x00 0x1c 0x20 0x00 0x05 0x00 0x00 0x2a 0x30
            0x01 0x05 0x00 0x00 0x1c 0x20 0x00 0x0a 0x00 0x00 0x1c 0x20 0x01
            0x0e 0x00 0x00 0x0e 0x10 0x00 0x01 0x53 0x57 0x41 0x54 0x00 0x53
            0x41 0x53 0x54 0x00 0x43 0x41 0x54 0x00 0x57 0x41 0x53 0x54 0x00
            0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x54
            0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
            0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x07 0x00 0x00 0x00
            0x07 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x5d 0x00 0x00 0x00 0x07
            0x00 0x00 0x00 0x17 0xff 0xff 0xff 0xff 0x6d 0x7b 0x4b 0x78 0xff
            0xff 0xff 0xff 0x82 0x46 0xcf 0x68 0xff 0xff 0xff 0xff 0xcc 0xae
            0x8c 0x80 0xff 0xff 0xff 0xff 0xcd 0x9e 0x6f 0x70 0x00 0x00 0x00
            0x00 0x26 0x06 0xa7 0xe0 0x00 0x00 0x00 0x00 0x2d 0x9d 0xea 0xe0
            0x00 0x00 0x00 0x00 0x2e 0x69 0x1c 0x10 0x00 0x00 0x00 0x00 0x2f
            0x7d 0xe9 0x00 0x00 0x00 0x00 0x00 0x30 0x48 0xfe 0x10 0x00 0x00
            0x00 0x00 0x31 0x67 0x05 0x80 0x00 0x00 0x00 0x00 0x32 0x28 0xe0
            0x10 0x00 0x00 0x00 0x00 0x33 0x46 0xe7 0x80 0x00 0x00 0x00 0x00
            0x34 0x11 0xfc 0x90 0x00 0x00 0x00 0x00 0x35 0x26 0xc9 0x80 0x00
            0x00 0x00 0x00 0x35 0xf1 0xde 0x90 0x00 0x00 0x00 0x00 0x37 0x06
            0xab 0x80 0x00 0x00 0x00 0x00 0x37 0xd1 0xc0 0x90 0x00 0x00 0x00
            0x00 0x38 0xe6 0x8d 0x80 0x00 0x00 0x00 0x00 0x39 0xb1 0xa2 0x90
            0x00 0x00 0x00 0x00 0x3a 0xc6 0x6f 0x80 0x00 0x00 0x00 0x00 0x3b
            0x91 0x84 0x90 0x00 0x00 0x00 0x00 0x3c 0xaf 0x8c 0x00 0x00 0x00
            0x00 0x00 0x3d 0x71 0x66 0x90 0x00 0x00 0x00 0x00 0x3e 0x8f 0x6e
            0x00 0x00 0x00 0x00 0x00 0x3f 0x5a 0x83 0x10 0x00 0x00 0x00 0x00
            0x40 0x6f 0x50 0x00 0x00 0x00 0x00 0x00 0x41 0x3a 0x65 0x10 0x00
            0x00 0x00 0x00 0x42 0x4f 0x32 0x00 0x00 0x00 0x00 0x00 0x43 0x1a
            0x47 0x10 0x00 0x00 0x00 0x00 0x44 0x2f 0x14 0x00 0x00 0x00 0x00
            0x00 0x44 0xfa 0x29 0x10 0x00 0x00 0x00 0x00 0x46 0x0e 0xf6 0x00
            0x00 0x00 0x00 0x00 0x46 0xda 0x0b 0x10 0x00 0x00 0x00 0x00 0x47
            0xf8 0x12 0x80 0x00 0x00 0x00 0x00 0x48 0xc3 0x27 0x90 0x00 0x00
            0x00 0x00 0x49 0xd7 0xf4 0x80 0x00 0x00 0x00 0x00 0x4a 0xa3 0x09
            0x90 0x00 0x00 0x00 0x00 0x4b 0xb7 0xd6 0x80 0x00 0x00 0x00 0x00
            0x4c 0x82 0xeb 0x90 0x00 0x00 0x00 0x00 0x4d 0x97 0xb8 0x80 0x00
            0x00 0x00 0x00 0x4e 0x62 0xcd 0x90 0x00 0x00 0x00 0x00 0x4f 0x77
            0x9a 0x80 0x00 0x00 0x00 0x00 0x50 0x42 0xaf 0x90 0x00 0x00 0x00
            0x00 0x51 0x60 0xb7 0x00 0x00 0x00 0x00 0x00 0x52 0x22 0x91 0x90
            0x00 0x00 0x00 0x00 0x53 0x40 0x99 0x00 0x00 0x00 0x00 0x00 0x54
            0x0b 0xae 0x10 0x00 0x00 0x00 0x00 0x55 0x20 0x7b 0x00 0x00 0x00
            0x00 0x00 0x55 0xeb 0x90 0x10 0x00 0x00 0x00 0x00 0x57 0x00 0x5d
            0x00 0x00 0x00 0x00 0x00 0x57 0xcb 0x72 0x10 0x00 0x00 0x00 0x00
            0x58 0xe0 0x3f 0x00 0x00 0x00 0x00 0x00 0x59 0xab 0x54 0x10 0x00
            0x00 0x00 0x00 0x5a 0xc0 0x21 0x00 0x00 0x00 0x00 0x00 0x5b 0x8b
            0x36 0x10 0x00 0x00 0x00 0x00 0x5c 0xa9 0x3d 0x80 0x00 0x00 0x00
            0x00 0x5d 0x6b 0x18 0x10 0x00 0x00 0x00 0x00 0x5e 0x89 0x1f 0x80
            0x00 0x00 0x00 0x00 0x5f 0x54 0x34 0x90 0x00 0x00 0x00 0x00 0x60
            0x69 0x01 0x80 0x00 0x00 0x00 0x00 0x61 0x34 0x16 0x90 0x00 0x00
            0x00 0x00 0x62 0x48 0xe3 0x80 0x00 0x00 0x00 0x00 0x63 0x13 0xf8
            0x90 0x00 0x00 0x00 0x00 0x64 0x28 0xc5 0x80 0x00 0x00 0x00 0x00
            0x64 0xf3 0xda 0x90 0x00 0x00 0x00 0x00 0x66 0x11 0xe2 0x00 0x00
            0x00 0x00 0x00 0x66 0xd3 0xbc 0x90 0x00 0x00 0x00 0x00 0x67 0xf1
            0xc4 0x00 0x00 0x00 0x00 0x00 0x68 0xbc 0xd9 0x10 0x00 0x00 0x00
            0x00 0x69 0xd1 0xa6 0x00 0x00 0x00 0x00 0x00 0x6a 0x9c 0xbb 0x10
            0x00 0x00 0x00 0x00 0x6b 0xb1 0x88 0x00 0x00 0x00 0x00 0x00 0x6c
            0x7c 0x9d 0x10 0x00 0x00 0x00 0x00 0x6d 0x91 0x6a 0x00 0x00 0x00
            0x00 0x00 0x6e 0x5c 0x7f 0x10 0x00 0x00 0x00 0x00 0x6f 0x71 0x4c
            0x00 0x00 0x00 0x00 0x00 0x70 0x3c 0x61 0x10 0x00 0x00 0x00 0x00
            0x71 0x5a 0x68 0x80 0x00 0x00 0x00 0x00 0x72 0x1c 0x43 0x10 0x00
            0x00 0x00 0x00 0x73 0x3a 0x4a 0x80 0x00 0x00 0x00 0x00 0x74 0x05
            0x5f 0x90 0x00 0x00 0x00 0x00 0x75 0x1a 0x2c 0x80 0x00 0x00 0x00
            0x00 0x75 0xe5 0x41 0x90 0x00 0x00 0x00 0x00 0x76 0xfa 0x0e 0x80
            0x00 0x00 0x00 0x00 0x77 0xc5 0x23 0x90 0x00 0x00 0x00 0x00 0x78
            0xd9 0xf0 0x80 0x00 0x00 0x00 0x00 0x79 0xa5 0x05 0x90 0x00 0x00
            0x00 0x00 0x7a 0xb9 0xd2 0x80 0x00 0x00 0x00 0x00 0x7b 0x84 0xe7
            0x90 0x00 0x00 0x00 0x00 0x7c 0xa2 0xef 0x00 0x00 0x00 0x00 0x00
            0x7d 0x6e 0x04 0x10 0x00 0x00 0x00 0x00 0x7e 0x82 0xd1 0x00 0x00
            0x00 0x00 0x00 0x7f 0x4d 0xe6 0x10 0x01 0x02 0x03 0x02 0x04 0x06
            0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05
            0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06
            0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05
            0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06
            0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05
            0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06
            0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x00 0x00 0x10 0x08
            0x00 0x00 0x00 0x00 0x15 0x18 0x00 0x04 0x00 0x00 0x1c 0x20 0x00
            0x09 0x00 0x00 0x2a 0x30 0x01 0x09 0x00 0x00 0x1c 0x20 0x00 0x0e
            0x00 0x00 0x1c 0x20 0x01 0x12 0x00 0x00 0x0e 0x10 0x00 0x05 0x4c
            0x4d 0x54 0x00 0x53 0x57 0x41 0x54 0x00 0x53 0x41 0x53 0x54 0x00
            0x43 0x41 0x54 0x00 0x57 0x41 0x53 0x54 0x00 0x00 0x00 0x00 0x00
            0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0a 0x57 0x41
            0x54 0x2d 0x31 0x57 0x41 0x53 0x54 0x2c 0x4d 0x39 0x2e 0x31 0x2e
            0x30 0x2c 0x4d 0x34 0x2e 0x31 0x2e 0x30 0x0a
	}]
	close $f
	set ::tcl::clock::ZoneinfoPaths \
	    [linsert $::tcl::clock::ZoneinfoPaths 0 $tzdir]
	::tcl::clock::ClearCaches
    }
    -body {







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







37958
37959
37960
37961
37962
37963
37964
37965
37966
37967
37968
37969
37970
37971
37972
37973
37974
37975
37976
37977
37978
37979
37980
37981
37982
37983
37984
37985
37986
37987
37988
37989
37990
37991
37992
37993
37994
37995
37996
37997
37998
37999
38000
38001
38002
38003
38004
38005
38006
38007
38008
38009
38010
38011
38012
38013
38014
38015
38016
38017
38018
38019
38020
38021
38022
38023
38024
38025
38026
38027
38028
38029
38030
38031
38032
38033
38034
38035
38036
38037
38038
38039
38040
38041
38042
38043
38044
38045
38046
38047
38048
38049
38050
38051
38052
38053
38054
38055
38056
38057
38058
38059
38060
38061
38062
38063
38064
38065
38066
38067
38068
38069
38070
38071
38072
38073
38074
38075
38076
38077
38078
38079
38080
38081
38082
38083
38084
38085
38086
38087
38088
38089
38090
38091
    -setup {
	clock format [clock seconds]
	set tzdir [makeDirectory zoneinfo]
	set tzdir2 [makeDirectory Test $tzdir]
	set tzfile [makeFile {} Windhoek $tzdir2]
	set f [open $tzfile wb]
	puts -nonewline $f [binary format c* {
	    0x54 0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
	    0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x06 0x00 0x00
	    0x00 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x5c 0x00 0x00 0x00
	    0x06 0x00 0x00 0x00 0x13 0x82 0x46 0xcf 0x68 0xcc 0xae 0x8c 0x80
	    0xcd 0x9e 0x6f 0x70 0x26 0x06 0xa7 0xe0 0x2d 0x9d 0xea 0xe0 0x2e
	    0x69 0x1c 0x10 0x2f 0x7d 0xe9 0x00 0x30 0x48 0xfe 0x10 0x31 0x67
	    0x05 0x80 0x32 0x28 0xe0 0x10 0x33 0x46 0xe7 0x80 0x34 0x11 0xfc
	    0x90 0x35 0x26 0xc9 0x80 0x35 0xf1 0xde 0x90 0x37 0x06 0xab 0x80
	    0x37 0xd1 0xc0 0x90 0x38 0xe6 0x8d 0x80 0x39 0xb1 0xa2 0x90 0x3a
	    0xc6 0x6f 0x80 0x3b 0x91 0x84 0x90 0x3c 0xaf 0x8c 0x00 0x3d 0x71
	    0x66 0x90 0x3e 0x8f 0x6e 0x00 0x3f 0x5a 0x83 0x10 0x40 0x6f 0x50
	    0x00 0x41 0x3a 0x65 0x10 0x42 0x4f 0x32 0x00 0x43 0x1a 0x47 0x10
	    0x44 0x2f 0x14 0x00 0x44 0xfa 0x29 0x10 0x46 0x0e 0xf6 0x00 0x46
	    0xda 0x0b 0x10 0x47 0xf8 0x12 0x80 0x48 0xc3 0x27 0x90 0x49 0xd7
	    0xf4 0x80 0x4a 0xa3 0x09 0x90 0x4b 0xb7 0xd6 0x80 0x4c 0x82 0xeb
	    0x90 0x4d 0x97 0xb8 0x80 0x4e 0x62 0xcd 0x90 0x4f 0x77 0x9a 0x80
	    0x50 0x42 0xaf 0x90 0x51 0x60 0xb7 0x00 0x52 0x22 0x91 0x90 0x53
	    0x40 0x99 0x00 0x54 0x0b 0xae 0x10 0x55 0x20 0x7b 0x00 0x55 0xeb
	    0x90 0x10 0x57 0x00 0x5d 0x00 0x57 0xcb 0x72 0x10 0x58 0xe0 0x3f
	    0x00 0x59 0xab 0x54 0x10 0x5a 0xc0 0x21 0x00 0x5b 0x8b 0x36 0x10
	    0x5c 0xa9 0x3d 0x80 0x5d 0x6b 0x18 0x10 0x5e 0x89 0x1f 0x80 0x5f
	    0x54 0x34 0x90 0x60 0x69 0x01 0x80 0x61 0x34 0x16 0x90 0x62 0x48
	    0xe3 0x80 0x63 0x13 0xf8 0x90 0x64 0x28 0xc5 0x80 0x64 0xf3 0xda
	    0x90 0x66 0x11 0xe2 0x00 0x66 0xd3 0xbc 0x90 0x67 0xf1 0xc4 0x00
	    0x68 0xbc 0xd9 0x10 0x69 0xd1 0xa6 0x00 0x6a 0x9c 0xbb 0x10 0x6b
	    0xb1 0x88 0x00 0x6c 0x7c 0x9d 0x10 0x6d 0x91 0x6a 0x00 0x6e 0x5c
	    0x7f 0x10 0x6f 0x71 0x4c 0x00 0x70 0x3c 0x61 0x10 0x71 0x5a 0x68
	    0x80 0x72 0x1c 0x43 0x10 0x73 0x3a 0x4a 0x80 0x74 0x05 0x5f 0x90
	    0x75 0x1a 0x2c 0x80 0x75 0xe5 0x41 0x90 0x76 0xfa 0x0e 0x80 0x77
	    0xc5 0x23 0x90 0x78 0xd9 0xf0 0x80 0x79 0xa5 0x05 0x90 0x7a 0xb9
	    0xd2 0x80 0x7b 0x84 0xe7 0x90 0x7c 0xa2 0xef 0x00 0x7d 0x6e 0x04
	    0x10 0x7e 0x82 0xd1 0x00 0x7f 0x4d 0xe6 0x10 0x01 0x02 0x01 0x03
	    0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05
	    0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04
	    0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05
	    0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04
	    0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05
	    0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04
	    0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x00 0x00 0x15
	    0x18 0x00 0x00 0x00 0x00 0x1c 0x20 0x00 0x05 0x00 0x00 0x2a 0x30
	    0x01 0x05 0x00 0x00 0x1c 0x20 0x00 0x0a 0x00 0x00 0x1c 0x20 0x01
	    0x0e 0x00 0x00 0x0e 0x10 0x00 0x01 0x53 0x57 0x41 0x54 0x00 0x53
	    0x41 0x53 0x54 0x00 0x43 0x41 0x54 0x00 0x57 0x41 0x53 0x54 0x00
	    0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x54
	    0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
	    0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x07 0x00 0x00 0x00
	    0x07 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x5d 0x00 0x00 0x00 0x07
	    0x00 0x00 0x00 0x17 0xff 0xff 0xff 0xff 0x6d 0x7b 0x4b 0x78 0xff
	    0xff 0xff 0xff 0x82 0x46 0xcf 0x68 0xff 0xff 0xff 0xff 0xcc 0xae
	    0x8c 0x80 0xff 0xff 0xff 0xff 0xcd 0x9e 0x6f 0x70 0x00 0x00 0x00
	    0x00 0x26 0x06 0xa7 0xe0 0x00 0x00 0x00 0x00 0x2d 0x9d 0xea 0xe0
	    0x00 0x00 0x00 0x00 0x2e 0x69 0x1c 0x10 0x00 0x00 0x00 0x00 0x2f
	    0x7d 0xe9 0x00 0x00 0x00 0x00 0x00 0x30 0x48 0xfe 0x10 0x00 0x00
	    0x00 0x00 0x31 0x67 0x05 0x80 0x00 0x00 0x00 0x00 0x32 0x28 0xe0
	    0x10 0x00 0x00 0x00 0x00 0x33 0x46 0xe7 0x80 0x00 0x00 0x00 0x00
	    0x34 0x11 0xfc 0x90 0x00 0x00 0x00 0x00 0x35 0x26 0xc9 0x80 0x00
	    0x00 0x00 0x00 0x35 0xf1 0xde 0x90 0x00 0x00 0x00 0x00 0x37 0x06
	    0xab 0x80 0x00 0x00 0x00 0x00 0x37 0xd1 0xc0 0x90 0x00 0x00 0x00
	    0x00 0x38 0xe6 0x8d 0x80 0x00 0x00 0x00 0x00 0x39 0xb1 0xa2 0x90
	    0x00 0x00 0x00 0x00 0x3a 0xc6 0x6f 0x80 0x00 0x00 0x00 0x00 0x3b
	    0x91 0x84 0x90 0x00 0x00 0x00 0x00 0x3c 0xaf 0x8c 0x00 0x00 0x00
	    0x00 0x00 0x3d 0x71 0x66 0x90 0x00 0x00 0x00 0x00 0x3e 0x8f 0x6e
	    0x00 0x00 0x00 0x00 0x00 0x3f 0x5a 0x83 0x10 0x00 0x00 0x00 0x00
	    0x40 0x6f 0x50 0x00 0x00 0x00 0x00 0x00 0x41 0x3a 0x65 0x10 0x00
	    0x00 0x00 0x00 0x42 0x4f 0x32 0x00 0x00 0x00 0x00 0x00 0x43 0x1a
	    0x47 0x10 0x00 0x00 0x00 0x00 0x44 0x2f 0x14 0x00 0x00 0x00 0x00
	    0x00 0x44 0xfa 0x29 0x10 0x00 0x00 0x00 0x00 0x46 0x0e 0xf6 0x00
	    0x00 0x00 0x00 0x00 0x46 0xda 0x0b 0x10 0x00 0x00 0x00 0x00 0x47
	    0xf8 0x12 0x80 0x00 0x00 0x00 0x00 0x48 0xc3 0x27 0x90 0x00 0x00
	    0x00 0x00 0x49 0xd7 0xf4 0x80 0x00 0x00 0x00 0x00 0x4a 0xa3 0x09
	    0x90 0x00 0x00 0x00 0x00 0x4b 0xb7 0xd6 0x80 0x00 0x00 0x00 0x00
	    0x4c 0x82 0xeb 0x90 0x00 0x00 0x00 0x00 0x4d 0x97 0xb8 0x80 0x00
	    0x00 0x00 0x00 0x4e 0x62 0xcd 0x90 0x00 0x00 0x00 0x00 0x4f 0x77
	    0x9a 0x80 0x00 0x00 0x00 0x00 0x50 0x42 0xaf 0x90 0x00 0x00 0x00
	    0x00 0x51 0x60 0xb7 0x00 0x00 0x00 0x00 0x00 0x52 0x22 0x91 0x90
	    0x00 0x00 0x00 0x00 0x53 0x40 0x99 0x00 0x00 0x00 0x00 0x00 0x54
	    0x0b 0xae 0x10 0x00 0x00 0x00 0x00 0x55 0x20 0x7b 0x00 0x00 0x00
	    0x00 0x00 0x55 0xeb 0x90 0x10 0x00 0x00 0x00 0x00 0x57 0x00 0x5d
	    0x00 0x00 0x00 0x00 0x00 0x57 0xcb 0x72 0x10 0x00 0x00 0x00 0x00
	    0x58 0xe0 0x3f 0x00 0x00 0x00 0x00 0x00 0x59 0xab 0x54 0x10 0x00
	    0x00 0x00 0x00 0x5a 0xc0 0x21 0x00 0x00 0x00 0x00 0x00 0x5b 0x8b
	    0x36 0x10 0x00 0x00 0x00 0x00 0x5c 0xa9 0x3d 0x80 0x00 0x00 0x00
	    0x00 0x5d 0x6b 0x18 0x10 0x00 0x00 0x00 0x00 0x5e 0x89 0x1f 0x80
	    0x00 0x00 0x00 0x00 0x5f 0x54 0x34 0x90 0x00 0x00 0x00 0x00 0x60
	    0x69 0x01 0x80 0x00 0x00 0x00 0x00 0x61 0x34 0x16 0x90 0x00 0x00
	    0x00 0x00 0x62 0x48 0xe3 0x80 0x00 0x00 0x00 0x00 0x63 0x13 0xf8
	    0x90 0x00 0x00 0x00 0x00 0x64 0x28 0xc5 0x80 0x00 0x00 0x00 0x00
	    0x64 0xf3 0xda 0x90 0x00 0x00 0x00 0x00 0x66 0x11 0xe2 0x00 0x00
	    0x00 0x00 0x00 0x66 0xd3 0xbc 0x90 0x00 0x00 0x00 0x00 0x67 0xf1
	    0xc4 0x00 0x00 0x00 0x00 0x00 0x68 0xbc 0xd9 0x10 0x00 0x00 0x00
	    0x00 0x69 0xd1 0xa6 0x00 0x00 0x00 0x00 0x00 0x6a 0x9c 0xbb 0x10
	    0x00 0x00 0x00 0x00 0x6b 0xb1 0x88 0x00 0x00 0x00 0x00 0x00 0x6c
	    0x7c 0x9d 0x10 0x00 0x00 0x00 0x00 0x6d 0x91 0x6a 0x00 0x00 0x00
	    0x00 0x00 0x6e 0x5c 0x7f 0x10 0x00 0x00 0x00 0x00 0x6f 0x71 0x4c
	    0x00 0x00 0x00 0x00 0x00 0x70 0x3c 0x61 0x10 0x00 0x00 0x00 0x00
	    0x71 0x5a 0x68 0x80 0x00 0x00 0x00 0x00 0x72 0x1c 0x43 0x10 0x00
	    0x00 0x00 0x00 0x73 0x3a 0x4a 0x80 0x00 0x00 0x00 0x00 0x74 0x05
	    0x5f 0x90 0x00 0x00 0x00 0x00 0x75 0x1a 0x2c 0x80 0x00 0x00 0x00
	    0x00 0x75 0xe5 0x41 0x90 0x00 0x00 0x00 0x00 0x76 0xfa 0x0e 0x80
	    0x00 0x00 0x00 0x00 0x77 0xc5 0x23 0x90 0x00 0x00 0x00 0x00 0x78
	    0xd9 0xf0 0x80 0x00 0x00 0x00 0x00 0x79 0xa5 0x05 0x90 0x00 0x00
	    0x00 0x00 0x7a 0xb9 0xd2 0x80 0x00 0x00 0x00 0x00 0x7b 0x84 0xe7
	    0x90 0x00 0x00 0x00 0x00 0x7c 0xa2 0xef 0x00 0x00 0x00 0x00 0x00
	    0x7d 0x6e 0x04 0x10 0x00 0x00 0x00 0x00 0x7e 0x82 0xd1 0x00 0x00
	    0x00 0x00 0x00 0x7f 0x4d 0xe6 0x10 0x01 0x02 0x03 0x02 0x04 0x06
	    0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05
	    0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06
	    0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05
	    0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06
	    0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05
	    0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06
	    0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x00 0x00 0x10 0x08
	    0x00 0x00 0x00 0x00 0x15 0x18 0x00 0x04 0x00 0x00 0x1c 0x20 0x00
	    0x09 0x00 0x00 0x2a 0x30 0x01 0x09 0x00 0x00 0x1c 0x20 0x00 0x0e
	    0x00 0x00 0x1c 0x20 0x01 0x12 0x00 0x00 0x0e 0x10 0x00 0x05 0x4c
	    0x4d 0x54 0x00 0x53 0x57 0x41 0x54 0x00 0x53 0x41 0x53 0x54 0x00
	    0x43 0x41 0x54 0x00 0x57 0x41 0x53 0x54 0x00 0x00 0x00 0x00 0x00
	    0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0a 0x57 0x41
	    0x54 0x2d 0x31 0x57 0x41 0x53 0x54 0x2c 0x4d 0x39 0x2e 0x31 0x2e
	    0x30 0x2c 0x4d 0x34 0x2e 0x31 0x2e 0x30 0x0a
	}]
	close $f
	set ::tcl::clock::ZoneinfoPaths \
	    [linsert $::tcl::clock::ZoneinfoPaths 0 $tzdir]
	::tcl::clock::ClearCaches
    }
    -body {
Changes to tests/cmdAH.test.
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324


# Maps utf-{16,32}{le,be} to utf-16, utf-32 and
# others to "". Used to test utf-16, utf-32 based
# on system endianness
proc endianUtf {enc} {
    if {$::tcl_platform(byteOrder) eq "littleEndian"} {
        set endian le
    } else {
        set endian be
    }
    if {$enc eq "utf-16$endian" || $enc eq "utf-32$endian"} {
        return [string range $enc 0 5]
    }
    return ""
}

#
# Check errors for invalid number of arguments
proc badnumargs {id cmd cmdargs} {
    variable numargErrors
    test $id.a "Syntax error: $cmd $cmdargs" \
        -body [list {*}$cmd {*}$cmdargs] \
        -result $numargErrors($cmd) \
        -match regexp \
        -returnCodes error
    test $id.b "Syntax error: $cmd (byte compiled)" \
        -setup [list proc compiled_proc {} [list {*}$cmd {*}$cmdargs]] \
        -body {compiled_proc} \
        -cleanup {rename compiled_proc {}} \
        -result $numargErrors($cmd) \
        -match regexp \
        -returnCodes error
}

# Wraps tests resulting in unknown encoding errors
proc unknownencodingtest {id cmd} {
    set result "unknown encoding \"[lindex $cmd end-1]\""
    test $id.a "Unknown encoding error: $cmd" \
        -body [list encoding {*}$cmd] \
        -result $result \
        -returnCodes error
    test $id.b "Syntax error: $cmd (byte compiled)" \
        -setup [list proc encoding_test {} [list encoding {*}$cmd]] \
        -body {encoding_test} \
        -cleanup {rename encoding_test {}} \
        -result $result \
        -returnCodes error
}

# Wraps tests for conversion, successful or not.
# Really more general than just for encoding conversion.
proc testconvert {id body result args} {
    test $id.a $body \
        -body $body \
        -result $result \
        {*}$args
    dict append args -setup \n[list proc compiled_script {} $body]
    dict append args -cleanup "\nrename compiled_script {}"
    test $id.b "$body (byte compiled)" \
        -body {compiled_script} \
        -result $result \
        {*}$args
}

# Wrapper to verify encoding convert{to,from} ?-profile?
# Generates tests for compiled and uncompiled implementation.
# Also generates utf-{16,32} tests if passed encoding is utf-{16,32}{le,be}
# The enc and profile are appended to id to generate the test id
proc testprofile {id converter enc profile data result args} {
    testconvert $id.$enc.$profile [list encoding $converter -profile $profile $enc $data] $result {*}$args
    if {[set enc2 [endianUtf $enc]] ne ""} {
        # If utf{16,32}-{le,be}, also do utf{16,32}
        testconvert $id.$enc2.$profile [list encoding $converter -profile $profile $enc2 $data] $result {*}$args
    }

    # If this is the default profile, generate a test without specifying profile
    if {$profile eq $::encDefaultProfile} {
        testconvert $id.$enc.default [list encoding $converter $enc $data] $result {*}$args
        if {[set enc2 [endianUtf $enc]] ne ""} {
            # If utf{16,32}-{le,be}, also do utf{16,32}
            testconvert $id.$enc2.default [list encoding $converter $enc2 $data] $result {*}$args
        }
    }
}


# Wrapper to verify encoding convert{to,from} -failindex ?-profile?
# Generates tests for compiled and uncompiled implementation.
# Also generates utf-{16,32} tests if passed encoding is utf-{16,32}{le,be}
# The enc and profile are appended to id to generate the test id
proc testfailindex {id converter enc data result failidx {profile default}} {
    testconvert $id.$enc.$profile "list \[encoding $converter -profile $profile -failindex idx $enc [list $data]\] \[set idx\]" [list $result $failidx]
    if {[set enc2 [endianUtf $enc]] ne ""} {
        # If utf{16,32}-{le,be}, also do utf{16,32}
        testconvert $id.$enc2.$profile "list \[encoding $converter -profile $profile -failindex idx $enc2 [list $data]\] \[set idx]" [list $result $failidx]
    }

    # If this is the default profile, generate a test without specifying profile
    if {$profile eq $::encDefaultProfile} {
        testconvert $id.$enc.default "list \[encoding $converter -failindex idx $enc [list $data]\] \[set idx]" [list $result $failidx]
        if {[set enc2 [endianUtf $enc]] ne ""} {
            # If utf{16,32}-{le,be}, also do utf{16,32}
            testconvert $id.$enc2.default "list \[encoding $converter -failindex idx $enc2 [list $data]\] \[set idx]" [list $result $failidx]
        }
    }
}

test cmdAH-4.1.1 {encoding} -returnCodes error -body {
    encoding
} -result {wrong # args: should be "encoding subcommand ?arg ...?"}
test cmdAH-4.1.2 {Tcl_EncodingObjCmd} -returnCodes error -body {







|

|


|









|
|
|
|

|
|
|
|
|
|






|
|
|

|
|
|
|
|






|
|
|



|
|
|









|
|




|
|
|
|
|











|
|




|
|
|
|
|







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324


# Maps utf-{16,32}{le,be} to utf-16, utf-32 and
# others to "". Used to test utf-16, utf-32 based
# on system endianness
proc endianUtf {enc} {
    if {$::tcl_platform(byteOrder) eq "littleEndian"} {
	set endian le
    } else {
	set endian be
    }
    if {$enc eq "utf-16$endian" || $enc eq "utf-32$endian"} {
	return [string range $enc 0 5]
    }
    return ""
}

#
# Check errors for invalid number of arguments
proc badnumargs {id cmd cmdargs} {
    variable numargErrors
    test $id.a "Syntax error: $cmd $cmdargs" \
	-body [list {*}$cmd {*}$cmdargs] \
	-result $numargErrors($cmd) \
	-match regexp \
	-returnCodes error
    test $id.b "Syntax error: $cmd (byte compiled)" \
	-setup [list proc compiled_proc {} [list {*}$cmd {*}$cmdargs]] \
	-body {compiled_proc} \
	-cleanup {rename compiled_proc {}} \
	-result $numargErrors($cmd) \
	-match regexp \
	-returnCodes error
}

# Wraps tests resulting in unknown encoding errors
proc unknownencodingtest {id cmd} {
    set result "unknown encoding \"[lindex $cmd end-1]\""
    test $id.a "Unknown encoding error: $cmd" \
	-body [list encoding {*}$cmd] \
	-result $result \
	-returnCodes error
    test $id.b "Syntax error: $cmd (byte compiled)" \
	-setup [list proc encoding_test {} [list encoding {*}$cmd]] \
	-body {encoding_test} \
	-cleanup {rename encoding_test {}} \
	-result $result \
	-returnCodes error
}

# Wraps tests for conversion, successful or not.
# Really more general than just for encoding conversion.
proc testconvert {id body result args} {
    test $id.a $body \
	-body $body \
	-result $result \
	{*}$args
    dict append args -setup \n[list proc compiled_script {} $body]
    dict append args -cleanup "\nrename compiled_script {}"
    test $id.b "$body (byte compiled)" \
	-body {compiled_script} \
	-result $result \
	{*}$args
}

# Wrapper to verify encoding convert{to,from} ?-profile?
# Generates tests for compiled and uncompiled implementation.
# Also generates utf-{16,32} tests if passed encoding is utf-{16,32}{le,be}
# The enc and profile are appended to id to generate the test id
proc testprofile {id converter enc profile data result args} {
    testconvert $id.$enc.$profile [list encoding $converter -profile $profile $enc $data] $result {*}$args
    if {[set enc2 [endianUtf $enc]] ne ""} {
	# If utf{16,32}-{le,be}, also do utf{16,32}
	testconvert $id.$enc2.$profile [list encoding $converter -profile $profile $enc2 $data] $result {*}$args
    }

    # If this is the default profile, generate a test without specifying profile
    if {$profile eq $::encDefaultProfile} {
	testconvert $id.$enc.default [list encoding $converter $enc $data] $result {*}$args
	if {[set enc2 [endianUtf $enc]] ne ""} {
	    # If utf{16,32}-{le,be}, also do utf{16,32}
	    testconvert $id.$enc2.default [list encoding $converter $enc2 $data] $result {*}$args
	}
    }
}


# Wrapper to verify encoding convert{to,from} -failindex ?-profile?
# Generates tests for compiled and uncompiled implementation.
# Also generates utf-{16,32} tests if passed encoding is utf-{16,32}{le,be}
# The enc and profile are appended to id to generate the test id
proc testfailindex {id converter enc data result failidx {profile default}} {
    testconvert $id.$enc.$profile "list \[encoding $converter -profile $profile -failindex idx $enc [list $data]\] \[set idx\]" [list $result $failidx]
    if {[set enc2 [endianUtf $enc]] ne ""} {
	# If utf{16,32}-{le,be}, also do utf{16,32}
	testconvert $id.$enc2.$profile "list \[encoding $converter -profile $profile -failindex idx $enc2 [list $data]\] \[set idx]" [list $result $failidx]
    }

    # If this is the default profile, generate a test without specifying profile
    if {$profile eq $::encDefaultProfile} {
	testconvert $id.$enc.default "list \[encoding $converter -failindex idx $enc [list $data]\] \[set idx]" [list $result $failidx]
	if {[set enc2 [endianUtf $enc]] ne ""} {
	    # If utf{16,32}-{le,be}, also do utf{16,32}
	    testconvert $id.$enc2.default "list \[encoding $converter -failindex idx $enc2 [list $data]\] \[set idx]" [list $result $failidx]
	}
    }
}

test cmdAH-4.1.1 {encoding} -returnCodes error -body {
    encoding
} -result {wrong # args: should be "encoding subcommand ?arg ...?"}
test cmdAH-4.1.2 {Tcl_EncodingObjCmd} -returnCodes error -body {
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
    if {"knownBug" in $ctrl} continue
    set bytes [binary decode hex $hex]
    set prefix A
    set suffix B
    set prefix_bytes [encoding convertto $enc A]
    set suffix_bytes [encoding convertto $enc B]
    foreach profile $encProfiles {
        testprofile cmdAH-4.3.13.$hex.solo convertfrom $enc $profile $bytes $str
        testprofile cmdAH-4.3.13.$hex.lead convertfrom $enc $profile $bytes$suffix_bytes $str$suffix
        testprofile cmdAH-4.3.13.$hex.tail convertfrom $enc $profile $prefix_bytes$bytes $prefix$str
        testprofile cmdAH-4.3.13.$hex.middle convertfrom $enc $profile $prefix_bytes$bytes$suffix_bytes $prefix$str$suffix
    }
}

# convertfrom ?-profile? : invalid byte sequences
foreach {enc hex profile str failidx ctrl comment} $encInvalidBytes {
    if {"knownBug" in $ctrl} continue
    set bytes [binary format H* $hex]
    set prefix A
    set suffix B
    set prefix_bytes [encoding convertto $enc $prefix]
    set suffix_bytes [encoding convertto $enc $suffix]
    set prefixLen [string length $prefix_bytes]
    set result [list $str]
    # TODO - if the bad byte is unprintable, tcltest errors out when printing a mismatch
    # so glob it out in error message pattern for now.
    set errorWithoutPrefix [list "unexpected byte sequence starting at index $failidx: *" -returnCodes error -match glob]
    set errorWithPrefix [list "unexpected byte sequence starting at index [expr {$failidx+$prefixLen}]: *" -returnCodes error -match glob]
    if {$ctrl eq {} || "solo" in $ctrl} {
        if {$failidx == -1} {
            set result [list $str]
        } else {
            set result $errorWithoutPrefix
        }
        testprofile cmdAH-4.3.13.$hex.solo convertfrom $enc $profile $bytes {*}$result
    }
    if {$ctrl eq {} || "lead" in $ctrl} {
        if {$failidx == -1} {
            set result [list $str$suffix]
        } else {
            set result $errorWithoutPrefix
        }
        testprofile cmdAH-4.3.13.$hex.lead convertfrom $enc $profile $bytes$suffix_bytes {*}$result
    }
    if {$ctrl eq {} || "tail" in $ctrl} {
        if {$failidx == -1} {
            set result [list $prefix$str]
        } else {
            set result $errorWithPrefix
        }
        testprofile cmdAH-4.3.13.$hex.tail convertfrom $enc $profile $prefix_bytes$bytes {*}$result
    }
    if {$ctrl eq {} || "middle" in $ctrl} {
        if {$failidx == -1} {
            set result [list $prefix$str$suffix]
        } else {
            set result $errorWithPrefix
        }
        testprofile cmdAH-4.3.13.$hex.middle convertfrom $enc $profile $prefix_bytes$bytes$suffix_bytes {*}$result
    }
}

# convertfrom -failindex ?-profile? - valid data
foreach {enc str hex ctrl comment} $encValidStrings {
    if {"knownBug" in $ctrl} continue
    set bytes [binary decode hex $hex]
    set prefix A
    set suffix B
    set prefix_bytes [encoding convertto $enc $prefix]
    set suffix_bytes [encoding convertto $enc $suffix]
    foreach profile $encProfiles {
        testfailindex cmdAH-4.3.14.$hex.solo convertfrom $enc $bytes $str -1 $profile
        testfailindex cmdAH-4.3.14.$hex.lead convertfrom $enc $bytes$suffix_bytes $str$suffix -1 $profile
        testfailindex cmdAH-4.3.14.$hex.tail convertfrom $enc $prefix_bytes$bytes $prefix$str -1 $profile
        testfailindex cmdAH-4.3.14.$hex.middle convertfrom $enc $prefix_bytes$bytes$suffix_bytes $prefix$str$suffix -1 $profile
    }
}

# convertfrom -failindex ?-profile? - invalid data
foreach {enc hex profile str failidx ctrl comment} $encInvalidBytes {
    if {"knownBug" in $ctrl} continue
    # There are multiple test cases based on location of invalid bytes
    set bytes [binary decode hex $hex]
    set prefix A
    set suffix B
    set prefix_bytes [encoding convertto $enc $prefix]
    set suffix_bytes [encoding convertto $enc $suffix]
    set prefixLen [string length $prefix_bytes]
    if {$ctrl eq {} || "solo" in $ctrl} {
        testfailindex cmdAH-4.3.14.$hex.solo convertfrom $enc $bytes $str $failidx $profile
    }
    if {$ctrl eq {} || "lead" in $ctrl} {
        if {$failidx == -1} {
            # If success expected
            set result $str$suffix
        } else {
            # Failure expected
            set result ""
        }
        testfailindex cmdAH-4.3.14.$hex.lead convertfrom $enc $bytes$suffix_bytes $result $failidx $profile
    }
    if {$ctrl eq {} || "tail" in $ctrl} {
        set expected_failidx $failidx
        if {$failidx == -1} {
            # If success expected
            set result $prefix$str
        } else {
            # Failure expected
            set result $prefix
            incr expected_failidx $prefixLen
        }
        testfailindex cmdAH-4.3.14.$hex.tail convertfrom $enc $prefix_bytes$bytes $result $expected_failidx $profile
    }
    if {$ctrl eq {} || "middle" in $ctrl} {
        set expected_failidx $failidx
        if {$failidx == -1} {
            # If success expected
            set result $prefix$str$suffix
        } else {
            # Failure expected
            set result $prefix
            incr expected_failidx $prefixLen
        }
        testfailindex cmdAH-4.3.14.$hex.middle convertfrom $enc $prefix_bytes$bytes$suffix_bytes $result $expected_failidx $profile
    }
}

#
# encoding convertto 4.4.*

badnumargs cmdAH-4.4.1 {encoding convertto} {}







|
|
|
|


















|
|
|
|
|
|


|
|
|
|
|
|


|
|
|
|
|
|


|
|
|
|
|
|












|
|
|
|














|


|
|
|
|
|
|
|
|


|
|
|
|
|
|
|
|
|
|


|
|
|
|
|
|
|
|
|
|







378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
    if {"knownBug" in $ctrl} continue
    set bytes [binary decode hex $hex]
    set prefix A
    set suffix B
    set prefix_bytes [encoding convertto $enc A]
    set suffix_bytes [encoding convertto $enc B]
    foreach profile $encProfiles {
	testprofile cmdAH-4.3.13.$hex.solo convertfrom $enc $profile $bytes $str
	testprofile cmdAH-4.3.13.$hex.lead convertfrom $enc $profile $bytes$suffix_bytes $str$suffix
	testprofile cmdAH-4.3.13.$hex.tail convertfrom $enc $profile $prefix_bytes$bytes $prefix$str
	testprofile cmdAH-4.3.13.$hex.middle convertfrom $enc $profile $prefix_bytes$bytes$suffix_bytes $prefix$str$suffix
    }
}

# convertfrom ?-profile? : invalid byte sequences
foreach {enc hex profile str failidx ctrl comment} $encInvalidBytes {
    if {"knownBug" in $ctrl} continue
    set bytes [binary format H* $hex]
    set prefix A
    set suffix B
    set prefix_bytes [encoding convertto $enc $prefix]
    set suffix_bytes [encoding convertto $enc $suffix]
    set prefixLen [string length $prefix_bytes]
    set result [list $str]
    # TODO - if the bad byte is unprintable, tcltest errors out when printing a mismatch
    # so glob it out in error message pattern for now.
    set errorWithoutPrefix [list "unexpected byte sequence starting at index $failidx: *" -returnCodes error -match glob]
    set errorWithPrefix [list "unexpected byte sequence starting at index [expr {$failidx+$prefixLen}]: *" -returnCodes error -match glob]
    if {$ctrl eq {} || "solo" in $ctrl} {
	if {$failidx == -1} {
	    set result [list $str]
	} else {
	    set result $errorWithoutPrefix
	}
	testprofile cmdAH-4.3.13.$hex.solo convertfrom $enc $profile $bytes {*}$result
    }
    if {$ctrl eq {} || "lead" in $ctrl} {
	if {$failidx == -1} {
	    set result [list $str$suffix]
	} else {
	    set result $errorWithoutPrefix
	}
	testprofile cmdAH-4.3.13.$hex.lead convertfrom $enc $profile $bytes$suffix_bytes {*}$result
    }
    if {$ctrl eq {} || "tail" in $ctrl} {
	if {$failidx == -1} {
	    set result [list $prefix$str]
	} else {
	    set result $errorWithPrefix
	}
	testprofile cmdAH-4.3.13.$hex.tail convertfrom $enc $profile $prefix_bytes$bytes {*}$result
    }
    if {$ctrl eq {} || "middle" in $ctrl} {
	if {$failidx == -1} {
	    set result [list $prefix$str$suffix]
	} else {
	    set result $errorWithPrefix
	}
	testprofile cmdAH-4.3.13.$hex.middle convertfrom $enc $profile $prefix_bytes$bytes$suffix_bytes {*}$result
    }
}

# convertfrom -failindex ?-profile? - valid data
foreach {enc str hex ctrl comment} $encValidStrings {
    if {"knownBug" in $ctrl} continue
    set bytes [binary decode hex $hex]
    set prefix A
    set suffix B
    set prefix_bytes [encoding convertto $enc $prefix]
    set suffix_bytes [encoding convertto $enc $suffix]
    foreach profile $encProfiles {
	testfailindex cmdAH-4.3.14.$hex.solo convertfrom $enc $bytes $str -1 $profile
	testfailindex cmdAH-4.3.14.$hex.lead convertfrom $enc $bytes$suffix_bytes $str$suffix -1 $profile
	testfailindex cmdAH-4.3.14.$hex.tail convertfrom $enc $prefix_bytes$bytes $prefix$str -1 $profile
	testfailindex cmdAH-4.3.14.$hex.middle convertfrom $enc $prefix_bytes$bytes$suffix_bytes $prefix$str$suffix -1 $profile
    }
}

# convertfrom -failindex ?-profile? - invalid data
foreach {enc hex profile str failidx ctrl comment} $encInvalidBytes {
    if {"knownBug" in $ctrl} continue
    # There are multiple test cases based on location of invalid bytes
    set bytes [binary decode hex $hex]
    set prefix A
    set suffix B
    set prefix_bytes [encoding convertto $enc $prefix]
    set suffix_bytes [encoding convertto $enc $suffix]
    set prefixLen [string length $prefix_bytes]
    if {$ctrl eq {} || "solo" in $ctrl} {
	testfailindex cmdAH-4.3.14.$hex.solo convertfrom $enc $bytes $str $failidx $profile
    }
    if {$ctrl eq {} || "lead" in $ctrl} {
	if {$failidx == -1} {
	    # If success expected
	    set result $str$suffix
	} else {
	    # Failure expected
	    set result ""
	}
	testfailindex cmdAH-4.3.14.$hex.lead convertfrom $enc $bytes$suffix_bytes $result $failidx $profile
    }
    if {$ctrl eq {} || "tail" in $ctrl} {
	set expected_failidx $failidx
	if {$failidx == -1} {
	    # If success expected
	    set result $prefix$str
	} else {
	    # Failure expected
	    set result $prefix
	    incr expected_failidx $prefixLen
	}
	testfailindex cmdAH-4.3.14.$hex.tail convertfrom $enc $prefix_bytes$bytes $result $expected_failidx $profile
    }
    if {$ctrl eq {} || "middle" in $ctrl} {
	set expected_failidx $failidx
	if {$failidx == -1} {
	    # If success expected
	    set result $prefix$str$suffix
	} else {
	    # Failure expected
	    set result $prefix
	    incr expected_failidx $prefixLen
	}
	testfailindex cmdAH-4.3.14.$hex.middle convertfrom $enc $prefix_bytes$bytes$suffix_bytes $result $expected_failidx $profile
    }
}

#
# encoding convertto 4.4.*

badnumargs cmdAH-4.4.1 {encoding convertto} {}
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
    set bytes [binary decode hex $hex]
    set printable [tcltest::Asciify $str]
    set prefix A
    set suffix B
    set prefix_bytes [encoding convertto $enc A]
    set suffix_bytes [encoding convertto $enc B]
    foreach profile $encProfiles {
        testprofile cmdAH-4.4.13.$printable.solo convertto $enc $profile $str $bytes
        testprofile cmdAH-4.4.13.$printable.lead convertto $enc $profile $str$suffix $bytes$suffix_bytes
        testprofile cmdAH-4.4.13.$printable.tail convertto $enc $profile $prefix$str $prefix_bytes$bytes
        testprofile cmdAH-4.4.13.$printable.middle convertto $enc $profile $prefix$str$suffix $prefix_bytes$bytes$suffix_bytes
    }
}

# convertto ?-profile? : invalid byte sequences
foreach {enc str profile hex failidx ctrl comment} $encUnencodableStrings {
    if {"knownBug" in $ctrl} continue
    set bytes [binary decode hex $hex]
    set printable [tcltest::Asciify $str]
    set prefix A
    set suffix B
    set prefix_bytes [encoding convertto $enc $prefix]
    set suffix_bytes [encoding convertto $enc $suffix]
    set prefixLen [string length $prefix_bytes]
    set result [list $bytes]
    # TODO - if the bad byte is unprintable, tcltest errors out when printing a mismatch
    # so glob it out in error message pattern for now.
    set errorWithoutPrefix [list "unexpected character at index $failidx: *" -returnCodes error -match glob]
    set errorWithPrefix [list "unexpected character at index [expr {$failidx+$prefixLen}]: *" -returnCodes error -match glob]
    if {$ctrl eq {} || "solo" in $ctrl} {
        if {$failidx == -1} {
            set result [list $bytes]
        } else {
            set result $errorWithoutPrefix
        }
        testprofile cmdAH-4.4.13.$printable.solo convertto $enc $profile $str {*}$result
    }
    if {$ctrl eq {} || "lead" in $ctrl} {
        if {$failidx == -1} {
            set result [list $bytes$suffix_bytes]
        } else {
            set result $errorWithoutPrefix
        }
        testprofile cmdAH-4.4.13.$printable.lead convertto $enc $profile $str$suffix {*}$result
    }
    if {$ctrl eq {} || "tail" in $ctrl} {
        if {$failidx == -1} {
            set result [list $prefix_bytes$bytes]
        } else {
            set result $errorWithPrefix
        }
        testprofile cmdAH-4.4.13.$printable.tail convertto $enc $profile $prefix$str {*}$result
    }
    if {$ctrl eq {} || "middle" in $ctrl} {
        if {$failidx == -1} {
            set result [list $prefix_bytes$bytes$suffix_bytes]
        } else {
            set result $errorWithPrefix
        }
        testprofile cmdAH-4.4.13.$printable.middle convertto $enc $profile $prefix$str$suffix {*}$result
    }
}

# convertto -failindex ?-profile? - valid data
foreach {enc str hex ctrl comment} $encValidStrings {
    if {"knownBug" in $ctrl} continue
    set bytes [binary decode hex $hex]
    set printable [tcltest::Asciify $str]
    set prefix A
    set suffix B
    set prefix_bytes [encoding convertto $enc A]
    set suffix_bytes [encoding convertto $enc B]
    foreach profile $encProfiles {
        testfailindex cmdAH-4.4.14.$enc.$printable.solo convertto $enc $str $bytes -1 $profile
        testfailindex cmdAH-4.4.14.$enc.$printable.lead convertto $enc $str$suffix $bytes$suffix_bytes -1 $profile
        testfailindex cmdAH-4.4.14.$enc.$printable.tail convertto $enc $prefix$str $prefix_bytes$bytes -1 $profile
        testfailindex cmdAH-4.4.14.$enc.$printable.middle convertto $enc $prefix$str$suffix $prefix_bytes$bytes$suffix_bytes -1 $profile
    }
}

# convertto -failindex ?-profile? - invalid data
foreach {enc str profile hex failidx ctrl comment} $encUnencodableStrings {
    if {"knownBug" in $ctrl} continue
    set bytes [binary decode hex $hex]
    set printable [tcltest::Asciify $str]
    set prefix A
    set suffix B
    set prefixLen [string length [encoding convertto $enc $prefix]]
    if {$ctrl eq {} || "solo" in $ctrl} {
        testfailindex cmdAH-4.4.14.$printable.solo convertto $enc $str $bytes $failidx $profile
    }
    if {$ctrl eq {} || "lead" in $ctrl} {
        if {$failidx == -1} {
            # If success expected
            set result $bytes$suffix
        } else {
            # Failure expected
            set result ""
        }
        testfailindex cmdAH-4.4.14.$printable.lead convertto $enc $str$suffix $result $failidx $profile
    }
    if {$ctrl eq {} || "tail" in $ctrl} {
        set expected_failidx $failidx
        if {$failidx == -1} {
            # If success expected
            set result $prefix$bytes
        } else {
            # Failure expected
            set result $prefix
            incr expected_failidx $prefixLen
        }
        testfailindex cmdAH-4.4.14.$printable.tail convertto $enc $prefix$str $result $expected_failidx $profile
    }
    if {$ctrl eq {} || "middle" in $ctrl} {
        set expected_failidx $failidx
        if {$failidx == -1} {
            # If success expected
            set result $prefix$bytes$suffix
        } else {
            # Failure expected
            set result $prefix
            incr expected_failidx $prefixLen
        }
        testfailindex cmdAH-4.4.14.$printable.middle convertto $enc $prefix$str$suffix $result $expected_failidx $profile
    }
}

test cmdAH-4.4.xx {convertto -profile strict} -constraints {testbytestring knownBug} -body {
    # TODO - what does testbytestring even test? Invalid UTF8 in the Tcl_Obj bytes field
    encoding convertto -profile strict utf-8 A[testbytestring \x80]B
} -returnCodes error -result {unexpected byte sequence starting at index 1: '\x80'}







|
|
|
|



















|
|
|
|
|
|


|
|
|
|
|
|


|
|
|
|
|
|


|
|
|
|
|
|













|
|
|
|












|


|
|
|
|
|
|
|
|


|
|
|
|
|
|
|
|
|
|


|
|
|
|
|
|
|
|
|
|







543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
    set bytes [binary decode hex $hex]
    set printable [tcltest::Asciify $str]
    set prefix A
    set suffix B
    set prefix_bytes [encoding convertto $enc A]
    set suffix_bytes [encoding convertto $enc B]
    foreach profile $encProfiles {
	testprofile cmdAH-4.4.13.$printable.solo convertto $enc $profile $str $bytes
	testprofile cmdAH-4.4.13.$printable.lead convertto $enc $profile $str$suffix $bytes$suffix_bytes
	testprofile cmdAH-4.4.13.$printable.tail convertto $enc $profile $prefix$str $prefix_bytes$bytes
	testprofile cmdAH-4.4.13.$printable.middle convertto $enc $profile $prefix$str$suffix $prefix_bytes$bytes$suffix_bytes
    }
}

# convertto ?-profile? : invalid byte sequences
foreach {enc str profile hex failidx ctrl comment} $encUnencodableStrings {
    if {"knownBug" in $ctrl} continue
    set bytes [binary decode hex $hex]
    set printable [tcltest::Asciify $str]
    set prefix A
    set suffix B
    set prefix_bytes [encoding convertto $enc $prefix]
    set suffix_bytes [encoding convertto $enc $suffix]
    set prefixLen [string length $prefix_bytes]
    set result [list $bytes]
    # TODO - if the bad byte is unprintable, tcltest errors out when printing a mismatch
    # so glob it out in error message pattern for now.
    set errorWithoutPrefix [list "unexpected character at index $failidx: *" -returnCodes error -match glob]
    set errorWithPrefix [list "unexpected character at index [expr {$failidx+$prefixLen}]: *" -returnCodes error -match glob]
    if {$ctrl eq {} || "solo" in $ctrl} {
	if {$failidx == -1} {
	    set result [list $bytes]
	} else {
	    set result $errorWithoutPrefix
	}
	testprofile cmdAH-4.4.13.$printable.solo convertto $enc $profile $str {*}$result
    }
    if {$ctrl eq {} || "lead" in $ctrl} {
	if {$failidx == -1} {
	    set result [list $bytes$suffix_bytes]
	} else {
	    set result $errorWithoutPrefix
	}
	testprofile cmdAH-4.4.13.$printable.lead convertto $enc $profile $str$suffix {*}$result
    }
    if {$ctrl eq {} || "tail" in $ctrl} {
	if {$failidx == -1} {
	    set result [list $prefix_bytes$bytes]
	} else {
	    set result $errorWithPrefix
	}
	testprofile cmdAH-4.4.13.$printable.tail convertto $enc $profile $prefix$str {*}$result
    }
    if {$ctrl eq {} || "middle" in $ctrl} {
	if {$failidx == -1} {
	    set result [list $prefix_bytes$bytes$suffix_bytes]
	} else {
	    set result $errorWithPrefix
	}
	testprofile cmdAH-4.4.13.$printable.middle convertto $enc $profile $prefix$str$suffix {*}$result
    }
}

# convertto -failindex ?-profile? - valid data
foreach {enc str hex ctrl comment} $encValidStrings {
    if {"knownBug" in $ctrl} continue
    set bytes [binary decode hex $hex]
    set printable [tcltest::Asciify $str]
    set prefix A
    set suffix B
    set prefix_bytes [encoding convertto $enc A]
    set suffix_bytes [encoding convertto $enc B]
    foreach profile $encProfiles {
	testfailindex cmdAH-4.4.14.$enc.$printable.solo convertto $enc $str $bytes -1 $profile
	testfailindex cmdAH-4.4.14.$enc.$printable.lead convertto $enc $str$suffix $bytes$suffix_bytes -1 $profile
	testfailindex cmdAH-4.4.14.$enc.$printable.tail convertto $enc $prefix$str $prefix_bytes$bytes -1 $profile
	testfailindex cmdAH-4.4.14.$enc.$printable.middle convertto $enc $prefix$str$suffix $prefix_bytes$bytes$suffix_bytes -1 $profile
    }
}

# convertto -failindex ?-profile? - invalid data
foreach {enc str profile hex failidx ctrl comment} $encUnencodableStrings {
    if {"knownBug" in $ctrl} continue
    set bytes [binary decode hex $hex]
    set printable [tcltest::Asciify $str]
    set prefix A
    set suffix B
    set prefixLen [string length [encoding convertto $enc $prefix]]
    if {$ctrl eq {} || "solo" in $ctrl} {
	testfailindex cmdAH-4.4.14.$printable.solo convertto $enc $str $bytes $failidx $profile
    }
    if {$ctrl eq {} || "lead" in $ctrl} {
	if {$failidx == -1} {
	    # If success expected
	    set result $bytes$suffix
	} else {
	    # Failure expected
	    set result ""
	}
	testfailindex cmdAH-4.4.14.$printable.lead convertto $enc $str$suffix $result $failidx $profile
    }
    if {$ctrl eq {} || "tail" in $ctrl} {
	set expected_failidx $failidx
	if {$failidx == -1} {
	    # If success expected
	    set result $prefix$bytes
	} else {
	    # Failure expected
	    set result $prefix
	    incr expected_failidx $prefixLen
	}
	testfailindex cmdAH-4.4.14.$printable.tail convertto $enc $prefix$str $result $expected_failidx $profile
    }
    if {$ctrl eq {} || "middle" in $ctrl} {
	set expected_failidx $failidx
	if {$failidx == -1} {
	    # If success expected
	    set result $prefix$bytes$suffix
	} else {
	    # Failure expected
	    set result $prefix
	    incr expected_failidx $prefixLen
	}
	testfailindex cmdAH-4.4.14.$printable.middle convertto $enc $prefix$str$suffix $result $expected_failidx $profile
    }
}

test cmdAH-4.4.xx {convertto -profile strict} -constraints {testbytestring knownBug} -body {
    # TODO - what does testbytestring even test? Invalid UTF8 in the Tcl_Obj bytes field
    encoding convertto -profile strict utf-8 A[testbytestring \x80]B
} -returnCodes error -result {unexpected byte sequence starting at index 1: '\x80'}
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
test cmdAH-16.1 {Tcl_FileObjCmd: readable} {
    -returnCodes error
    -body   {file readable a b}
    -result {wrong # args: should be "file readable name"}
}
test cmdAH-16.2 {Tcl_FileObjCmd: readable} {
    -constraints testchmod
    -setup  	 {testchmod 0o444 $gorpfile}
    -body   	 {file readable $gorpfile}
    -result 	 1
}
test cmdAH-16.3 {Tcl_FileObjCmd: readable} {
    -constraints {unix notRoot testchmod notWsl}
    -setup  	 {testchmod 0o333 $gorpfile}
    -body   	 {file readable $gorpfile}
    -result 	 0
}

# writable
test cmdAH-17.1 {Tcl_FileObjCmd: writable} {
    -returnCodes error
    -body   {file writable a b}
    -result {wrong # args: should be "file writable name"}
}
test cmdAH-17.2 {Tcl_FileObjCmd: writable} {
    -constraints {notRoot testchmod}
    -setup  	 {testchmod 0o555 $gorpfile}
    -body   	 {file writable $gorpfile}
    -result 	 0
}
test cmdAH-17.3 {Tcl_FileObjCmd: writable} {
    -constraints testchmod
    -setup  	 {testchmod 0o222 $gorpfile}
    -body   	 {file writable $gorpfile}
    -result 	 1
}

# executable
removeFile $gorpfile
removeDirectory $dirfile
set dirfile [makeDirectory dir.file]
set gorpfile [makeFile abcde gorp.file]







|
|
|



|
|
|










|
|
|



|
|
|







1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
test cmdAH-16.1 {Tcl_FileObjCmd: readable} {
    -returnCodes error
    -body   {file readable a b}
    -result {wrong # args: should be "file readable name"}
}
test cmdAH-16.2 {Tcl_FileObjCmd: readable} {
    -constraints testchmod
    -setup	 {testchmod 0o444 $gorpfile}
    -body	 {file readable $gorpfile}
    -result	 1
}
test cmdAH-16.3 {Tcl_FileObjCmd: readable} {
    -constraints {unix notRoot testchmod notWsl}
    -setup	 {testchmod 0o333 $gorpfile}
    -body	 {file readable $gorpfile}
    -result	 0
}

# writable
test cmdAH-17.1 {Tcl_FileObjCmd: writable} {
    -returnCodes error
    -body   {file writable a b}
    -result {wrong # args: should be "file writable name"}
}
test cmdAH-17.2 {Tcl_FileObjCmd: writable} {
    -constraints {notRoot testchmod}
    -setup	 {testchmod 0o555 $gorpfile}
    -body	 {file writable $gorpfile}
    -result	 0
}
test cmdAH-17.3 {Tcl_FileObjCmd: writable} {
    -constraints testchmod
    -setup	 {testchmod 0o222 $gorpfile}
    -body	 {file writable $gorpfile}
    -result	 1
}

# executable
removeFile $gorpfile
removeDirectory $dirfile
set dirfile [makeDirectory dir.file]
set gorpfile [makeFile abcde gorp.file]
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
    file exe $gorpfile
} 1
test cmdAH-18.5 {Tcl_FileObjCmd: executable} -constraints {win} -body {
    # On windows, must be a .exe, .com, etc.
    set x {}
    set gorpexes {}
    foreach ext {exe com cmd bat} {
        lappend x [file exe nosuchfile.$ext]
        set gorpexe [makeFile foo gorp.$ext]
        lappend gorpexes $gorpexe
        lappend x [file exe $gorpexe] [file exe [string toupper $gorpexe]]
    }
    set x
} -cleanup {
    foreach gorpexe $gorpexes {
        removeFile $gorpexe
    }
} -result {0 1 1 0 1 1 0 1 1 0 1 1}
test cmdAH-18.6 {Tcl_FileObjCmd: executable} {} {
    # Directories are always executable.
    file exe $dirfile
} 1








|
|
|
|




|







1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
    file exe $gorpfile
} 1
test cmdAH-18.5 {Tcl_FileObjCmd: executable} -constraints {win} -body {
    # On windows, must be a .exe, .com, etc.
    set x {}
    set gorpexes {}
    foreach ext {exe com cmd bat} {
	lappend x [file exe nosuchfile.$ext]
	set gorpexe [makeFile foo gorp.$ext]
	lappend gorpexes $gorpexe
	lappend x [file exe $gorpexe] [file exe [string toupper $gorpexe]]
    }
    set x
} -cleanup {
    foreach gorpexe $gorpexes {
	removeFile $gorpexe
    }
} -result {0 1 1 0 1 1 0 1 1 0 1 1}
test cmdAH-18.6 {Tcl_FileObjCmd: executable} {} {
    # Directories are always executable.
    file exe $dirfile
} 1

1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
    file owned a b
} -result {wrong # args: should be "file owned name"}
test cmdAH-25.2 {Tcl_FileObjCmd: owned} -constraints win -setup {
    set fn $gorpfile
    # prefer temp file to check owner (try to avoid bug [7de2d722bd]):
    if {
	[info exists ::env(TEMP)] && [file isdirectory $::env(TEMP)] &&
        [file dirname $fn] ne [file normalize $::env(TEMP)]
    } {
	set fn [file join $::env(TEMP)/test-owner-from-tcl.txt]
	set fn [makeFile "data" test-owner-from-tcl.txt $::env(TEMP)]
    }
    # be sure we have really owned this file before trying to check that
    # (avoid dependency on admin with UAC and the setting "System objects:
    # Default owner for objects created by members of the Administrators group"):







|







1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
    file owned a b
} -result {wrong # args: should be "file owned name"}
test cmdAH-25.2 {Tcl_FileObjCmd: owned} -constraints win -setup {
    set fn $gorpfile
    # prefer temp file to check owner (try to avoid bug [7de2d722bd]):
    if {
	[info exists ::env(TEMP)] && [file isdirectory $::env(TEMP)] &&
	[file dirname $fn] ne [file normalize $::env(TEMP)]
    } {
	set fn [file join $::env(TEMP)/test-owner-from-tcl.txt]
	set fn [makeFile "data" test-owner-from-tcl.txt $::env(TEMP)]
    }
    # be sure we have really owned this file before trying to check that
    # (avoid dependency on admin with UAC and the setting "System objects:
    # Default owner for objects created by members of the Administrators group"):
Changes to tests/cmdIL.test.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# Used for constraining memory leak tests
testConstraint memory [llength [info commands memory]]
proc memusage {} {
    set fd [open /proc/[pid]/statm]
    set line [gets $fd]
    if {[llength $line] != 7} {
        error "Unexpected /proc/pid/statm format"
    }
    set result [lindex $line 5]
    close $fd
    return $result
}
testConstraint hasMemUsage [expr {![catch {memusage}]}]








|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# Used for constraining memory leak tests
testConstraint memory [llength [info commands memory]]
proc memusage {} {
    set fd [open /proc/[pid]/statm]
    set line [gets $fd]
    if {[llength $line] != 7} {
	error "Unexpected /proc/pid/statm format"
    }
    set result [lindex $line 5]
    close $fd
    return $result
}
testConstraint hasMemUsage [expr {![catch {memusage}]}]

620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
    }}
} -result {1 {can't set "x": variable is array} a}
test cmdIL-6.12 {lassign command - memory leak testing} -setup {
    unset -nocomplain x y
    set x(x) {}
    set y FAIL
    proc getbytes {} {
        set lines [split [memory info] "\n"]
        lindex [lindex $lines 3] 3
    }
    proc stress {} {
	global x y
	lassign {} y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y
	catch {lassign {} y y y y y y y y y y y y y y y y y y y y y y y y y x}
	catch {lassign {} x}
    }







|
|







620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
    }}
} -result {1 {can't set "x": variable is array} a}
test cmdIL-6.12 {lassign command - memory leak testing} -setup {
    unset -nocomplain x y
    set x(x) {}
    set y FAIL
    proc getbytes {} {
	set lines [split [memory info] "\n"]
	lindex [lindex $lines 3] 3
    }
    proc stress {} {
	global x y
	lassign {} y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y
	catch {lassign {} y y y y y y y y y y y y y y y y y y y y y y y y y x}
	catch {lassign {} x}
    }
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
	list [catch {$lassign a y x} msg] $msg $y
    }}
} -result {1 {can't set "x": variable is array} a}
test cmdIL-6.24 {lassign command - memory leak testing} -setup {
    set x(x) {}
    set y FAIL
    proc getbytes {} {
        set lines [split [memory info] "\n"]
        lindex [lindex $lines 3] 3
    }
    proc stress {} {
	global x y
	set lassign lassign
	$lassign {} y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y
	catch {$lassign {} y y y y y y y y y y y y y y y y y y y y y y y y y x}
	catch {$lassign {} x}







|
|







727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
	list [catch {$lassign a y x} msg] $msg $y
    }}
} -result {1 {can't set "x": variable is array} a}
test cmdIL-6.24 {lassign command - memory leak testing} -setup {
    set x(x) {}
    set y FAIL
    proc getbytes {} {
	set lines [split [memory info] "\n"]
	lindex [lindex $lines 3] 3
    }
    proc stress {} {
	global x y
	set lassign lassign
	$lassign {} y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y
	catch {$lassign {} y y y y y y y y y y y y y y y y y y y y y y y y y x}
	catch {$lassign {} x}
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
    lremove {a b c d e} 1 3 1 4 0
} -result {c}

# This belongs in info test, but adding tests there breaks tests
# that compute source file line numbers.
test info-20.6 {Bug 3587651} -setup {
    namespace eval my {namespace eval tcl {namespace eval mathfunc {
        proc demo x {return 42}
    }}}} -body {    namespace eval my {expr {"demo" in [info functions]}}} -cleanup {
    namespace delete my
} -result 1

# cleanup
::tcltest::cleanupTests
return

# Local Variables:
# mode: tcl
# End:







|











865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
    lremove {a b c d e} 1 3 1 4 0
} -result {c}

# This belongs in info test, but adding tests there breaks tests
# that compute source file line numbers.
test info-20.6 {Bug 3587651} -setup {
    namespace eval my {namespace eval tcl {namespace eval mathfunc {
	proc demo x {return 42}
    }}}} -body {    namespace eval my {expr {"demo" in [info functions]}}} -cleanup {
    namespace delete my
} -result 1

# cleanup
::tcltest::cleanupTests
return

# Local Variables:
# mode: tcl
# End:
Changes to tests/cmdInfo.test.
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

test cmdinfo-5.1 {Names for commands created when inside namespaces} \
	{testcmdtoken} {
    # create namespace cmdInfoNs1
    namespace eval cmdInfoNs1 {}   ;# creates namespace cmdInfoNs1
    # create namespace cmdInfoNs1::cmdInfoNs2 and execute a script in it
    set x [namespace eval cmdInfoNs1::cmdInfoNs2 {
        # the following creates a cmd in the global namespace
        testcmdtoken create testCmd
    }]
    set y [testcmdtoken name $x]
    rename ::testCmd newTestCmd
    lappend y {*}[testcmdtoken name $x]
} {testCmd ::testCmd newTestCmd ::newTestCmd}

test cmdinfo-6.1 {Names for commands created when outside namespaces} \







|
|







78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

test cmdinfo-5.1 {Names for commands created when inside namespaces} \
	{testcmdtoken} {
    # create namespace cmdInfoNs1
    namespace eval cmdInfoNs1 {}   ;# creates namespace cmdInfoNs1
    # create namespace cmdInfoNs1::cmdInfoNs2 and execute a script in it
    set x [namespace eval cmdInfoNs1::cmdInfoNs2 {
	# the following creates a cmd in the global namespace
	testcmdtoken create testCmd
    }]
    set y [testcmdtoken name $x]
    rename ::testCmd newTestCmd
    lappend y {*}[testcmdtoken name $x]
} {testCmd ::testCmd newTestCmd ::newTestCmd}

test cmdinfo-6.1 {Names for commands created when outside namespaces} \
Changes to tests/cmdMZ.test.
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
    split {}
} {}
test cmdMZ-4.9 {Tcl_SplitObjCmd: basic split commands} {
    split {   }
} {{} {} {} {}}
test cmdMZ-4.10 {Tcl_SplitObjCmd: basic split commands} {
    apply {{} {
        set x {}
        foreach f [split {]\n} {}] {
            append x $f
        }
        return $x
    }}
} {]\n}
test cmdMZ-4.11 {Tcl_SplitObjCmd: basic split commands} {
    apply {{} {
        set x ab\x00c
        set y [split $x {}]
	binary scan $y c* z
        return $z
    }}
} {97 32 98 32 0 32 99}
test cmdMZ-4.12 {Tcl_SplitObjCmd: basic split commands} {
    split "a0ab1b2bbb3\x00c4" ab\x00c
} {{} 0 {} 1 2 {} {} 3 {} 4}
test cmdMZ-4.13 {Tcl_SplitObjCmd: basic split commands} {
    # if not UTF-8 aware, result is "a {} {} b qwå {} N wq"







|
|
|
|
|




|
|

|







286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
    split {}
} {}
test cmdMZ-4.9 {Tcl_SplitObjCmd: basic split commands} {
    split {   }
} {{} {} {} {}}
test cmdMZ-4.10 {Tcl_SplitObjCmd: basic split commands} {
    apply {{} {
	set x {}
	foreach f [split {]\n} {}] {
	    append x $f
	}
	return $x
    }}
} {]\n}
test cmdMZ-4.11 {Tcl_SplitObjCmd: basic split commands} {
    apply {{} {
	set x ab\x00c
	set y [split $x {}]
	binary scan $y c* z
	return $z
    }}
} {97 32 98 32 0 32 99}
test cmdMZ-4.12 {Tcl_SplitObjCmd: basic split commands} {
    split "a0ab1b2bbb3\x00c4" ab\x00c
} {{} 0 {} 1 2 {} {} 3 {} 4}
test cmdMZ-4.13 {Tcl_SplitObjCmd: basic split commands} {
    # if not UTF-8 aware, result is "a {} {} b qwå {} N wq"
Changes to tests/compExpr-old.test.
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
    return $c
}
proc hello_world {} {
    global a
    set a ""
    set L1 [set l0 [set h_1 [set q 0]]]
    for {put_hello_char [expr [put_hello_char [expr [set h 7]*10+2]]+29]} {$l0?[put_hello_char $l0]
        :!$h_1} {put_hello_char $ll;expr {$L1==2?[set ll [expr 32+0-0+[set bar 0]]]:0}} {expr {[incr L1]==[expr 1+([string length "abc"]-[string length "abc"])]
        ?[set ll [set l0 [expr 54<<1]]]:$ll==108&&$L1<3?
        [incr ll [expr 1|1<<1]; set ll $ll; set ll $ll; set ll $ll; set ll $ll; set l0 [expr ([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])]; set l0; set l0 $l0; set l0; set l0]:$L1==4&&$ll==32?[set ll [expr 19+$h1+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+[set foo [expr ([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])]]]]
        :[set q [expr $q-$h1+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])]]};expr {$L1==5?[incr ll -8; set ll $ll; set ll]:$q&&$h1&&1};expr {$L1==4+2
        ?[incr ll 3]:[expr ([string length "abc"]-[string length "abc"])+1]};expr {$ll==($h<<4)+2+0&&$L1!=6?[incr ll -6]:[set h1 [expr 100+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])]]}
        expr {$L1!=1<<3?[incr q [expr ([string length "abc"]-[string length "abc"])-1]]:[set h_1 [set ll $h1]]}
    }
    set a
}

proc 12days {a b c} {
    global xxx
    expr {1<$a?[expr {$a<3?[12days -79 -13 [string range $c [12days -87 \







|
|
|
|
|
|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
    return $c
}
proc hello_world {} {
    global a
    set a ""
    set L1 [set l0 [set h_1 [set q 0]]]
    for {put_hello_char [expr [put_hello_char [expr [set h 7]*10+2]]+29]} {$l0?[put_hello_char $l0]
	:!$h_1} {put_hello_char $ll;expr {$L1==2?[set ll [expr 32+0-0+[set bar 0]]]:0}} {expr {[incr L1]==[expr 1+([string length "abc"]-[string length "abc"])]
	?[set ll [set l0 [expr 54<<1]]]:$ll==108&&$L1<3?
	[incr ll [expr 1|1<<1]; set ll $ll; set ll $ll; set ll $ll; set ll $ll; set l0 [expr ([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])]; set l0; set l0 $l0; set l0; set l0]:$L1==4&&$ll==32?[set ll [expr 19+$h1+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+[set foo [expr ([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])]]]]
	:[set q [expr $q-$h1+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])]]};expr {$L1==5?[incr ll -8; set ll $ll; set ll]:$q&&$h1&&1};expr {$L1==4+2
	?[incr ll 3]:[expr ([string length "abc"]-[string length "abc"])+1]};expr {$ll==($h<<4)+2+0&&$L1!=6?[incr ll -6]:[set h1 [expr 100+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])]]}
	expr {$L1!=1<<3?[incr q [expr ([string length "abc"]-[string length "abc"])-1]]:[set h_1 [set ll $h1]]}
    }
    set a
}

proc 12days {a b c} {
    global xxx
    expr {1<$a?[expr {$a<3?[12days -79 -13 [string range $c [12days -87 \
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
} -returnCodes error -match glob -result *

test compExpr-old-16.1 {GetToken: checks whether integer token starting with "0x" (e.g., "0x$") is invalid} {
    catch {unset a}
    set a(VALUE) ff15
    set i 123
    if {[expr 0x$a(VALUE)] & 16} {
        set i {}
    }
    set i
} {}
test compExpr-old-16.2 {GetToken: check for string literal in braces} {
    expr {{1}}
} {1}








|







588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
} -returnCodes error -match glob -result *

test compExpr-old-16.1 {GetToken: checks whether integer token starting with "0x" (e.g., "0x$") is invalid} {
    catch {unset a}
    set a(VALUE) ff15
    set i 123
    if {[expr 0x$a(VALUE)] & 16} {
	set i {}
    }
    set i
} {}
test compExpr-old-16.2 {GetToken: check for string literal in braces} {
    expr {{1}}
} {1}

619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
} 11

# Check "expr" and interpreter result object resetting before appending
# an error msg during evaluation of exprs not in {}s

test compExpr-old-19.1 {expr and interpreter result object resetting} {
    proc p {} {
        set t  10.0
        set x  2.0
        set dx 0.2
        set f  {$dx-$x/10}
        set g  {-$x/5}
        set center 1.0
        set x  [expr $x-$center]
        set dx [expr $dx+$g]
        set x  [expr $x+$f+$center]
        set x  [expr $x+$f+$center]
        set y  [expr round($x)]
    }
    p
} 3

# cleanup
if {[info exists a]} {
    unset a
}
::tcltest::cleanupTests
return







|
|
|
|
|
|
|
|
|
|
|










619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
} 11

# Check "expr" and interpreter result object resetting before appending
# an error msg during evaluation of exprs not in {}s

test compExpr-old-19.1 {expr and interpreter result object resetting} {
    proc p {} {
	set t  10.0
	set x  2.0
	set dx 0.2
	set f  {$dx-$x/10}
	set g  {-$x/5}
	set center 1.0
	set x  [expr $x-$center]
	set dx [expr $dx+$g]
	set x  [expr $x+$f+$center]
	set x  [expr $x+$f+$center]
	set y  [expr round($x)]
    }
    p
} 3

# cleanup
if {[info exists a]} {
    unset a
}
::tcltest::cleanupTests
return
Changes to tests/compExpr.test.
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
} -cleanup {
    unset end i tmp
    rename getbytes {}
} -result 0

test compExpr-7.2 {[Bug 1869989]: expr parser memleak} -constraints memory -setup {
    proc getbytes {} {
        set lines [split [memory info] \n]
        lindex $lines 3 3
    }
} -body {
    set i 5
    set end [getbytes]
    while {[incr i -1]} {
        expr ${i}000
        set tmp $end
        set end [getbytes]
    }
    set leakedBytes [expr {$end - $tmp}]
} -cleanup {
    unset end i tmp
    rename getbytes {}
} -result 0

proc extract {opcodes descriptor} {
    set instructions [dict values [dict get $descriptor instructions]]
    return [lmap i $instructions {
	if {[lindex $i 0] in $opcodes} {string cat $i} else continue
    }]
}

test compExpr-8.1 {TIP 582: expression comments} -setup {} -body {
    extract {loadStk add} [tcl::unsupported::getbytecode script {expr {
        $abc
	# + $def
	+ $ghi
    }}]
} -result {loadStk loadStk add}
test compExpr-8.2 {TIP 582: expression comments} -setup {} -body {
    extract {loadStk add} [tcl::unsupported::getbytecode script {expr {
        $abc
	# + $def
	# + $ghi }}]
} -result loadStk
test compExpr-8.3 {TIP 582: expression comments} -setup {} -body {
    extract {loadStk add} [tcl::unsupported::getbytecode script {expr {
        $abc
	# + $def\
	+ $ghi
    }}]
} -result loadStk
test compExpr-8.4 {TIP 582: expression comments} -setup {} -body {
    extract {loadStk add} [tcl::unsupported::getbytecode script {expr {
        $abc
	# + $def\\
	+ $ghi
    }}]
} -result {loadStk loadStk add}

# cleanup
catch {unset a}







|
|





|
|
|
















|






|





|






|







350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
} -cleanup {
    unset end i tmp
    rename getbytes {}
} -result 0

test compExpr-7.2 {[Bug 1869989]: expr parser memleak} -constraints memory -setup {
    proc getbytes {} {
	set lines [split [memory info] \n]
	lindex $lines 3 3
    }
} -body {
    set i 5
    set end [getbytes]
    while {[incr i -1]} {
	expr ${i}000
	set tmp $end
	set end [getbytes]
    }
    set leakedBytes [expr {$end - $tmp}]
} -cleanup {
    unset end i tmp
    rename getbytes {}
} -result 0

proc extract {opcodes descriptor} {
    set instructions [dict values [dict get $descriptor instructions]]
    return [lmap i $instructions {
	if {[lindex $i 0] in $opcodes} {string cat $i} else continue
    }]
}

test compExpr-8.1 {TIP 582: expression comments} -setup {} -body {
    extract {loadStk add} [tcl::unsupported::getbytecode script {expr {
	$abc
	# + $def
	+ $ghi
    }}]
} -result {loadStk loadStk add}
test compExpr-8.2 {TIP 582: expression comments} -setup {} -body {
    extract {loadStk add} [tcl::unsupported::getbytecode script {expr {
	$abc
	# + $def
	# + $ghi }}]
} -result loadStk
test compExpr-8.3 {TIP 582: expression comments} -setup {} -body {
    extract {loadStk add} [tcl::unsupported::getbytecode script {expr {
	$abc
	# + $def\
	+ $ghi
    }}]
} -result loadStk
test compExpr-8.4 {TIP 582: expression comments} -setup {} -body {
    extract {loadStk add} [tcl::unsupported::getbytecode script {expr {
	$abc
	# + $def\\
	+ $ghi
    }}]
} -result {loadStk loadStk add}

# cleanup
catch {unset a}
Changes to tests/compile.test.
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

test compile-1.1 {TclCompileString: look up cmds in proc ns, not current ns} -setup {
    catch {namespace delete test_ns_compile}
    catch {unset x}
} -body {
    set x 123
    namespace eval test_ns_compile {
        proc set {args} {
            global x
            lappend x test_ns_compile::set
        }
        proc p {} {
            set 0
        }
    }
    list [test_ns_compile::p] [set x]
} -result {{123 test_ns_compile::set} {123 test_ns_compile::set}}
test compile-1.2 {TclCompileString, error result is reset if TclGetLong determines word isn't an integer} {
    proc p {x} {info commands 3m}
    list [catch {p} msg] $msg
} {1 {wrong # args: should be "p x"}}

test compile-2.1 {TclCompileDollarVar: global scalar name with ::s} -setup {
    catch {unset x}
} -body {
    set x 123
    list $::x [expr {"x" in [info globals]}]
} -result {123 1}
test compile-2.2 {TclCompileDollarVar: global scalar name with ::s} -setup {
    catch {unset y}
} -body {
    proc p {} {
        set ::y 789
        return $::y
    }
    list [p] $::y [expr {"y" in [info globals]}]
} -result {789 789 1}
test compile-2.3 {TclCompileDollarVar: global array name with ::s} -setup {
    catch {unset a}
} -body {
    set ::a(1) 2
    list $::a(1) [set ::a($::a(1)) 3] $::a(2) [expr {"a" in [info globals]}]
} -result {2 3 3 1}
test compile-2.4 {TclCompileDollarVar: global scalar name with ::s} -setup {
    catch {unset a}
} -body {
    proc p {} {
        set ::a(1) 1
        return $::a($::a(1))
    }
    list [p] $::a(1) [expr {"a" in [info globals]}]
} -result {1 1 1}
test compile-2.5 {TclCompileDollarVar: global array, called as ${arrName(0)}} -setup {
    catch {unset a}
} -body {
    proc p {} {
	global a
        set a(1) 1
        return ${a(1)}$::a(1)$a(1)
    }
    list [p] $::a(1) [expr {"a" in [info globals]}]
} -result {111 1 1}

test compile-3.1 {TclCompileCatchCmd: only catch cmds with scalar vars are compiled inline} -setup {
    catch {unset a}
} -body {
    set a(1) xyzzyx
    proc p {} {
        global a
        catch {set x 123} a(1)
    }
    list [p] $a(1)
} -result {0 123}
test compile-3.2 {TclCompileCatchCmd: non-local variables} {
    set ::foo 1
    proc catch-test {} {
	catch {set x 3} ::foo







|
|
|
|
|
|
|


















|
|













|
|








|
|









|
|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

test compile-1.1 {TclCompileString: look up cmds in proc ns, not current ns} -setup {
    catch {namespace delete test_ns_compile}
    catch {unset x}
} -body {
    set x 123
    namespace eval test_ns_compile {
	proc set {args} {
	    global x
	    lappend x test_ns_compile::set
	}
	proc p {} {
	    set 0
	}
    }
    list [test_ns_compile::p] [set x]
} -result {{123 test_ns_compile::set} {123 test_ns_compile::set}}
test compile-1.2 {TclCompileString, error result is reset if TclGetLong determines word isn't an integer} {
    proc p {x} {info commands 3m}
    list [catch {p} msg] $msg
} {1 {wrong # args: should be "p x"}}

test compile-2.1 {TclCompileDollarVar: global scalar name with ::s} -setup {
    catch {unset x}
} -body {
    set x 123
    list $::x [expr {"x" in [info globals]}]
} -result {123 1}
test compile-2.2 {TclCompileDollarVar: global scalar name with ::s} -setup {
    catch {unset y}
} -body {
    proc p {} {
	set ::y 789
	return $::y
    }
    list [p] $::y [expr {"y" in [info globals]}]
} -result {789 789 1}
test compile-2.3 {TclCompileDollarVar: global array name with ::s} -setup {
    catch {unset a}
} -body {
    set ::a(1) 2
    list $::a(1) [set ::a($::a(1)) 3] $::a(2) [expr {"a" in [info globals]}]
} -result {2 3 3 1}
test compile-2.4 {TclCompileDollarVar: global scalar name with ::s} -setup {
    catch {unset a}
} -body {
    proc p {} {
	set ::a(1) 1
	return $::a($::a(1))
    }
    list [p] $::a(1) [expr {"a" in [info globals]}]
} -result {1 1 1}
test compile-2.5 {TclCompileDollarVar: global array, called as ${arrName(0)}} -setup {
    catch {unset a}
} -body {
    proc p {} {
	global a
	set a(1) 1
	return ${a(1)}$::a(1)$a(1)
    }
    list [p] $::a(1) [expr {"a" in [info globals]}]
} -result {111 1 1}

test compile-3.1 {TclCompileCatchCmd: only catch cmds with scalar vars are compiled inline} -setup {
    catch {unset a}
} -body {
    set a(1) xyzzyx
    proc p {} {
	global a
	catch {set x 123} a(1)
    }
    list [p] $a(1)
} -result {0 123}
test compile-3.2 {TclCompileCatchCmd: non-local variables} {
    set ::foo 1
    proc catch-test {} {
	catch {set x 3} ::foo
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278

test compile-6.1 {TclCompileSetCmd: global scalar names with ::s} -setup {
    catch {unset x}
    catch {unset y}
} -body {
    set x 123
    proc p {} {
        set ::y 789
        return $::y
    }
    list $::x [expr {"x" in [info globals]}] \
         [p] $::y [expr {"y" in [info globals]}]
} -result {123 1 789 789 1}
test compile-6.2 {TclCompileSetCmd: global array names with ::s} -setup {
    catch {unset a}
} -body {
    set ::a(1) 2
    proc p {} {
        set ::a(1) 1
        return $::a($::a(1))
    }
    list $::a(1) [p] [set ::a($::a(1)) 3] $::a(1) [expr {"a" in [info globals]}]
} -result {2 1 3 3 1}
test compile-6.3 {TclCompileSetCmd: namespace var names with ::s} -setup {
    catch {namespace delete test_ns_compile}
    catch {unset x}
} -body {
    namespace eval test_ns_compile {
        variable v hello
        variable arr
        set ::x $::test_ns_compile::v
	set ::test_ns_compile::arr(1) 123
    }
    list $::x $::test_ns_compile::arr(1)
} -result {hello 123}

test compile-7.1 {TclCompileWhileCmd: command substituted test expression} {
    set i 0







|
|


|






|
|








|
|
|







241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278

test compile-6.1 {TclCompileSetCmd: global scalar names with ::s} -setup {
    catch {unset x}
    catch {unset y}
} -body {
    set x 123
    proc p {} {
	set ::y 789
	return $::y
    }
    list $::x [expr {"x" in [info globals]}] \
	 [p] $::y [expr {"y" in [info globals]}]
} -result {123 1 789 789 1}
test compile-6.2 {TclCompileSetCmd: global array names with ::s} -setup {
    catch {unset a}
} -body {
    set ::a(1) 2
    proc p {} {
	set ::a(1) 1
	return $::a($::a(1))
    }
    list $::a(1) [p] [set ::a($::a(1)) 3] $::a(1) [expr {"a" in [info globals]}]
} -result {2 1 3 3 1}
test compile-6.3 {TclCompileSetCmd: namespace var names with ::s} -setup {
    catch {namespace delete test_ns_compile}
    catch {unset x}
} -body {
    namespace eval test_ns_compile {
	variable v hello
	variable arr
	set ::x $::test_ns_compile::v
	set ::test_ns_compile::arr(1) 123
    }
    list $::x $::test_ns_compile::arr(1)
} -result {hello 123}

test compile-7.1 {TclCompileWhileCmd: command substituted test expression} {
    set i 0
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
} {0 4}
test compile-8.3 {CollectArgInfo: handle "]" at end of command properly} {
    set x ]
} {]}

test compile-9.1 {UpdateStringOfByteCode: called for duplicate of compiled empty object} {
    proc p {} {
        set x {}
        eval $x
        append x { }
        eval $x
    }
    p
} {}

test compile-10.1 {BLACKBOX: exception stack overflow} {
    set x {{0}}
    set y 0







|
|
|
|







293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
} {0 4}
test compile-8.3 {CollectArgInfo: handle "]" at end of command properly} {
    set x ]
} {]}

test compile-9.1 {UpdateStringOfByteCode: called for duplicate of compiled empty object} {
    proc p {} {
	set x {}
	eval $x
	append x { }
	eval $x
    }
    p
} {}

test compile-10.1 {BLACKBOX: exception stack overflow} {
    set x {{0}}
    set y 0
Changes to tests/dict.test.
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
} -result {{foo bar bar foo} 6}
test dict-17.12 {dict filter command: script} -returnCodes error -body {
    dict filter {a b} script {k v} {
	concat $k $v
    }
} -cleanup {
    unset k v
} -result {expected boolean value but got "a b"}
test dict-17.13 {dict filter command: script} -body {
    list [catch {dict filter {a b} script {k v} {error x}} msg] $msg \
	    $::errorInfo
} -cleanup {
    unset k v msg
} -result {1 x {x
    while executing







|







1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
} -result {{foo bar bar foo} 6}
test dict-17.12 {dict filter command: script} -returnCodes error -body {
    dict filter {a b} script {k v} {
	concat $k $v
    }
} -cleanup {
    unset k v
} -result {expected boolean value but got a list}
test dict-17.13 {dict filter command: script} -body {
    list [catch {dict filter {a b} script {k v} {error x}} msg] $msg \
	    $::errorInfo
} -cleanup {
    unset k v msg
} -result {1 x {x
    while executing
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
    unset ld
} -result {8 3 8}

# This is a test for a specific bug.
# It shows a bad ref counter when running with memdebug on.
test dict-19.1 {memory bug} {
    apply {{} {
        set successors [dict create x {c d}]
        dict set successors x a b
        dict get $successors x
    }}
} [dict create c d a b]
test dict-19.2 {dict: testing for leaks} -constraints memory -body {
    # This test is made to stress object reference management
    memtest {
	apply {{} {
	    # A shared invalid dictionary







|
|
|







1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
    unset ld
} -result {8 3 8}

# This is a test for a specific bug.
# It shows a bad ref counter when running with memdebug on.
test dict-19.1 {memory bug} {
    apply {{} {
	set successors [dict create x {c d}]
	dict set successors x a b
	dict get $successors x
    }}
} [dict create c d a b]
test dict-19.2 {dict: testing for leaks} -constraints memory -body {
    # This test is made to stress object reference management
    memtest {
	apply {{} {
	    # A shared invalid dictionary
Changes to tests/encoding.test.
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131

}

test encoding-29.0 {get encoding nul terminator lengths} -constraints {
    testencoding
} -body {
    list \
        [testencoding nullength ascii] \
        [testencoding nullength utf-16] \
        [testencoding nullength utf-32] \
        [testencoding nullength gb12345] \
        [testencoding nullength ksc5601]
} -result {1 2 4 2 2}

test encoding-30.0 {encoding convertto large strings UINT_MAX} -constraints {
    perf
} -body {
    # Test to ensure not misinterpreted as -1
    list [string length [set s [string repeat A 0xFFFFFFFF]]] [string equal $s [encoding convertto ascii $s]]







|
|
|
|
|







1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131

}

test encoding-29.0 {get encoding nul terminator lengths} -constraints {
    testencoding
} -body {
    list \
	[testencoding nullength ascii] \
	[testencoding nullength utf-16] \
	[testencoding nullength utf-32] \
	[testencoding nullength gb12345] \
	[testencoding nullength ksc5601]
} -result {1 2 4 2 2}

test encoding-30.0 {encoding convertto large strings UINT_MAX} -constraints {
    perf
} -body {
    # Test to ensure not misinterpreted as -1
    list [string length [set s [string repeat A 0xFFFFFFFF]]] [string equal $s [encoding convertto ascii $s]]
Changes to tests/env.test.
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
    proc manglechar c {
	return [format {\u%04x} [scan $c %c]]
    }

    set names [lsort [array names env]]
    if {$tcl_platform(platform) eq "windows"} {
	lrem names HOME
        lrem names COMSPEC
	lrem names ComSpec
	lrem names ""
    }
    foreach name @keep@ {
	lrem names $name
    }
    foreach p $names {







|







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
    proc manglechar c {
	return [format {\u%04x} [scan $c %c]]
    }

    set names [lsort [array names env]]
    if {$tcl_platform(platform) eq "windows"} {
	lrem names HOME
	lrem names COMSPEC
	lrem names ComSpec
	lrem names ""
    }
    foreach name @keep@ {
	lrem names $name
    }
    foreach p $names {
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417

test env-7.3 {
    [9b4702]: testing existence of env(some_thing) should not destroy trace
} -setup setup1 -body {
    apply {{} {
      catch {unset ::env(test7_3)}
      proc foo args {
        set ::env(test7_3) ok
      }
      trace add variable ::env(not_yet_existent) write foo
      info exists ::env(not_yet_existent)
      set ::env(not_yet_existent) "Now I'm here";
      return [info exists ::env(test7_3)]
    }}
} -cleanup cleanup1 -result 1







|







403
404
405
406
407
408
409
410
411
412
413
414
415
416
417

test env-7.3 {
    [9b4702]: testing existence of env(some_thing) should not destroy trace
} -setup setup1 -body {
    apply {{} {
      catch {unset ::env(test7_3)}
      proc foo args {
	set ::env(test7_3) ok
      }
      trace add variable ::env(not_yet_existent) write foo
      info exists ::env(not_yet_existent)
      set ::env(not_yet_existent) "Now I'm here";
      return [info exists ::env(test7_3)]
    }}
} -cleanup cleanup1 -result 1
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
    }
} -result {}

test env-10.0 {
    Unequal environment strings test should test unequal
} -constraints {unix haveBash utf8system knownBug} -setup {
    set tclScript [makeFile {
        puts [string equal $env(XX) $env(YY)]
    } tclScript]
    set shellCode {
        export XX=$'\351'
        export YY=$'\303\251'
    }
    append shellCode "[info nameofexecutable] $tclScript\n"
    set shScript [makeFile $shellCode shScript]
} -body {
    exec {*}[auto_execok bash] $shScript
} -result 0








|


|
|







513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
    }
} -result {}

test env-10.0 {
    Unequal environment strings test should test unequal
} -constraints {unix haveBash utf8system knownBug} -setup {
    set tclScript [makeFile {
	puts [string equal $env(XX) $env(YY)]
    } tclScript]
    set shellCode {
	export XX=$'\351'
	export YY=$'\303\251'
    }
    append shellCode "[info nameofexecutable] $tclScript\n"
    set shScript [makeFile $shellCode shScript]
} -body {
    exec {*}[auto_execok bash] $shScript
} -result 0

Changes to tests/error.test.
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
    # This test is non-portable: it generates a memory fault on machines like
    # DEC Alphas (infinite recursion overflows stack?)
    #
    # That claims sounds like a bug to be fixed rather than a portability
    # problem. Anyhow, I believe it's out of date (bug's been fixed) so this
    # test is re-enabled.
    proc p {} {
        uplevel 1 catch p error
    }
    p
} 0

# Check errors nested in procedures. Also check the optional argument to
# "error" to generate a new error trace.








|







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
    # This test is non-portable: it generates a memory fault on machines like
    # DEC Alphas (infinite recursion overflows stack?)
    #
    # That claims sounds like a bug to be fixed rather than a portability
    # problem. Anyhow, I believe it's out of date (bug's been fixed) so this
    # test is re-enabled.
    proc p {} {
	uplevel 1 catch p error
    }
    p
} 0

# Check errors nested in procedures. Also check the optional argument to
# "error" to generate a new error trace.

Changes to tests/event.test.
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
} {even 16
}

test event-10.1 {Tcl_Exit procedure} {stdio} {
    set child [open |[list [interpreter]] r+]
    puts $child "exit 3"
    list [catch {close $child} msg] $msg [lindex $::errorCode 0] \
        [lindex $::errorCode 2]
} {1 {child process exited abnormally} CHILDSTATUS 3}

test event-11.1 {Tcl_VwaitCmd procedure} -body {
    vwait
} -result {}
test event-11.3 {Tcl_VwaitCmd procedure} -setup {
    catch {unset x}







|







502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
} {even 16
}

test event-10.1 {Tcl_Exit procedure} {stdio} {
    set child [open |[list [interpreter]] r+]
    puts $child "exit 3"
    list [catch {close $child} msg] $msg [lindex $::errorCode 0] \
	[lindex $::errorCode 2]
} {1 {child process exited abnormally} CHILDSTATUS 3}

test event-11.1 {Tcl_VwaitCmd procedure} -body {
    vwait
} -result {}
test event-11.3 {Tcl_VwaitCmd procedure} -setup {
    catch {unset x}
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
    }
} {}
test event-11.8 {Bug 16828b3744} -setup {
    oo::class create A {
	variable continue

	method start {} {
           after idle [self] destroy

           set continue 0
           vwait [namespace current]::continue
	}
	destructor {
           set continue 1
	}
    }
} -body {
    [A new] start
} -cleanup {
    A destroy
} -result {}







|

|
|


|







592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
    }
} {}
test event-11.8 {Bug 16828b3744} -setup {
    oo::class create A {
	variable continue

	method start {} {
	   after idle [self] destroy

	   set continue 0
	   vwait [namespace current]::continue
	}
	destructor {
	   set continue 1
	}
    }
} -body {
    [A new] start
} -cleanup {
    A destroy
} -result {}
Changes to tests/exec.test.
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
Third line}

test exec-17.1 {inheriting standard I/O} -constraints {exec} -setup {
    set path(script) [makeFile {} script]
    set f [open $path(script) w]
    puts $f [list lassign [list \
	    [info nameofexecutable] $path(gorp.file) $path(echo) $path(sleep) \
        ] exe file echo sleep]
    puts $f {
	close stdout
	set f [open $file w]
	catch {exec $exe $echo foobar &}
	exec $exe $sleep 2
	close $f
    }







|







636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
Third line}

test exec-17.1 {inheriting standard I/O} -constraints {exec} -setup {
    set path(script) [makeFile {} script]
    set f [open $path(script) w]
    puts $f [list lassign [list \
	    [info nameofexecutable] $path(gorp.file) $path(echo) $path(sleep) \
	] exe file echo sleep]
    puts $f {
	close stdout
	set f [open $file w]
	catch {exec $exe $echo foobar &}
	exec $exe $sleep 2
	close $f
    }
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
    exec [makeFile "echo %1> $log" exec201.CMD] "Testing exec-20.1"
    viewFile $log
} -result "\"Testing exec-20.1\""

# Test with encoding mismatches (Bug 0f1ddc0df7fb7)
test exec-21.1 {exec encoding mismatch on stdout} -setup {
    set path(script) [makeFile {
        fconfigure stdout -translation binary
        puts a\xe9b
    } script]
    set enc [encoding system]
    encoding system utf-8
} -cleanup {
    removeFile $path(script)
    encoding system $enc
} -body {
    exec [info nameofexecutable] $path(script)
} -result a\uFFFDb
test exec-21.2 {exec encoding mismatch on stderr} -setup {
    set path(script) [makeFile {
        fconfigure stderr -translation binary
        puts stderr a\xe9b
    } script]
    set enc [encoding system]
    encoding system utf-8
} -cleanup {
    removeFile $path(script)
    encoding system $enc
} -body {







|
|











|
|







712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
    exec [makeFile "echo %1> $log" exec201.CMD] "Testing exec-20.1"
    viewFile $log
} -result "\"Testing exec-20.1\""

# Test with encoding mismatches (Bug 0f1ddc0df7fb7)
test exec-21.1 {exec encoding mismatch on stdout} -setup {
    set path(script) [makeFile {
	fconfigure stdout -translation binary
	puts a\xe9b
    } script]
    set enc [encoding system]
    encoding system utf-8
} -cleanup {
    removeFile $path(script)
    encoding system $enc
} -body {
    exec [info nameofexecutable] $path(script)
} -result a\uFFFDb
test exec-21.2 {exec encoding mismatch on stderr} -setup {
    set path(script) [makeFile {
	fconfigure stderr -translation binary
	puts stderr a\xe9b
    } script]
    set enc [encoding system]
    encoding system utf-8
} -cleanup {
    removeFile $path(script)
    encoding system $enc
} -body {
Changes to tests/execute.test.
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587

test execute-4.1 {Tcl_GetCommandFromObj, convert to tclCmdNameType} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    unset -nocomplain x
    unset -nocomplain y
} -body {
    namespace eval test_ns_1 {
        namespace export cmd1
        proc cmd1 {args} {return "cmd1: $args"}
        proc cmd2 {args} {return "cmd2: $args"}
    }
    namespace eval test_ns_1::test_ns_2 {
        namespace import ::test_ns_1::*
    }
    set x "test_ns_1::"
    set y "test_ns_2::"
    list [namespace which -command ${x}${y}cmd1] \
         [catch {namespace which -command ${x}${y}cmd2} msg] $msg \
         [catch {namespace which -command ${x}${y}:cmd2} msg] $msg
} -result {::test_ns_1::test_ns_2::cmd1 0 {} 0 {}}
test execute-4.2 {Tcl_GetCommandFromObj, check if cached tclCmdNameType is invalid} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {rename foo ""}
    unset -nocomplain l
} -body {
    proc foo {} {
        return "global foo"
    }
    namespace eval test_ns_1 {
        proc whichFoo {} {
            return [namespace which -command foo]
        }
    }
    set l ""
    lappend l [test_ns_1::whichFoo]
    namespace eval test_ns_1 {
        proc foo {} {
            return "namespace foo"
        }
    }
    lappend l [test_ns_1::whichFoo]
} -result {::foo ::test_ns_1::foo}
test execute-4.3 {Tcl_GetCommandFromObj, command never found} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {rename foo ""}
} -body {
    namespace eval test_ns_1 {
        proc foo {} {
            return "namespace foo"
        }
    }
    namespace eval test_ns_1 {
        proc foo {} {
            return "namespace foo"
        }
    }
    list [namespace eval test_ns_1 {namespace which -command foo}] \
         [rename test_ns_1::foo ""] \
         [catch {namespace eval test_ns_1 {namespace which -command foo}} msg] $msg
} -result {::test_ns_1::foo {} 0 {}}

test execute-5.1 {SetCmdNameFromAny, set cmd name to empty heap string if NULL} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    unset -nocomplain l
} -body {
    proc {} {} {return {}}
    {}
    set l {}
    lindex {} 0
    {}
} -result {}

test execute-6.1 {UpdateStringOfCmdName: called for duplicate of empty cmdName object} {
    proc {} {} {}
    proc { } {} {}
    proc p {} {
        set x {}
        $x
        append x { }
        $x
    }
    p
} {}
test execute-6.2 {Evaluate an expression in a variable; compile the first time, do not the second} {
    set w {3*5}
    proc a {obj} {expr $obj}
    set res "[a $w]:[a $w]"







|
|
|


|




|
|







|


|
|
|




|
|
|








|
|
|


|
|
|


|
|

















|
|
|
|







501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587

test execute-4.1 {Tcl_GetCommandFromObj, convert to tclCmdNameType} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    unset -nocomplain x
    unset -nocomplain y
} -body {
    namespace eval test_ns_1 {
	namespace export cmd1
	proc cmd1 {args} {return "cmd1: $args"}
	proc cmd2 {args} {return "cmd2: $args"}
    }
    namespace eval test_ns_1::test_ns_2 {
	namespace import ::test_ns_1::*
    }
    set x "test_ns_1::"
    set y "test_ns_2::"
    list [namespace which -command ${x}${y}cmd1] \
	 [catch {namespace which -command ${x}${y}cmd2} msg] $msg \
	 [catch {namespace which -command ${x}${y}:cmd2} msg] $msg
} -result {::test_ns_1::test_ns_2::cmd1 0 {} 0 {}}
test execute-4.2 {Tcl_GetCommandFromObj, check if cached tclCmdNameType is invalid} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {rename foo ""}
    unset -nocomplain l
} -body {
    proc foo {} {
	return "global foo"
    }
    namespace eval test_ns_1 {
	proc whichFoo {} {
	    return [namespace which -command foo]
	}
    }
    set l ""
    lappend l [test_ns_1::whichFoo]
    namespace eval test_ns_1 {
	proc foo {} {
	    return "namespace foo"
	}
    }
    lappend l [test_ns_1::whichFoo]
} -result {::foo ::test_ns_1::foo}
test execute-4.3 {Tcl_GetCommandFromObj, command never found} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {rename foo ""}
} -body {
    namespace eval test_ns_1 {
	proc foo {} {
	    return "namespace foo"
	}
    }
    namespace eval test_ns_1 {
	proc foo {} {
	    return "namespace foo"
	}
    }
    list [namespace eval test_ns_1 {namespace which -command foo}] \
	 [rename test_ns_1::foo ""] \
	 [catch {namespace eval test_ns_1 {namespace which -command foo}} msg] $msg
} -result {::test_ns_1::foo {} 0 {}}

test execute-5.1 {SetCmdNameFromAny, set cmd name to empty heap string if NULL} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    unset -nocomplain l
} -body {
    proc {} {} {return {}}
    {}
    set l {}
    lindex {} 0
    {}
} -result {}

test execute-6.1 {UpdateStringOfCmdName: called for duplicate of empty cmdName object} {
    proc {} {} {}
    proc { } {} {}
    proc p {} {
	set x {}
	$x
	append x { }
	$x
    }
    p
} {}
test execute-6.2 {Evaluate an expression in a variable; compile the first time, do not the second} {
    set w {3*5}
    proc a {obj} {expr $obj}
    set res "[a $w]:[a $w]"
Changes to tests/expr-old.test.
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
test expr-old-1.50 {integer operators} {expr +36} 36
test expr-old-1.51 {integer operators} {expr +--++36} 36
test expr-old-1.52 {integer operators} {expr +36%+5} 1
test expr-old-1.53 {integer operators} {
    unset -nocomplain x
    set x yes
    list [expr {1 && $x}] [expr {$x && 1}] \
         [expr {0 || $x}] [expr {$x || 0}]
} {1 1 1 1}

# Check the floating-point operators individually, along with
# automatic conversion to integers where needed.

test expr-old-2.1 {floating-point operators} {expr -4.2} -4.2
test expr-old-2.2 {floating-point operators} {expr -(1.125+4.25)} -5.375







|







138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
test expr-old-1.50 {integer operators} {expr +36} 36
test expr-old-1.51 {integer operators} {expr +--++36} 36
test expr-old-1.52 {integer operators} {expr +36%+5} 1
test expr-old-1.53 {integer operators} {
    unset -nocomplain x
    set x yes
    list [expr {1 && $x}] [expr {$x && 1}] \
	 [expr {0 || $x}] [expr {$x || 0}]
} {1 1 1 1}

# Check the floating-point operators individually, along with
# automatic conversion to integers where needed.

test expr-old-2.1 {floating-point operators} {expr -4.2} -4.2
test expr-old-2.2 {floating-point operators} {expr -(1.125+4.25)} -5.375
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
    list [catch {expr func_2(1.0)} msg] $msg
} -match glob -result {1 {* "*func_2"}}
test expr-old-34.2 {errors in math functions} -body {
    expr func|(1.0)
} -returnCodes error -match glob -result *
test expr-old-34.3 {errors in math functions} {
    list [catch {expr {hypot("a b", 2.0)}} msg] $msg
} {1 {expected floating-point number but got "a b"}}
test expr-old-34.4 {errors in math functions} -body {
    expr hypot(1.0 2.0)
} -returnCodes error -match glob -result *
test expr-old-34.5 {errors in math functions} -body {
    expr hypot(1.0, 2.0
} -returnCodes error -match glob -result *
test expr-old-34.6 {errors in math functions} -body {







|







892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
    list [catch {expr func_2(1.0)} msg] $msg
} -match glob -result {1 {* "*func_2"}}
test expr-old-34.2 {errors in math functions} -body {
    expr func|(1.0)
} -returnCodes error -match glob -result *
test expr-old-34.3 {errors in math functions} {
    list [catch {expr {hypot("a b", 2.0)}} msg] $msg
} {1 {expected floating-point number but got a list}}
test expr-old-34.4 {errors in math functions} -body {
    expr hypot(1.0 2.0)
} -returnCodes error -match glob -result *
test expr-old-34.5 {errors in math functions} -body {
    expr hypot(1.0, 2.0
} -returnCodes error -match glob -result *
test expr-old-34.6 {errors in math functions} -body {
Changes to tests/expr.test.
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
    return $c
}
proc hello_world {} {
    global a
    set a ""
    set L1 [set l0 [set h_1 [set q 0]]]
    for {put_hello_char [expr [put_hello_char [expr [set h 7]*10+2]]+29]} {$l0?[put_hello_char $l0]
        :!$h_1} {put_hello_char $ll;expr {$L1==2?[set ll [expr 32+0-0+[set bar 0]]]:0}} {expr {[incr L1]==[expr 1+([string length "abc"]-[string length "abc"])]
        ?[set ll [set l0 [expr 54<<1]]]:$ll==108&&$L1<3?
        [incr ll [expr 1|1<<1]; set ll $ll; set ll $ll; set ll $ll; set ll $ll; set l0 [expr ([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])]; set l0; set l0 $l0; set l0; set l0]:$L1==4&&$ll==32?[set ll [expr 19+$h1+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+[set foo [expr ([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])]]]]
        :[set q [expr $q-$h1+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])]]};expr {$L1==5?[incr ll -8; set ll $ll; set ll]:$q&&$h1&&1};expr {$L1==4+2
        ?[incr ll 3]:[expr ([string length "abc"]-[string length "abc"])+1]};expr {$ll==($h<<4)+2+0&&$L1!=6?[incr ll -6]:[set h1 [expr 100+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])]]}
        expr {$L1!=1<<3?[incr q [expr ([string length "abc"]-[string length "abc"])-1]]:[set h_1 [set ll $h1]]}
    }
    set a
}

proc 12days {a b c} {
    global xxx
    expr {1<$a?[expr {$a<3?[12days -79 -13 [string range $c [12days -87 \







|
|
|
|
|
|







93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
    return $c
}
proc hello_world {} {
    global a
    set a ""
    set L1 [set l0 [set h_1 [set q 0]]]
    for {put_hello_char [expr [put_hello_char [expr [set h 7]*10+2]]+29]} {$l0?[put_hello_char $l0]
	:!$h_1} {put_hello_char $ll;expr {$L1==2?[set ll [expr 32+0-0+[set bar 0]]]:0}} {expr {[incr L1]==[expr 1+([string length "abc"]-[string length "abc"])]
	?[set ll [set l0 [expr 54<<1]]]:$ll==108&&$L1<3?
	[incr ll [expr 1|1<<1]; set ll $ll; set ll $ll; set ll $ll; set ll $ll; set l0 [expr ([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])]; set l0; set l0 $l0; set l0; set l0]:$L1==4&&$ll==32?[set ll [expr 19+$h1+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+[set foo [expr ([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])]]]]
	:[set q [expr $q-$h1+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])]]};expr {$L1==5?[incr ll -8; set ll $ll; set ll]:$q&&$h1&&1};expr {$L1==4+2
	?[incr ll 3]:[expr ([string length "abc"]-[string length "abc"])+1]};expr {$ll==($h<<4)+2+0&&$L1!=6?[incr ll -6]:[set h1 [expr 100+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])]]}
	expr {$L1!=1<<3?[incr q [expr ([string length "abc"]-[string length "abc"])-1]]:[set h_1 [set ll $h1]]}
    }
    set a
}

proc 12days {a b c} {
    global xxx
    expr {1<$a?[expr {$a<3?[12days -79 -13 [string range $c [12days -87 \
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
test expr-11.13b {CompileAddExpr: runtime error} ieeeFloatingPoint {
    list [catch {expr {2.3/0.0}} msg] $msg
} {0 Inf}
test expr-11.14 {CompileAddExpr: runtime error} {
    list [catch {expr {24.0+[lseq 2 4]}} msg] $msg
} {1 {cannot use a list as right operand of "+"}}
test expr-11.15 {CompileAddExpr: runtime error} {
    list [catch {expr {{1 2 3}+24.0}} msg] $msg
} {1 {cannot use non-numeric string "1 2 3" as left operand of "+"}}
test expr-11.16 {CompileAddExpr: runtime error} {
    list [catch {expr {~[dict create foo bar]}} msg] $msg
} {1 {cannot use non-numeric string "foo bar" as operand of "~"}}

test expr-12.1 {CompileMultiplyExpr: just unary expr} {expr ~4} -5
test expr-12.2 {CompileMultiplyExpr: just unary expr} {expr --5} 5
test expr-12.3 {CompileMultiplyExpr: just unary expr} {expr !27} 0
test expr-12.4 {CompileMultiplyExpr: just unary expr} {expr ~0xff00ff} -16711936
test expr-12.5 {CompileMultiplyExpr: error in unary expr} -body {
    expr ~x







|
|


|







501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
test expr-11.13b {CompileAddExpr: runtime error} ieeeFloatingPoint {
    list [catch {expr {2.3/0.0}} msg] $msg
} {0 Inf}
test expr-11.14 {CompileAddExpr: runtime error} {
    list [catch {expr {24.0+[lseq 2 4]}} msg] $msg
} {1 {cannot use a list as right operand of "+"}}
test expr-11.15 {CompileAddExpr: runtime error} {
    list [catch {expr {{1 2 "}+24.0}} msg] $msg
} {1 {cannot use non-numeric string "1 2 "" as left operand of "+"}}
test expr-11.16 {CompileAddExpr: runtime error} {
    list [catch {expr {~[dict create foo bar]}} msg] $msg
} {1 {cannot use a list as operand of "~"}}

test expr-12.1 {CompileMultiplyExpr: just unary expr} {expr ~4} -5
test expr-12.2 {CompileMultiplyExpr: just unary expr} {expr --5} 5
test expr-12.3 {CompileMultiplyExpr: just unary expr} {expr !27} 0
test expr-12.4 {CompileMultiplyExpr: just unary expr} {expr ~0xff00ff} -16711936
test expr-12.5 {CompileMultiplyExpr: error in unary expr} -body {
    expr ~x
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721


test expr-16.1 {GetToken: checks whether integer token starting with "0x" (e.g., "0x$") is invalid} {
    catch {unset a}
    set a(VALUE) ff15
    set i 123
    if {[expr 0x$a(VALUE)] & 16} {
        set i {}
    }
    set i
} {}
test expr-16.2 {GetToken: check for string literal in braces} {
    expr {{1}}
} {1}








|







707
708
709
710
711
712
713
714
715
716
717
718
719
720
721


test expr-16.1 {GetToken: checks whether integer token starting with "0x" (e.g., "0x$") is invalid} {
    catch {unset a}
    set a(VALUE) ff15
    set i 123
    if {[expr 0x$a(VALUE)] & 16} {
	set i {}
    }
    set i
} {}
test expr-16.2 {GetToken: check for string literal in braces} {
    expr {{1}}
} {1}

741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
} { }

# Check "expr" and interpreter result object resetting before appending
# an error msg during evaluation of exprs not in {}s

test expr-19.1 {expr and interpreter result object resetting} {
    proc p {} {
        set t  10.0
        set x  2.0
        set dx 0.2
        set f  {$dx-$x/10}
        set g  {-$x/5}
        set center 1.0
        set x  [expr $x-$center]
        set dx [expr $dx+$g]
        set x  [expr $x+$f+$center]
        set x  [expr $x+$f+$center]
        set y  [expr round($x)]
    }
    p
} 3

# Test for incorrect "double evaluation" semantics

test expr-20.1 {wrong brace matching} {







|
|
|
|
|
|
|
|
|
|
|







741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
} { }

# Check "expr" and interpreter result object resetting before appending
# an error msg during evaluation of exprs not in {}s

test expr-19.1 {expr and interpreter result object resetting} {
    proc p {} {
	set t  10.0
	set x  2.0
	set dx 0.2
	set f  {$dx-$x/10}
	set g  {-$x/5}
	set center 1.0
	set x  [expr $x-$center]
	set dx [expr $dx+$g]
	set x  [expr $x+$f+$center]
	set x  [expr $x+$f+$center]
	set y  [expr round($x)]
    }
    p
} 3

# Test for incorrect "double evaluation" semantics

test expr-20.1 {wrong brace matching} {
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
    proc exprtraceproc {args} {
       upvar #0 exprtracecounter counter
       set argc [llength $args]
       set extraargs [lrange $args 0 [expr {$argc - 4}]]
       set name [lindex $args [expr {$argc - 3}]]
       upvar 1 $name var
       if {[incr counter] % 2 == 1} {
           set var "$counter oops [concat $extraargs]"
       } else {
           set var "$counter + [concat $extraargs]"
       }
    }
    trace add variable exprtracevar read [list exprtraceproc 10]
    list [catch {expr "$exprtracevar + 20"} a] $a \
        [catch {expr "$exprtracevar + 20"} b] $b \
        [unset exprtracevar exprtracecounter]
} -match glob -result {1 * 0 32 {}}
test expr-20.3 {broken substitution of integer digits} {
    # fails with 8.0.x, but not 8.1b2
    list [set a 000; expr 0x1$a] [set a 1; expr ${a}000]
} {4096 1000}
test expr-20.4 {proper double evaluation compilation, error case} {
    catch {unset a}; # make sure $a doesn't exist







|

|




|
|







777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
    proc exprtraceproc {args} {
       upvar #0 exprtracecounter counter
       set argc [llength $args]
       set extraargs [lrange $args 0 [expr {$argc - 4}]]
       set name [lindex $args [expr {$argc - 3}]]
       upvar 1 $name var
       if {[incr counter] % 2 == 1} {
	   set var "$counter oops [concat $extraargs]"
       } else {
	   set var "$counter + [concat $extraargs]"
       }
    }
    trace add variable exprtracevar read [list exprtraceproc 10]
    list [catch {expr "$exprtracevar + 20"} a] $a \
	[catch {expr "$exprtracevar + 20"} b] $b \
	[unset exprtracevar exprtracecounter]
} -match glob -result {1 * 0 32 {}}
test expr-20.3 {broken substitution of integer digits} {
    # fails with 8.0.x, but not 8.1b2
    list [set a 000; expr 0x1$a] [set a 1; expr ${a}000]
} {4096 1000}
test expr-20.4 {proper double evaluation compilation, error case} {
    catch {unset a}; # make sure $a doesn't exist
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
    list [catch {expr + {[incr]}} msg] $msg
} {1 {wrong # args: should be "incr varName ?increment?"}}
test expr-20.7 {handling of compile error in runtime case} {
    list [catch {expr + {[error foo]}} msg] $msg
} {1 foo}

# Test for non-numeric boolean literal handling
test expr-21.1 	{non-numeric boolean literals} {expr false } false
test expr-21.2 	{non-numeric boolean literals} {expr true  } true
test expr-21.3 	{non-numeric boolean literals} {expr off   } off
test expr-21.4 	{non-numeric boolean literals} {expr on    } on
test expr-21.5 	{non-numeric boolean literals} {expr no    } no
test expr-21.6 	{non-numeric boolean literals} {expr yes   } yes
test expr-21.7 	{non-numeric boolean literals} {expr !false} 1
test expr-21.8 	{non-numeric boolean literals} {expr !true } 0
test expr-21.9 	{non-numeric boolean literals} {expr !off  } 1
test expr-21.10 {non-numeric boolean literals} {expr !on   } 0
test expr-21.11 {non-numeric boolean literals} {expr !no   } 1
test expr-21.12 {non-numeric boolean literals} {expr !yes  } 0
test expr-21.13 {non-numeric boolean literals} -body {
    expr !truef
} -returnCodes error -match glob -result *
test expr-21.14 {non-numeric boolean literals} {







|
|
|
|
|
|
|
|
|







807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
    list [catch {expr + {[incr]}} msg] $msg
} {1 {wrong # args: should be "incr varName ?increment?"}}
test expr-20.7 {handling of compile error in runtime case} {
    list [catch {expr + {[error foo]}} msg] $msg
} {1 foo}

# Test for non-numeric boolean literal handling
test expr-21.1	{non-numeric boolean literals} {expr false } false
test expr-21.2	{non-numeric boolean literals} {expr true  } true
test expr-21.3	{non-numeric boolean literals} {expr off   } off
test expr-21.4	{non-numeric boolean literals} {expr on    } on
test expr-21.5	{non-numeric boolean literals} {expr no    } no
test expr-21.6	{non-numeric boolean literals} {expr yes   } yes
test expr-21.7	{non-numeric boolean literals} {expr !false} 1
test expr-21.8	{non-numeric boolean literals} {expr !true } 0
test expr-21.9	{non-numeric boolean literals} {expr !off  } 1
test expr-21.10 {non-numeric boolean literals} {expr !on   } 0
test expr-21.11 {non-numeric boolean literals} {expr !no   } 1
test expr-21.12 {non-numeric boolean literals} {expr !yes  } 0
test expr-21.13 {non-numeric boolean literals} -body {
    expr !truef
} -returnCodes error -match glob -result *
test expr-21.14 {non-numeric boolean literals} {
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
test expr-31.14 {boolean conversion} {expr bool(wide(5))} 1
test expr-31.15 {boolean conversion} -body {
    expr bool("fred")
} -returnCodes error -match glob -result *

test expr-32.1 {expr mod basics} {
    set mod_nums [list \
        {-3 1} {-3 2} {-3 3} {-3 4} {-3 5} \
        {-3 -1} {-3 -2} {-3 -3} {-3 -4} {-3 -5} \
        {-2 1} {-2 2} {-2 3} {-2 4} {-2 5} \
        {-2 -1} {-2 -2} {-2 -3} {-2 -4} {-2 -5} \
        {-1 1} {-1 2} {-1 3} {-1 4} {-1 5} \
        {-1 -1} {-1 -2} {-1 -3} {-1 -4} {-1 -5} \
        {0 -100} {0 -1} {0 1} {0 100} \
        {1 1} {1 2} {1 3} {1 4} {1 5} \
        {1 -1} {1 -2} {1 -3} {1 -4} {1 -5} \
        {2 1} {2 2} {2 3} {2 4} {2 5} \
        {2 -1} {2 -2} {2 -3} {2 -4} {2 -5} \
        {3 1} {3 2} {3 3} {3 4} {3 5} \
        {3 -1} {3 -2} {3 -3} {3 -4} {3 -5} \
        ]
    set results [list]
    foreach pair $mod_nums {
        set dividend [lindex $pair 0]
        set divisor [lindex $pair 1]
        lappend results [expr {$dividend % $divisor}]
    }
    set results
} [list \
    0 1 0 1 2 \
    0 -1 0 -3 -3 \
    0 0 1 2 3 \
    0 0 -2 -2 -2 \
    0 1 2 3 4 \
    0 -1 -1 -1 -1 \
    0 0 0 0 \
    0 1 1 1 1 \
    0 -1 -2 -3 -4 \
    0 0 2 2 2 \
    0 0 -1 -2 -3 \
    0 1 0 3 3 \
    0 -1 0 -1 -2 \
    ]

test expr-32.2 {expr div basics} {
    set mod_nums [list \
        {-3 1} {-3 2} {-3 3} {-3 4} {-3 5} \
        {-3 -1} {-3 -2} {-3 -3} {-3 -4} {-3 -5} \
        {-2 1} {-2 2} {-2 3} {-2 4} {-2 5} \
        {-2 -1} {-2 -2} {-2 -3} {-2 -4} {-2 -5} \
        {-1 1} {-1 2} {-1 3} {-1 4} {-1 5} \
        {-1 -1} {-1 -2} {-1 -3} {-1 -4} {-1 -5} \
        {0 -100} {0 -1} {0 1} {0 100} \
        {1 1} {1 2} {1 3} {1 4} {1 5} \
        {1 -1} {1 -2} {1 -3} {1 -4} {1 -5} \
        {2 1} {2 2} {2 3} {2 4} {2 5} \
        {2 -1} {2 -2} {2 -3} {2 -4} {2 -5} \
        {3 1} {3 2} {3 3} {3 4} {3 5} \
        {3 -1} {3 -2} {3 -3} {3 -4} {3 -5} \
        ]
    set results [list]
    foreach pair $mod_nums {
        set dividend [lindex $pair 0]
        set divisor [lindex $pair 1]
        lappend results [expr {$dividend / $divisor}]
    }
    set results
} [list \
    -3 -2 -1 -1 -1 \
    3 1 1 0 0 \
    -2 -1 -1 -1 -1 \
    2 1 0 0 0 \







|
|
|
|
|
|
|
|
|
|
|
|
|
|


|
|
|




















|
|
|
|
|
|
|
|
|
|
|
|
|
|


|
|
|







5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
test expr-31.14 {boolean conversion} {expr bool(wide(5))} 1
test expr-31.15 {boolean conversion} -body {
    expr bool("fred")
} -returnCodes error -match glob -result *

test expr-32.1 {expr mod basics} {
    set mod_nums [list \
	{-3 1} {-3 2} {-3 3} {-3 4} {-3 5} \
	{-3 -1} {-3 -2} {-3 -3} {-3 -4} {-3 -5} \
	{-2 1} {-2 2} {-2 3} {-2 4} {-2 5} \
	{-2 -1} {-2 -2} {-2 -3} {-2 -4} {-2 -5} \
	{-1 1} {-1 2} {-1 3} {-1 4} {-1 5} \
	{-1 -1} {-1 -2} {-1 -3} {-1 -4} {-1 -5} \
	{0 -100} {0 -1} {0 1} {0 100} \
	{1 1} {1 2} {1 3} {1 4} {1 5} \
	{1 -1} {1 -2} {1 -3} {1 -4} {1 -5} \
	{2 1} {2 2} {2 3} {2 4} {2 5} \
	{2 -1} {2 -2} {2 -3} {2 -4} {2 -5} \
	{3 1} {3 2} {3 3} {3 4} {3 5} \
	{3 -1} {3 -2} {3 -3} {3 -4} {3 -5} \
	]
    set results [list]
    foreach pair $mod_nums {
	set dividend [lindex $pair 0]
	set divisor [lindex $pair 1]
	lappend results [expr {$dividend % $divisor}]
    }
    set results
} [list \
    0 1 0 1 2 \
    0 -1 0 -3 -3 \
    0 0 1 2 3 \
    0 0 -2 -2 -2 \
    0 1 2 3 4 \
    0 -1 -1 -1 -1 \
    0 0 0 0 \
    0 1 1 1 1 \
    0 -1 -2 -3 -4 \
    0 0 2 2 2 \
    0 0 -1 -2 -3 \
    0 1 0 3 3 \
    0 -1 0 -1 -2 \
    ]

test expr-32.2 {expr div basics} {
    set mod_nums [list \
	{-3 1} {-3 2} {-3 3} {-3 4} {-3 5} \
	{-3 -1} {-3 -2} {-3 -3} {-3 -4} {-3 -5} \
	{-2 1} {-2 2} {-2 3} {-2 4} {-2 5} \
	{-2 -1} {-2 -2} {-2 -3} {-2 -4} {-2 -5} \
	{-1 1} {-1 2} {-1 3} {-1 4} {-1 5} \
	{-1 -1} {-1 -2} {-1 -3} {-1 -4} {-1 -5} \
	{0 -100} {0 -1} {0 1} {0 100} \
	{1 1} {1 2} {1 3} {1 4} {1 5} \
	{1 -1} {1 -2} {1 -3} {1 -4} {1 -5} \
	{2 1} {2 2} {2 3} {2 4} {2 5} \
	{2 -1} {2 -2} {2 -3} {2 -4} {2 -5} \
	{3 1} {3 2} {3 3} {3 4} {3 5} \
	{3 -1} {3 -2} {3 -3} {3 -4} {3 -5} \
	]
    set results [list]
    foreach pair $mod_nums {
	set dividend [lindex $pair 0]
	set divisor [lindex $pair 1]
	lappend results [expr {$dividend / $divisor}]
    }
    set results
} [list \
    -3 -2 -1 -1 -1 \
    3 1 1 0 0 \
    -2 -1 -1 -1 -1 \
    2 1 0 0 0 \
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
    set max_long_hex "0x7FFFFFFF "

    # Convert to integer (long, not wide) internal rep
    set max_long 2147483647
    string is integer $max_long

    list \
        [expr {" $max_long_str "}] \
        [expr {$max_long_str + 0}] \
        [expr {$max_long + 0}] \
        [expr {2147483647 + 0}] \
        [expr {$max_long == $max_long_hex}] \
        [expr {int(2147483647 + 1) > 0}] \

} {2147483647 2147483647 2147483647 2147483647 1 1}
test expr-33.2 {parse smallest long value} {
    set min_long_str -2147483648
    set min_long_hex "-0x80000000 "

    set min_long -2147483648
    # This will convert to integer (not wide) internal rep
    string is integer $min_long

    # Note: If the final expression returns 0 then the
    # expression literal is being promoted to a wide type
    # when it should be parsed as a long type.
    list \
        [expr {" $min_long_str "}] \
        [expr {$min_long_str + 0}] \
        [expr {$min_long + 0}] \
        [expr {-2147483648 + 0}] \
        [expr {$min_long == $min_long_hex}] \
        [expr {int(-2147483648 - 1) == -0x80000001}] \

} {-2147483648 -2147483648 -2147483648 -2147483648 1 1}
test expr-33.3 {parse largest wide value} wideIs64bit {
    set max_wide_str 9223372036854775807
    set max_wide_hex "0x7FFFFFFFFFFFFFFF "

    # Convert to wide integer
    set max_wide 9223372036854775807
    string is integer $max_wide

    list \
        [expr {" $max_wide_str "}] \
        [expr {$max_wide_str + 0}] \
        [expr {$max_wide + 0}] \
        [expr {9223372036854775807 + 0}] \
        [expr {$max_wide == $max_wide_hex}] \
        [expr {wide(9223372036854775807 + 1) < 0}] \

} {9223372036854775807 9223372036854775807 9223372036854775807 9223372036854775807 1 1}
test expr-33.4 {parse smallest wide value} wideIs64bit {
    set min_wide_str -9223372036854775808
    set min_wide_hex "-0x8000000000000000 "

    set min_wide -9223372036854775808
    # Convert to wide integer
    string is integer $min_wide

    # Note: If the final expression returns 0 then the
    # wide integer is not being parsed correctly with
    # the leading - sign.
    list \
        [expr {" $min_wide_str "}] \
        [expr {$min_wide_str + 0}] \
        [expr {$min_wide + 0}] \
        [expr {-9223372036854775808 + 0}] \
        [expr {$min_wide == $min_wide_hex}] \
        [expr {wide(-9223372036854775808 - 1) == 0x7FFFFFFFFFFFFFFF}] \

} {-9223372036854775808 -9223372036854775808 -9223372036854775808 -9223372036854775808 1 1}

set min -2147483648
set max 2147483647

test expr-34.1 {expr edge cases} {







|
|
|
|
|
|














|
|
|
|
|
|











|
|
|
|
|
|














|
|
|
|
|
|







5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
    set max_long_hex "0x7FFFFFFF "

    # Convert to integer (long, not wide) internal rep
    set max_long 2147483647
    string is integer $max_long

    list \
	[expr {" $max_long_str "}] \
	[expr {$max_long_str + 0}] \
	[expr {$max_long + 0}] \
	[expr {2147483647 + 0}] \
	[expr {$max_long == $max_long_hex}] \
	[expr {int(2147483647 + 1) > 0}] \

} {2147483647 2147483647 2147483647 2147483647 1 1}
test expr-33.2 {parse smallest long value} {
    set min_long_str -2147483648
    set min_long_hex "-0x80000000 "

    set min_long -2147483648
    # This will convert to integer (not wide) internal rep
    string is integer $min_long

    # Note: If the final expression returns 0 then the
    # expression literal is being promoted to a wide type
    # when it should be parsed as a long type.
    list \
	[expr {" $min_long_str "}] \
	[expr {$min_long_str + 0}] \
	[expr {$min_long + 0}] \
	[expr {-2147483648 + 0}] \
	[expr {$min_long == $min_long_hex}] \
	[expr {int(-2147483648 - 1) == -0x80000001}] \

} {-2147483648 -2147483648 -2147483648 -2147483648 1 1}
test expr-33.3 {parse largest wide value} wideIs64bit {
    set max_wide_str 9223372036854775807
    set max_wide_hex "0x7FFFFFFFFFFFFFFF "

    # Convert to wide integer
    set max_wide 9223372036854775807
    string is integer $max_wide

    list \
	[expr {" $max_wide_str "}] \
	[expr {$max_wide_str + 0}] \
	[expr {$max_wide + 0}] \
	[expr {9223372036854775807 + 0}] \
	[expr {$max_wide == $max_wide_hex}] \
	[expr {wide(9223372036854775807 + 1) < 0}] \

} {9223372036854775807 9223372036854775807 9223372036854775807 9223372036854775807 1 1}
test expr-33.4 {parse smallest wide value} wideIs64bit {
    set min_wide_str -9223372036854775808
    set min_wide_hex "-0x8000000000000000 "

    set min_wide -9223372036854775808
    # Convert to wide integer
    string is integer $min_wide

    # Note: If the final expression returns 0 then the
    # wide integer is not being parsed correctly with
    # the leading - sign.
    list \
	[expr {" $min_wide_str "}] \
	[expr {$min_wide_str + 0}] \
	[expr {$min_wide + 0}] \
	[expr {-9223372036854775808 + 0}] \
	[expr {$min_wide == $min_wide_hex}] \
	[expr {wide(-9223372036854775808 - 1) == 0x7FFFFFFFFFFFFFFF}] \

} {-9223372036854775808 -9223372036854775808 -9223372036854775808 -9223372036854775808 1 1}

set min -2147483648
set max 2147483647

test expr-34.1 {expr edge cases} {
7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
    }
    set trouble
} {}
test expr-47.14 {isqrt() - lseq} {
    list [catch {expr {isqrt([lseq 1 3])}} result] $result
} {1 {expected number but got a list}}
test expr-47.15 {isqrt() - lseq} {
    list [catch {expr {isqrt({1 2 3})}} result] $result
} {1 {expected number but got a list}}
test expr-47.16 {isqrt() - lseq} {
    list [catch {expr {isqrt([dict create foo bar])}} result] $result
} {1 {expected number but got a list}}

test expr-48.1 {Bug 1770224} {
    expr {-0x8000000000000001 >> 0x8000000000000000}
} -1







|
|







7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
    }
    set trouble
} {}
test expr-47.14 {isqrt() - lseq} {
    list [catch {expr {isqrt([lseq 1 3])}} result] $result
} {1 {expected number but got a list}}
test expr-47.15 {isqrt() - lseq} {
    list [catch {expr {isqrt({1 2 "})}} result] $result
} {1 {expected number but got "1 2 ""}}
test expr-47.16 {isqrt() - lseq} {
    list [catch {expr {isqrt([dict create foo bar])}} result] $result
} {1 {expected number but got a list}}

test expr-48.1 {Bug 1770224} {
    expr {-0x8000000000000001 >> 0x8000000000000000}
} -1
Changes to tests/fCmd.test.
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
	} on error {} {
	    # try the location given to use on the commandline to tcltest
	    ::tcltest::loadTestedCommands
	    load $::reglib Registry
	}
	testConstraint reg 1
    } regError]} {
        catch {package require registry; testConstraint reg 1}
    }
}

testConstraint notInCIenv [expr {![info exists ::env(CI)] || !$::env(CI)}]

# File permissions broken on wsl without some "exotic" wsl configuration
testConstraint notWsl [expr {[llength [array names ::env *WSL*]] == 0}]







|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
	} on error {} {
	    # try the location given to use on the commandline to tcltest
	    ::tcltest::loadTestedCommands
	    load $::reglib Registry
	}
	testConstraint reg 1
    } regError]} {
	catch {package require registry; testConstraint reg 1}
    }
}

testConstraint notInCIenv [expr {![info exists ::env(CI)] || !$::env(CI)}]

# File permissions broken on wsl without some "exotic" wsl configuration
testConstraint notWsl [expr {[llength [array names ::env *WSL*]] == 0}]
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
    }
    if {$user eq ""} {
	set user "root"
    }
}
if {[testConstraint win]} {
    catch {
        set user $::env(USERNAME)
    }
    if {$user eq ""} {
        set user Administrator
    }
}

# Try getting a lower case glob pattern that will match the home directory of
# a given user to test ~user and [file tildeexpand ~user]. Note this may not
# be the same as ~ even when "user" is current user. For example, on Unix
# platforms ~ will return HOME envvar, but ~user will lookup password file
# bypassing HOME. If home directory not found, returns *$user* so caller can
# succeed by using glob matching under the hope that the path contains
# the user name.
proc gethomedirglob {user} {
    if {[testConstraint unix]} {
        if {![catch {
            exec {*}[auto_execok sh] -c "echo ~$user"
        } home]} {
            set home [string trim $home]
            if {$home ne ""} {
                # Expect exact match (except case), no glob * added
                return [string tolower $home]
            }
        }
    } elseif {[testConstraint reg]} {
        # Windows with registry extension loaded
        if {![catch {
            set sid [exec {*}[auto_execok powershell] -Command "(Get-LocalUser -Name '$user')\[0\].sid.Value"]
            set sid [string trim $sid]
            # Get path from the Windows registry
            set home [registry get "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\$sid" ProfileImagePath]
            set home [string trim [string tolower $home]]
        } result]} {
            if {$home ne ""} {
                # file join for \ -> /
                return [file join [string tolower $home]]
            }
        }
    }

    # Caller will need to use glob matching and hope user
    # name is in the home directory path
    return *[string tolower $user]*
}








|


|












|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
    }
    if {$user eq ""} {
	set user "root"
    }
}
if {[testConstraint win]} {
    catch {
	set user $::env(USERNAME)
    }
    if {$user eq ""} {
	set user Administrator
    }
}

# Try getting a lower case glob pattern that will match the home directory of
# a given user to test ~user and [file tildeexpand ~user]. Note this may not
# be the same as ~ even when "user" is current user. For example, on Unix
# platforms ~ will return HOME envvar, but ~user will lookup password file
# bypassing HOME. If home directory not found, returns *$user* so caller can
# succeed by using glob matching under the hope that the path contains
# the user name.
proc gethomedirglob {user} {
    if {[testConstraint unix]} {
	if {![catch {
	    exec {*}[auto_execok sh] -c "echo ~$user"
	} home]} {
	    set home [string trim $home]
	    if {$home ne ""} {
		# Expect exact match (except case), no glob * added
		return [string tolower $home]
	    }
	}
    } elseif {[testConstraint reg]} {
	# Windows with registry extension loaded
	if {![catch {
	    set sid [exec {*}[auto_execok powershell] -Command "(Get-LocalUser -Name '$user')\[0\].sid.Value"]
	    set sid [string trim $sid]
	    # Get path from the Windows registry
	    set home [registry get "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\$sid" ProfileImagePath]
	    set home [string trim [string tolower $home]]
	} result]} {
	    if {$home ne ""} {
		# file join for \ -> /
		return [file join [string tolower $home]]
	    }
	}
    }

    # Caller will need to use glob matching and hope user
    # name is in the home directory path
    return *[string tolower $user]*
}

173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
    }
    return [string match $matchString $fileString]
}

proc openup {path} {
    # Double check for inadvertent ~ -> home directory mapping
    if {[string match ~* $path]} {
        set file ./$path
    }
    testchmod 0o777 $path
    if {[file isdirectory $path]} {
	catch {
	    foreach p [glob -directory $path *] {
		openup $p
	    }
	}
    }
}

proc cleanup {args} {
    set wd [list .]
    foreach p [concat $wd $args] {
	set x ""
	catch {
	    set x [glob -directory $p tf* td* ~*]
	}
	foreach file $x {
            # Double check for inadvertent ~ -> home directory mapping
            if {[string match ~* $file]} {
                set file ./$file
            }
	    if {
		[catch {file delete -force -- $file}]
		&& [testConstraint testchmod]
	    } then {
		catch {openup $file}
		catch {file delete -force -- $file}
	    }







|



















|
|
|
|







173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
    }
    return [string match $matchString $fileString]
}

proc openup {path} {
    # Double check for inadvertent ~ -> home directory mapping
    if {[string match ~* $path]} {
	set file ./$path
    }
    testchmod 0o777 $path
    if {[file isdirectory $path]} {
	catch {
	    foreach p [glob -directory $path *] {
		openup $p
	    }
	}
    }
}

proc cleanup {args} {
    set wd [list .]
    foreach p [concat $wd $args] {
	set x ""
	catch {
	    set x [glob -directory $p tf* td* ~*]
	}
	foreach file $x {
	    # Double check for inadvertent ~ -> home directory mapping
	    if {[string match ~* $file]} {
		set file ./$file
	    }
	    if {
		[catch {file delete -force -- $file}]
		&& [testConstraint testchmod]
	    } then {
		catch {openup $file}
		catch {file delete -force -- $file}
	    }
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
    createfile tfs3
    createfile tfs4
    createfile tfd1
    createfile tfd2
    createfile tfd3
    createfile tfd4
    if {$::tcl_platform(platform) eq "windows"} {
        # On Windows testchmode will attach an ACL which file copy cannot handle
        # so use good old attributes which file copy does understand
        file attribute tfs3 -readonly 1
        file attribute tfs4 -readonly 1
        file attribute tfd2 -readonly 1
        file attribute tfd4 -readonly 1
    } else {
        testchmod 0o444 tfs3
        testchmod 0o444 tfs4
        testchmod 0o444 tfd2
        testchmod 0o444 tfd4
    }
    set msg [list [catch {file copy tf1 tf2} msg] $msg]
    file copy -force tfs1 tfd1
    file copy -force tfs2 tfd2
    file copy -force tfs3 tfd3
    file copy -force tfs4 tfd4
    list [lsort [glob tf*]] $msg [file writable tfd1] [file writable tfd2] [file writable tfd3] [file writable tfd4]







|
|
|
|
|
|

|
|
|
|







1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
    createfile tfs3
    createfile tfs4
    createfile tfd1
    createfile tfd2
    createfile tfd3
    createfile tfd4
    if {$::tcl_platform(platform) eq "windows"} {
	# On Windows testchmode will attach an ACL which file copy cannot handle
	# so use good old attributes which file copy does understand
	file attribute tfs3 -readonly 1
	file attribute tfs4 -readonly 1
	file attribute tfd2 -readonly 1
	file attribute tfd4 -readonly 1
    } else {
	testchmod 0o444 tfs3
	testchmod 0o444 tfs4
	testchmod 0o444 tfd2
	testchmod 0o444 tfd4
    }
    set msg [list [catch {file copy tf1 tf2} msg] $msg]
    file copy -force tfs1 tfd1
    file copy -force tfs2 tfd2
    file copy -force tfs3 tfd3
    file copy -force tfs4 tfd4
    list [lsort [glob tf*]] $msg [file writable tfd1] [file writable tfd2] [file writable tfd3] [file writable tfd4]
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
    # Get the localized version of the folder name by looking in the registry.
    set mydocsname [registry get {HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders} Personal]
} -constraints {win reg} -body {
    file writable $mydocsname
} -result 1
test fCmd-30.2 {file readable on 'NTUSER.DAT'} -constraints {win notWine} -body {
    expr {[info exists env(USERPROFILE)]
          && [file exists $env(USERPROFILE)/NTUSER.DAT]
          && [file readable $env(USERPROFILE)/NTUSER.DAT]}
} -result 1
# At least one CI environment (GitHub Actions) is set up with the page file in
# an unusual location; skip the test if that is so.
test fCmd-30.3 {file readable on 'pagefile.sys'} -constraints {win notInCIenv} -body {
    set r {}
    if {[info exists env(SystemDrive)]} {
        set path $env(SystemDrive)/pagefile.sys
        lappend r exists [file exists $path]
        lappend r readable [file readable $path]
        lappend r stat [catch {file stat $path a} e] $e
    }
    return $r
} -result {exists 1 readable 0 stat 0 {}}

test fCmd-31.1 {file home} -body {
    file home
} -result [file join $::env(HOME)]







|
|






|
|
|
|







2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
    # Get the localized version of the folder name by looking in the registry.
    set mydocsname [registry get {HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders} Personal]
} -constraints {win reg} -body {
    file writable $mydocsname
} -result 1
test fCmd-30.2 {file readable on 'NTUSER.DAT'} -constraints {win notWine} -body {
    expr {[info exists env(USERPROFILE)]
	  && [file exists $env(USERPROFILE)/NTUSER.DAT]
	  && [file readable $env(USERPROFILE)/NTUSER.DAT]}
} -result 1
# At least one CI environment (GitHub Actions) is set up with the page file in
# an unusual location; skip the test if that is so.
test fCmd-30.3 {file readable on 'pagefile.sys'} -constraints {win notInCIenv} -body {
    set r {}
    if {[info exists env(SystemDrive)]} {
	set path $env(SystemDrive)/pagefile.sys
	lappend r exists [file exists $path]
	lappend r readable [file readable $path]
	lappend r stat [catch {file stat $path a} e] $e
    }
    return $r
} -result {exists 1 readable 0 stat 0 {}}

test fCmd-31.1 {file home} -body {
    file home
} -result [file join $::env(HOME)]
Changes to tests/fileName.test.
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
} globTest/a1/

test filename-14.31 {Bug 2918610} -setup {
    set d [makeDirectory foo]
    makeFile {} bar.soom $d
} -body {
    foreach fn [glob $d/bar.soom] {
        set root [file rootname $fn]
        close [open $root {WRONLY CREAT}]
    }
    llength [glob -directory $d *]
} -cleanup {
    file delete -force $d/bar
    removeFile bar.soom $d
    removeDirectory foo
} -result 2







|
|







1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
} globTest/a1/

test filename-14.31 {Bug 2918610} -setup {
    set d [makeDirectory foo]
    makeFile {} bar.soom $d
} -body {
    foreach fn [glob $d/bar.soom] {
	set root [file rootname $fn]
	close [open $root {WRONLY CREAT}]
    }
    llength [glob -directory $d *]
} -cleanup {
    file delete -force $d/bar
    removeFile bar.soom $d
    removeDirectory foo
} -result 2
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
} {absolute absolute absolute absolute absolute absolute relative}
if {[testConstraint testsetplatform]} {
    testsetplatform $platform
}
test filename-17.2 {windows specific glob with executable} -body {
    makeDirectory execglob
    foreach ext {exe com cmd bat notexecutable} {
        makeFile contents execglob/abc.$ext
    }
    lsort [glob -nocomplain -dir [temporaryDirectory]/execglob -tails -types x *]
} -constraints {win} -cleanup {
    foreach ext {exe com cmd bat ps1 notexecutable} {
        removeFile execglob/abc.$ext
    }
    removeDirectory execglob
} -result {abc.bat abc.cmd abc.com abc.exe}
test filename-17.3 {Bug 2571597} win {
    set p /a
    file pathtype $p
    file normalize $p







|




|







1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
} {absolute absolute absolute absolute absolute absolute relative}
if {[testConstraint testsetplatform]} {
    testsetplatform $platform
}
test filename-17.2 {windows specific glob with executable} -body {
    makeDirectory execglob
    foreach ext {exe com cmd bat notexecutable} {
	makeFile contents execglob/abc.$ext
    }
    lsort [glob -nocomplain -dir [temporaryDirectory]/execglob -tails -types x *]
} -constraints {win} -cleanup {
    foreach ext {exe com cmd bat ps1 notexecutable} {
	removeFile execglob/abc.$ext
    }
    removeDirectory execglob
} -result {abc.bat abc.cmd abc.com abc.exe}
test filename-17.3 {Bug 2571597} win {
    set p /a
    file pathtype $p
    file normalize $p
Changes to tests/fileSystem.test.
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
    set ::ddelib [info loaded {} Dde]
    set ::regver  [package require registry]
    set ::reglib [info loaded {} Registry]
    testConstraint loaddll [expr {$::ddelib ne "" && $::reglib ne ""}]
}

# Test for commands defined in tcl::test package
testConstraint testfilesystem  	    [llength [info commands ::testfilesystem]]
testConstraint testsetplatform 	    [llength [info commands ::testsetplatform]]
testConstraint testsimplefilesystem [llength [info commands ::testsimplefilesystem]]
# Some things fail under all Continuous Integration systems for subtle reasons
# such as CI often running with elevated privileges in a container.
testConstraint notInCIenv           [expr {![info exists ::env(CI)]}]

cd [tcltest::temporaryDirectory]
makeFile "test file" gorp.file







|
|







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
    set ::ddelib [info loaded {} Dde]
    set ::regver  [package require registry]
    set ::reglib [info loaded {} Registry]
    testConstraint loaddll [expr {$::ddelib ne "" && $::reglib ne ""}]
}

# Test for commands defined in tcl::test package
testConstraint testfilesystem	    [llength [info commands ::testfilesystem]]
testConstraint testsetplatform	    [llength [info commands ::testsetplatform]]
testConstraint testsimplefilesystem [llength [info commands ::testsimplefilesystem]]
# Some things fail under all Continuous Integration systems for subtle reasons
# such as CI often running with elevated privileges in a container.
testConstraint notInCIenv           [expr {![info exists ::env(CI)]}]

cd [tcltest::temporaryDirectory]
makeFile "test file" gorp.file
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
		testConstraint unusedDrive 1
		break
	    }
	}

	set dir [pwd]
	try {
            set drives [lmap vol [file volumes] {
                if {$vol eq [zipfs root] || [catch {cd $vol}]} {
                    continue
                }
                set vol
            }]
	    testConstraint moreThanOneDrive [expr {[llength $drives] > 1}]
	} finally {
	    cd $dir
	}
    }
} ::tcl::test::fileSystem}








|
|
|
|
|
|







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
		testConstraint unusedDrive 1
		break
	    }
	}

	set dir [pwd]
	try {
	    set drives [lmap vol [file volumes] {
		if {$vol eq [zipfs root] || [catch {cd $vol}]} {
		    continue
		}
		set vol
	    }]
	    testConstraint moreThanOneDrive [expr {[llength $drives] > 1}]
	} finally {
	    cd $dir
	}
    }
} ::tcl::test::fileSystem}

280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
    set oldhome $::env(HOME)
    set olduserhome [file home $::tcl_platform(user)]
    set ::env(HOME) [file join $oldhome temp]
} -cleanup {
    set ::env(HOME) $oldhome
} -body {
    list [string equal [file home] $::env(HOME)] \
        [string equal $olduserhome [file home $::tcl_platform(user)]]
} -result {1 1}
test filesystem-1.31 {link normalisation: link near filesystem root} {testsetplatform} {
    testsetplatform unix
    file normalize /foo/../bar
} {/bar}
test filesystem-1.32 {link normalisation: link near filesystem root} {testsetplatform} {
    testsetplatform unix







|







280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
    set oldhome $::env(HOME)
    set olduserhome [file home $::tcl_platform(user)]
    set ::env(HOME) [file join $oldhome temp]
} -cleanup {
    set ::env(HOME) $oldhome
} -body {
    list [string equal [file home] $::env(HOME)] \
	[string equal $olduserhome [file home $::tcl_platform(user)]]
} -result {1 1}
test filesystem-1.31 {link normalisation: link near filesystem root} {testsetplatform} {
    testsetplatform unix
    file normalize /foo/../bar
} {/bar}
test filesystem-1.32 {link normalisation: link near filesystem root} {testsetplatform} {
    testsetplatform unix
Changes to tests/for.test.
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
    }
    set a
} {2}
test for-2.5 {continue tests, nested loops} {
    set msg {}
    for {set i 1} {$i <= 4} {incr i} {
	for {set a 1} {$a <= 2} {incr a} {
            if {$i>=2 && $a>=2} continue
            set msg [concat $msg "$i.$a"]
        }
    }
    set msg
} {1.1 1.2 2.1 3.1 4.1}
test for-2.6 {continue tests, long command body} {
    set a {}
    for {set i 1} {$i<6} {incr i} {
	if {$i==2} continue







|
|
|







158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
    }
    set a
} {2}
test for-2.5 {continue tests, nested loops} {
    set msg {}
    for {set i 1} {$i <= 4} {incr i} {
	for {set a 1} {$a <= 2} {incr a} {
	    if {$i>=2 && $a>=2} continue
	    set msg [concat $msg "$i.$a"]
	}
    }
    set msg
} {1.1 1.2 2.1 3.1 4.1}
test for-2.6 {continue tests, long command body} {
    set a {}
    for {set i 1} {$i<6} {incr i} {
	if {$i==2} continue
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
	}
	set a [concat $a $i]
    }
    set a
} {1 3}
test for-2.7 {continue tests, uncompiled [for]} -body {
    set file [makeFile {
    	set guard 0
	for {set i 20} {$i > 0} {incr i -1} {
	    if {[incr guard]>30} {return BAD}
	    continue
	}
	return GOOD
    } source.file]
    source $file







|







201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
	}
	set a [concat $a $i]
    }
    set a
} {1 3}
test for-2.7 {continue tests, uncompiled [for]} -body {
    set file [makeFile {
	set guard 0
	for {set i 20} {$i > 0} {incr i -1} {
	    if {[incr guard]>30} {return BAD}
	    continue
	}
	return GOOD
    } source.file]
    source $file
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
    }
    set a
} {1 2}
test for-3.4 {break tests, nested loops} {
    set msg {}
    for {set i 1} {$i <= 4} {incr i} {
	for {set a 1} {$a <= 2} {incr a} {
            if {$i>=2 && $a>=2} break
            set msg [concat $msg "$i.$a"]
        }
    }
    set msg
} {1.1 1.2 2.1 3.1 4.1}
test for-3.5 {break tests, long command body} {
    set a {}
    for {set i 1} {$i<6} {incr i} {
	if {$i==2} continue







|
|
|







234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
    }
    set a
} {1 2}
test for-3.4 {break tests, nested loops} {
    set msg {}
    for {set i 1} {$i <= 4} {incr i} {
	for {set a 1} {$a <= 2} {incr a} {
	    if {$i>=2 && $a>=2} break
	    set msg [concat $msg "$i.$a"]
	}
    }
    set msg
} {1.1 1.2 2.1 3.1 4.1}
test for-3.5 {break tests, long command body} {
    set a {}
    for {set i 1} {$i<6} {incr i} {
	if {$i==2} continue
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
    }
    set a
} {1 3}
# A simplified version of exmh's mail formatting routine to stress "for",
# "break", "while", and "if".
proc formatMail {} {
    array set lines {
        0 {Return-path: george@tcl} \
        1 {Return-path: <george@tcl>} \
        2 {Received: from tcl by tcl.Somewhere.COM (SMI-8.6/SMI-SVR4)} \
        3 {	id LAA10027; Wed, 11 Sep 1996 11:14:53 -0700} \
        4 {Message-id: <199609111814.LAA10027@tcl.Somewhere.COM>} \
        5 {X-mailer: exmh version 1.6.9 8/22/96} \
        6 {Mime-version: 1.0} \
        7 {Content-type: text/plain; charset=iso-8859-1} \
        8 {Content-transfer-encoding: quoted-printable} \
        9 {Content-length: 2162} \
        10 {To: fred} \
        11 {Subject: tcl7.6} \
        12 {Date: Wed, 11 Sep 1996 11:14:53 -0700} \
        13 {From: George <george@tcl>} \
        14 {The Tcl 7.6 and Tk 4.2 releases} \
        15 {} \
        16 {This page contains information about Tcl 7.6 and Tk4.2, which are the most recent} \
        17 {releases of the Tcl scripting language and the Tk toolkit. The first beta versions of these} \
        18 {releases were released on August 30, 1996. These releases contain only minor changes,} \
        19 {so we hope to have only a single beta release and to go final in early October, 1996.} \
        20 {} \
        21 {} \
        22 {What's new} \
        23 {} \
        24 {The most important changes in the releases are summarized below. See the README} \
        25 {and changes files in the distributions for more complete information on what has} \
        26 {changed, including both feature changes and bug fixes.} \
        27 {} \
        28 {     There are new options to the file command for copying files (file copy),} \
        29 {     deleting files and directories (file delete), creating directories (file} \
        30 {     mkdir), and renaming files (file rename).} \
        31 {     The implementation of exec has been improved greatly for Windows 95 and} \
        32 {     Windows NT.} \
        33 {     There is a new memory allocator for the Macintosh version, which should be} \
        34 {     more efficient than the old one.} \
        35 {     Tk's grid geometry manager has been completely rewritten. The layout} \
        36 {     algorithm produces much better layouts than before, especially where rows or} \
        37 {     columns were stretchable.} \
        38 {     There are new commands for creating common dialog boxes:} \
        39 {     tk_chooseColor, tk_getOpenFile, tk_getSaveFile and} \
        40 {     tk_messageBox. These use native dialog boxes if they are available.} \
        41 {     There is a new virtual event mechanism for handling events in a more portable} \
        42 {     way. See the new command event. It also allows events (both physical and} \
        43 {     virtual) to be generated dynamically.} \
        44 {} \
        45 {Tcl 7.6 and Tk 4.2 are backwards-compatible with Tcl 7.5 and Tk 4.1 except for} \
        46 {changes in the C APIs for custom channel drivers. Scripts written for earlier releases} \
        47 {should work on these new releases as well.} \
        48 {} \
        49 {Obtaining The Releases} \
        50 {} \
        51 {Binary Releases} \
        52 {} \
        53 {Precompiled releases are available for the following platforms: } \
        54 {} \
        55 {     Windows 3.1, Windows 95, and Windows NT: Fetch} \
        56 {     ftp://ftp.sunlabs.com/pub/tcl/win42b1.exe, then execute it. The file is a} \
        57 {     self-extracting executable. It will install the Tcl and Tk libraries, the wish and} \
        58 {     tclsh programs, and documentation.} \
        59 {     Macintosh (both 68K and PowerPC): Fetch} \
        60 {     ftp://ftp.sunlabs.com/pub/tcl/mactk4.2b1.sea.hqx. The file is in binhex format,} \
        61 {     which is understood by Fetch, StuffIt, and many other Mac utilities. The} \
        62 {     unpacked file is a self-installing executable: double-click on it and it will create a} \
        63 {     folder containing all that you need to run Tcl and Tk. } \
        64 {        UNIX (Solaris 2.* and SunOS, other systems soon to follow). Easy to install} \
        65 {     binary packages are now for sale at the Sun Labs Tcl/Tk Shop. Check it out!} \
    }
    set result ""
    set NL "
"
    set tag {level= type=text/plain part=0 sel Charset}
    set ix [lsearch -regexp $tag text/enriched]
    if {$ix < 0} {







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
    }
    set a
} {1 3}
# A simplified version of exmh's mail formatting routine to stress "for",
# "break", "while", and "if".
proc formatMail {} {
    array set lines {
	0 {Return-path: george@tcl} \
	1 {Return-path: <george@tcl>} \
	2 {Received: from tcl by tcl.Somewhere.COM (SMI-8.6/SMI-SVR4)} \
	3 {	id LAA10027; Wed, 11 Sep 1996 11:14:53 -0700} \
	4 {Message-id: <199609111814.LAA10027@tcl.Somewhere.COM>} \
	5 {X-mailer: exmh version 1.6.9 8/22/96} \
	6 {Mime-version: 1.0} \
	7 {Content-type: text/plain; charset=iso-8859-1} \
	8 {Content-transfer-encoding: quoted-printable} \
	9 {Content-length: 2162} \
	10 {To: fred} \
	11 {Subject: tcl7.6} \
	12 {Date: Wed, 11 Sep 1996 11:14:53 -0700} \
	13 {From: George <george@tcl>} \
	14 {The Tcl 7.6 and Tk 4.2 releases} \
	15 {} \
	16 {This page contains information about Tcl 7.6 and Tk4.2, which are the most recent} \
	17 {releases of the Tcl scripting language and the Tk toolkit. The first beta versions of these} \
	18 {releases were released on August 30, 1996. These releases contain only minor changes,} \
	19 {so we hope to have only a single beta release and to go final in early October, 1996.} \
	20 {} \
	21 {} \
	22 {What's new} \
	23 {} \
	24 {The most important changes in the releases are summarized below. See the README} \
	25 {and changes files in the distributions for more complete information on what has} \
	26 {changed, including both feature changes and bug fixes.} \
	27 {} \
	28 {     There are new options to the file command for copying files (file copy),} \
	29 {     deleting files and directories (file delete), creating directories (file} \
	30 {     mkdir), and renaming files (file rename).} \
	31 {     The implementation of exec has been improved greatly for Windows 95 and} \
	32 {     Windows NT.} \
	33 {     There is a new memory allocator for the Macintosh version, which should be} \
	34 {     more efficient than the old one.} \
	35 {     Tk's grid geometry manager has been completely rewritten. The layout} \
	36 {     algorithm produces much better layouts than before, especially where rows or} \
	37 {     columns were stretchable.} \
	38 {     There are new commands for creating common dialog boxes:} \
	39 {     tk_chooseColor, tk_getOpenFile, tk_getSaveFile and} \
	40 {     tk_messageBox. These use native dialog boxes if they are available.} \
	41 {     There is a new virtual event mechanism for handling events in a more portable} \
	42 {     way. See the new command event. It also allows events (both physical and} \
	43 {     virtual) to be generated dynamically.} \
	44 {} \
	45 {Tcl 7.6 and Tk 4.2 are backwards-compatible with Tcl 7.5 and Tk 4.1 except for} \
	46 {changes in the C APIs for custom channel drivers. Scripts written for earlier releases} \
	47 {should work on these new releases as well.} \
	48 {} \
	49 {Obtaining The Releases} \
	50 {} \
	51 {Binary Releases} \
	52 {} \
	53 {Precompiled releases are available for the following platforms: } \
	54 {} \
	55 {     Windows 3.1, Windows 95, and Windows NT: Fetch} \
	56 {     ftp://ftp.sunlabs.com/pub/tcl/win42b1.exe, then execute it. The file is a} \
	57 {     self-extracting executable. It will install the Tcl and Tk libraries, the wish and} \
	58 {     tclsh programs, and documentation.} \
	59 {     Macintosh (both 68K and PowerPC): Fetch} \
	60 {     ftp://ftp.sunlabs.com/pub/tcl/mactk4.2b1.sea.hqx. The file is in binhex format,} \
	61 {     which is understood by Fetch, StuffIt, and many other Mac utilities. The} \
	62 {     unpacked file is a self-installing executable: double-click on it and it will create a} \
	63 {     folder containing all that you need to run Tcl and Tk. } \
	64 {        UNIX (Solaris 2.* and SunOS, other systems soon to follow). Easy to install} \
	65 {     binary packages are now for sale at the Sun Labs Tcl/Tk Shop. Check it out!} \
    }
    set result ""
    set NL "
"
    set tag {level= type=text/plain part=0 sel Charset}
    set ix [lsearch -regexp $tag text/enriched]
    if {$ix < 0} {
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
Tcl/Tk Shop. Check it out!
}

# Check that "break" resets the interpreter's result

test for-4.1 {break must reset the interp result} {
    catch {
        set z GLOBTESTDIR/dir2/file2.c
        if {[string match GLOBTESTDIR/dir2/* $z]} {
            break
        }
    } j
    set j
} {}

# Test for incorrect "double evaluation" semantics

test for-5.1 {possible delayed substitution of increment command} {







|
|
|
|







580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
Tcl/Tk Shop. Check it out!
}

# Check that "break" resets the interpreter's result

test for-4.1 {break must reset the interp result} {
    catch {
	set z GLOBTESTDIR/dir2/file2.c
	if {[string match GLOBTESTDIR/dir2/* $z]} {
	    break
	}
    } j
    set j
} {}

# Test for incorrect "double evaluation" semantics

test for-5.1 {possible delayed substitution of increment command} {
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
test for-6.16 {Tcl_ForObjCmd: for command result} {
    set z for
    set a [$z {set i 0} {$i < 5} {incr i} {if $i==3 break}]
    set a
} {}
test for-6.17 {Tcl_ForObjCmd: for command result} {
    list \
        [catch {for {break} {1} {} {}} err] $err \
        [catch {for {continue} {1} {} {}} err] $err \
        [catch {for {} {[break]} {} {}} err] $err \
        [catch {for {} {[continue]} {} {}} err] $err \
        [catch {for {} {1} {break} {}} err] $err \
        [catch {for {} {1} {continue} {}} err] $err \
} [list \
    3 {} \
    4 {} \
    3 {} \
    4 {} \
    0 {} \
    4 {} \
    ]
test for-6.18 {Tcl_ForObjCmd: for command result} {
    proc p6181 {} {
        for {break} {1} {} {}
    }
    proc p6182 {} {
        for {continue} {1} {} {}
    }
    proc p6183 {} {
        for {} {[break]} {} {}
    }
    proc p6184 {} {
        for {} {[continue]} {} {}
    }
    proc p6185 {} {
        for {} {1} {break} {}
    }
    proc p6186 {} {
        for {} {1} {continue} {}
    }
    list \
        [catch {p6181} err] $err \
        [catch {p6182} err] $err \
        [catch {p6183} err] $err \
        [catch {p6184} err] $err \
        [catch {p6185} err] $err \
        [catch {p6186} err] $err
} [list \
    1 {invoked "break" outside of a loop} \
    1 {invoked "continue" outside of a loop} \
    1 {invoked "break" outside of a loop} \
    1 {invoked "continue" outside of a loop} \
    0 {} \
    1 {invoked "continue" outside of a loop} \







|
|
|
|
|
|










|


|


|


|


|


|


|
|
|
|
|
|







773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
test for-6.16 {Tcl_ForObjCmd: for command result} {
    set z for
    set a [$z {set i 0} {$i < 5} {incr i} {if $i==3 break}]
    set a
} {}
test for-6.17 {Tcl_ForObjCmd: for command result} {
    list \
	[catch {for {break} {1} {} {}} err] $err \
	[catch {for {continue} {1} {} {}} err] $err \
	[catch {for {} {[break]} {} {}} err] $err \
	[catch {for {} {[continue]} {} {}} err] $err \
	[catch {for {} {1} {break} {}} err] $err \
	[catch {for {} {1} {continue} {}} err] $err \
} [list \
    3 {} \
    4 {} \
    3 {} \
    4 {} \
    0 {} \
    4 {} \
    ]
test for-6.18 {Tcl_ForObjCmd: for command result} {
    proc p6181 {} {
	for {break} {1} {} {}
    }
    proc p6182 {} {
	for {continue} {1} {} {}
    }
    proc p6183 {} {
	for {} {[break]} {} {}
    }
    proc p6184 {} {
	for {} {[continue]} {} {}
    }
    proc p6185 {} {
	for {} {1} {break} {}
    }
    proc p6186 {} {
	for {} {1} {continue} {}
    }
    list \
	[catch {p6181} err] $err \
	[catch {p6182} err] $err \
	[catch {p6183} err] $err \
	[catch {p6184} err] $err \
	[catch {p6185} err] $err \
	[catch {p6186} err] $err
} [list \
    1 {invoked "break" outside of a loop} \
    1 {invoked "continue" outside of a loop} \
    1 {invoked "break" outside of a loop} \
    1 {invoked "continue" outside of a loop} \
    0 {} \
    1 {invoked "continue" outside of a loop} \
Changes to tests/foreach.test.
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
    foreach a {} b {1 2 3} c {1 2} d {1 2 3 4} e {{1 2}} {
	append x $a $b $c $d $e
    }
    set x
} {1111 2222334}
test foreach-2.8 {foreach only sets vars if repeating loop} {
    proc foo {} {
        set rgb {65535 0 0}
        foreach {r g b} [set rgb] {}
        return "r=$r, g=$g, b=$b"
    }
    foo
} {r=65535, g=0, b=0}
test foreach-2.9 {foreach only supports local scalar variables} {
    proc foo {} {
        set x {}
        foreach {a(3)} {1 2 3 4} {lappend x [set {a(3)}]}
        set x
    }
    foo
} {1 2 3 4}

test foreach-3.1 {compiled foreach backward jump works correctly} {
    catch {unset x}
    proc foo {arrayName} {
        upvar 1 $arrayName a
        set l {}
        foreach member [array names a] {
            lappend l [list $member [set a($member)]]
        }
        return $l
    }
    array set x {0 zero 1 one 2 two 3 three}
    lsort [foo x]
} [lsort {{0 zero} {1 one} {2 two} {3 three}}]

test foreach-4.1 {noncompiled foreach and shared variable or value list objects that are converted to another type} {
    catch {unset x}
    foreach {12.0} {a b c} {
        set x 12.0
        set x [expr {$x + 1}]
    }
    set x
} 13.0

# Check "continue".

test foreach-5.1 {continue tests} {catch continue} 4







|
|
|





|
|
|







|
|
|
|
|
|








|
|







128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
    foreach a {} b {1 2 3} c {1 2} d {1 2 3 4} e {{1 2}} {
	append x $a $b $c $d $e
    }
    set x
} {1111 2222334}
test foreach-2.8 {foreach only sets vars if repeating loop} {
    proc foo {} {
	set rgb {65535 0 0}
	foreach {r g b} [set rgb] {}
	return "r=$r, g=$g, b=$b"
    }
    foo
} {r=65535, g=0, b=0}
test foreach-2.9 {foreach only supports local scalar variables} {
    proc foo {} {
	set x {}
	foreach {a(3)} {1 2 3 4} {lappend x [set {a(3)}]}
	set x
    }
    foo
} {1 2 3 4}

test foreach-3.1 {compiled foreach backward jump works correctly} {
    catch {unset x}
    proc foo {arrayName} {
	upvar 1 $arrayName a
	set l {}
	foreach member [array names a] {
	    lappend l [list $member [set a($member)]]
	}
	return $l
    }
    array set x {0 zero 1 one 2 two 3 three}
    lsort [foo x]
} [lsort {{0 zero} {1 one} {2 two} {3 three}}]

test foreach-4.1 {noncompiled foreach and shared variable or value list objects that are converted to another type} {
    catch {unset x}
    foreach {12.0} {a b c} {
	set x 12.0
	set x [expr {$x + 1}]
    }
    set x
} 13.0

# Check "continue".

test foreach-5.1 {continue tests} {catch continue} 4
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
} -result {2}

# Test for incorrect "double evaluation" semantics
test foreach-7.1 {delayed substitution of body} {
    proc foo {} {
       set a 0
       foreach a [list 1 2 3] "
           set x $a
       "
       set x
    }
    foo
} {0}

# Test for [Bug 1189274]; crash on failure







|







224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
} -result {2}

# Test for incorrect "double evaluation" semantics
test foreach-7.1 {delayed substitution of body} {
    proc foo {} {
       set a 0
       foreach a [list 1 2 3] "
	   set x $a
       "
       set x
    }
    foo
} {0}

# Test for [Bug 1189274]; crash on failure
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
    list [catch { foo } msg] $msg
} {1 {foreach varlist is empty}}

test foreach-9.2 {line numbers} -setup {
    proc linenumber {} {dict get [info frame -1] line}
} -body {
    apply {n {
        foreach x y {*}{
        } {return [incr n -[linenumber]]}
    }} [linenumber]
} -cleanup {
    rename linenumber {}
} -result 1

test foreach-10.1 {foreach: [Bug 1671087]} -setup {
    proc demo {} {







|
|







256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
    list [catch { foo } msg] $msg
} {1 {foreach varlist is empty}}

test foreach-9.2 {line numbers} -setup {
    proc linenumber {} {dict get [info frame -1] line}
} -body {
    apply {n {
	foreach x y {*}{
	} {return [incr n -[linenumber]]}
    }} [linenumber]
} -cleanup {
    rename linenumber {}
} -result 1

test foreach-10.1 {foreach: [Bug 1671087]} -setup {
    proc demo {} {
Changes to tests/format.test.
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
set a "0123456789"
set b ""
for {set i 0} {$i < 290} {incr i} {
    append b $a
}
for {set i 290} {$i < 400} {incr i} {
    test format-16.[expr {$i -289}] {testing MAX_FLOAT_SIZE} {
        format {%s} $b
    } $b
    append b "x"
}

test format-17.1 {testing %d with wide} {
    format %d 7810179016327718216
} 1819043144







|







526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
set a "0123456789"
set b ""
for {set i 0} {$i < 290} {incr i} {
    append b $a
}
for {set i 290} {$i < 400} {incr i} {
    test format-16.[expr {$i -289}] {testing MAX_FLOAT_SIZE} {
	format {%s} $b
    } $b
    append b "x"
}

test format-17.1 {testing %d with wide} {
    format %d 7810179016327718216
} 1819043144
Changes to tests/get.test.
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
    list [catch {testgetint 44 foo} msg] $msg
} {1 {expected integer but got "foo"}}
test get-1.5 {Tcl_GetInt procedure} testgetint {
    list [catch {testgetint 44 {16	 }} msg] $msg
} {0 60}
test get-1.6 {Tcl_GetInt procedure} testgetint {
    list [catch {testgetint 44 {16	 x}} msg] $msg
} {1 {expected integer but got "16	 x"}}
test get-1.7 {Tcl_GetInt procedure} testgetint {
    list [catch {testgetint 44 18446744073709551616} msg] $msg $errorCode
} {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}}
test get-1.8 {Tcl_GetInt procedure} {testgetint longIs64bit} {
    testgetint 18446744073709551614
} {-2}
test get-1.9 {Tcl_GetInt procedure} {testgetint longIs64bit} {







|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
    list [catch {testgetint 44 foo} msg] $msg
} {1 {expected integer but got "foo"}}
test get-1.5 {Tcl_GetInt procedure} testgetint {
    list [catch {testgetint 44 {16	 }} msg] $msg
} {0 60}
test get-1.6 {Tcl_GetInt procedure} testgetint {
    list [catch {testgetint 44 {16	 x}} msg] $msg
} {1 {expected integer but got a list}}
test get-1.7 {Tcl_GetInt procedure} testgetint {
    list [catch {testgetint 44 18446744073709551616} msg] $msg $errorCode
} {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}}
test get-1.8 {Tcl_GetInt procedure} {testgetint longIs64bit} {
    testgetint 18446744073709551614
} {-2}
test get-1.9 {Tcl_GetInt procedure} {testgetint longIs64bit} {
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
    # SF bug #634856
    set result ""
    set numbers [list 1 +1 ++1 +-1 -+1 -1 --1 "- +1" "+12345678987654321" "++12345678987654321"]
    foreach num $numbers {
	lappend result [catch {format %ld $num} msg] $msg
    }
    set result
} {0 1 0 1 1 {expected integer but got "++1"} 1 {expected integer but got "+-1"} 1 {expected integer but got "-+1"} 0 -1 1 {expected integer but got "--1"} 1 {expected integer but got "- +1"} 0 12345678987654321 1 {expected integer but got "++12345678987654321"}}
test get-3.2 {Tcl_GetDouble(FromObj), bad numbers} {
    set result ""
    set numbers [list 1.0 +1.0 ++1.0 +-1.0 -+1.0 -1.0 --1.0 "- +1.0"]
    foreach num $numbers {
	lappend result [catch {format %g $num} msg] $msg
    }
    set result
} {0 1 0 1 1 {expected floating-point number but got "++1.0"} 1 {expected floating-point number but got "+-1.0"} 1 {expected floating-point number but got "-+1.0"} 0 -1 1 {expected floating-point number but got "--1.0"} 1 {expected floating-point number but got "- +1.0"}}
# Bug 7114ac6141
test get-3.3 {tcl_GetInt with iffy numbers} testgetint {
    lmap x {0 " 0" "0 " " 0 " " 0xa " " 010 " " 0o10 " " 0b10 "} {
	catch {testgetint 44 $x} x
	set x
    }
} {44 44 44 44 54 54 52 46}

test get-3.4 {Tcl_GetDouble with iffy numbers} testdoubleobj {
    lmap x {0 0.0 " .0" ".0 " " 0e0 " "09" "- 0" "-0" "0o12" "0b10" "2_0.3_4e+1_5" _1.0e+2 1_.0e+2 1._0e+2 1.0_e+2 1.0e_+2 1.0e+_2 1.0e+2_ 1_1.0e+0_2 2__2.0e+2__2 54321________} {
	catch {testdoubleobj set 1 $x} x
	set x
    }
} {0.0 0.0 0.0 0.0 0.0 9.0 {expected floating-point number but got "- 0"} 0.0 10.0 2.0 20340000000000000.0 {expected floating-point number but got "_1.0e+2"} {expected floating-point number but got "1_.0e+2"} {expected floating-point number but got "1._0e+2"} {expected floating-point number but got "1.0_e+2"} {expected floating-point number but got "1.0e_+2"} {expected floating-point number but got "1.0e+_2"} {expected floating-point number but got "1.0e+2_"} 1100.0 2.2e+23 {expected floating-point number but got "54321________"}}

test get-3.5 {tcl_GetInt with numeric whitespace (i.e. '_')} testgetint {
    lmap x {0_0 " 1_0" "0_2 " " 3_3 " 14__23__32___4 " 0x0_a " 0b1111_1111 " 0_07 " " 0o1_0 " " 0b_1_0 " " 0_b1_0 " _33 42_ 0_x15 0_o17 0_d19 0x_b 0o_2_0 0o2__3_4} {
	catch {testgetint $x} x
	set x
    }
} {0 10 2 33 1423324 10 255 7 8 {expected integer but got " 0b_1_0 "} {expected integer but got " 0_b1_0 "} {expected integer but got "_33"} {expected integer but got "42_"} {expected integer but got "0_x15"} {expected integer but got "0_o17"} {expected integer but got "0_d19"} {expected integer but got "0x_b"} {expected integer but got "0o_2_0"} 156}







|







|













|







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
    # SF bug #634856
    set result ""
    set numbers [list 1 +1 ++1 +-1 -+1 -1 --1 "- +1" "+12345678987654321" "++12345678987654321"]
    foreach num $numbers {
	lappend result [catch {format %ld $num} msg] $msg
    }
    set result
} {0 1 0 1 1 {expected integer but got "++1"} 1 {expected integer but got "+-1"} 1 {expected integer but got "-+1"} 0 -1 1 {expected integer but got "--1"} 1 {expected integer but got a list} 0 12345678987654321 1 {expected integer but got "++12345678987654321"}}
test get-3.2 {Tcl_GetDouble(FromObj), bad numbers} {
    set result ""
    set numbers [list 1.0 +1.0 ++1.0 +-1.0 -+1.0 -1.0 --1.0 "- +1.0"]
    foreach num $numbers {
	lappend result [catch {format %g $num} msg] $msg
    }
    set result
} {0 1 0 1 1 {expected floating-point number but got "++1.0"} 1 {expected floating-point number but got "+-1.0"} 1 {expected floating-point number but got "-+1.0"} 0 -1 1 {expected floating-point number but got "--1.0"} 1 {expected floating-point number but got a list}}
# Bug 7114ac6141
test get-3.3 {tcl_GetInt with iffy numbers} testgetint {
    lmap x {0 " 0" "0 " " 0 " " 0xa " " 010 " " 0o10 " " 0b10 "} {
	catch {testgetint 44 $x} x
	set x
    }
} {44 44 44 44 54 54 52 46}

test get-3.4 {Tcl_GetDouble with iffy numbers} testdoubleobj {
    lmap x {0 0.0 " .0" ".0 " " 0e0 " "09" "- 0" "-0" "0o12" "0b10" "2_0.3_4e+1_5" _1.0e+2 1_.0e+2 1._0e+2 1.0_e+2 1.0e_+2 1.0e+_2 1.0e+2_ 1_1.0e+0_2 2__2.0e+2__2 54321________} {
	catch {testdoubleobj set 1 $x} x
	set x
    }
} {0.0 0.0 0.0 0.0 0.0 9.0 {expected floating-point number but got a list} 0.0 10.0 2.0 20340000000000000.0 {expected floating-point number but got "_1.0e+2"} {expected floating-point number but got "1_.0e+2"} {expected floating-point number but got "1._0e+2"} {expected floating-point number but got "1.0_e+2"} {expected floating-point number but got "1.0e_+2"} {expected floating-point number but got "1.0e+_2"} {expected floating-point number but got "1.0e+2_"} 1100.0 2.2e+23 {expected floating-point number but got "54321________"}}

test get-3.5 {tcl_GetInt with numeric whitespace (i.e. '_')} testgetint {
    lmap x {0_0 " 1_0" "0_2 " " 3_3 " 14__23__32___4 " 0x0_a " 0b1111_1111 " 0_07 " " 0o1_0 " " 0b_1_0 " " 0_b1_0 " _33 42_ 0_x15 0_o17 0_d19 0x_b 0o_2_0 0o2__3_4} {
	catch {testgetint $x} x
	set x
    }
} {0 10 2 33 1423324 10 255 7 8 {expected integer but got " 0b_1_0 "} {expected integer but got " 0_b1_0 "} {expected integer but got "_33"} {expected integer but got "42_"} {expected integer but got "0_x15"} {expected integer but got "0_o17"} {expected integer but got "0_d19"} {expected integer but got "0x_b"} {expected integer but got "0o_2_0"} 156}
Changes to tests/http.test.
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
if 0 {
    # For debugging: run with a single value of ThreadLevel: 0|1|2
    set ThreadLevel 0
    testConstraint ThreadLevelSummary 1
}
if {![info exists ThreadLevel]} {
    if {[catch {package require Thread}] == 0} {
        set ValueRange {0 1 2}
    } else {
        set ValueRange {0 1}
    }

    # For each value of ThreadLevel, source this file recursively in the
    # same interpreter.
    foreach ThreadLevel $ValueRange {
        source [info script]
    }
    if {[llength $threadStack]} {
	eval [lpop threadStack]
    }
    catch {unset ThreadLevel}
    catch {unset ValueRange}
    if {![testConstraint ThreadLevelSummary]} {
        ::tcltest::cleanupTests
    }
    return
}

catch {puts "==== Test with ThreadLevel $ThreadLevel ===="}
http::config -threadlevel $ThreadLevel








|

|





|







|







74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
if 0 {
    # For debugging: run with a single value of ThreadLevel: 0|1|2
    set ThreadLevel 0
    testConstraint ThreadLevelSummary 1
}
if {![info exists ThreadLevel]} {
    if {[catch {package require Thread}] == 0} {
	set ValueRange {0 1 2}
    } else {
	set ValueRange {0 1}
    }

    # For each value of ThreadLevel, source this file recursively in the
    # same interpreter.
    foreach ThreadLevel $ValueRange {
	source [info script]
    }
    if {[llength $threadStack]} {
	eval [lpop threadStack]
    }
    catch {unset ThreadLevel}
    catch {unset ValueRange}
    if {![testConstraint ThreadLevelSummary]} {
	::tcltest::cleanupTests
    }
    return
}

catch {puts "==== Test with ThreadLevel $ThreadLevel ===="}
http::config -threadlevel $ThreadLevel

447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
    # We only want to see if the URL gets parsed correctly. This is
    # the case if http::geturl succeeds or returns a socket related
    # error. If the parsing is wrong, we'll get a parse error.
    # It'd be better to separate the URL parser from http::geturl, so
    # that it can be tested without also trying to make a connection.
    set error [catch {http::geturl $ipv6url -validate 1} token]
    if {$error && [string match "couldn't open socket: *" $token]} {
            set error 0
    }
    set error
} -cleanup {
    catch {http::cleanup $token}
} -result 0
test http-3.30.$ThreadLevel {http::geturl query without path} -body {
    set token [http::geturl $authorityurl?var=val]







|







447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
    # We only want to see if the URL gets parsed correctly. This is
    # the case if http::geturl succeeds or returns a socket related
    # error. If the parsing is wrong, we'll get a parse error.
    # It'd be better to separate the URL parser from http::geturl, so
    # that it can be tested without also trying to make a connection.
    set error [catch {http::geturl $ipv6url -validate 1} token]
    if {$error && [string match "couldn't open socket: *" $token]} {
	set error 0
    }
    set error
} -cleanup {
    catch {http::cleanup $token}
} -result 0
test http-3.30.$ThreadLevel {http::geturl query without path} -body {
    set token [http::geturl $authorityurl?var=val]
Changes to tests/http11.test.
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package require http 2.10
#http::register http 80 ::socket

# start the server
variable httpd_output
proc create_httpd {} {
    proc httpd_read {chan} {
        variable httpd_output
        if {[gets $chan line] >= 0} {
            #puts stderr "read '$line'"
            set httpd_output $line
        }
        if {[eof $chan]} {
            puts stderr "eof from httpd"
            fileevent $chan readable {}
            close $chan
        }
    }
    variable httpd_output
    set httpd_script [file join [pwd] [file dirname [info script]] httpd11.tcl]
    set httpd [open "|[list [interpreter] -encoding utf-8 $httpd_script]" r+]
    fconfigure $httpd -buffering line -blocking 0
    fileevent $httpd readable [list httpd_read $httpd]
    vwait httpd_output
    variable httpd_port [lindex $httpd_output 2]
    return $httpd
}

proc halt_httpd {} {
    variable httpd_output
    variable httpd
    if {[info exists httpd]} {
        puts $httpd "quit"
        vwait httpd_output
        close $httpd
    }
    unset -nocomplain httpd_output httpd
}

proc meta {tok {key ""}} {
    if {$key eq ""} {
        return [http::meta $tok]
    } else {
        return [http::metaValue $tok $key]
    }
}

proc state {tok {key ""}} {
    upvar 1 $tok state
    if {$key ne ""} {
        if {[array names state -exact $key] ne {}} {
            return $state($key)
        } else {
            return ""
        }
    }
    set res [array get state]
    dict set res body <elided>
    return $res
}

proc check_crc {tok args} {
    set crc [meta $tok x-crc32]
    set data [expr {[llength $args] ? [lindex $args 0] : [http::data $tok]}]
    set chk [format %x [zlib crc32 $data]]
    if {$crc ne $chk} {
        return  "crc32 mismatch: $crc ne $chk"
    }
    return "ok"
}

makeFile "<html><head><title>test</title></head><body><p>this is a test</p>\n[string repeat {<p>This is a tcl test file.</p>} 4192]\n</body></html>" testdoc.html

makeFile "<html><head><title>test</title></head><body><p>this is a test</p>\n[string repeat {<p>This is a tcl test file.</p>} 5000]\n</body></html>" largedoc.html

# To write a separate summary for each value of ThreadLevel, set constraint ThreadLevelSummary.
#testConstraint ThreadLevelSummary 0

if 0 {
    # For debugging: run with a single value of ThreadLevel: 0|1|2
    set ThreadLevel 0
    testConstraint ThreadLevelSummary 1
}
if {![info exists ThreadLevel]} {
    if {[catch {package require Thread}] == 0} {
        set ValueRange {0 1 2}
    } else {
        set ValueRange {0 1}
    }

    # For each value of ThreadLevel, source this file recursively in the
    # same interpreter.
    foreach ThreadLevel $ValueRange {
        source [info script]
    }
    catch {unset ThreadLevel}
    catch {unset ValueRange}
    if {![testConstraint ThreadLevelSummary]} {
        ::tcltest::cleanupTests
    }
    return
}

catch {puts "==== Test with ThreadLevel $ThreadLevel ===="}
http::config -threadlevel $ThreadLevel








|
|
|
|
|
|
|
|
|
|















|
|
|






|

|






|
|
|
|
|











|


















|

|





|




|







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package require http 2.10
#http::register http 80 ::socket

# start the server
variable httpd_output
proc create_httpd {} {
    proc httpd_read {chan} {
	variable httpd_output
	if {[gets $chan line] >= 0} {
	    #puts stderr "read '$line'"
	    set httpd_output $line
	}
	if {[eof $chan]} {
	    puts stderr "eof from httpd"
	    fileevent $chan readable {}
	    close $chan
	}
    }
    variable httpd_output
    set httpd_script [file join [pwd] [file dirname [info script]] httpd11.tcl]
    set httpd [open "|[list [interpreter] -encoding utf-8 $httpd_script]" r+]
    fconfigure $httpd -buffering line -blocking 0
    fileevent $httpd readable [list httpd_read $httpd]
    vwait httpd_output
    variable httpd_port [lindex $httpd_output 2]
    return $httpd
}

proc halt_httpd {} {
    variable httpd_output
    variable httpd
    if {[info exists httpd]} {
	puts $httpd "quit"
	vwait httpd_output
	close $httpd
    }
    unset -nocomplain httpd_output httpd
}

proc meta {tok {key ""}} {
    if {$key eq ""} {
	return [http::meta $tok]
    } else {
	return [http::metaValue $tok $key]
    }
}

proc state {tok {key ""}} {
    upvar 1 $tok state
    if {$key ne ""} {
	if {[array names state -exact $key] ne {}} {
	    return $state($key)
	} else {
	    return ""
	}
    }
    set res [array get state]
    dict set res body <elided>
    return $res
}

proc check_crc {tok args} {
    set crc [meta $tok x-crc32]
    set data [expr {[llength $args] ? [lindex $args 0] : [http::data $tok]}]
    set chk [format %x [zlib crc32 $data]]
    if {$crc ne $chk} {
	return  "crc32 mismatch: $crc ne $chk"
    }
    return "ok"
}

makeFile "<html><head><title>test</title></head><body><p>this is a test</p>\n[string repeat {<p>This is a tcl test file.</p>} 4192]\n</body></html>" testdoc.html

makeFile "<html><head><title>test</title></head><body><p>this is a test</p>\n[string repeat {<p>This is a tcl test file.</p>} 5000]\n</body></html>" largedoc.html

# To write a separate summary for each value of ThreadLevel, set constraint ThreadLevelSummary.
#testConstraint ThreadLevelSummary 0

if 0 {
    # For debugging: run with a single value of ThreadLevel: 0|1|2
    set ThreadLevel 0
    testConstraint ThreadLevelSummary 1
}
if {![info exists ThreadLevel]} {
    if {[catch {package require Thread}] == 0} {
	set ValueRange {0 1 2}
    } else {
	set ValueRange {0 1}
    }

    # For each value of ThreadLevel, source this file recursively in the
    # same interpreter.
    foreach ThreadLevel $ValueRange {
	source [info script]
    }
    catch {unset ThreadLevel}
    catch {unset ValueRange}
    if {![testConstraint ThreadLevelSummary]} {
	::tcltest::cleanupTests
    }
    return
}

catch {puts "==== Test with ThreadLevel $ThreadLevel ===="}
http::config -threadlevel $ThreadLevel

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close}

test http11-1.1.$ThreadLevel "normal,gzip,non-chunked" -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
                 -timeout 10000 -headers {accept-encoding gzip}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
        [meta $tok content-encoding] [meta $tok transfer-encoding] \
        [http::meta $tok content-encoding] [http::meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok gzip {} {content-encoding gzip} {}}

test http11-1.2.$ThreadLevel "normal,deflated,non-chunked" -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
                 -timeout 10000 -headers {accept-encoding deflate}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
        [meta $tok content-encoding] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok deflate {}}

test http11-1.2.1.$ThreadLevel "normal,deflated,non-chunked,msdeflate" -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1&msdeflate=1 \
                 -timeout 10000 -headers {accept-encoding deflate}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
        [meta $tok content-encoding] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok deflate {}}

test http11-1.3.$ThreadLevel "normal,compressed,non-chunked" -constraints badCompress -setup {
    # The Tcl "compress" algorithm appears to be incorrect and has been removed.
    # Bug [a13b9d0ce1].
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
                 -timeout 10000 -headers {accept-encoding compress}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
        [meta $tok content-encoding] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok compress {}}

test http11-1.4.$ThreadLevel "normal,identity,non-chunked" -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
                 -timeout 10000 -headers {accept-encoding identity}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
        [meta $tok content-encoding] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok {} {}}

test http11-1.5.$ThreadLevel "normal request for document, unsupported coding" -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
                 -timeout 10000 -headers {accept-encoding unsupported}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
        [meta $tok content-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok {}}

test http11-1.6.$ThreadLevel "normal, specify 1.1 " -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
                 -protocol 1.1 -timeout 10000]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
        [meta $tok connection] [meta $tok transfer-encoding] \
        [http::meta $tok connection] [http::meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close chunked {connection close} {transfer-encoding chunked}}

test http11-1.7.$ThreadLevel "normal, 1.1 and keepalive " -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
                 -protocol 1.1 -keepalive 1 -timeout 10000]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
        [meta $tok connection] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok {} chunked}

test http11-1.8.$ThreadLevel "normal, 1.1 and keepalive, server close" -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
                 -protocol 1.1 -keepalive 1 -timeout 10000]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
        [meta $tok connection] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close {}}

test http11-1.9.$ThreadLevel "normal,gzip,chunked" -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
                 -timeout 10000 -headers {accept-encoding gzip}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
        [meta $tok content-encoding] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok gzip chunked}

test http11-1.10.$ThreadLevel "normal,deflate,chunked" -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
                 -timeout 10000 -headers {accept-encoding deflate}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
        [meta $tok content-encoding] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok deflate chunked}

test http11-1.10.1.$ThreadLevel "normal,deflate,chunked,msdeflate" -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?msdeflate=1 \
                 -timeout 10000 -headers {accept-encoding deflate}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
        [meta $tok content-encoding] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok deflate chunked}

test http11-1.11.$ThreadLevel "normal,compress,chunked" -constraints badCompress -setup {
    # The Tcl "compress" algorithm appears to be incorrect and has been removed.
    # Bug [a13b9d0ce1].
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
                 -timeout 10000 -headers {accept-encoding compress}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
        [meta $tok content-encoding] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok compress chunked}

test http11-1.12.$ThreadLevel "normal,identity,chunked" -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
                 -timeout 10000 -headers {accept-encoding identity}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
        [meta $tok content-encoding] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok {} chunked}

test http11-1.13.$ThreadLevel "normal, 1.1 and keepalive as server default, no zip" -setup {
    variable httpd [create_httpd]
    set zipTmp [http::config -zip]
    http::config -zip 0
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?transfer= \
                 -protocol 1.1 -keepalive 1 -timeout 10000]
    http::wait $tok
    set res1 [list [http::status $tok] [http::code $tok] [check_crc $tok] \
        [meta $tok connection] [meta $tok transfer-encoding] [state $tok reusing] [state $tok connection]]
    set toj [http::geturl http://localhost:$httpd_port/testdoc.html?transfer= \
                 -protocol 1.1 -keepalive 1 -timeout 10000]
    http::wait $toj
    set res2 [list [http::status $toj] [http::code $toj] [check_crc $toj] \
        [meta $toj connection] [meta $toj transfer-encoding] [state $toj reusing] [state $toj connection]]
    concat $res1 -- $res2
} -cleanup {
    catch {http::cleanup $tok}
    catch {http::cleanup $toj}
    halt_httpd
    http::config -zip $zipTmp
} -result {ok {HTTP/1.1 200 OK} ok {} {} 0 keep-alive -- ok {HTTP/1.1 200 OK} ok {} {} 1 keep-alive}







|


|
|









|


|









|


|











|


|









|


|









|


|









|


|
|









|


|









|


|









|


|









|


|









|


|











|


|









|


|











|


|

|


|







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close}

test http11-1.1.$ThreadLevel "normal,gzip,non-chunked" -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
		 -timeout 10000 -headers {accept-encoding gzip}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
	[meta $tok content-encoding] [meta $tok transfer-encoding] \
	[http::meta $tok content-encoding] [http::meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok gzip {} {content-encoding gzip} {}}

test http11-1.2.$ThreadLevel "normal,deflated,non-chunked" -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
		 -timeout 10000 -headers {accept-encoding deflate}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
	[meta $tok content-encoding] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok deflate {}}

test http11-1.2.1.$ThreadLevel "normal,deflated,non-chunked,msdeflate" -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1&msdeflate=1 \
		 -timeout 10000 -headers {accept-encoding deflate}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
	[meta $tok content-encoding] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok deflate {}}

test http11-1.3.$ThreadLevel "normal,compressed,non-chunked" -constraints badCompress -setup {
    # The Tcl "compress" algorithm appears to be incorrect and has been removed.
    # Bug [a13b9d0ce1].
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
		 -timeout 10000 -headers {accept-encoding compress}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
	[meta $tok content-encoding] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok compress {}}

test http11-1.4.$ThreadLevel "normal,identity,non-chunked" -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
		 -timeout 10000 -headers {accept-encoding identity}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
	[meta $tok content-encoding] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok {} {}}

test http11-1.5.$ThreadLevel "normal request for document, unsupported coding" -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
		 -timeout 10000 -headers {accept-encoding unsupported}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
	[meta $tok content-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok {}}

test http11-1.6.$ThreadLevel "normal, specify 1.1 " -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
		 -protocol 1.1 -timeout 10000]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
	[meta $tok connection] [meta $tok transfer-encoding] \
	[http::meta $tok connection] [http::meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close chunked {connection close} {transfer-encoding chunked}}

test http11-1.7.$ThreadLevel "normal, 1.1 and keepalive " -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
		 -protocol 1.1 -keepalive 1 -timeout 10000]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
	[meta $tok connection] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok {} chunked}

test http11-1.8.$ThreadLevel "normal, 1.1 and keepalive, server close" -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
		 -protocol 1.1 -keepalive 1 -timeout 10000]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
	[meta $tok connection] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close {}}

test http11-1.9.$ThreadLevel "normal,gzip,chunked" -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
		 -timeout 10000 -headers {accept-encoding gzip}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
	[meta $tok content-encoding] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok gzip chunked}

test http11-1.10.$ThreadLevel "normal,deflate,chunked" -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
		 -timeout 10000 -headers {accept-encoding deflate}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
	[meta $tok content-encoding] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok deflate chunked}

test http11-1.10.1.$ThreadLevel "normal,deflate,chunked,msdeflate" -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?msdeflate=1 \
		 -timeout 10000 -headers {accept-encoding deflate}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
	[meta $tok content-encoding] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok deflate chunked}

test http11-1.11.$ThreadLevel "normal,compress,chunked" -constraints badCompress -setup {
    # The Tcl "compress" algorithm appears to be incorrect and has been removed.
    # Bug [a13b9d0ce1].
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
		 -timeout 10000 -headers {accept-encoding compress}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
	[meta $tok content-encoding] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok compress chunked}

test http11-1.12.$ThreadLevel "normal,identity,chunked" -setup {
    variable httpd [create_httpd]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
		 -timeout 10000 -headers {accept-encoding identity}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok] \
	[meta $tok content-encoding] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok {} chunked}

test http11-1.13.$ThreadLevel "normal, 1.1 and keepalive as server default, no zip" -setup {
    variable httpd [create_httpd]
    set zipTmp [http::config -zip]
    http::config -zip 0
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?transfer= \
		 -protocol 1.1 -keepalive 1 -timeout 10000]
    http::wait $tok
    set res1 [list [http::status $tok] [http::code $tok] [check_crc $tok] \
	[meta $tok connection] [meta $tok transfer-encoding] [state $tok reusing] [state $tok connection]]
    set toj [http::geturl http://localhost:$httpd_port/testdoc.html?transfer= \
		 -protocol 1.1 -keepalive 1 -timeout 10000]
    http::wait $toj
    set res2 [list [http::status $toj] [http::code $toj] [check_crc $toj] \
	[meta $toj connection] [meta $toj transfer-encoding] [state $toj reusing] [state $toj connection]]
    concat $res1 -- $res2
} -cleanup {
    catch {http::cleanup $tok}
    catch {http::cleanup $toj}
    halt_httpd
    http::config -zip $zipTmp
} -result {ok {HTTP/1.1 200 OK} ok {} {} 0 keep-alive -- ok {HTTP/1.1 200 OK} ok {} {} 1 keep-alive}
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
}

test http11-2.0.$ThreadLevel "-channel" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
                 -timeout 5000 -channel $chan]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
        [meta $tok connection] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close chunked}

test http11-2.1.$ThreadLevel "-channel, encoding gzip" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
                 -timeout 5000 -channel $chan -headers {accept-encoding gzip}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    set diff [expr {[file size testdoc.html] - [file size testfile.tmp]}]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
        [meta $tok connection] [meta $tok content-encoding]\
        [meta $tok transfer-encoding] -- $diff bytes lost
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close gzip chunked -- 0 bytes lost}

# Cf. Bug [3610253] "CopyChunk does not drain decompressor(s)"
# This test failed before the bugfix.
# The pass/fail depended on file size.
test http11-2.1.1.$ThreadLevel "-channel, encoding gzip" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
    set fileName largedoc.html
} -body {
    set tok [http::geturl http://localhost:$httpd_port/$fileName \
                 -timeout 5000 -channel $chan -headers {accept-encoding gzip}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    set diff [expr {[file size $fileName] - [file size testfile.tmp]}]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
        [meta $tok connection] [meta $tok content-encoding]\
        [meta $tok transfer-encoding] -- $diff bytes lost
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close gzip chunked -- 0 bytes lost}

test http11-2.2.$ThreadLevel "-channel, encoding deflate" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
                 -timeout 5000 -channel $chan -headers {accept-encoding deflate}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
        [meta $tok connection] [meta $tok content-encoding]\
        [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close deflate chunked}

test http11-2.2.1.$ThreadLevel "-channel, encoding deflate,msdeflate" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?msdeflate=1 \
                 -timeout 5000 -channel $chan -headers {accept-encoding deflate}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
        [meta $tok connection] [meta $tok content-encoding]\
        [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close deflate chunked}

test http11-2.3.$ThreadLevel "-channel,encoding compress" -constraints badCompress -setup {
    # The Tcl "compress" algorithm appears to be incorrect and has been removed.
    # Bug [a13b9d0ce1].
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
                 -timeout 5000 -channel $chan \
                 -headers {accept-encoding compress}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
        [meta $tok connection] [meta $tok content-encoding]\
        [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close compress chunked}

test http11-2.4.$ThreadLevel "-channel,encoding identity" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
                 -timeout 5000 -channel $chan \
                 -headers {accept-encoding identity}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
        [meta $tok connection] [meta $tok content-encoding]\
        [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close {} chunked}

test http11-2.4.1.$ThreadLevel "-channel,encoding identity with -progress" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
    set logdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
                 -timeout 5000 -channel $chan \
                 -headers {accept-encoding identity} \
                 -progress [namespace code [list progress logdata]]]

    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
        [meta $tok connection] [meta $tok content-encoding]\
        [meta $tok transfer-encoding] \
        [expr {[lindex $logdata 0] - [lindex $logdata 1]}] \
        [expr {[lindex $logdata 0] - [string length $data]}]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
    unset -nocomplain logdata data
} -result {ok {HTTP/1.1 200 OK} ok close {} chunked 0 0}

test http11-2.4.2.$ThreadLevel "-channel,encoding identity with -progress progressPause enters event loop" -constraints knownBug -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
    set logdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
                 -timeout 5000 -channel $chan \
                 -headers {accept-encoding identity} \
                 -progress [namespace code [list progressPause logdata]]]

    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
        [meta $tok connection] [meta $tok content-encoding]\
        [meta $tok transfer-encoding] \
        [expr {[lindex $logdata 0] - [lindex $logdata 1]}] \
        [expr {[lindex $logdata 0] - [string length $data]}]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
    unset -nocomplain logdata data ::WaitHere
} -result {ok {HTTP/1.1 200 OK} ok close {} chunked 0 0}

test http11-2.5.$ThreadLevel "-channel,encoding unsupported" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
                 -timeout 5000 -channel $chan \
                 -headers {accept-encoding unsupported}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
        [meta $tok connection] [meta $tok content-encoding]\
        [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close {} chunked}

test http11-2.6.$ThreadLevel "-channel,encoding gzip,non-chunked" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
                 -timeout 5000 -channel $chan -headers {accept-encoding gzip}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
        [meta $tok connection] [meta $tok content-encoding]\
        [meta $tok transfer-encoding]\
        [expr {[file size testdoc.html]-[file size testfile.tmp]}]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close gzip {} 0}

test http11-2.7.$ThreadLevel "-channel,encoding deflate,non-chunked" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
                 -timeout 5000 -channel $chan -headers {accept-encoding deflate}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
        [meta $tok connection] [meta $tok content-encoding]\
        [meta $tok transfer-encoding]\
        [expr {[file size testdoc.html]-[file size testfile.tmp]}]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close deflate {} 0}

test http11-2.7.1.$ThreadLevel "-channel,encoding deflate,non-chunked,msdeflate" -constraints knownBug -setup {
    # Test fails because a -channel can only try one un-deflate algorithm, and the
    # compliant "decompress" is tried, not the non-compliant "inflate" of
    # the MS browser implementation.
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1&msdeflate=1 \
                 -timeout 5000 -channel $chan -headers {accept-encoding deflate}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
        [meta $tok connection] [meta $tok content-encoding]\
        [meta $tok transfer-encoding]\
        [expr {[file size testdoc.html]-[file size testfile.tmp]}]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close deflate {} 0}

test http11-2.8.$ThreadLevel "-channel,encoding compress,non-chunked" -constraints badCompress -setup {
    # The Tcl "compress" algorithm appears to be incorrect and has been removed.
    # Bug [a13b9d0ce1].
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
                 -timeout 5000 -channel $chan -headers {accept-encoding compress}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
        [meta $tok connection] [meta $tok content-encoding]\
        [meta $tok transfer-encoding]\
        [expr {[file size testdoc.html]-[file size testfile.tmp]}]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close compress {} 0}

test http11-2.9.$ThreadLevel "-channel,encoding identity,non-chunked" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
                 -timeout 5000 -channel $chan -headers {accept-encoding identity}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
        [meta $tok connection] [meta $tok content-encoding]\
        [meta $tok transfer-encoding]\
        [expr {[file size testdoc.html]-[file size testfile.tmp]}]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close {} {} 0}

test http11-2.10.$ThreadLevel "-channel,deflate,keepalive" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
                 -timeout 5000 -channel $chan -keepalive 1 \
		 -headers {accept-encoding deflate}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
        [meta $tok connection] [meta $tok content-encoding]\
        [meta $tok transfer-encoding]\
        [expr {[file size testdoc.html]-[file size testfile.tmp]}]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok {} deflate chunked 0}

test http11-2.10.1.$ThreadLevel "-channel,deflate,keepalive,msdeflate" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?msdeflate=1 \
                 -timeout 5000 -channel $chan -keepalive 1 \
		 -headers {accept-encoding deflate}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
        [meta $tok connection] [meta $tok content-encoding]\
        [meta $tok transfer-encoding]\
        [expr {[file size testdoc.html]-[file size testfile.tmp]}]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok {} deflate chunked 0}

test http11-2.11.$ThreadLevel "-channel,identity,keepalive" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
                 -headers {accept-encoding identity} \
                 -timeout 5000 -channel $chan -keepalive 1]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
        [meta $tok connection] [meta $tok content-encoding]\
        [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok {} {} chunked}

test http11-2.12.$ThreadLevel "-channel,negotiate,keepalive" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
                 -timeout 5000 -channel $chan -keepalive 1]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
        [meta $tok connection] [meta $tok content-encoding]\
        [meta $tok transfer-encoding] [meta $tok x-requested-encodings]\
        [expr {[file size testdoc.html]-[file size testfile.tmp]}]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok {} gzip chunked gzip,deflate 0}








|




|












|





|
|
















|





|
|












|




|
|












|




|
|














|
|




|
|












|
|




|
|













|
|
|





|
|
|
|














|
|
|





|
|
|
|













|
|




|
|












|




|
|
|












|




|
|
|















|




|
|
|














|




|
|
|












|




|
|
|












|





|
|
|












|





|
|
|












|
|




|
|












|




|
|
|







359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
}

test http11-2.0.$ThreadLevel "-channel" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
		 -timeout 5000 -channel $chan]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
	[meta $tok connection] [meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close chunked}

test http11-2.1.$ThreadLevel "-channel, encoding gzip" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
		 -timeout 5000 -channel $chan -headers {accept-encoding gzip}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    set diff [expr {[file size testdoc.html] - [file size testfile.tmp]}]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
	[meta $tok connection] [meta $tok content-encoding]\
	[meta $tok transfer-encoding] -- $diff bytes lost
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close gzip chunked -- 0 bytes lost}

# Cf. Bug [3610253] "CopyChunk does not drain decompressor(s)"
# This test failed before the bugfix.
# The pass/fail depended on file size.
test http11-2.1.1.$ThreadLevel "-channel, encoding gzip" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
    set fileName largedoc.html
} -body {
    set tok [http::geturl http://localhost:$httpd_port/$fileName \
		 -timeout 5000 -channel $chan -headers {accept-encoding gzip}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    set diff [expr {[file size $fileName] - [file size testfile.tmp]}]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
	[meta $tok connection] [meta $tok content-encoding]\
	[meta $tok transfer-encoding] -- $diff bytes lost
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close gzip chunked -- 0 bytes lost}

test http11-2.2.$ThreadLevel "-channel, encoding deflate" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
		 -timeout 5000 -channel $chan -headers {accept-encoding deflate}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
	[meta $tok connection] [meta $tok content-encoding]\
	[meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close deflate chunked}

test http11-2.2.1.$ThreadLevel "-channel, encoding deflate,msdeflate" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?msdeflate=1 \
		 -timeout 5000 -channel $chan -headers {accept-encoding deflate}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
	[meta $tok connection] [meta $tok content-encoding]\
	[meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close deflate chunked}

test http11-2.3.$ThreadLevel "-channel,encoding compress" -constraints badCompress -setup {
    # The Tcl "compress" algorithm appears to be incorrect and has been removed.
    # Bug [a13b9d0ce1].
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
		 -timeout 5000 -channel $chan \
		 -headers {accept-encoding compress}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
	[meta $tok connection] [meta $tok content-encoding]\
	[meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close compress chunked}

test http11-2.4.$ThreadLevel "-channel,encoding identity" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
		 -timeout 5000 -channel $chan \
		 -headers {accept-encoding identity}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
	[meta $tok connection] [meta $tok content-encoding]\
	[meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close {} chunked}

test http11-2.4.1.$ThreadLevel "-channel,encoding identity with -progress" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
    set logdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
		 -timeout 5000 -channel $chan \
		 -headers {accept-encoding identity} \
		 -progress [namespace code [list progress logdata]]]

    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
	[meta $tok connection] [meta $tok content-encoding]\
	[meta $tok transfer-encoding] \
	[expr {[lindex $logdata 0] - [lindex $logdata 1]}] \
	[expr {[lindex $logdata 0] - [string length $data]}]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
    unset -nocomplain logdata data
} -result {ok {HTTP/1.1 200 OK} ok close {} chunked 0 0}

test http11-2.4.2.$ThreadLevel "-channel,encoding identity with -progress progressPause enters event loop" -constraints knownBug -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
    set logdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
		 -timeout 5000 -channel $chan \
		 -headers {accept-encoding identity} \
		 -progress [namespace code [list progressPause logdata]]]

    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
	[meta $tok connection] [meta $tok content-encoding]\
	[meta $tok transfer-encoding] \
	[expr {[lindex $logdata 0] - [lindex $logdata 1]}] \
	[expr {[lindex $logdata 0] - [string length $data]}]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
    unset -nocomplain logdata data ::WaitHere
} -result {ok {HTTP/1.1 200 OK} ok close {} chunked 0 0}

test http11-2.5.$ThreadLevel "-channel,encoding unsupported" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
		 -timeout 5000 -channel $chan \
		 -headers {accept-encoding unsupported}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
	[meta $tok connection] [meta $tok content-encoding]\
	[meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close {} chunked}

test http11-2.6.$ThreadLevel "-channel,encoding gzip,non-chunked" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
		 -timeout 5000 -channel $chan -headers {accept-encoding gzip}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
	[meta $tok connection] [meta $tok content-encoding]\
	[meta $tok transfer-encoding]\
	[expr {[file size testdoc.html]-[file size testfile.tmp]}]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close gzip {} 0}

test http11-2.7.$ThreadLevel "-channel,encoding deflate,non-chunked" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
		 -timeout 5000 -channel $chan -headers {accept-encoding deflate}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
	[meta $tok connection] [meta $tok content-encoding]\
	[meta $tok transfer-encoding]\
	[expr {[file size testdoc.html]-[file size testfile.tmp]}]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close deflate {} 0}

test http11-2.7.1.$ThreadLevel "-channel,encoding deflate,non-chunked,msdeflate" -constraints knownBug -setup {
    # Test fails because a -channel can only try one un-deflate algorithm, and the
    # compliant "decompress" is tried, not the non-compliant "inflate" of
    # the MS browser implementation.
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1&msdeflate=1 \
		 -timeout 5000 -channel $chan -headers {accept-encoding deflate}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
	[meta $tok connection] [meta $tok content-encoding]\
	[meta $tok transfer-encoding]\
	[expr {[file size testdoc.html]-[file size testfile.tmp]}]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close deflate {} 0}

test http11-2.8.$ThreadLevel "-channel,encoding compress,non-chunked" -constraints badCompress -setup {
    # The Tcl "compress" algorithm appears to be incorrect and has been removed.
    # Bug [a13b9d0ce1].
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
		 -timeout 5000 -channel $chan -headers {accept-encoding compress}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
	[meta $tok connection] [meta $tok content-encoding]\
	[meta $tok transfer-encoding]\
	[expr {[file size testdoc.html]-[file size testfile.tmp]}]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close compress {} 0}

test http11-2.9.$ThreadLevel "-channel,encoding identity,non-chunked" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
		 -timeout 5000 -channel $chan -headers {accept-encoding identity}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
	[meta $tok connection] [meta $tok content-encoding]\
	[meta $tok transfer-encoding]\
	[expr {[file size testdoc.html]-[file size testfile.tmp]}]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close {} {} 0}

test http11-2.10.$ThreadLevel "-channel,deflate,keepalive" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
		 -timeout 5000 -channel $chan -keepalive 1 \
		 -headers {accept-encoding deflate}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
	[meta $tok connection] [meta $tok content-encoding]\
	[meta $tok transfer-encoding]\
	[expr {[file size testdoc.html]-[file size testfile.tmp]}]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok {} deflate chunked 0}

test http11-2.10.1.$ThreadLevel "-channel,deflate,keepalive,msdeflate" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?msdeflate=1 \
		 -timeout 5000 -channel $chan -keepalive 1 \
		 -headers {accept-encoding deflate}]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
	[meta $tok connection] [meta $tok content-encoding]\
	[meta $tok transfer-encoding]\
	[expr {[file size testdoc.html]-[file size testfile.tmp]}]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok {} deflate chunked 0}

test http11-2.11.$ThreadLevel "-channel,identity,keepalive" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
		 -headers {accept-encoding identity} \
		 -timeout 5000 -channel $chan -keepalive 1]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
	[meta $tok connection] [meta $tok content-encoding]\
	[meta $tok transfer-encoding]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok {} {} chunked}

test http11-2.12.$ThreadLevel "-channel,negotiate,keepalive" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
		 -timeout 5000 -channel $chan -keepalive 1]
    http::wait $tok
    seek $chan 0
    set data [read $chan]
    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
	[meta $tok connection] [meta $tok content-encoding]\
	[meta $tok transfer-encoding] [meta $tok x-requested-encodings]\
	[expr {[file size testdoc.html]-[file size testfile.tmp]}]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok {} gzip chunked gzip,deflate 0}

788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
}

test http11-3.0.$ThreadLevel "-handler,close,identity" -setup {
    variable httpd [create_httpd]
    set testdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
                 -timeout 10000 -handler [namespace code [list handler testdata]]]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
        [meta $tok connection] [meta $tok content-encoding] \
        [meta $tok transfer-encoding] \
        [expr {[file size testdoc.html]-[string length $testdata]}]
} -cleanup {
    catch {http::cleanup $tok}
    unset -nocomplain testdata
    halt_httpd
} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0}

test http11-3.1.$ThreadLevel "-handler,protocol1.0" -setup {
    variable httpd [create_httpd]
    set testdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
                 -timeout 10000 -protocol 1.0 \
                 -handler [namespace code [list handler testdata]]]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
        [meta $tok connection] [meta $tok content-encoding] \
        [meta $tok transfer-encoding] \
        [expr {[file size testdoc.html]-[string length $testdata]}]
} -cleanup {
    catch {http::cleanup $tok}
    unset -nocomplain testdata
    halt_httpd
} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0}

test http11-3.2.$ThreadLevel "-handler,close,chunked" -setup {
    variable httpd [create_httpd]
    set testdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
                 -timeout 10000 -keepalive 0 -binary 1\
                 -handler [namespace code [list handler testdata]]]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
        [meta $tok connection] [meta $tok content-encoding] \
        [meta $tok transfer-encoding] \
        [expr {[file size testdoc.html]-[string length $testdata]}]
} -cleanup {
    catch {http::cleanup $tok}
    unset -nocomplain testdata
    halt_httpd
} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0}

test http11-3.3.$ThreadLevel "-handler,keepalive,chunked" -setup {
    variable httpd [create_httpd]
    set testdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
                 -timeout 10000 -keepalive 1 -binary 1\
                 -handler [namespace code [list handler testdata]]]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
        [meta $tok connection] [meta $tok content-encoding] \
        [meta $tok transfer-encoding] \
        [expr {[file size testdoc.html]-[string length $testdata]}]
} -cleanup {
    catch {http::cleanup $tok}
    unset -nocomplain testdata
    halt_httpd
} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0}

# http11-3.4







|


|
|
|











|
|


|
|
|











|
|


|
|
|











|
|


|
|
|







788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
}

test http11-3.0.$ThreadLevel "-handler,close,identity" -setup {
    variable httpd [create_httpd]
    set testdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
		 -timeout 10000 -handler [namespace code [list handler testdata]]]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
	[meta $tok connection] [meta $tok content-encoding] \
	[meta $tok transfer-encoding] \
	[expr {[file size testdoc.html]-[string length $testdata]}]
} -cleanup {
    catch {http::cleanup $tok}
    unset -nocomplain testdata
    halt_httpd
} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0}

test http11-3.1.$ThreadLevel "-handler,protocol1.0" -setup {
    variable httpd [create_httpd]
    set testdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
		 -timeout 10000 -protocol 1.0 \
		 -handler [namespace code [list handler testdata]]]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
	[meta $tok connection] [meta $tok content-encoding] \
	[meta $tok transfer-encoding] \
	[expr {[file size testdoc.html]-[string length $testdata]}]
} -cleanup {
    catch {http::cleanup $tok}
    unset -nocomplain testdata
    halt_httpd
} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0}

test http11-3.2.$ThreadLevel "-handler,close,chunked" -setup {
    variable httpd [create_httpd]
    set testdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
		 -timeout 10000 -keepalive 0 -binary 1\
		 -handler [namespace code [list handler testdata]]]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
	[meta $tok connection] [meta $tok content-encoding] \
	[meta $tok transfer-encoding] \
	[expr {[file size testdoc.html]-[string length $testdata]}]
} -cleanup {
    catch {http::cleanup $tok}
    unset -nocomplain testdata
    halt_httpd
} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0}

test http11-3.3.$ThreadLevel "-handler,keepalive,chunked" -setup {
    variable httpd [create_httpd]
    set testdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
		 -timeout 10000 -keepalive 1 -binary 1\
		 -handler [namespace code [list handler testdata]]]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
	[meta $tok connection] [meta $tok content-encoding] \
	[meta $tok transfer-encoding] \
	[expr {[file size testdoc.html]-[string length $testdata]}]
} -cleanup {
    catch {http::cleanup $tok}
    unset -nocomplain testdata
    halt_httpd
} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0}

# http11-3.4
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
# open.  In HTTP/1.0 this is not the case, and this is a test that
# the Tcl client assumes "Connection: close" by default in HTTP/1.0.
test http11-3.4.$ThreadLevel "-handler,close,identity; HTTP/1.0 server does not send Connection: close header or Content-Length" -setup {
    variable httpd [create_httpd]
    set testdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1&nosendclose=any \
                 -timeout 10000 -handler [namespace code [list handler testdata]]]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
        [meta $tok connection] [meta $tok content-encoding] \
        [meta $tok transfer-encoding] \
        [expr {[file size testdoc.html]-[string length $testdata]}]
} -cleanup {
    catch {http::cleanup $tok}
    unset -nocomplain testdata
    halt_httpd
} -result {ok {HTTP/1.0 200 OK} ok {} {} {} 0}

# It is not forbidden for a handler to enter the event loop.
test http11-3.5.$ThreadLevel "-handler,close,identity as http11-3.0 but handlerPause enters event loop" -setup {
    variable httpd [create_httpd]
    set testdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
                 -timeout 10000 -handler [namespace code [list handlerPause testdata]]]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
        [meta $tok connection] [meta $tok content-encoding] \
        [meta $tok transfer-encoding] \
        [expr {[file size testdoc.html]-[string length $testdata]}]
} -cleanup {
    catch {http::cleanup $tok}
    unset -nocomplain testdata ::WaitHere
    halt_httpd
} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0}

test http11-3.6.$ThreadLevel "-handler,close,identity as http11-3.0 but with -progress" -setup {
    variable httpd [create_httpd]
    set testdata ""
    set logdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
                 -timeout 10000 -handler [namespace code [list handler testdata]] \
                 -progress [namespace code [list progress logdata]]]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
        [meta $tok connection] [meta $tok content-encoding] \
        [meta $tok transfer-encoding] \
        [expr {[file size testdoc.html]-[string length $testdata]}] \
        [expr {[lindex $logdata 0] - [lindex $logdata 1]}] \
        [expr {[lindex $logdata 0] - [string length $testdata]}]
} -cleanup {
    catch {http::cleanup $tok}
    unset -nocomplain testdata logdata ::WaitHere
    halt_httpd
} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0 0 0}

test http11-3.7.$ThreadLevel "-handler,close,identity as http11-3.0 but with -progress progressPause enters event loop" -setup {
    variable httpd [create_httpd]
    set testdata ""
    set logdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
                 -timeout 10000 -handler [namespace code [list handler testdata]] \
                 -progress [namespace code [list progressPause logdata]]]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
        [meta $tok connection] [meta $tok content-encoding] \
        [meta $tok transfer-encoding] \
        [expr {[file size testdoc.html]-[string length $testdata]}] \
        [expr {[lindex $logdata 0] - [lindex $logdata 1]}] \
        [expr {[lindex $logdata 0] - [string length $testdata]}]
} -cleanup {
    catch {http::cleanup $tok}
    unset -nocomplain testdata logdata ::WaitHere
    halt_httpd
} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0 0 0}

test http11-3.8.$ThreadLevel "close,identity no -handler but with -progress" -setup {
    variable httpd [create_httpd]
    set logdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
                 -timeout 10000 \
                 -progress [namespace code [list progress logdata]] \
                 -headers {accept-encoding {}}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok]\
        [meta $tok connection] [meta $tok content-encoding] \
        [meta $tok transfer-encoding] \
        [expr {[file size testdoc.html]-[string length [http::data $tok]]}] \
        [expr {[lindex $logdata 0] - [lindex $logdata 1]}] \
        [expr {[lindex $logdata 0] - [string length [http::data $tok]]}]
} -cleanup {
    catch {http::cleanup $tok}
    unset -nocomplain logdata ::WaitHere
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close {} {} 0 0 0}

test http11-3.9.$ThreadLevel "close,identity no -handler but with -progress progressPause enters event loop" -setup {
    variable httpd [create_httpd]
    set logdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
                 -timeout 10000 \
                 -progress [namespace code [list progressPause logdata]] \
                 -headers {accept-encoding {}}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok]\
        [meta $tok connection] [meta $tok content-encoding] \
        [meta $tok transfer-encoding] \
        [expr {[file size testdoc.html]-[string length [http::data $tok]]}] \
        [expr {[lindex $logdata 0] - [lindex $logdata 1]}] \
        [expr {[lindex $logdata 0] - [string length [http::data $tok]]}]
} -cleanup {
    catch {http::cleanup $tok}
    unset -nocomplain logdata ::WaitHere
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close {} {} 0 0 0}

test http11-4.0.$ThreadLevel "normal post request" -setup {
    variable httpd [create_httpd]
} -body {
    set query [http::formatQuery q 1 z 2]
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
                 -query $query -timeout 10000]
    http::wait $tok
    list status [http::status $tok] code [http::code $tok]\
        crc [check_crc $tok]\
        connection [meta $tok connection]\
        query-length [meta $tok x-query-length]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {status ok code {HTTP/1.1 200 OK} crc ok connection close query-length 7}

test http11-4.1.$ThreadLevel "normal post request, check query length" -setup {
    variable httpd [create_httpd]
} -body {
    set query [http::formatQuery q 1 z 2]
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
                 -headers [list x-check-query yes] \
                 -query $query -timeout 10000]
    http::wait $tok
    list status [http::status $tok] code [http::code $tok]\
        crc [check_crc $tok]\
        connection [meta $tok connection]\
        query-length [meta $tok x-query-length]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {status ok code {HTTP/1.1 200 OK} crc ok connection close query-length 7}

test http11-4.2.$ThreadLevel "normal post request, check long query length" -setup {
    variable httpd [create_httpd]
} -body {
    set query [string repeat a 24576]
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html\
                 -headers [list x-check-query yes]\
                 -query $query -timeout 10000]
    http::wait $tok
    list status [http::status $tok] code [http::code $tok]\
        crc [check_crc $tok]\
        connection [meta $tok connection]\
        query-length [meta $tok x-query-length]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {status ok code {HTTP/1.1 200 OK} crc ok connection close query-length 24576}

test http11-4.3.$ThreadLevel "normal post request, check channel query length" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
    puts -nonewline $chan [string repeat [encoding convertto utf-8 "This is a test\n"] 8192]
    flush $chan
    seek $chan 0
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html\
                 -headers [list x-check-query yes]\
                 -querychannel $chan -timeout 10000]
    http::wait $tok
    list status [http::status $tok] code [http::code $tok]\
        crc [check_crc $tok]\
        connection [meta $tok connection]\
        query-length [meta $tok x-query-length]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {status ok code {HTTP/1.1 200 OK} crc ok connection close query-length 122880}








|


|
|
|












|


|
|
|












|
|


|
|
|
|
|












|
|


|
|
|
|
|











|
|
|


|
|
|
|
|











|
|
|


|
|
|
|
|











|


|
|
|










|
|


|
|
|










|
|


|
|
|













|
|


|
|
|







869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
# open.  In HTTP/1.0 this is not the case, and this is a test that
# the Tcl client assumes "Connection: close" by default in HTTP/1.0.
test http11-3.4.$ThreadLevel "-handler,close,identity; HTTP/1.0 server does not send Connection: close header or Content-Length" -setup {
    variable httpd [create_httpd]
    set testdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1&nosendclose=any \
		 -timeout 10000 -handler [namespace code [list handler testdata]]]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
	[meta $tok connection] [meta $tok content-encoding] \
	[meta $tok transfer-encoding] \
	[expr {[file size testdoc.html]-[string length $testdata]}]
} -cleanup {
    catch {http::cleanup $tok}
    unset -nocomplain testdata
    halt_httpd
} -result {ok {HTTP/1.0 200 OK} ok {} {} {} 0}

# It is not forbidden for a handler to enter the event loop.
test http11-3.5.$ThreadLevel "-handler,close,identity as http11-3.0 but handlerPause enters event loop" -setup {
    variable httpd [create_httpd]
    set testdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
		 -timeout 10000 -handler [namespace code [list handlerPause testdata]]]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
	[meta $tok connection] [meta $tok content-encoding] \
	[meta $tok transfer-encoding] \
	[expr {[file size testdoc.html]-[string length $testdata]}]
} -cleanup {
    catch {http::cleanup $tok}
    unset -nocomplain testdata ::WaitHere
    halt_httpd
} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0}

test http11-3.6.$ThreadLevel "-handler,close,identity as http11-3.0 but with -progress" -setup {
    variable httpd [create_httpd]
    set testdata ""
    set logdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
		 -timeout 10000 -handler [namespace code [list handler testdata]] \
		 -progress [namespace code [list progress logdata]]]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
	[meta $tok connection] [meta $tok content-encoding] \
	[meta $tok transfer-encoding] \
	[expr {[file size testdoc.html]-[string length $testdata]}] \
	[expr {[lindex $logdata 0] - [lindex $logdata 1]}] \
	[expr {[lindex $logdata 0] - [string length $testdata]}]
} -cleanup {
    catch {http::cleanup $tok}
    unset -nocomplain testdata logdata ::WaitHere
    halt_httpd
} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0 0 0}

test http11-3.7.$ThreadLevel "-handler,close,identity as http11-3.0 but with -progress progressPause enters event loop" -setup {
    variable httpd [create_httpd]
    set testdata ""
    set logdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
		 -timeout 10000 -handler [namespace code [list handler testdata]] \
		 -progress [namespace code [list progressPause logdata]]]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
	[meta $tok connection] [meta $tok content-encoding] \
	[meta $tok transfer-encoding] \
	[expr {[file size testdoc.html]-[string length $testdata]}] \
	[expr {[lindex $logdata 0] - [lindex $logdata 1]}] \
	[expr {[lindex $logdata 0] - [string length $testdata]}]
} -cleanup {
    catch {http::cleanup $tok}
    unset -nocomplain testdata logdata ::WaitHere
    halt_httpd
} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0 0 0}

test http11-3.8.$ThreadLevel "close,identity no -handler but with -progress" -setup {
    variable httpd [create_httpd]
    set logdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
		 -timeout 10000 \
		 -progress [namespace code [list progress logdata]] \
		 -headers {accept-encoding {}}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok]\
	[meta $tok connection] [meta $tok content-encoding] \
	[meta $tok transfer-encoding] \
	[expr {[file size testdoc.html]-[string length [http::data $tok]]}] \
	[expr {[lindex $logdata 0] - [lindex $logdata 1]}] \
	[expr {[lindex $logdata 0] - [string length [http::data $tok]]}]
} -cleanup {
    catch {http::cleanup $tok}
    unset -nocomplain logdata ::WaitHere
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close {} {} 0 0 0}

test http11-3.9.$ThreadLevel "close,identity no -handler but with -progress progressPause enters event loop" -setup {
    variable httpd [create_httpd]
    set logdata ""
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
		 -timeout 10000 \
		 -progress [namespace code [list progressPause logdata]] \
		 -headers {accept-encoding {}}]
    http::wait $tok
    list [http::status $tok] [http::code $tok] [check_crc $tok]\
	[meta $tok connection] [meta $tok content-encoding] \
	[meta $tok transfer-encoding] \
	[expr {[file size testdoc.html]-[string length [http::data $tok]]}] \
	[expr {[lindex $logdata 0] - [lindex $logdata 1]}] \
	[expr {[lindex $logdata 0] - [string length [http::data $tok]]}]
} -cleanup {
    catch {http::cleanup $tok}
    unset -nocomplain logdata ::WaitHere
    halt_httpd
} -result {ok {HTTP/1.1 200 OK} ok close {} {} 0 0 0}

test http11-4.0.$ThreadLevel "normal post request" -setup {
    variable httpd [create_httpd]
} -body {
    set query [http::formatQuery q 1 z 2]
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
		 -query $query -timeout 10000]
    http::wait $tok
    list status [http::status $tok] code [http::code $tok]\
	crc [check_crc $tok]\
	connection [meta $tok connection]\
	query-length [meta $tok x-query-length]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {status ok code {HTTP/1.1 200 OK} crc ok connection close query-length 7}

test http11-4.1.$ThreadLevel "normal post request, check query length" -setup {
    variable httpd [create_httpd]
} -body {
    set query [http::formatQuery q 1 z 2]
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
		 -headers [list x-check-query yes] \
		 -query $query -timeout 10000]
    http::wait $tok
    list status [http::status $tok] code [http::code $tok]\
	crc [check_crc $tok]\
	connection [meta $tok connection]\
	query-length [meta $tok x-query-length]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {status ok code {HTTP/1.1 200 OK} crc ok connection close query-length 7}

test http11-4.2.$ThreadLevel "normal post request, check long query length" -setup {
    variable httpd [create_httpd]
} -body {
    set query [string repeat a 24576]
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html\
		 -headers [list x-check-query yes]\
		 -query $query -timeout 10000]
    http::wait $tok
    list status [http::status $tok] code [http::code $tok]\
	crc [check_crc $tok]\
	connection [meta $tok connection]\
	query-length [meta $tok x-query-length]
} -cleanup {
    catch {http::cleanup $tok}
    halt_httpd
} -result {status ok code {HTTP/1.1 200 OK} crc ok connection close query-length 24576}

test http11-4.3.$ThreadLevel "normal post request, check channel query length" -setup {
    variable httpd [create_httpd]
    set chan [open [makeFile {} testfile.tmp] wb+]
    puts -nonewline $chan [string repeat [encoding convertto utf-8 "This is a test\n"] 8192]
    flush $chan
    seek $chan 0
} -body {
    set tok [http::geturl http://localhost:$httpd_port/testdoc.html\
		 -headers [list x-check-query yes]\
		 -querychannel $chan -timeout 10000]
    http::wait $tok
    list status [http::status $tok] code [http::code $tok]\
	crc [check_crc $tok]\
	connection [meta $tok connection]\
	query-length [meta $tok x-query-length]
} -cleanup {
    catch {http::cleanup $tok}
    close $chan
    removeFile testfile.tmp
    halt_httpd
} -result {status ok code {HTTP/1.1 200 OK} crc ok connection close query-length 122880}

Changes to tests/httpPipeline.test.
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
if 0 {
    # For debugging: run with a single value of ThreadLevel: 0|1|2
    set ThreadLevel 0
    testConstraint ThreadLevelSummary 1
}
if {![info exists ThreadLevel]} {
    if {[catch {package require Thread}] == 0} {
        set ValueRange {0 1 2}
    } else {
        set ValueRange {0 1}
    }

    # For each value of ThreadLevel, source this file recursively in the
    # same interpreter.
    foreach ThreadLevel $ValueRange {
        source [info script]
    }
    catch {unset ThreadLevel}
    catch {unset ValueRange}
    if {![testConstraint ThreadLevelSummary]} {
        ::tcltest::cleanupTests
    }
    return
}

catch {puts "==== Test with ThreadLevel $ThreadLevel ===="}
http::config -threadlevel $ThreadLevel








|

|





|




|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
if 0 {
    # For debugging: run with a single value of ThreadLevel: 0|1|2
    set ThreadLevel 0
    testConstraint ThreadLevelSummary 1
}
if {![info exists ThreadLevel]} {
    if {[catch {package require Thread}] == 0} {
	set ValueRange {0 1 2}
    } else {
	set ValueRange {0 1}
    }

    # For each value of ThreadLevel, source this file recursively in the
    # same interpreter.
    foreach ThreadLevel $ValueRange {
	source [info script]
    }
    catch {unset ThreadLevel}
    catch {unset ValueRange}
    if {![testConstraint ThreadLevelSummary]} {
	::tcltest::cleanupTests
    }
    return
}

catch {puts "==== Test with ThreadLevel $ThreadLevel ===="}
http::config -threadlevel $ThreadLevel

479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
	    return -code error {no matching script}
	}
    }


    if {$ca < 3} {
	# Not Keep-Alive.
        set result "Passed all sanity checks."

    } elseif {$ca == 3} {
        # Keep-Alive, not pipelined.
        set result {}
        append result "Passed all sanity checks.\n"
        append result "Have overlaps including response body:\n"

    } else {
        # Keep-Alive, pipelined: ($ca == 4)
        set result {}
        append result "Passed all sanity checks.\n"
        append result "Overlap-free without response body:\n"
        append result "$resShort"
    }

    # - The special case of test *.18*-testEof needs test results to be
    #   individually written.
    # - These test -repost 0 when there is a POST to apply it to, and the server
    #   timeout has not been detected.
    if {($cb == 18) && ($te == 1)} {
        if {$ca < 3} {
	    # Not Keep-Alive.
	    set result "Passed all sanity checks."

	} elseif {$ca == 3 && $delay == 0} {
	    # Keep-Alive, not pipelined.
            set result [MakeMessage {
		|Problems with sanity checks:
		|Wrong sequence for token ::http::2 - {A B C D X X X}
		|- and error(s) X
		|Wrong sequence for token ::http::3 - {A X X}
		|- and error(s) X
		|Wrong sequence for token ::http::4 - {A X X X}
		|- and error(s) X
		|
		|Have overlaps including response body:
		|
	    }]

	} elseif {$ca == 3} {
	    # Keep-Alive, not pipelined.
            set result [MakeMessage {
		|Problems with sanity checks:
		|Wrong sequence for token ::http::2 - {A B C D X X X}
		|- and error(s) X
		|
		|Have overlaps including response body:
		|
	    }]

	} elseif {$delay == 0} {
	    # Keep-Alive, pipelined: ($ca == 4)
            set result [MakeMessage {
		|Problems with sanity checks:
		|Wrong sequence for token ::http::2 - {A B C D X X X}
		|- and error(s) X
		|Wrong sequence for token ::http::3 - {A X X}
		|- and error(s) X
		|Wrong sequence for token ::http::4 - {A X X X}
		|- and error(s) X
		|
		|Overlap-free without response body:
		|
	    }]

	} else {
            set result [MakeMessage {
		|Problems with sanity checks:
		|Wrong sequence for token ::http::2 - {A B C D X X X}
		|- and error(s) X
		|
		|Overlap-free without response body:
		|
	    }]

        }
    }

    return [list "$start$middle$end" $result]
}

# ------------------------------------------------------------------------------
#  Proc MakeMessage







|


|
|
|
|


|
|
|
|
|







|





|














|










|













|








|







479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
	    return -code error {no matching script}
	}
    }


    if {$ca < 3} {
	# Not Keep-Alive.
	set result "Passed all sanity checks."

    } elseif {$ca == 3} {
	# Keep-Alive, not pipelined.
	set result {}
	append result "Passed all sanity checks.\n"
	append result "Have overlaps including response body:\n"

    } else {
	# Keep-Alive, pipelined: ($ca == 4)
	set result {}
	append result "Passed all sanity checks.\n"
	append result "Overlap-free without response body:\n"
	append result "$resShort"
    }

    # - The special case of test *.18*-testEof needs test results to be
    #   individually written.
    # - These test -repost 0 when there is a POST to apply it to, and the server
    #   timeout has not been detected.
    if {($cb == 18) && ($te == 1)} {
	if {$ca < 3} {
	    # Not Keep-Alive.
	    set result "Passed all sanity checks."

	} elseif {$ca == 3 && $delay == 0} {
	    # Keep-Alive, not pipelined.
	    set result [MakeMessage {
		|Problems with sanity checks:
		|Wrong sequence for token ::http::2 - {A B C D X X X}
		|- and error(s) X
		|Wrong sequence for token ::http::3 - {A X X}
		|- and error(s) X
		|Wrong sequence for token ::http::4 - {A X X X}
		|- and error(s) X
		|
		|Have overlaps including response body:
		|
	    }]

	} elseif {$ca == 3} {
	    # Keep-Alive, not pipelined.
	    set result [MakeMessage {
		|Problems with sanity checks:
		|Wrong sequence for token ::http::2 - {A B C D X X X}
		|- and error(s) X
		|
		|Have overlaps including response body:
		|
	    }]

	} elseif {$delay == 0} {
	    # Keep-Alive, pipelined: ($ca == 4)
	    set result [MakeMessage {
		|Problems with sanity checks:
		|Wrong sequence for token ::http::2 - {A B C D X X X}
		|- and error(s) X
		|Wrong sequence for token ::http::3 - {A X X}
		|- and error(s) X
		|Wrong sequence for token ::http::4 - {A X X X}
		|- and error(s) X
		|
		|Overlap-free without response body:
		|
	    }]

	} else {
	    set result [MakeMessage {
		|Problems with sanity checks:
		|Wrong sequence for token ::http::2 - {A B C D X X X}
		|- and error(s) X
		|
		|Overlap-free without response body:
		|
	    }]

	}
    }

    return [list "$start$middle$end" $result]
}

# ------------------------------------------------------------------------------
#  Proc MakeMessage
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
    set notPiped    {}
    set notIncluded {}

    # --------------------------------------------------------------------------
    # Custom code for specific tests
    # --------------------------------------------------------------------------
    if {$header < 3} {
        set skipOverlaps 1
        for {set i 1} {$i <= $num} {incr i} {
	    lappend notPiped $i
        }
    } elseif {$header > 2 && $footer == 18 && $te == 1} {
        set skipOverlaps 1
        if {$delay == 0} {
	    # Transaction 1 is conventional.
	    # Check that transactions 2,3,4 are cancelled.
	    set notPiped {1}
	    set notIncluded $notPiped
        } else {
	    # Transaction 1 is conventional.
	    # Check that transaction 2 is cancelled.
	    # The timing of transactions 3 and 4 is uncertain.
	    set notPiped {1 3 4}
	    set notIncluded $notPiped
	}
    } elseif {$footer in {20 22 23 24 25}} {
	# Transaction 2 uses its own socket.
	set notPiped    2
	set notIncluded $notPiped
    } else {
    }
    # --------------------------------------------------------------------------
    # End of custom code for specific tests
    # --------------------------------------------------------------------------


    set Results [logAnalyse $num $skipOverlaps $notIncluded $notPiped]
    lassign $Results msg cleanE cleanF dirtyE dirtyF
    if {$msg eq {}} {
        set msg "Passed all sanity checks."
    } else {
        set msg "Problems with sanity checks:\n$msg"
    }

    if 0 {
        puts $msg
        puts "Overlap-free including response body:\n$cleanF"
        puts "Have overlaps including response body:\n$dirtyF"
        puts "Overlap-free without response body:\n$cleanE"
        puts "Have overlaps without response body:\n$dirtyE"
    }

    if {$header < 3} {
        # No ordering, just check that transactions all finish
        set result $msg
    } elseif {$header == 3} {
        # Not pipelined - check overlaps with response body.
        set result "$msg\nHave overlaps including response body:\n$dirtyF"
    } else {
        # Pipelined - check overlaps without response body.  Check that the
        # first request, the first requests after replay, and POSTs are clean.
        set result "$msg\nOverlap-free without response body:\n$cleanE"
    }
    set ::nTokens $num
    return $result
}


# ------------------------------------------------------------------------------







|
|

|

|
|




|




















|

|



|
|
|
|
|



|
|

|
|

|
|
|







613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
    set notPiped    {}
    set notIncluded {}

    # --------------------------------------------------------------------------
    # Custom code for specific tests
    # --------------------------------------------------------------------------
    if {$header < 3} {
	set skipOverlaps 1
	for {set i 1} {$i <= $num} {incr i} {
	    lappend notPiped $i
	}
    } elseif {$header > 2 && $footer == 18 && $te == 1} {
	set skipOverlaps 1
	if {$delay == 0} {
	    # Transaction 1 is conventional.
	    # Check that transactions 2,3,4 are cancelled.
	    set notPiped {1}
	    set notIncluded $notPiped
	} else {
	    # Transaction 1 is conventional.
	    # Check that transaction 2 is cancelled.
	    # The timing of transactions 3 and 4 is uncertain.
	    set notPiped {1 3 4}
	    set notIncluded $notPiped
	}
    } elseif {$footer in {20 22 23 24 25}} {
	# Transaction 2 uses its own socket.
	set notPiped    2
	set notIncluded $notPiped
    } else {
    }
    # --------------------------------------------------------------------------
    # End of custom code for specific tests
    # --------------------------------------------------------------------------


    set Results [logAnalyse $num $skipOverlaps $notIncluded $notPiped]
    lassign $Results msg cleanE cleanF dirtyE dirtyF
    if {$msg eq {}} {
	set msg "Passed all sanity checks."
    } else {
	set msg "Problems with sanity checks:\n$msg"
    }

    if 0 {
	puts $msg
	puts "Overlap-free including response body:\n$cleanF"
	puts "Have overlaps including response body:\n$dirtyF"
	puts "Overlap-free without response body:\n$cleanE"
	puts "Have overlaps without response body:\n$dirtyE"
    }

    if {$header < 3} {
	# No ordering, just check that transactions all finish
	set result $msg
    } elseif {$header == 3} {
	# Not pipelined - check overlaps with response body.
	set result "$msg\nHave overlaps including response body:\n$dirtyF"
    } else {
	# Pipelined - check overlaps without response body.  Check that the
	# first request, the first requests after replay, and POSTs are clean.
	set result "$msg\nOverlap-free without response body:\n$cleanE"
    }
    set ::nTokens $num
    return $result
}


# ------------------------------------------------------------------------------
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
#     connection ater the current request.
# - Any other variables should be ignored.
# ------------------------------------------------------------------------------

namespace eval ::httpTestScript {
    variable URL
    array set URL {
        a  http://test-tcl-http.kerlin.org/index.html?page=privacy
        b  http://test-tcl-http.kerlin.org/index.html?page=conditions
        c  http://test-tcl-http.kerlin.org/index.html?page=welcome
    }
}


# ------------------------------------------------------------------------------
# (5) Define the tests
# ------------------------------------------------------------------------------







|
|
|







706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
#     connection ater the current request.
# - Any other variables should be ignored.
# ------------------------------------------------------------------------------

namespace eval ::httpTestScript {
    variable URL
    array set URL {
	a  http://test-tcl-http.kerlin.org/index.html?page=privacy
	b  http://test-tcl-http.kerlin.org/index.html?page=conditions
	c  http://test-tcl-http.kerlin.org/index.html?page=welcome
    }
}


# ------------------------------------------------------------------------------
# (5) Define the tests
# ------------------------------------------------------------------------------
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
# ------------------------------------------------------------------------------

proc SetTestEof {test} {
    set body [info body ::http::KeepSocket]
    set subs "    set TEST_EOF $test"
    set count [regsub -line -all -- {^\s*set TEST_EOF .*$} $body $subs newBody]
    if {$count != 1} {
        return -code error {proc ::http::KeepSocket has unexpected form}
    }
    proc ::http::KeepSocket {token} $newBody
    return
}

for {set header 1} {$header <= 4} {incr header} {
    if {$header == 4} {
	setHttpTestOptions -dotted 1
	set match glob
    } else {
	setHttpTestOptions -dotted 0
	set match exact
    }

    if {$header == 2} {
        set cons0 {serverNeeded duplicate}
    } else {
        set cons0 serverNeeded
    }

    for {set footer 1} {$footer <= 25} {incr footer} {
        foreach {delay label} {
	       0 a
	       1 b
	       2 c
	       3 d
	       5 e
	       8 f
	      12 g
	     100 h
	     500 i
	    2000 j
	} {
	  foreach te {0 1} {
	    if {$te} {
	        set tag testEof
	    } else {
	        set tag normal
	    }
	    set suffix {}
	    set cons $cons0

	    # ------------------------------------------------------------------
	    # Custom code for individual tests
	    # ------------------------------------------------------------------







|















|

|



|













|

|







755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
# ------------------------------------------------------------------------------

proc SetTestEof {test} {
    set body [info body ::http::KeepSocket]
    set subs "    set TEST_EOF $test"
    set count [regsub -line -all -- {^\s*set TEST_EOF .*$} $body $subs newBody]
    if {$count != 1} {
	return -code error {proc ::http::KeepSocket has unexpected form}
    }
    proc ::http::KeepSocket {token} $newBody
    return
}

for {set header 1} {$header <= 4} {incr header} {
    if {$header == 4} {
	setHttpTestOptions -dotted 1
	set match glob
    } else {
	setHttpTestOptions -dotted 0
	set match exact
    }

    if {$header == 2} {
	set cons0 {serverNeeded duplicate}
    } else {
	set cons0 serverNeeded
    }

    for {set footer 1} {$footer <= 25} {incr footer} {
	foreach {delay label} {
	       0 a
	       1 b
	       2 c
	       3 d
	       5 e
	       8 f
	      12 g
	     100 h
	     500 i
	    2000 j
	} {
	  foreach te {0 1} {
	    if {$te} {
		set tag testEof
	    } else {
		set tag normal
	    }
	    set suffix {}
	    set cons $cons0

	    # ------------------------------------------------------------------
	    # Custom code for individual tests
	    # ------------------------------------------------------------------
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
		# Test use WAIT and depend on server timeout before this time.
		lappend cons timeout1s
	    }
	    # ------------------------------------------------------------------
	    # End of custom code.
	    # ------------------------------------------------------------------

            set name "pipeline test header $header footer $footer delay $delay $tag$suffix"


	    # Here's the test:
            test httpPipeline-${header}.${footer}${label}-${tag}-$ThreadLevel $name \
            -constraints $cons \
            -setup [string map [list TE $te] {
		# Restore default values for tests:
		http::config -pipeline 1 -postfresh 0 -repost 1
                http::init
                set http::http(uid) 0
		SetTestEof {TE}
	    }] -body [list RunTest $header $footer $delay $te] -cleanup {
		# Restore default values for tests:
		http::config -pipeline 1 -postfresh 0 -repost 1
		cleanupHttpTestScript
		SetTestEof 0
		cleanupHttpTest







|



|
|
|


|
|







842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
		# Test use WAIT and depend on server timeout before this time.
		lappend cons timeout1s
	    }
	    # ------------------------------------------------------------------
	    # End of custom code.
	    # ------------------------------------------------------------------

	    set name "pipeline test header $header footer $footer delay $delay $tag$suffix"


	    # Here's the test:
	    test httpPipeline-${header}.${footer}${label}-${tag}-$ThreadLevel $name \
	    -constraints $cons \
	    -setup [string map [list TE $te] {
		# Restore default values for tests:
		http::config -pipeline 1 -postfresh 0 -repost 1
		http::init
		set http::http(uid) 0
		SetTestEof {TE}
	    }] -body [list RunTest $header $footer $delay $te] -cleanup {
		# Restore default values for tests:
		http::config -pipeline 1 -postfresh 0 -repost 1
		cleanupHttpTestScript
		SetTestEof 0
		cleanupHttpTest
Changes to tests/httpProxy.test.
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
if 0 {
    # For debugging: run with a single value of ThreadLevel: 0|1|2
    set ThreadLevel 0
    testConstraint ThreadLevelSummary 1
}
if {![info exists ThreadLevel]} {
    if {[catch {package require Thread}] == 0} {
        set ValueRange {0 1 2}
    } else {
        set ValueRange {0 1}
    }

    # For each value of ThreadLevel, source this file recursively in the
    # same interpreter.
    foreach ThreadLevel $ValueRange {
        source [info script]
    }
    catch {unset ThreadLevel}
    catch {unset ValueRange}
    if {![testConstraint ThreadLevelSummary]} {
        putsBlurb
        ::tcltest::cleanupTests
    }
    return
}

catch {puts "==== Test with ThreadLevel $ThreadLevel ===="}
http::config -threadlevel $ThreadLevel

testConstraint needsTls         [expr {    [testConstraint needsTclTls]
                                        || [testConstraint needsTwapi]
                                        || [testConstraint needsTwapiFull]
                                }]

if {[testConstraint needsTclTls]} {
    package require tls
    http::register https 443 [list ::tls::socket -ssl2 0 -ssl3 0 \
            -tls1 0 -tls1.1 0 -tls1.2 1 -tls1.3 0 -autoservername 1] ::tls::socketCmd 1 1
    testConstraint knownTwapiFullBugThreadlevelAny 1
    testConstraint knownTwapiFullBugThreadUsed 1
} elseif {[testConstraint needsTwapi]} {
    # "Original" http::register with 3 arguments has the same capabilities as
    # in http 2.9 and earlier.  This means that:
    # (1) it cannot open a socket in a background thread (this option stops a
    #     slow DNS lookup from blocking a [socket -async] command); and







|

|





|




|
|








|
|
|




|







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
if 0 {
    # For debugging: run with a single value of ThreadLevel: 0|1|2
    set ThreadLevel 0
    testConstraint ThreadLevelSummary 1
}
if {![info exists ThreadLevel]} {
    if {[catch {package require Thread}] == 0} {
	set ValueRange {0 1 2}
    } else {
	set ValueRange {0 1}
    }

    # For each value of ThreadLevel, source this file recursively in the
    # same interpreter.
    foreach ThreadLevel $ValueRange {
	source [info script]
    }
    catch {unset ThreadLevel}
    catch {unset ValueRange}
    if {![testConstraint ThreadLevelSummary]} {
	putsBlurb
	::tcltest::cleanupTests
    }
    return
}

catch {puts "==== Test with ThreadLevel $ThreadLevel ===="}
http::config -threadlevel $ThreadLevel

testConstraint needsTls         [expr {    [testConstraint needsTclTls]
					|| [testConstraint needsTwapi]
					|| [testConstraint needsTwapiFull]
				}]

if {[testConstraint needsTclTls]} {
    package require tls
    http::register https 443 [list ::tls::socket -ssl2 0 -ssl3 0 \
	    -tls1 0 -tls1.1 0 -tls1.2 1 -tls1.3 0 -autoservername 1] ::tls::socketCmd 1 1
    testConstraint knownTwapiFullBugThreadlevelAny 1
    testConstraint knownTwapiFullBugThreadUsed 1
} elseif {[testConstraint needsTwapi]} {
    # "Original" http::register with 3 arguments has the same capabilities as
    # in http 2.9 and earlier.  This means that:
    # (1) it cannot open a socket in a background thread (this option stops a
    #     slow DNS lookup from blocking a [socket -async] command); and
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
    #
    source [file join [file dirname [info script]] twapiTlsPlus.tcl]
    package require twapiTlsPlus
    http::register https 443 ::twapiTlsPlus::socket ::twapiTlsPlus::socketCmd 1 1
    testConstraint knownTwapiFullBugThreadlevelAny [testConstraint knownBug]

    if {($ThreadLevel == 1)} {
        if {[catch {package require Thread}]} {
            set usingThread 0
        } else {
            set usingThread 2
        }
    } else {
        set usingThread $ThreadLevel
    }
    if {$usingThread} {
        testConstraint knownTwapiFullBugThreadUsed [testConstraint knownBug]
    } else {
        testConstraint knownTwapiFullBugThreadUsed 1
    }
} else {
}

# Testing with Squid
# - Example Squid configuration for Enterprise Linux 8 (Red Hat, Oracle, Rocky,
#   Alma, ...) is in file tests/httpProxySquidConfigForEL8.tar.gz.







|
|
|
|
|

|


|

|







124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
    #
    source [file join [file dirname [info script]] twapiTlsPlus.tcl]
    package require twapiTlsPlus
    http::register https 443 ::twapiTlsPlus::socket ::twapiTlsPlus::socketCmd 1 1
    testConstraint knownTwapiFullBugThreadlevelAny [testConstraint knownBug]

    if {($ThreadLevel == 1)} {
	if {[catch {package require Thread}]} {
	    set usingThread 0
	} else {
	    set usingThread 2
	}
    } else {
	set usingThread $ThreadLevel
    }
    if {$usingThread} {
	testConstraint knownTwapiFullBugThreadUsed [testConstraint knownBug]
    } else {
	testConstraint knownTwapiFullBugThreadUsed 1
    }
} else {
}

# Testing with Squid
# - Example Squid configuration for Enterprise Linux 8 (Red Hat, Oracle, Rocky,
#   Alma, ...) is in file tests/httpProxySquidConfigForEL8.tar.gz.
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
test httpProxy-1.1.$ThreadLevel {squid is running - ipv4 no-auth} -constraints {needsSquidNoAuth} -setup {
} -body {
    after $fetchPause

    set token [http::geturl http://$n4host:$n4port/]
    set ri [http::responseInfo $token]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed]"
} -result {complete ok 400 -- none} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res
}

test httpProxy-1.2.$ThreadLevel {squid is running - ipv6 no-auth} -constraints {needsSquidNoAuth} -setup {
} -body {
    after $fetchPause

    set token [http::geturl http://\[$n6host\]:$n6port/]
    set ri [http::responseInfo $token]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed]"
} -result {complete ok 400 -- none} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res
}

test httpProxy-1.3.$ThreadLevel {squid is running - ipv4 with-auth} -constraints {needsSquidAuth} -setup {
} -body {
    after $fetchPause

    set token [http::geturl http://$a4host:$a4port/]
    set ri [http::responseInfo $token]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed]"
} -result {complete ok 400 -- none} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res
}

test httpProxy-1.4.$ThreadLevel {squid is running - ipv6 with-auth} -constraints {needsSquidAuth} -setup {
} -body {
    after $fetchPause

    set token [http::geturl http://\[$a6host\]:$a6port/]
    set ri [http::responseInfo $token]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed]"
} -result {complete ok 400 -- none} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res
}

test httpProxy-2.1.$ThreadLevel {http no-proxy no-auth} -constraints {} -setup {
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- none -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res
}

test httpProxy-2.2.$ThreadLevel {https no-proxy no-auth} -constraints {needsTls knownTwapiFullBugThreadUsed} -setup {
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- none -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res
}

test httpProxy-2.3.$ThreadLevel {http with-proxy ipv4 no-auth} -constraints {needsSquidNoAuth} -setup {
   http::config -proxyhost $n4host -proxyport $n4port -proxynot {127.0.0.1 localhost} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- HttpProxy -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res
    http::config -proxyhost {} -proxyport {} -proxynot {}
}

test httpProxy-2.4.$ThreadLevel {https with-proxy ipv4 no-auth} -constraints {needsSquidNoAuth needsTls knownTwapiFullBugThreadlevelAny} -setup {
   http::config -proxyhost $n4host -proxyport $n4port -proxynot {127.0.0.1 localhost} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- SecureProxy -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res
    http::config -proxyhost {} -proxyport {} -proxynot {}
}

test httpProxy-2.5.$ThreadLevel {http with-proxy ipv6 no-auth} -constraints {needsSquidNoAuth} -setup {
   http::config -proxyhost $n6host -proxyport $n6port -proxynot {::1 localhost} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- HttpProxy -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res
    http::config -proxyhost {} -proxyport {} -proxynot {}
}

test httpProxy-2.6.$ThreadLevel {https with-proxy ipv6 no-auth} -constraints {needsSquidNoAuth needsTls knownTwapiFullBugThreadlevelAny} -setup {
   http::config -proxyhost $n6host -proxyport $n6port -proxynot {::1 localhost} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- SecureProxy -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res
    http::config -proxyhost {} -proxyport {} -proxynot {}
}

test httpProxy-3.1.$ThreadLevel {http no-proxy with-auth valid-creds-provided} -constraints {} -setup {
   http::config -proxyhost {} -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth $aliceCreds
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- none 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-3.2.$ThreadLevel {https no-proxy with-auth valid-creds-provided} -constraints {needsTls knownTwapiFullBugThreadUsed} -setup {
   http::config -proxyhost {} -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth $aliceCreds
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- none 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-3.3.$ThreadLevel {http with-proxy ipv4 with-auth valid-creds-provided} -constraints {needsSquidAuth} -setup {
   http::config -proxyhost $a4host -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth $aliceCreds
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- HttpProxy 1 1 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-3.4.$ThreadLevel {https with-proxy ipv4 with-auth valid-creds-provided} -constraints {needsSquidAuth needsTls knownTwapiFullBugThreadlevelAny} -setup {
   http::config -proxyhost $a4host -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth $aliceCreds
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- SecureProxy 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-3.5.$ThreadLevel {http with-proxy ipv6 with-auth valid-creds-provided} -constraints {needsSquidAuth} -setup {
   http::config -proxyhost $a6host -proxyport $a6port -proxynot {::1 localhost} -proxyauth $aliceCreds
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- HttpProxy 1 1 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-3.6.$ThreadLevel {https with-proxy ipv6 with-auth valid-creds-provided} -constraints {needsSquidAuth needsTls knownTwapiFullBugThreadlevelAny} -setup {
   http::config -proxyhost $a6host -proxyport $a6port -proxynot {::1 localhost} -proxyauth $aliceCreds
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- SecureProxy 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-3.7.$ThreadLevel {http with-proxy ipv4 with-auth valid-creds-provided; check that 2nd valid request with creds is possible, and keep-alive works} -constraints {needsSquidAuth} -setup {







|












|












|












|













|
|













|
|













|
|














|
|














|
|














|
|
















|
|
















|
|
















|
|
















|
|
















|
|
















|
|







196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
test httpProxy-1.1.$ThreadLevel {squid is running - ipv4 no-auth} -constraints {needsSquidNoAuth} -setup {
} -body {
    after $fetchPause

    set token [http::geturl http://$n4host:$n4port/]
    set ri [http::responseInfo $token]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed]"
} -result {complete ok 400 -- none} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res
}

test httpProxy-1.2.$ThreadLevel {squid is running - ipv6 no-auth} -constraints {needsSquidNoAuth} -setup {
} -body {
    after $fetchPause

    set token [http::geturl http://\[$n6host\]:$n6port/]
    set ri [http::responseInfo $token]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed]"
} -result {complete ok 400 -- none} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res
}

test httpProxy-1.3.$ThreadLevel {squid is running - ipv4 with-auth} -constraints {needsSquidAuth} -setup {
} -body {
    after $fetchPause

    set token [http::geturl http://$a4host:$a4port/]
    set ri [http::responseInfo $token]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed]"
} -result {complete ok 400 -- none} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res
}

test httpProxy-1.4.$ThreadLevel {squid is running - ipv6 with-auth} -constraints {needsSquidAuth} -setup {
} -body {
    after $fetchPause

    set token [http::geturl http://\[$a6host\]:$a6port/]
    set ri [http::responseInfo $token]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed]"
} -result {complete ok 400 -- none} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res
}

test httpProxy-2.1.$ThreadLevel {http no-proxy no-auth} -constraints {} -setup {
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- none -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res
}

test httpProxy-2.2.$ThreadLevel {https no-proxy no-auth} -constraints {needsTls knownTwapiFullBugThreadUsed} -setup {
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- none -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res
}

test httpProxy-2.3.$ThreadLevel {http with-proxy ipv4 no-auth} -constraints {needsSquidNoAuth} -setup {
   http::config -proxyhost $n4host -proxyport $n4port -proxynot {127.0.0.1 localhost} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- HttpProxy -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res
    http::config -proxyhost {} -proxyport {} -proxynot {}
}

test httpProxy-2.4.$ThreadLevel {https with-proxy ipv4 no-auth} -constraints {needsSquidNoAuth needsTls knownTwapiFullBugThreadlevelAny} -setup {
   http::config -proxyhost $n4host -proxyport $n4port -proxynot {127.0.0.1 localhost} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- SecureProxy -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res
    http::config -proxyhost {} -proxyport {} -proxynot {}
}

test httpProxy-2.5.$ThreadLevel {http with-proxy ipv6 no-auth} -constraints {needsSquidNoAuth} -setup {
   http::config -proxyhost $n6host -proxyport $n6port -proxynot {::1 localhost} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- HttpProxy -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res
    http::config -proxyhost {} -proxyport {} -proxynot {}
}

test httpProxy-2.6.$ThreadLevel {https with-proxy ipv6 no-auth} -constraints {needsSquidNoAuth needsTls knownTwapiFullBugThreadlevelAny} -setup {
   http::config -proxyhost $n6host -proxyport $n6port -proxynot {::1 localhost} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- SecureProxy -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res
    http::config -proxyhost {} -proxyport {} -proxynot {}
}

test httpProxy-3.1.$ThreadLevel {http no-proxy with-auth valid-creds-provided} -constraints {} -setup {
   http::config -proxyhost {} -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth $aliceCreds
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- none 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-3.2.$ThreadLevel {https no-proxy with-auth valid-creds-provided} -constraints {needsTls knownTwapiFullBugThreadUsed} -setup {
   http::config -proxyhost {} -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth $aliceCreds
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- none 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-3.3.$ThreadLevel {http with-proxy ipv4 with-auth valid-creds-provided} -constraints {needsSquidAuth} -setup {
   http::config -proxyhost $a4host -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth $aliceCreds
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- HttpProxy 1 1 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-3.4.$ThreadLevel {https with-proxy ipv4 with-auth valid-creds-provided} -constraints {needsSquidAuth needsTls knownTwapiFullBugThreadlevelAny} -setup {
   http::config -proxyhost $a4host -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth $aliceCreds
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- SecureProxy 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-3.5.$ThreadLevel {http with-proxy ipv6 with-auth valid-creds-provided} -constraints {needsSquidAuth} -setup {
   http::config -proxyhost $a6host -proxyport $a6port -proxynot {::1 localhost} -proxyauth $aliceCreds
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- HttpProxy 1 1 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-3.6.$ThreadLevel {https with-proxy ipv6 with-auth valid-creds-provided} -constraints {needsSquidAuth needsTls knownTwapiFullBugThreadlevelAny} -setup {
   http::config -proxyhost $a6host -proxyport $a6port -proxynot {::1 localhost} -proxyauth $aliceCreds
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- SecureProxy 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-3.7.$ThreadLevel {http with-proxy ipv4 with-auth valid-creds-provided; check that 2nd valid request with creds is possible, and keep-alive works} -constraints {needsSquidAuth} -setup {
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 200 -- HttpProxy 1 1 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}







|
|







462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 200 -- HttpProxy 1 1 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 200 -- HttpProxy 1 1 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}







|
|







493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 200 -- HttpProxy 1 1 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 200 -- SecureProxy 0 0 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}







|
|







524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 200 -- SecureProxy 0 0 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 200 -- SecureProxy 0 0 -- -1 done 0} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}







|
|







557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 200 -- SecureProxy 0 0 -- -1 done 0} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 200 -- HttpProxy 1 1 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}







|
|







586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 200 -- HttpProxy 1 1 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
    after cancel $can0

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 200 -- HttpProxy 1 1 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can0 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}







|
|







621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
    after cancel $can0

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 200 -- HttpProxy 1 1 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can0 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 200 -- HttpProxy 1 1 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}







|
|







652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 200 -- HttpProxy 1 1 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 200 -- SecureProxy 0 0 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}







|
|







683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 200 -- SecureProxy 0 0 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
    after cancel $can0

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 200 -- SecureProxy 0 0 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can0 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}







|
|







720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
    after cancel $can0

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 200 -- SecureProxy 0 0 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can0 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 200 -- SecureProxy 0 0 -- -1 done 0} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-4.1.$ThreadLevel {http no-proxy with-auth no-creds-provided} -constraints {} -setup {
   http::config -proxyhost {} -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- none 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-4.2.$ThreadLevel {https no-proxy with-auth no-creds-provided} -constraints {needsTls knownTwapiFullBugThreadUsed} -setup {
   http::config -proxyhost {} -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- none 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-4.3.$ThreadLevel {http with-proxy ipv4 with-auth no-creds-provided} -constraints {needsSquidAuth} -setup {
   http::config -proxyhost $a4host -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 407 -- HttpProxy 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-4.4.$ThreadLevel {https with-proxy ipv4 with-auth no-creds-provided} -constraints {needsSquidAuth needsTls knownTwapiFullBugThreadlevelAny} -setup {
   http::config -proxyhost $a4host -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 407 -- SecureProxyFailed 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-4.5.$ThreadLevel {http with-proxy ipv6 with-auth no-creds-provided} -constraints {needsSquidAuth} -setup {
   http::config -proxyhost $a6host -proxyport $a6port -proxynot {::1 localhost} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 407 -- HttpProxy 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-4.6.$ThreadLevel {https with-proxy ipv6 with-auth no-creds-provided} -constraints {needsSquidAuth needsTls knownTwapiFullBugThreadlevelAny} -setup {
   http::config -proxyhost $a6host -proxyport $a6port -proxynot {::1 localhost} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 407 -- SecureProxyFailed 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-4.7.$ThreadLevel {http with-proxy ipv4 with-auth no-creds-provided; check that 2nd request is possible} -constraints {needsSquidAuth} -setup {







|
|


















|
|
















|
|
















|
|
















|
|
















|
|
















|
|







754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 200 -- SecureProxy 0 0 -- -1 done 0} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-4.1.$ThreadLevel {http no-proxy with-auth no-creds-provided} -constraints {} -setup {
   http::config -proxyhost {} -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- none 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-4.2.$ThreadLevel {https no-proxy with-auth no-creds-provided} -constraints {needsTls knownTwapiFullBugThreadUsed} -setup {
   http::config -proxyhost {} -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- none 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-4.3.$ThreadLevel {http with-proxy ipv4 with-auth no-creds-provided} -constraints {needsSquidAuth} -setup {
   http::config -proxyhost $a4host -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 407 -- HttpProxy 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-4.4.$ThreadLevel {https with-proxy ipv4 with-auth no-creds-provided} -constraints {needsSquidAuth needsTls knownTwapiFullBugThreadlevelAny} -setup {
   http::config -proxyhost $a4host -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 407 -- SecureProxyFailed 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-4.5.$ThreadLevel {http with-proxy ipv6 with-auth no-creds-provided} -constraints {needsSquidAuth} -setup {
   http::config -proxyhost $a6host -proxyport $a6port -proxynot {::1 localhost} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 407 -- HttpProxy 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-4.6.$ThreadLevel {https with-proxy ipv6 with-auth no-creds-provided} -constraints {needsSquidAuth needsTls knownTwapiFullBugThreadlevelAny} -setup {
   http::config -proxyhost $a6host -proxyport $a6port -proxynot {::1 localhost} -proxyauth {}
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 407 -- SecureProxyFailed 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-4.7.$ThreadLevel {http with-proxy ipv4 with-auth no-creds-provided; check that 2nd request is possible} -constraints {needsSquidAuth} -setup {
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- HttpProxy 0 0 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}







|
|







891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- HttpProxy 0 0 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- SecureProxyFailed 0 0 -- -1 done 0} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}







|
|







922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- SecureProxyFailed 0 0 -- -1 done 0} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- HttpProxy 0 0 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}







|
|







951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- HttpProxy 0 0 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
    after cancel $can0

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- HttpProxy 0 0 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can0 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}







|
|







986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
    after cancel $can0

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- HttpProxy 0 0 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can0 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- SecureProxyFailed 0 0 -- -1 done 0} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}







|
|







1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- SecureProxyFailed 0 0 -- -1 done 0} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
    after cancel $can0

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- SecureProxyFailed 0 0 -- -1 done 0} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can0 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-5.1.$ThreadLevel {http no-proxy with-auth bad-creds-provided} -constraints {} -setup {
   http::config -proxyhost {} -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth $badCreds
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- none 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-5.2.$ThreadLevel {https no-proxy with-auth bad-creds-provided} -constraints {needsTls knownTwapiFullBugThreadUsed} -setup {
   http::config -proxyhost {} -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth $badCreds
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- none 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-5.3.$ThreadLevel {http with-proxy ipv4 with-auth bad-creds-provided} -constraints {needsSquidAuth} -setup {
   http::config -proxyhost $a4host -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth $badCreds
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 407 -- HttpProxy 1 1 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-5.4.$ThreadLevel {https with-proxy ipv4 with-auth bad-creds-provided} -constraints {needsSquidAuth needsTls knownTwapiFullBugThreadlevelAny} -setup {
   http::config -proxyhost $a4host -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth $badCreds
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 407 -- SecureProxyFailed 1 1 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-5.5.$ThreadLevel {http with-proxy ipv6 with-auth bad-creds-provided} -constraints {needsSquidAuth} -setup {
   http::config -proxyhost $a6host -proxyport $a6port -proxynot {::1 localhost} -proxyauth $badCreds
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 407 -- HttpProxy 1 1 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-5.6.$ThreadLevel {https with-proxy ipv6 with-auth bad-creds-provided} -constraints {needsSquidAuth needsTls knownTwapiFullBugThreadlevelAny} -setup {
   http::config -proxyhost $a6host -proxyport $a6port -proxynot {::1 localhost} -proxyauth $badCreds
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 407 -- SecureProxyFailed 1 1 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-5.7.$ThreadLevel {http with-proxy ipv4 with-auth bad-creds-provided; check that 2nd request is possible} -constraints {needsSquidAuth} -setup {







|
|


















|
|
















|
|
















|
|
















|
|
















|
|
















|
|







1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
    after cancel $can0

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $aliceCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- SecureProxyFailed 0 0 -- -1 done 0} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can0 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-5.1.$ThreadLevel {http no-proxy with-auth bad-creds-provided} -constraints {} -setup {
   http::config -proxyhost {} -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth $badCreds
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- none 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-5.2.$ThreadLevel {https no-proxy with-auth bad-creds-provided} -constraints {needsTls knownTwapiFullBugThreadUsed} -setup {
   http::config -proxyhost {} -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth $badCreds
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 200 -- none 0 0 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-5.3.$ThreadLevel {http with-proxy ipv4 with-auth bad-creds-provided} -constraints {needsSquidAuth} -setup {
   http::config -proxyhost $a4host -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth $badCreds
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 407 -- HttpProxy 1 1 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-5.4.$ThreadLevel {https with-proxy ipv4 with-auth bad-creds-provided} -constraints {needsSquidAuth needsTls knownTwapiFullBugThreadlevelAny} -setup {
   http::config -proxyhost $a4host -proxyport $a4port -proxynot {127.0.0.1 localhost} -proxyauth $badCreds
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 407 -- SecureProxyFailed 1 1 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-5.5.$ThreadLevel {http with-proxy ipv6 with-auth bad-creds-provided} -constraints {needsSquidAuth} -setup {
   http::config -proxyhost $a6host -proxyport $a6port -proxynot {::1 localhost} -proxyauth $badCreds
} -body {
    after $fetchPause

    set token [http::geturl http://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 407 -- HttpProxy 1 1 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-5.6.$ThreadLevel {https with-proxy ipv6 with-auth bad-creds-provided} -constraints {needsSquidAuth needsTls knownTwapiFullBugThreadlevelAny} -setup {
   http::config -proxyhost $a6host -proxyport $a6port -proxynot {::1 localhost} -proxyauth $badCreds
} -body {
    after $fetchPause

    set token [http::geturl https://www.google.com/]
    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*]"
} -result {complete ok 407 -- SecureProxyFailed 1 1 -- -1} -cleanup {
    catch {http::cleanup $token}
    unset -nocomplain token ri res pos1 pos2
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}

test httpProxy-5.7.$ThreadLevel {http with-proxy ipv4 with-auth bad-creds-provided; check that 2nd request is possible} -constraints {needsSquidAuth} -setup {
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- HttpProxy 1 1 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}







|
|







1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- HttpProxy 1 1 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
    after cancel $can0

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- HttpProxy 1 1 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can0 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}







|
|







1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
    after cancel $can0

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- HttpProxy 1 1 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can0 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- SecureProxyFailed 1 1 -- -1 done 0} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}







|
|







1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- SecureProxyFailed 1 1 -- -1 done 0} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
    after cancel $can0

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- SecureProxyFailed 1 1 -- -1 done 0} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can0 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}







|
|







1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
    after cancel $can0

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- SecureProxyFailed 1 1 -- -1 done 0} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can0 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- HttpProxy 1 1 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}







|
|







1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- HttpProxy 1 1 -- -1 done 1} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
             [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
             [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- SecureProxyFailed 1 1 -- -1 done 0} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}







|
|







1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
    after cancel $can

    set ri [http::responseInfo $token]
    set pos1 [lsearch -exact [string tolower [set ${token}(requestHeaders)]] proxy-authorization]
    set pos2 [lsearch -exact [set ${token}(requestHeaders)] $badCreds]
    set same [string equal [set ${token0}(sock)] [set ${token}(sock)]]
    set res "[dict get $ri stage] [dict get $ri status] [dict get $ri responseCode] --\
	     [dict get $ri proxyUsed] [expr {$pos1 > -1}] [expr {$pos2 > -1}] --\
	     [lsearch -glob [array get ::http::socketMapping] HTTP_PLACEHOLDER_*] [set ${token}(z)] $same"
} -result {complete ok 407 -- SecureProxyFailed 1 1 -- -1 done 0} -cleanup {
    catch {http::cleanup $token0}
    catch {http::cleanup $token}
    unset -nocomplain token0 token ri res pos1 pos2 can same
    array unset ::http::socketMapping
    http::config -proxyhost {} -proxyport {} -proxynot {} -proxyauth {}
}
Changes to tests/httpTest.tcl.
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#    catch {puts stdout "Start time (zero ms) is $TestStartTimeInMs"}
}

namespace eval ::httpTest {
    variable testResults {}
    variable testOptions
    array set testOptions {
        -verbose 0
        -dotted  1
    }
    # -verbose - 0 quiet 1 write to stdout 2 write more
    # -dotted  - (boolean) use dots for absences in lists of transactions
}

proc httpTest::Puts {txt} {
    variable testOptions
    if {$testOptions(-verbose) > 0} {
        puts stdout $txt
        flush stdout
    }
    return
}

# http::Log
#
# A special-purpose logger used for running tests.
# - Processes Log calls that have "^" in their arguments, and records them in
#   variable ::httpTest::testResults.
# - Also writes them to stdout (using Puts) if ($testOptions(-verbose) > 0).
# - Also writes Log calls that do not have "^", if ($testOptions(-verbose) > 1).

proc http::Log {args} {
    variable TestStartTimeInMs
    set time [expr {[clock milliseconds] - $TestStartTimeInMs}]
    set txt [list $time {*}$args]
    if {[string first ^ $txt] >= 0} {
        ::httpTest::LogRecord $txt
        ::httpTest::Puts $txt
    } elseif {$::httpTest::testOptions(-verbose) > 1} {
        ::httpTest::Puts $txt
    }
    return
}
# The http::Log routine above needs the variable ::httpTest::testOptions
# Set up to destroy it when that variable goes away.
trace add variable ::httpTest::testOptions unset {apply {args {
    proc ::http::Log args {}
}}}

# Called by http::Log (the "testing" version) to record logs for later analysis.

proc httpTest::LogRecord {txt} {
    variable testResults

    set pos [string first ^ $txt]
    set len [string length  $txt]
    if {$pos > $len - 3} {
        puts stdout "Logging Error: $txt"
        puts stdout "Fix this call to Log in http-*.tm so it has ^ then\
		a letter then a numeral."
        flush stdout
    } elseif {$pos < 0} {
        # Called by mistake.
    } else {
        set letter [string index $txt [incr pos]]
        set number [string index $txt [incr pos]]
        # Max 9 requests!
        lappend testResults [list $letter $number]
    }

    return
}


# ------------------------------------------------------------------------------







|
|








|
|

















|
|

|

















|
|

|

|

|
|
|
|







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#    catch {puts stdout "Start time (zero ms) is $TestStartTimeInMs"}
}

namespace eval ::httpTest {
    variable testResults {}
    variable testOptions
    array set testOptions {
	-verbose 0
	-dotted  1
    }
    # -verbose - 0 quiet 1 write to stdout 2 write more
    # -dotted  - (boolean) use dots for absences in lists of transactions
}

proc httpTest::Puts {txt} {
    variable testOptions
    if {$testOptions(-verbose) > 0} {
	puts stdout $txt
	flush stdout
    }
    return
}

# http::Log
#
# A special-purpose logger used for running tests.
# - Processes Log calls that have "^" in their arguments, and records them in
#   variable ::httpTest::testResults.
# - Also writes them to stdout (using Puts) if ($testOptions(-verbose) > 0).
# - Also writes Log calls that do not have "^", if ($testOptions(-verbose) > 1).

proc http::Log {args} {
    variable TestStartTimeInMs
    set time [expr {[clock milliseconds] - $TestStartTimeInMs}]
    set txt [list $time {*}$args]
    if {[string first ^ $txt] >= 0} {
	::httpTest::LogRecord $txt
	::httpTest::Puts $txt
    } elseif {$::httpTest::testOptions(-verbose) > 1} {
	::httpTest::Puts $txt
    }
    return
}
# The http::Log routine above needs the variable ::httpTest::testOptions
# Set up to destroy it when that variable goes away.
trace add variable ::httpTest::testOptions unset {apply {args {
    proc ::http::Log args {}
}}}

# Called by http::Log (the "testing" version) to record logs for later analysis.

proc httpTest::LogRecord {txt} {
    variable testResults

    set pos [string first ^ $txt]
    set len [string length  $txt]
    if {$pos > $len - 3} {
	puts stdout "Logging Error: $txt"
	puts stdout "Fix this call to Log in http-*.tm so it has ^ then\
		a letter then a numeral."
	flush stdout
    } elseif {$pos < 0} {
	# Called by mistake.
    } else {
	set letter [string index $txt [incr pos]]
	set number [string index $txt [incr pos]]
	# Max 9 requests!
	lappend testResults [list $letter $number]
    }

    return
}


# ------------------------------------------------------------------------------
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
proc httpTest::TestOverlaps {someResults n term msg badTrans notPiped} {
    variable testOptions

    # Check whether transactions overlap:
    set clean {}
    set dirty {}
    for {set i 1} {$i <= $n} {incr i} {
        if {$i in $badTrans} {
            continue
        }
        set myStart   [lsearch -exact $someResults [list B $i]]
        set myEnd     [lsearch -exact $someResults [list $term $i]]

        if {($myStart < 0 || $myEnd < 0)} {
            set res "Cannot find positions of transaction $i"
	    append msg $res \n
	    Puts $res
        }

	set overlaps {}
	for {set j $myStart} {$j <= $myEnd} {incr j} {
	    lassign [lindex $someResults $j] letter number
	    if {$number != $i && $letter ne "A" && $number ni $notPiped} {
		lappend overlaps $number
	    }
	}

        if {[llength $overlaps] == 0} {
	    set res "Transaction $i has no overlaps"
	    Puts $res
	    lappend clean $i
	    if {$testOptions(-dotted)} {
		# N.B. results from different segments are concatenated.
		lappend dirty .
	    } else {
	    }
        } else {
	    set res "Transaction $i overlaps with [join $overlaps { }]"
	    Puts $res
	    lappend dirty $i
	    if {$testOptions(-dotted)} {
		# N.B. results from different segments are concatenated.
		lappend clean .
	    } else {
	    }
        }
    }
    return [list $msg $clean $dirty]
}

# httpTest::PipelineNext --
#
# Test whether prevPair, pair are valid as consecutive elements of a pipelined







|
|
|
|
|

|
|


|









|








|








|







143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
proc httpTest::TestOverlaps {someResults n term msg badTrans notPiped} {
    variable testOptions

    # Check whether transactions overlap:
    set clean {}
    set dirty {}
    for {set i 1} {$i <= $n} {incr i} {
	if {$i in $badTrans} {
	    continue
	}
	set myStart   [lsearch -exact $someResults [list B $i]]
	set myEnd     [lsearch -exact $someResults [list $term $i]]

	if {($myStart < 0 || $myEnd < 0)} {
	    set res "Cannot find positions of transaction $i"
	    append msg $res \n
	    Puts $res
	}

	set overlaps {}
	for {set j $myStart} {$j <= $myEnd} {incr j} {
	    lassign [lindex $someResults $j] letter number
	    if {$number != $i && $letter ne "A" && $number ni $notPiped} {
		lappend overlaps $number
	    }
	}

	if {[llength $overlaps] == 0} {
	    set res "Transaction $i has no overlaps"
	    Puts $res
	    lappend clean $i
	    if {$testOptions(-dotted)} {
		# N.B. results from different segments are concatenated.
		lappend dirty .
	    } else {
	    }
	} else {
	    set res "Transaction $i overlaps with [join $overlaps { }]"
	    Puts $res
	    lappend dirty $i
	    if {$testOptions(-dotted)} {
		# N.B. results from different segments are concatenated.
		lappend clean .
	    } else {
	    }
	}
    }
    return [list $msg $clean $dirty]
}

# httpTest::PipelineNext --
#
# Test whether prevPair, pair are valid as consecutive elements of a pipelined
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
# any          - (boolean) iff true, accept any increasing sequence of integers.
#                If false, integers must increase by 1.
#
# Return value - boolean, true iff the two pairs are valid consecutive elements.

proc httpTest::PipelineNext {Start End prevPair pair any} {
    if {$prevPair eq {}} {
        return 1
    }

    lassign $prevPair letter number
    lassign $pair newLetter newNumber
    if {$letter eq $Start} {
	return [expr {($newLetter eq $End) && ($newNumber == $number)}]
    } elseif {$any} {
        set nxt [list $Start [expr {$number + 1}]]
	return [expr {($newLetter eq $Start) && ($newNumber > $number)}]
    } else {
        set nxt [list $Start [expr {$number + 1}]]
	return [expr {($newLetter eq $Start) && ($newNumber == $number + 1)}]
    }
}

# httpTest::TestPipeline --
#
# Given a sequence of "pair" elements, check that the elements whose string is
# $Start or $End form a valid pipeline. Ignore other elements.
#
# Return value: {} if valid pipeline, otherwise a non-empty error message.

proc httpTest::TestPipeline {someResults n Start End msg desc badTrans} {
    set sequence {}
    set prevPair {}
    set ok 1
    set any [llength $badTrans]
    foreach pair $someResults {
        lassign $pair letter number
        if {($letter in [list $Start $End]) && ($number ni $badTrans)} {
            lappend sequence $pair
            if {![PipelineNext $Start $End $prevPair $pair $any]} {
		set ok 0
		break
            }
            set prevPair $pair
        }
    }

    if {!$ok} {
        set res "$desc are not pipelined: {$sequence}"
        append msg $res \n
        Puts $res
    }
    return $msg
}

# httpTest::TestSequence --
#
# Examine each transaction from 1 to $n, ignoring any that are listed
# in $badTrans.
# Check that each transaction has elements A to F, in alphabetical order.

proc httpTest::TestSequence {someResults n msg badTrans} {
    variable testOptions

    for {set i 1} {$i <= $n} {incr i} {
        if {$i in $badTrans} {
	    continue
        }
        set sequence {}
        foreach pair $someResults {
            lassign $pair letter number
            if {$number == $i} {
                lappend sequence $letter
            }
        }
        if {$sequence eq {A B C D E F}} {
        } else {
            set res "Wrong sequence for token ::http::$i - {$sequence}"
	    append msg $res \n
	    Puts $res
            if {"X" in $sequence} {
                set res "- and error(s) X"
		append msg $res \n
		Puts $res
            }
            if {"Y" in $sequence} {
                set res "- and warnings(s) Y"
		append msg $res \n
		Puts $res
            }
        }
    }
    return $msg
}

#
# Arguments:
# someResults  - list of elements, each a list of a letter and a number







|







|


|

















|
|
|
|


|
|
|



|
|
|














|

|
|
|
|
|
|
|
|
|
|
|


|
|


|
|
|


|
|







210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
# any          - (boolean) iff true, accept any increasing sequence of integers.
#                If false, integers must increase by 1.
#
# Return value - boolean, true iff the two pairs are valid consecutive elements.

proc httpTest::PipelineNext {Start End prevPair pair any} {
    if {$prevPair eq {}} {
	return 1
    }

    lassign $prevPair letter number
    lassign $pair newLetter newNumber
    if {$letter eq $Start} {
	return [expr {($newLetter eq $End) && ($newNumber == $number)}]
    } elseif {$any} {
	set nxt [list $Start [expr {$number + 1}]]
	return [expr {($newLetter eq $Start) && ($newNumber > $number)}]
    } else {
	set nxt [list $Start [expr {$number + 1}]]
	return [expr {($newLetter eq $Start) && ($newNumber == $number + 1)}]
    }
}

# httpTest::TestPipeline --
#
# Given a sequence of "pair" elements, check that the elements whose string is
# $Start or $End form a valid pipeline. Ignore other elements.
#
# Return value: {} if valid pipeline, otherwise a non-empty error message.

proc httpTest::TestPipeline {someResults n Start End msg desc badTrans} {
    set sequence {}
    set prevPair {}
    set ok 1
    set any [llength $badTrans]
    foreach pair $someResults {
	lassign $pair letter number
	if {($letter in [list $Start $End]) && ($number ni $badTrans)} {
	    lappend sequence $pair
	    if {![PipelineNext $Start $End $prevPair $pair $any]} {
		set ok 0
		break
	    }
	    set prevPair $pair
	}
    }

    if {!$ok} {
	set res "$desc are not pipelined: {$sequence}"
	append msg $res \n
	Puts $res
    }
    return $msg
}

# httpTest::TestSequence --
#
# Examine each transaction from 1 to $n, ignoring any that are listed
# in $badTrans.
# Check that each transaction has elements A to F, in alphabetical order.

proc httpTest::TestSequence {someResults n msg badTrans} {
    variable testOptions

    for {set i 1} {$i <= $n} {incr i} {
	if {$i in $badTrans} {
	    continue
	}
	set sequence {}
	foreach pair $someResults {
	    lassign $pair letter number
	    if {$number == $i} {
		lappend sequence $letter
	    }
	}
	if {$sequence eq {A B C D E F}} {
	} else {
	    set res "Wrong sequence for token ::http::$i - {$sequence}"
	    append msg $res \n
	    Puts $res
	    if {"X" in $sequence} {
		set res "- and error(s) X"
		append msg $res \n
		Puts $res
	    }
	    if {"Y" in $sequence} {
		set res "- and warnings(s) Y"
		append msg $res \n
		Puts $res
	    }
	}
    }
    return $msg
}

#
# Arguments:
# someResults  - list of elements, each a list of a letter and a number
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
# MostAnalysis for processing.

proc httpTest::ProcessRetries {someResults n msg skipOverlaps notIncluded notPiped} {
    variable testOptions

    set nextRetry [lsearch -glob -index 0 $someResults {[PQR]}]
    if {$nextRetry < 0} {
        return [MostAnalysis $someResults $n $msg $skipOverlaps $notIncluded $notPiped]
    }
    set badTrans $notIncluded
    set tryCount 0
    set try $nextRetry
    incr tryCount
    lassign [lindex $someResults $try] letter number
    Puts "Processing retry [lindex $someResults $try]"
    set beforeTry [lrange $someResults 0 $try-1]
    Puts [join $beforeTry \n]
    set afterTry [lrange $someResults $try+1 end]

    set dummyTry   {}
    for {set i 1} {$i <= $n} {incr i} {
        set first [lsearch -exact $beforeTry [list A $i]]
        set last  [lsearch -exact $beforeTry [list F $i]]
        if {$first < 0} {
	    set res "Transaction $i was not started in connection number $tryCount"
	    # So lappend it to badTrans and don't include it in the call below of MostAnalysis.
	    # append msg $res \n
	    Puts $res
	    if {$i ni $badTrans} {
		lappend badTrans $i
	    } else {
	    }
        } elseif {$last < 0} {
	    set res "Transaction $i was started but unfinished in connection number $tryCount"
	    # So lappend it to badTrans and don't include it in the call below of MostAnalysis.
	    # append msg $res \n
	    Puts $res
	    lappend badTrans $i
	    lappend dummyTry [list A $i]
        } else {
	    set res "Transaction $i was started and finished in connection number $tryCount"
	    # So include it in the call below of MostAnalysis.
	    # So lappend it to notIncluded and don't include it in the recursive call of
	    # ProcessRetries which handles the later connections.
	    # append msg $res \n
	    Puts $res
	    lappend notIncluded $i
        }
    }

    # Analyse the part of the results before the first replay:
    set HeadResults [MostAnalysis $beforeTry $n $msg $skipOverlaps $badTrans $notPiped]
    lassign $HeadResults msg cleanE1 cleanF1 dirtyE1 dirtyF1

    # Pass the rest of the results to be processed recursively.







|













|
|
|








|






|







|







371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
# MostAnalysis for processing.

proc httpTest::ProcessRetries {someResults n msg skipOverlaps notIncluded notPiped} {
    variable testOptions

    set nextRetry [lsearch -glob -index 0 $someResults {[PQR]}]
    if {$nextRetry < 0} {
	return [MostAnalysis $someResults $n $msg $skipOverlaps $notIncluded $notPiped]
    }
    set badTrans $notIncluded
    set tryCount 0
    set try $nextRetry
    incr tryCount
    lassign [lindex $someResults $try] letter number
    Puts "Processing retry [lindex $someResults $try]"
    set beforeTry [lrange $someResults 0 $try-1]
    Puts [join $beforeTry \n]
    set afterTry [lrange $someResults $try+1 end]

    set dummyTry   {}
    for {set i 1} {$i <= $n} {incr i} {
	set first [lsearch -exact $beforeTry [list A $i]]
	set last  [lsearch -exact $beforeTry [list F $i]]
	if {$first < 0} {
	    set res "Transaction $i was not started in connection number $tryCount"
	    # So lappend it to badTrans and don't include it in the call below of MostAnalysis.
	    # append msg $res \n
	    Puts $res
	    if {$i ni $badTrans} {
		lappend badTrans $i
	    } else {
	    }
	} elseif {$last < 0} {
	    set res "Transaction $i was started but unfinished in connection number $tryCount"
	    # So lappend it to badTrans and don't include it in the call below of MostAnalysis.
	    # append msg $res \n
	    Puts $res
	    lappend badTrans $i
	    lappend dummyTry [list A $i]
	} else {
	    set res "Transaction $i was started and finished in connection number $tryCount"
	    # So include it in the call below of MostAnalysis.
	    # So lappend it to notIncluded and don't include it in the recursive call of
	    # ProcessRetries which handles the later connections.
	    # append msg $res \n
	    Puts $res
	    lappend notIncluded $i
	}
    }

    # Analyse the part of the results before the first replay:
    set HeadResults [MostAnalysis $beforeTry $n $msg $skipOverlaps $badTrans $notPiped]
    lassign $HeadResults msg cleanE1 cleanF1 dirtyE1 dirtyF1

    # Pass the rest of the results to be processed recursively.
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
    set testResults {}
    return
}

proc httpTest::setHttpTestOptions {key args} {
    variable testOptions
    if {$key ni {-dotted -verbose}} {
        return -code error {valid options are -dotted, -verbose}
    }
    set testOptions($key) {*}$args
}

namespace eval httpTest {
    namespace export cleanupHttpTest logAnalyse setHttpTestOptions
}







|







495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
    set testResults {}
    return
}

proc httpTest::setHttpTestOptions {key args} {
    variable testOptions
    if {$key ni {-dotted -verbose}} {
	return -code error {valid options are -dotted, -verbose}
    }
    set testOptions($key) {*}$args
}

namespace eval httpTest {
    namespace export cleanupHttpTest logAnalyse setHttpTestOptions
}
Changes to tests/httpTestScript.tcl.
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
    variable CountFinishedSoFar
    variable RequestList
    variable RequestsMade
    variable ExtraTime
    variable ActualKeepAlive

    if {[info exists StartDone] && ($StartDone == 1)} {
        set msg {START has been called twice without an intervening STOP}
        return -code error $msg
    }

    set StartDone 1
    set StopDone 0
    set TimeOutDone 0
    set CountFinishedSoFar 0
    set CountRequestedSoFar 0







|
|







98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
    variable CountFinishedSoFar
    variable RequestList
    variable RequestsMade
    variable ExtraTime
    variable ActualKeepAlive

    if {[info exists StartDone] && ($StartDone == 1)} {
	set msg {START has been called twice without an intervening STOP}
	return -code error $msg
    }

    set StartDone 1
    set StopDone 0
    set TimeOutDone 0
    set CountFinishedSoFar 0
    set CountRequestedSoFar 0
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
    variable RequestsWhenStopped
    variable TimeOutCode
    variable StartDone
    variable StopDone
    variable RequestsMade

    if {$StopDone} {
        # Don't do anything on a second call.
        return
    }

    if {![info exists StartDone]} {
        return -code error {initialise the script by calling command START}
    }

    set StopDone 1
    set StartDone 0
    set RequestsWhenStopped $CountRequestedSoFar
    unset -nocomplain StartDone

    if {$CountFinishedSoFar == $RequestsWhenStopped} {
        if {[info exists TimeOutCode]} {
            after cancel $TimeOutCode
        }
        set ::httpTestScript::FOREVER 0
    }
    return
}

# httpTestScript::DELAY --
# If there are no WAIT commands, this sets the delay in ms between subsequent
# calls to http::geturl.  Default 500ms.

proc httpTestScript::DELAY {t} {
    variable StartDone
    variable StopDone

    if {$StopDone} {
        return
    }

    if {![info exists StartDone]} {
        return -code error {initialise the script by calling command START}
    }

    variable Delay

    set Delay $t
    return
}

# httpTestScript::KEEPALIVE --
# Set the value passed to http::geturl for the -keepalive option.  Default 1.

proc httpTestScript::KEEPALIVE {b} {
    variable StartDone
    variable StopDone

    if {$StopDone} {
        return
    }

    if {![info exists StartDone]} {
        return -code error {initialise the script by calling command START}
    }

    variable KeepAlive
    set KeepAlive $b
    return
}

# httpTestScript::WAIT --
# Pause for a time in ms before processing any more commands.

proc httpTestScript::WAIT {t} {
    variable StartDone
    variable StopDone
    variable ExtraTime

    if {$StopDone} {
        return
    }

    if {![info exists StartDone]} {
        return -code error {initialise the script by calling command START}
    }

    if {(![string is integer -strict $t]) || $t < 0} {
        return -code error {argument to WAIT must be a non-negative integer}
    }

    incr ExtraTime $t

    return
}

# httpTestScript::PIPELINE --
# Pass a value to http::config -pipeline.

proc httpTestScript::PIPELINE {b} {
    variable StartDone
    variable StopDone

    if {$StopDone} {
        return
    }

    if {![info exists StartDone]} {
        return -code error {initialise the script by calling command START}
    }

    ::http::config -pipeline $b
    ##::http::Log http(-pipeline) is now [::http::config -pipeline]
    return
}

# httpTestScript::POSTFRESH --
# Pass a value to http::config -postfresh.

proc httpTestScript::POSTFRESH {b} {
    variable StartDone
    variable StopDone

    if {$StopDone} {
        return
    }

    if {![info exists StartDone]} {
        return -code error {initialise the script by calling command START}
    }

    ::http::config -postfresh $b
    ##::http::Log http(-postfresh) is now [::http::config -postfresh]
    return
}

# httpTestScript::REPOST --
# Pass a value to http::config -repost.

proc httpTestScript::REPOST {b} {
    variable StartDone
    variable StopDone

    if {$StopDone} {
        return
    }

    if {![info exists StartDone]} {
        return -code error {initialise the script by calling command START}
    }

    ::http::config -repost $b
    ##::http::Log http(-repost) is now [::http::config -repost]
    return
}








|
|



|








|
|
|
|













|



|
















|



|
















|



|



|















|



|















|



|















|



|







144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
    variable RequestsWhenStopped
    variable TimeOutCode
    variable StartDone
    variable StopDone
    variable RequestsMade

    if {$StopDone} {
	# Don't do anything on a second call.
	return
    }

    if {![info exists StartDone]} {
	return -code error {initialise the script by calling command START}
    }

    set StopDone 1
    set StartDone 0
    set RequestsWhenStopped $CountRequestedSoFar
    unset -nocomplain StartDone

    if {$CountFinishedSoFar == $RequestsWhenStopped} {
	if {[info exists TimeOutCode]} {
	    after cancel $TimeOutCode
	}
	set ::httpTestScript::FOREVER 0
    }
    return
}

# httpTestScript::DELAY --
# If there are no WAIT commands, this sets the delay in ms between subsequent
# calls to http::geturl.  Default 500ms.

proc httpTestScript::DELAY {t} {
    variable StartDone
    variable StopDone

    if {$StopDone} {
	return
    }

    if {![info exists StartDone]} {
	return -code error {initialise the script by calling command START}
    }

    variable Delay

    set Delay $t
    return
}

# httpTestScript::KEEPALIVE --
# Set the value passed to http::geturl for the -keepalive option.  Default 1.

proc httpTestScript::KEEPALIVE {b} {
    variable StartDone
    variable StopDone

    if {$StopDone} {
	return
    }

    if {![info exists StartDone]} {
	return -code error {initialise the script by calling command START}
    }

    variable KeepAlive
    set KeepAlive $b
    return
}

# httpTestScript::WAIT --
# Pause for a time in ms before processing any more commands.

proc httpTestScript::WAIT {t} {
    variable StartDone
    variable StopDone
    variable ExtraTime

    if {$StopDone} {
	return
    }

    if {![info exists StartDone]} {
	return -code error {initialise the script by calling command START}
    }

    if {(![string is integer -strict $t]) || $t < 0} {
	return -code error {argument to WAIT must be a non-negative integer}
    }

    incr ExtraTime $t

    return
}

# httpTestScript::PIPELINE --
# Pass a value to http::config -pipeline.

proc httpTestScript::PIPELINE {b} {
    variable StartDone
    variable StopDone

    if {$StopDone} {
	return
    }

    if {![info exists StartDone]} {
	return -code error {initialise the script by calling command START}
    }

    ::http::config -pipeline $b
    ##::http::Log http(-pipeline) is now [::http::config -pipeline]
    return
}

# httpTestScript::POSTFRESH --
# Pass a value to http::config -postfresh.

proc httpTestScript::POSTFRESH {b} {
    variable StartDone
    variable StopDone

    if {$StopDone} {
	return
    }

    if {![info exists StartDone]} {
	return -code error {initialise the script by calling command START}
    }

    ::http::config -postfresh $b
    ##::http::Log http(-postfresh) is now [::http::config -postfresh]
    return
}

# httpTestScript::REPOST --
# Pass a value to http::config -repost.

proc httpTestScript::REPOST {b} {
    variable StartDone
    variable StopDone

    if {$StopDone} {
	return
    }

    if {![info exists StartDone]} {
	return -code error {initialise the script by calling command START}
    }

    ::http::config -repost $b
    ##::http::Log http(-repost) is now [::http::config -repost]
    return
}

343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
    variable Delay
    variable ExtraTime
    variable StartDone
    variable StopDone
    variable KeepAlive

    if {$StopDone} {
        return
    }

    if {![info exists StartDone]} {
        return -code error {initialise the script by calling command START}
    }

    incr CountRequestedSoFar
    set idelay [expr {($CountRequestedSoFar - 1) * $Delay + 10 + $ExtraTime}]

    # Could pass values of -pipeline, -postfresh, -repost if it were
    # useful to change these mid-script.







|



|







343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
    variable Delay
    variable ExtraTime
    variable StartDone
    variable StopDone
    variable KeepAlive

    if {$StopDone} {
	return
    }

    if {![info exists StartDone]} {
	return -code error {initialise the script by calling command START}
    }

    incr CountRequestedSoFar
    set idelay [expr {($CountRequestedSoFar - 1) * $Delay + 10 + $ExtraTime}]

    # Could pass values of -pipeline, -postfresh, -repost if it were
    # useful to change these mid-script.
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
    set absUrl $URL($uriCode)
    if {$query eq {}} {
	if {$args ne {}} {
	    append absUrl & [join $args &]
	}
	set queryArgs {}
    } elseif {$validate} {
        return -code error {cannot have both -validate (HEAD) and -query (POST)}
    } else {
	set queryArgs [list -query [join $args &]]
    }

    if {[catch {
        ::http::geturl     $absUrl        \
                -validate  $validate      \
                -timeout   10000          \
                {*}$queryArgs             \
                -keepalive $keepAlive     \
                -command   ::httpTestScript::WhenFinished
    } token]} {
        set msg $token
        catch {puts stdout "Error: $msg"}
        return
    } else {
        # Request will begin.
    }

    return

}

proc httpTestScript::TimeOutNow {} {







|





|
|
|
|
|
|

|
|
|

|







371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
    set absUrl $URL($uriCode)
    if {$query eq {}} {
	if {$args ne {}} {
	    append absUrl & [join $args &]
	}
	set queryArgs {}
    } elseif {$validate} {
	return -code error {cannot have both -validate (HEAD) and -query (POST)}
    } else {
	set queryArgs [list -query [join $args &]]
    }

    if {[catch {
	::http::geturl     $absUrl        \
		-validate  $validate      \
		-timeout   10000          \
		{*}$queryArgs             \
		-keepalive $keepAlive     \
		-command   ::httpTestScript::WhenFinished
    } token]} {
	set msg $token
	catch {puts stdout "Error: $msg"}
	return
    } else {
	# Request will begin.
    }

    return

}

proc httpTestScript::TimeOutNow {} {
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
	}
    } err]} {
	::http::Log ^X$tk httpTestScript::WhenFinished failed with error status: $err - token $hToken
    }

    incr CountFinishedSoFar
    if {$StopDone && ($CountFinishedSoFar == $RequestsWhenStopped)} {
        if {[info exists TimeOutCode]} {
            after cancel $TimeOutCode
        }
        if {$RequestsMade ne $RequestList && $ActualKeepAlive} {
	    ::http::Log ^X$tk unexpected result - Script asked for "{$RequestList}" but got "{$RequestsMade}" - token $hToken
        }
        set ::httpTestScript::FOREVER 0
    }

    return
}


proc httpTestScript::runHttpTestScript {scr} {
    variable TimeOutDone
    variable RequestsWhenStopped

    after idle [list namespace eval ::httpTestScript $scr]
    vwait ::httpTestScript::FOREVER
    # N.B. does not automatically execute in this namespace, unlike some other events.
    # Release when all requests have been served or have timed out.

    if {$TimeOutDone} {
        return -code error {test script timed out}
    }

    return $RequestsWhenStopped
}


proc httpTestScript::cleanupHttpTestScript {} {
    variable TimeOutDone
    variable RequestsWhenStopped

    if {![info exists RequestsWhenStopped]} {
	return -code error {Cleanup Failed: RequestsWhenStopped is undefined}
    }

    for {set i 1} {$i <= $RequestsWhenStopped} {incr i} {
        http::cleanup ::http::$i
    }

    return
}







|
|
|
|

|
|
















|















|




459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
	}
    } err]} {
	::http::Log ^X$tk httpTestScript::WhenFinished failed with error status: $err - token $hToken
    }

    incr CountFinishedSoFar
    if {$StopDone && ($CountFinishedSoFar == $RequestsWhenStopped)} {
	if {[info exists TimeOutCode]} {
	    after cancel $TimeOutCode
	}
	if {$RequestsMade ne $RequestList && $ActualKeepAlive} {
	    ::http::Log ^X$tk unexpected result - Script asked for "{$RequestList}" but got "{$RequestsMade}" - token $hToken
	}
	set ::httpTestScript::FOREVER 0
    }

    return
}


proc httpTestScript::runHttpTestScript {scr} {
    variable TimeOutDone
    variable RequestsWhenStopped

    after idle [list namespace eval ::httpTestScript $scr]
    vwait ::httpTestScript::FOREVER
    # N.B. does not automatically execute in this namespace, unlike some other events.
    # Release when all requests have been served or have timed out.

    if {$TimeOutDone} {
	return -code error {test script timed out}
    }

    return $RequestsWhenStopped
}


proc httpTestScript::cleanupHttpTestScript {} {
    variable TimeOutDone
    variable RequestsWhenStopped

    if {![info exists RequestsWhenStopped]} {
	return -code error {Cleanup Failed: RequestsWhenStopped is undefined}
    }

    for {set i 1} {$i <= $RequestsWhenStopped} {incr i} {
	http::cleanup ::http::$i
    }

    return
}
Changes to tests/httpd.
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
	}
	return
    } elseif {$data(state) == "mime"} {

	# Read the HTTP headers

	set readCount [gets $sock line]
        if {[regexp {^([^:]+):(.*)$} $line -> key val]} {
            lappend data(meta) $key [string trim $val]
        }

    } elseif {$data(state) == "query"} {

	# Read the query data

	if {![info exists data(length_orig)]} {
	    set data(length_orig) $data(length)







|
|
|







80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
	}
	return
    } elseif {$data(state) == "mime"} {

	# Read the HTTP headers

	set readCount [gets $sock line]
	if {[regexp {^([^:]+):(.*)$} $line -> key val]} {
	    lappend data(meta) $key [string trim $val]
	}

    } elseif {$data(state) == "query"} {

	# Read the query data

	if {![info exists data(length_orig)]} {
	    set data(length_orig) $data(length)
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254

    # Catch errors from premature client closes

    catch {
	if {$data(proto) == "HEAD"} {
	    puts $sock "HTTP/1.0 200 OK"
	} else {
            # Split the response to test for [Bug 26245326]
	    puts -nonewline $sock "HT"
            flush $sock
            puts $sock "TP/1.0 200 Data follows"
	}
	puts $sock "Date: [clock format [clock seconds] \
                              -format {%a, %d %b %Y %H:%M:%S %Z}]"
	puts $sock "Content-Type: $type"
	puts $sock "Content-Length: [string length $html]"
        foreach {key val} $data(meta) {
            if {[string match "X-*" $key]} {
                puts $sock "$key: $val"
            }
        }
	puts $sock ""
	flush $sock
	if {$data(proto) != "HEAD"} {
	    fconfigure $sock -translation binary
	    puts -nonewline $sock $html
	}
    }
    httpd_log $sock Done ""
    httpdSockDone $sock
}







|

|
|


|


|
|
|
|
|










224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254

    # Catch errors from premature client closes

    catch {
	if {$data(proto) == "HEAD"} {
	    puts $sock "HTTP/1.0 200 OK"
	} else {
	    # Split the response to test for [Bug 26245326]
	    puts -nonewline $sock "HT"
	    flush $sock
	    puts $sock "TP/1.0 200 Data follows"
	}
	puts $sock "Date: [clock format [clock seconds] \
			      -format {%a, %d %b %Y %H:%M:%S %Z}]"
	puts $sock "Content-Type: $type"
	puts $sock "Content-Length: [string length $html]"
	foreach {key val} $data(meta) {
	    if {[string match "X-*" $key]} {
		puts $sock "$key: $val"
	    }
	}
	puts $sock ""
	flush $sock
	if {$data(proto) != "HEAD"} {
	    fconfigure $sock -translation binary
	    puts -nonewline $sock $html
	}
    }
    httpd_log $sock Done ""
    httpdSockDone $sock
}
Changes to tests/httpd11.tcl.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

package require Tcl

proc ::tcl::dict::get? {dict key} {
    if {[dict exists $dict $key]} {
        return [dict get $dict $key]
    }
    return
}
namespace ensemble configure dict \
    -map [linsert [namespace ensemble configure dict -map] end get? ::tcl::dict::get?]

proc make-chunk-generator {data {size 4096}} {
    variable _chunk_gen_uid
    if {![info exists _chunk_gen_uid]} {set _chunk_gen_uid 0}
    set lambda {{data size} {
        set pos 0
        yield
        while {1} {
            set payload [string range $data $pos [expr {$pos + $size - 1}]]
            incr pos $size
            set chunk [format %x [string length $payload]]\r\n$payload\r\n
            yield $chunk
            if {![string length $payload]} {return}
        }
    }}
    set name chunker[incr _chunk_gen_uid]
    coroutine $name ::apply $lambda $data $size
    return $name
}

proc get-chunks {data {compression gzip}} {
    switch -exact -- $compression {
        gzip     { set data [zlib gzip $data] }
        deflate  { set data [zlib deflate $data] }
        compress { set data [zlib compress $data] }
    }

    set data ""
    set chunker [make-chunk-generator $data 671]
    while {[string length [set chunk [$chunker]]]} {
        append data $chunk
    }
    return $data
}

proc blow-chunks {data {ochan stdout} {compression gzip}} {
    switch -exact -- $compression {
        gzip     { set data [zlib gzip $data] }
        deflate  { set data [zlib deflate $data] }
        compress { set data [zlib compress $data] }
    }

    set chunker [make-chunk-generator $data 671]
    while {[string length [set chunk [$chunker]]]} {
        puts -nonewline $ochan $chunk
    }
    return
}

proc mime-type {filename} {
    switch -exact -- [file extension $filename] {
        .htm - .html { return {text text/html}}
        .png { return {binary image/png} }
        .jpg { return {binary image/jpeg} }
        .gif { return {binary image/gif} }
        .css { return {text   text/css} }
        .xml { return {text   text/xml} }
        .xhtml {return {text  application/xml+html} }
        .svg { return {text image/svg+xml} }
        .txt - .tcl - .c - .h { return {text text/plain}}
    }
    return {binary text/plain}
}

proc Puts {chan s} {puts $chan $s; puts $s}

proc Service {chan addr port} {
    chan event $chan readable [info coroutine]
    while {1} {
        set meta {}
        chan configure $chan -buffering line -encoding iso8859-1 -translation crlf
        chan configure $chan -blocking 0
        yield
        while {[gets $chan line] < 0} {
            if {[eof $chan]} {chan event $chan readable {}; close $chan; return}
            yield
        }
        if {[eof $chan]} {chan event $chan readable {}; close $chan; return}
        foreach {req url protocol} {GET {} HTTP/1.1} break
        regexp {^(\S+)\s+(.*)\s(\S+)?$} $line -> req url protocol

        puts $line
        while {[gets $chan line] > 0} {
            if {[regexp {^([^:]+):(.*)$} $line -> key val]} {
                puts [list $key [string trim $val]]
                lappend meta [string tolower $key] [string trim $val]
            }
            yield
        }

        set encoding identity
        set transfer ""
        set close 1
        set type text/html
        set code "404 Not Found"
        set data "<html><head><title>Error 404</title></head>"
        append data "<body><h1>Not Found</h1><p>Try again.</p></body></html>"

        if {[scan $url {%[^?]?%s} path query] < 2} {
            set query ""
        }

        switch -exact -- $req {
            GET - HEAD {
            }
            POST {
                # Read the query.
                set qlen [dict get? $meta content-length]
                if {[string is integer -strict $qlen]} {
                    chan configure $chan -buffering none -translation binary
                    while {[string length $query] < $qlen} {
                        append query [read $chan $qlen]
                        if {[string length $query] < $qlen} {yield}
                    }
                    # Check for excess query bytes [Bug 2715421]
                    if {[dict get? $meta x-check-query] eq "yes"} {
                        chan configure $chan -blocking 0
                        append query [read $chan]
                    }
                }
            }
            default {
                # invalid request error 5??
            }
        }
        if {$query ne ""} {puts $query}

        set path [string trimleft $path /]
        set path [file join [pwd] $path]
        if {[file exists $path] && [file isfile $path]} {
            foreach {what type} [mime-type $path] break
            set f [open $path r]
            if {$what eq "binary"} {
                chan configure $f -translation binary
            } else {
                chan configure $f -encoding utf-8
            }
            set data [read $f]
            close $f
            set code "200 OK"
            set close [expr {[dict get? $meta connection] eq "close"}]
        }

        if {$protocol eq "HTTP/1.1"} {
	    foreach enc [split [dict get? $meta accept-encoding] ,] {
		set enc [string trim $enc]
		# The current implementation of "compress" appears to be
		# incorrect (bug [a13b9d0ce1]).  Keep it here for
		# experimentation only.  The tests that use it have the
		# constraint "badCompress".  The client code in http has
		# been removed, but can be restored from comments if
		# experimentation is desired.
		if {$enc in {deflate gzip compress}} {
		    set encoding $enc
		    break
		}
	    }
            set transfer chunked
        } else {
            set close 1
        }

        set nosendclose 0
        set msdeflate 0
        foreach pair [split $query &] {
            if {[scan $pair {%[^=]=%s} key val] != 2} {set val ""}
            switch -exact -- $key {
                nosendclose  {set nosendclose 1}
                close        {set close 1 ; set transfer 0}
                transfer     {set transfer $val}
                content-type {set type $val}
                msdeflate    {set msdeflate $val}
            }
        }
        if {$protocol eq "HTTP/1.1"} {
            set nosendclose 0
        }

        chan configure $chan -buffering line -encoding iso8859-1 -translation crlf
        Puts $chan "$protocol $code"
        Puts $chan "content-type: $type"
        Puts $chan [format "x-crc32: %08x" [zlib crc32 $data]]
        if {$req eq "POST"} {
            Puts $chan [format "x-query-length: %d" [string length $query]]
        }
        if {$close && (!$nosendclose)} {
            Puts $chan "connection: close"
        }
	Puts $chan "x-requested-encodings: [dict get? $meta accept-encoding]"
        if {$encoding eq "identity" && (!$nosendclose)} {
            Puts $chan "content-length: [string length $data]"
        } elseif {$encoding eq "identity"} {
            # This is a blatant attempt to confuse the client by sending neither
            # "Connection: close" nor "Content-Length" when in non-chunked mode.
            # See test http11-3.4.
        } else {
            Puts $chan "content-encoding: $encoding"
        }
        if {$transfer eq "chunked"} {
            Puts $chan "transfer-encoding: chunked"
        }
        puts $chan ""
        flush $chan

        chan configure $chan -buffering full -translation binary
        if {$encoding eq {deflate}} {
            # When http.tcl uses the correct decoder (bug [a13b9d0ce1]) for
            # "accept-encoding deflate", i.e. "zlib decompress", this choice of
            # encoding2 allows the tests to pass.  It appears to do "deflate"
            # correctly, but this has not been verified with a non-Tcl client.
            set encoding2 compress
        } else {
            set encoding2 $encoding
        }
        if {$transfer eq "chunked"} {
            blow-chunks $data $chan $encoding2
        } elseif {$encoding2 ne "identity" && $msdeflate eq {1}} {
            puts -nonewline $chan [string range [zlib $encoding2 $data] 2 end-4]
            # Used in some tests of "deflate" to produce the non-RFC-compliant
            # Microsoft version of "deflate".
        } elseif {$encoding2 ne "identity"} {
            puts -nonewline $chan [zlib $encoding2 $data]
        } else {
            puts -nonewline $chan $data
        }

        if {$close} {
            chan event $chan readable {}
            close $chan
            puts "close $chan"
            return
        } else {
            flush $chan
        }
        puts "pipeline $chan"
    }
}

proc Accept {chan addr port} {
    coroutine client$chan Service $chan $addr $port
    return
}

proc Control {chan} {
    if {[gets $chan line] >= 0} {
        if {[string trim $line] eq "quit"} {
            set ::forever 1
        }
    }
    if {[eof $chan]} {
        chan event $chan readable {}
    }
}

proc Main {{port 0}} {
    set server [socket -server Accept -myaddr localhost $port]
    puts [chan configure $server -sockname]
    flush stdout







|










|
|
|
|
|
|
|
|
|








|
|
|





|






|
|
|




|






|
|
|
|
|
|
|
|
|









|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|

|
|
|
|
|
|
|

|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|













|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|










|
|
|


|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

package require Tcl

proc ::tcl::dict::get? {dict key} {
    if {[dict exists $dict $key]} {
	return [dict get $dict $key]
    }
    return
}
namespace ensemble configure dict \
    -map [linsert [namespace ensemble configure dict -map] end get? ::tcl::dict::get?]

proc make-chunk-generator {data {size 4096}} {
    variable _chunk_gen_uid
    if {![info exists _chunk_gen_uid]} {set _chunk_gen_uid 0}
    set lambda {{data size} {
	set pos 0
	yield
	while {1} {
	    set payload [string range $data $pos [expr {$pos + $size - 1}]]
	    incr pos $size
	    set chunk [format %x [string length $payload]]\r\n$payload\r\n
	    yield $chunk
	    if {![string length $payload]} {return}
	}
    }}
    set name chunker[incr _chunk_gen_uid]
    coroutine $name ::apply $lambda $data $size
    return $name
}

proc get-chunks {data {compression gzip}} {
    switch -exact -- $compression {
	gzip     { set data [zlib gzip $data] }
	deflate  { set data [zlib deflate $data] }
	compress { set data [zlib compress $data] }
    }

    set data ""
    set chunker [make-chunk-generator $data 671]
    while {[string length [set chunk [$chunker]]]} {
	append data $chunk
    }
    return $data
}

proc blow-chunks {data {ochan stdout} {compression gzip}} {
    switch -exact -- $compression {
	gzip     { set data [zlib gzip $data] }
	deflate  { set data [zlib deflate $data] }
	compress { set data [zlib compress $data] }
    }

    set chunker [make-chunk-generator $data 671]
    while {[string length [set chunk [$chunker]]]} {
	puts -nonewline $ochan $chunk
    }
    return
}

proc mime-type {filename} {
    switch -exact -- [file extension $filename] {
	.htm - .html { return {text text/html}}
	.png { return {binary image/png} }
	.jpg { return {binary image/jpeg} }
	.gif { return {binary image/gif} }
	.css { return {text   text/css} }
	.xml { return {text   text/xml} }
	.xhtml {return {text  application/xml+html} }
	.svg { return {text image/svg+xml} }
	.txt - .tcl - .c - .h { return {text text/plain}}
    }
    return {binary text/plain}
}

proc Puts {chan s} {puts $chan $s; puts $s}

proc Service {chan addr port} {
    chan event $chan readable [info coroutine]
    while {1} {
	set meta {}
	chan configure $chan -buffering line -encoding iso8859-1 -translation crlf
	chan configure $chan -blocking 0
	yield
	while {[gets $chan line] < 0} {
	    if {[eof $chan]} {chan event $chan readable {}; close $chan; return}
	    yield
	}
	if {[eof $chan]} {chan event $chan readable {}; close $chan; return}
	foreach {req url protocol} {GET {} HTTP/1.1} break
	regexp {^(\S+)\s+(.*)\s(\S+)?$} $line -> req url protocol

	puts $line
	while {[gets $chan line] > 0} {
	    if {[regexp {^([^:]+):(.*)$} $line -> key val]} {
		puts [list $key [string trim $val]]
		lappend meta [string tolower $key] [string trim $val]
	    }
	    yield
	}

	set encoding identity
	set transfer ""
	set close 1
	set type text/html
	set code "404 Not Found"
	set data "<html><head><title>Error 404</title></head>"
	append data "<body><h1>Not Found</h1><p>Try again.</p></body></html>"

	if {[scan $url {%[^?]?%s} path query] < 2} {
	    set query ""
	}

	switch -exact -- $req {
	    GET - HEAD {
	    }
	    POST {
		# Read the query.
		set qlen [dict get? $meta content-length]
		if {[string is integer -strict $qlen]} {
		    chan configure $chan -buffering none -translation binary
		    while {[string length $query] < $qlen} {
			append query [read $chan $qlen]
			if {[string length $query] < $qlen} {yield}
		    }
		    # Check for excess query bytes [Bug 2715421]
		    if {[dict get? $meta x-check-query] eq "yes"} {
			chan configure $chan -blocking 0
			append query [read $chan]
		    }
		}
	    }
	    default {
		# invalid request error 5??
	    }
	}
	if {$query ne ""} {puts $query}

	set path [string trimleft $path /]
	set path [file join [pwd] $path]
	if {[file exists $path] && [file isfile $path]} {
	    foreach {what type} [mime-type $path] break
	    set f [open $path r]
	    if {$what eq "binary"} {
		chan configure $f -translation binary
	    } else {
		chan configure $f -encoding utf-8
	    }
	    set data [read $f]
	    close $f
	    set code "200 OK"
	    set close [expr {[dict get? $meta connection] eq "close"}]
	}

	if {$protocol eq "HTTP/1.1"} {
	    foreach enc [split [dict get? $meta accept-encoding] ,] {
		set enc [string trim $enc]
		# The current implementation of "compress" appears to be
		# incorrect (bug [a13b9d0ce1]).  Keep it here for
		# experimentation only.  The tests that use it have the
		# constraint "badCompress".  The client code in http has
		# been removed, but can be restored from comments if
		# experimentation is desired.
		if {$enc in {deflate gzip compress}} {
		    set encoding $enc
		    break
		}
	    }
	    set transfer chunked
	} else {
	    set close 1
	}

	set nosendclose 0
	set msdeflate 0
	foreach pair [split $query &] {
	    if {[scan $pair {%[^=]=%s} key val] != 2} {set val ""}
	    switch -exact -- $key {
		nosendclose  {set nosendclose 1}
		close        {set close 1 ; set transfer 0}
		transfer     {set transfer $val}
		content-type {set type $val}
		msdeflate    {set msdeflate $val}
	    }
	}
	if {$protocol eq "HTTP/1.1"} {
	    set nosendclose 0
	}

	chan configure $chan -buffering line -encoding iso8859-1 -translation crlf
	Puts $chan "$protocol $code"
	Puts $chan "content-type: $type"
	Puts $chan [format "x-crc32: %08x" [zlib crc32 $data]]
	if {$req eq "POST"} {
	    Puts $chan [format "x-query-length: %d" [string length $query]]
	}
	if {$close && (!$nosendclose)} {
	    Puts $chan "connection: close"
	}
	Puts $chan "x-requested-encodings: [dict get? $meta accept-encoding]"
	if {$encoding eq "identity" && (!$nosendclose)} {
	    Puts $chan "content-length: [string length $data]"
	} elseif {$encoding eq "identity"} {
	    # This is a blatant attempt to confuse the client by sending neither
	    # "Connection: close" nor "Content-Length" when in non-chunked mode.
	    # See test http11-3.4.
	} else {
	    Puts $chan "content-encoding: $encoding"
	}
	if {$transfer eq "chunked"} {
	    Puts $chan "transfer-encoding: chunked"
	}
	puts $chan ""
	flush $chan

	chan configure $chan -buffering full -translation binary
	if {$encoding eq {deflate}} {
	    # When http.tcl uses the correct decoder (bug [a13b9d0ce1]) for
	    # "accept-encoding deflate", i.e. "zlib decompress", this choice of
	    # encoding2 allows the tests to pass.  It appears to do "deflate"
	    # correctly, but this has not been verified with a non-Tcl client.
	    set encoding2 compress
	} else {
	    set encoding2 $encoding
	}
	if {$transfer eq "chunked"} {
	    blow-chunks $data $chan $encoding2
	} elseif {$encoding2 ne "identity" && $msdeflate eq {1}} {
	    puts -nonewline $chan [string range [zlib $encoding2 $data] 2 end-4]
	    # Used in some tests of "deflate" to produce the non-RFC-compliant
	    # Microsoft version of "deflate".
	} elseif {$encoding2 ne "identity"} {
	    puts -nonewline $chan [zlib $encoding2 $data]
	} else {
	    puts -nonewline $chan $data
	}

	if {$close} {
	    chan event $chan readable {}
	    close $chan
	    puts "close $chan"
	    return
	} else {
	    flush $chan
	}
	puts "pipeline $chan"
    }
}

proc Accept {chan addr port} {
    coroutine client$chan Service $chan $addr $port
    return
}

proc Control {chan} {
    if {[gets $chan line] >= 0} {
	if {[string trim $line] eq "quit"} {
	    set ::forever 1
	}
    }
    if {[eof $chan]} {
	chan event $chan readable {}
    }
}

proc Main {{port 0}} {
    set server [socket -server Accept -myaddr localhost $port]
    puts [chan configure $server -sockname]
    flush stdout
Changes to tests/icu.test.
1


2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
# Tests for tcl::unsupported::icu



if {"::tcltest" ni [namespace children]} {
    package require tcltest
    namespace import -force ::tcltest::*
}

# Force late loading of ICU if present
catch {::tcl::unsupported::icu}
testConstraint icu [llength [info commands ::tcl::unsupported::icu::detect]]

namespace eval icu {
    namespace path {::tcl::unsupported ::tcl::mathop}

    test icu-detect-0 {Return list of ICU encodings} -constraints icu -body {
	set encoders [icu detect]
	list [in UTF-8 $encoders] [in ISO-8859-1 $encoders]
    } -result {1 1}

    test icu-detect-1 {Guess encoding} -constraints icu -body {
	icu detect [readFile [info script]]
    } -result ISO-8859-1
    test icu-detect-2 {Get all possible encodings} -constraints icu -body {
	set encodings [icu detect [readFile [info script]] -all]
	list [in UTF-8 $encodings] [in ISO-8859-1 $encodings]
    } -result {1 1}

>
>

















>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# Tests for tcl::unsupported::icu
# Contains basic sanity checks only! Commands are not intended for
# production use.

if {"::tcltest" ni [namespace children]} {
    package require tcltest
    namespace import -force ::tcltest::*
}

# Force late loading of ICU if present
catch {::tcl::unsupported::icu}
testConstraint icu [llength [info commands ::tcl::unsupported::icu::detect]]

namespace eval icu {
    namespace path {::tcl::unsupported ::tcl::mathop}

    test icu-detect-0 {Return list of ICU encodings} -constraints icu -body {
	set encoders [icu detect]
	list [in UTF-8 $encoders] [in ISO-8859-1 $encoders]
    } -result {1 1}

    test icu-detect-1 {Guess encoding} -constraints icu -body {
	icu detect [readFile [info script]]
    } -result ISO-8859-1
    test icu-detect-2 {Get all possible encodings} -constraints icu -body {
	set encodings [icu detect [readFile [info script]] -all]
	list [in UTF-8 $encodings] [in ISO-8859-1 $encodings]
    } -result {1 1}
50
51
52
53
54
55
56
57



58






















































































































































































59
60
    test icu-icuToTcl-1 {Map ICU encoding - no map} -constraints icu -body {
	# Should not raise an error
	icu icuToTcl dummy
    } -result {}
    test icu-icuToTcl-2 {error case} -constraints icu -returnCodes error -body {
	icu icuToTcl gorp gorp
    } -result {wrong # args: should be "icu icuToTcl icuName"}
}


























































































































































































namespace delete icu
::tcltest::cleanupTests







|
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
    test icu-icuToTcl-1 {Map ICU encoding - no map} -constraints icu -body {
	# Should not raise an error
	icu icuToTcl dummy
    } -result {}
    test icu-icuToTcl-2 {error case} -constraints icu -returnCodes error -body {
	icu icuToTcl gorp gorp
    } -result {wrong # args: should be "icu icuToTcl icuName"}

    ###
    # icu convertfrom syntax and arg checks
    # These tests are NOT for testing encodings, that's elsewhere.

    test icu-convertfrom-error-0 {no args} -constraints icu -body {
        icu convertfrom
    } -result {wrong # args: should be "icu convertfrom ?-profile PROFILE? ICUENCNAME STRING"} -returnCodes error

    test icu-convertfrom-error-1 {one arg} -constraints icu -body {
        icu convertfrom ASCII
    } -result {wrong # args: should be "icu convertfrom ?-profile PROFILE? ICUENCNAME STRING"} -returnCodes error

    test icu-convertfrom-error-2 {missing option value} -constraints icu -body {
        icu convertfrom -profile strict ASCII
    } -result {Missing value for option -profile.} -returnCodes error

    test icu-convertfrom-error-3 {-failindex} -constraints icu -body {
        icu convertfrom -failindex failindex ASCII abc
    } -result {Option -failindex not implemented.} -returnCodes error

    test icu-convertfrom-error-4 {extra arg} -constraints icu -body {
        icu convertfrom -profile strict extra ASCII abc
    } -result {bad option "extra": must be -profile or -failindex} -returnCodes error

    test icu-convertfrom-error-5 {invalid profile} -constraints icu -body {
        icu convertfrom -profile tcl8 ASCII abc
    } -result {Invalid value "tcl8" supplied for option "-profile". Must be "strict" or "replace".} -returnCodes error

    test icu-convertfrom-error-6 {invalid encoding} -constraints icu -body {
        icu convertfrom nosuchencoding abc
    } -result {Could not get encoding converter.*} -match glob -returnCodes error

    test icu-convertfrom-0 {default success} -constraints icu -body {
        icu convertfrom UTF-8 \xf0\x9f\x98\x80
    } -result \U1F600

    test icu-convertfrom-1 {-profile strict success} -constraints icu -body {
        icu convertfrom -profile strict UTF-8 \xf0\x9f\x98\x80
    } -result \U1F600

    test icu-convertfrom-2 {-profile replace success} -constraints icu -body {
        icu convertfrom -profile replace UTF-8 \xf0\x9f\x98\x80
    } -result \U1F600

    test icu-convertfrom-3 {default invalid encoding} -constraints icu -body {
        icu convertfrom UTF-8 \xC0\x80
    } -result {ICU error while decoding. ICU error (12): U_ILLEGAL_CHAR_FOUND} -returnCodes error

    test icu-convertfrom-4 {-profile strict invalid encoding} -constraints icu -body {
        icu convertfrom -profile strict UTF-8 \xC0\x80
    } -result {ICU error while decoding. ICU error (12): U_ILLEGAL_CHAR_FOUND} -returnCodes error

    test icu-convertfrom-5 {-profile replace invalid encoding} -constraints icu -body {
        icu convertfrom -profile replace UTF-8 \xC0\x80
    } -result \UFFFD\uFFFD

    ###
    # icu convertto syntax and arg checks
    # These tests are NOT for testing encodings, that's elsewhere.

    test icu-convertto-error-0 {no args} -constraints icu -body {
        icu convertto
    } -result {wrong # args: should be "icu convertto ?-profile PROFILE? ICUENCNAME STRING"} -returnCodes error

    test icu-convertto-error-1 {one arg} -constraints icu -body {
        icu convertto ASCII
    } -result {wrong # args: should be "icu convertto ?-profile PROFILE? ICUENCNAME STRING"} -returnCodes error

    test icu-convertto-error-2 {missing option value} -constraints icu -body {
        icu convertto -profile strict ASCII
    } -result {Missing value for option -profile.} -returnCodes error

    test icu-convertto-error-3 {-failindex} -constraints icu -body {
        icu convertto -failindex failindex ASCII abc
    } -result {Option -failindex not implemented.} -returnCodes error

    test icu-convertto-error-4 {extra arg} -constraints icu -body {
        icu convertto -profile strict extra ASCII abc
    } -result {bad option "extra": must be -profile or -failindex} -returnCodes error

    test icu-convertto-error-5 {invalid profile} -constraints icu -body {
        icu convertto -profile tcl8 ASCII abc
    } -result {Invalid value "tcl8" supplied for option "-profile". Must be "strict" or "replace".} -returnCodes error

    test icu-convertto-error-6 {invalid encoding} -constraints icu -body {
        icu convertto nosuchencoding abc
    } -result {Could not get encoding converter.*} -match glob -returnCodes error

    test icu-convertto-0 {default success} -constraints icu -body {
        icu convertto UTF-8 \U1F600
    } -result \xf0\x9f\x98\x80

    test icu-convertto-1 {-profile strict success} -constraints icu -body {
        icu convertto -profile strict UTF-8 \U1F600
    } -result \xf0\x9f\x98\x80

    test icu-convertto-2 {-profile replace success} -constraints icu -body {
        icu convertto -profile replace UTF-8 \U1F600
    } -result \xf0\x9f\x98\x80

    test icu-convertto-3 {default unencodable character} -constraints icu -body {
        icu convertto ISO-8859-2 \U1F600
    } -result {ICU error while encoding. ICU error (10): U_INVALID_CHAR_FOUND} -returnCodes error

    test icu-convertto-4 {-profile strict unencodable character} -constraints icu -body {
        icu convertto -profile strict ISO-8859-2 \U1F600
    } -result {ICU error while encoding. ICU error (10): U_INVALID_CHAR_FOUND} -returnCodes error

    test icu-convertto-5 {-profile replace unencodable character} -constraints icu -body {
        icu convertto -profile replace ISO-8859-2 \U1F600
    } -result \x1A

    ###
    # Basic tests for normalization

    test icu-normalize-error-0 {no args} -constraints icu -body {
        icu normalize
    } -result {wrong # args: should be "icu normalize ?-profile PROFILE? ?-mode MODE? STRING"} -returnCodes error

    test icu-normalize-error-1 {missing -profile arg} -constraints icu -body {
        icu normalize -profile STRING
    } -result {Missing value for option -profile.} -returnCodes error

    test icu-normalize-error-2 {missing -mode arg} -constraints icu -body {
        icu normalize -mode STRING
    } -result {Missing value for option -mode.} -returnCodes error

    test icu-normalize-error-3 {extra arg} -constraints icu -body {
        icu normalize -profile strict STRING arg
    } -result {bad option "STRING": must be -profile or -mode} -returnCodes error

    test icu-normalize-error-4 {invalid profile} -constraints icu -body {
        icu normalize -profile tcl8 ASCII abc
    } -result {Invalid value "tcl8" supplied for option "-profile". Must be "strict" or "replace".} -returnCodes error

    test icu-normalize-error-6 {invalid mode} -constraints icu -body {
        icu normalize -mode xxx ASCII abc
    } -result {bad normalization mode "xxx": must be nfc, nfd, nfkc, or nfkd} -returnCodes error

    # Source is composed
    set s \uFB01anc\u00e9
    test icu-normalize-0 {Default normalization} -constraints icu -body {
        icu normalize $s
    } -result \uFB01anc\u00e9
    test icu-normalize-nfc-0 {NFC normalization} -constraints icu -body {
        icu normalize -mode nfc $s
    } -result \uFB01anc\u00e9
    test icu-normalize-nfd-0 {NFD normalization} -constraints icu -body {
        icu normalize -mode nfd $s
    } -result \uFB01ance\u0301
    test icu-normalize-nfkc-0 {NFKC normalization} -constraints icu -body {
        icu normalize -mode nfkc $s
    } -result fianc\u00e9
    test icu-normalize-nfkd-0 {NFKD normalization} -constraints icu -body {
        icu normalize -mode nfkd $s
    } -result fiance\u0301

    # Source is decomposed
    set s \uFB01ance\u0301
    test icu-normalize-1 {Default normalization} -constraints icu -body {
        icu normalize $s
    } -result \uFB01anc\u00e9
    test icu-normalize-nfc-0 {NFC normalization} -constraints icu -body {
        icu normalize -mode nfc $s
    } -result \uFB01anc\u00e9
    test icu-normalize-nfd-1 {NFD normalization} -constraints icu -body {
        icu normalize -mode nfd $s
    } -result \uFB01ance\u0301
    test icu-normalize-nfkc-1 {NFKC normalization} -constraints icu -body {
        icu normalize -mode nfkc $s
    } -result fianc\u00e9
    test icu-normalize-nfkd-1 {NFKD normalization} -constraints icu -body {
        icu normalize -mode nfkd $s
    } -result fiance\u0301

    # Source has multiple diacritics with different canonical ordering
    foreach s [list \u1EC7 e\u0302\u0323 e\u0323\u0302] {
        test icu-normalize-nfc-2 {fully composed} -constraints icu -body {
            icu normalize -mode nfc $s
        } -result \u1EC7
        test icu-normalize-nfc-2 {fully decomposed} -constraints icu -body {
            icu normalize -mode nfd $s
        } -result e\u0323\u0302
    }
}

namespace delete icu
::tcltest::cleanupTests
Changes to tests/icuUcmTests.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

# This file is automatically generated by ucm2tests.tcl.
# Edits will be overwritten on next generation.
#
# Tests comparing Tcl encodings to ICU.
# This file is NOT standalone. It should be sourced into a test script.

proc ucmConvertfromMismatches {enc map} {
    set mismatches {}
    foreach {unihex hex} $map {
        set unihex [string range 00000000$unihex end-7 end]; # Make 8 digits
        set unich [subst "\\U$unihex"]
        if {[encoding convertfrom -profile strict $enc [binary decode hex $hex]] ne $unich} {
            lappend mismatches "<[printable $unich],$hex>"
        }
    }
    return $mismatches
}
proc ucmConverttoMismatches {enc map} {
    set mismatches {}
    foreach {unihex hex} $map {
        set unihex [string range 00000000$unihex end-7 end]; # Make 8 digits
        set unich [subst "\\U$unihex"]
        if {[encoding convertto -profile strict $enc $unich] ne [binary decode hex $hex]} {
            lappend mismatches "<[printable $unich],$hex>"
        }
    }
    return $mismatches
}
if {[info commands printable] eq ""} {
    proc printable {s} {
        set print ""
        foreach c [split $s ""] {
            set i [scan $c %c]
            if {[string is print $c] && ($i <= 127)} {
                append print $c
            } elseif {$i <= 0xff} {
                append print \\x[format %02X $i]
            } elseif {$i <= 0xffff} {
                append print \\u[format %04X $i]
            } else {
                append print \\U[format %08X $i]
            }
        }
        return $print
    }
}


#
# cp1250 (generated from glibc-CP1250-2.1.2)











|
|
|
|
|






|
|
|
|
|





|
|
|
|
|
|
|
|
|
|
|
|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

# This file is automatically generated by ucm2tests.tcl.
# Edits will be overwritten on next generation.
#
# Tests comparing Tcl encodings to ICU.
# This file is NOT standalone. It should be sourced into a test script.

proc ucmConvertfromMismatches {enc map} {
    set mismatches {}
    foreach {unihex hex} $map {
	set unihex [string range 00000000$unihex end-7 end]; # Make 8 digits
	set unich [subst "\\U$unihex"]
	if {[encoding convertfrom -profile strict $enc [binary decode hex $hex]] ne $unich} {
	    lappend mismatches "<[printable $unich],$hex>"
	}
    }
    return $mismatches
}
proc ucmConverttoMismatches {enc map} {
    set mismatches {}
    foreach {unihex hex} $map {
	set unihex [string range 00000000$unihex end-7 end]; # Make 8 digits
	set unich [subst "\\U$unihex"]
	if {[encoding convertto -profile strict $enc $unich] ne [binary decode hex $hex]} {
	    lappend mismatches "<[printable $unich],$hex>"
	}
    }
    return $mismatches
}
if {[info commands printable] eq ""} {
    proc printable {s} {
	set print ""
	foreach c [split $s ""] {
	    set i [scan $c %c]
	    if {[string is print $c] && ($i <= 127)} {
		append print $c
	    } elseif {$i <= 0xff} {
		append print \\x[format %02X $i]
	    } elseif {$i <= 0xffff} {
		append print \\u[format %04X $i]
	    } else {
		append print \\U[format %08X $i]
	    }
	}
	return $print
    }
}


#
# cp1250 (generated from glibc-CP1250-2.1.2)

Changes to tests/if.test.
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
} -result 3
test if-1.17 {TclCompileIfCmd: if/elseif test in quotes} -setup {
    set a {}
} -body {
    if {"0 < 3"} {set a 1}
} -returnCodes error -cleanup {
    unset a
} -result {expected boolean value but got "0 < 3"}

test if-2.1 {TclCompileIfCmd: "elseif" after if/elseif test} -setup {
    set a {}
} -body {
    if 3>4 {set a 1} elseif 1 {set a 2}
    return $a
} -cleanup {







|







177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
} -result 3
test if-1.17 {TclCompileIfCmd: if/elseif test in quotes} -setup {
    set a {}
} -body {
    if {"0 < 3"} {set a 1}
} -returnCodes error -cleanup {
    unset a
} -result {expected boolean value but got a list}

test if-2.1 {TclCompileIfCmd: "elseif" after if/elseif test} -setup {
    set a {}
} -body {
    if 3>4 {set a 1} elseif 1 {set a 2}
    return $a
} -cleanup {
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
test if-5.17 {if cmd with computed command names: if/elseif test in quotes} -setup {
    set a {}
} -body {
    set z if
    $z {"0 < 3"} {set a 1}
} -returnCodes error -cleanup {
    unset a z
} -result {expected boolean value but got "0 < 3"}

test if-6.1 {if cmd with computed command names: "elseif" after if/elseif test} -setup {
    set a {}
} -body {
    set z if
    $z 3>4 {set a 1} elseif 1 {set a 2}
    return $a







|







749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
test if-5.17 {if cmd with computed command names: if/elseif test in quotes} -setup {
    set a {}
} -body {
    set z if
    $z {"0 < 3"} {set a 1}
} -returnCodes error -cleanup {
    unset a z
} -result {expected boolean value but got a list}

test if-6.1 {if cmd with computed command names: "elseif" after if/elseif test} -setup {
    set a {}
} -body {
    set z if
    $z 3>4 {set a 1} elseif 1 {set a 2}
    return $a
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
    proc iftraceproc {args} {
       upvar #0 iftracecounter counter
       set argc [llength $args]
       set extraargs [lrange $args 0 [expr {$argc - 4}]]
       set name [lindex $args [expr {$argc - 3}]]
       upvar 1 $name var
       if {[incr counter] % 2 == 1} {
           set var "$counter oops [concat $extraargs]"
       } else {
           set var "$counter + [concat $extraargs]"
       }
    }
    trace add variable iftracevar read [list iftraceproc 10]
    list [catch {if "$iftracevar + 20" {}} a] $a \
        [catch {if "$iftracevar + 20" {}} b] $b
} -cleanup {
    unset iftracevar iftracecounter a b
} -match glob -result {1 {*} 0 {}}

# cleanup
::tcltest::cleanupTests
return

# Local Variables:
# mode: tcl
# fill-column: 78
# End:







|

|




|












1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
    proc iftraceproc {args} {
       upvar #0 iftracecounter counter
       set argc [llength $args]
       set extraargs [lrange $args 0 [expr {$argc - 4}]]
       set name [lindex $args [expr {$argc - 3}]]
       upvar 1 $name var
       if {[incr counter] % 2 == 1} {
	   set var "$counter oops [concat $extraargs]"
       } else {
	   set var "$counter + [concat $extraargs]"
       }
    }
    trace add variable iftracevar read [list iftraceproc 10]
    list [catch {if "$iftracevar + 20" {}} a] $a \
	[catch {if "$iftracevar + 20" {}} b] $b
} -cleanup {
    unset iftracevar iftracecounter a b
} -match glob -result {1 {*} 0 {}}

# cleanup
::tcltest::cleanupTests
return

# Local Variables:
# mode: tcl
# fill-column: 78
# End:
Changes to tests/incr-old.test.
81
82
83
84
85
86
87
88
89
90
91
92
test incr-old-2.9 {incr errors} {
    set x +
    list [catch {incr x 1} msg] $msg
} {1 {expected integer but got "+"}}
test incr-old-2.10 {incr errors} {
    set x {20 x}
    list [catch {incr x 1} msg] $msg
} {1 {expected integer but got "20 x"}}

# cleanup
::tcltest::cleanupTests
return







|




81
82
83
84
85
86
87
88
89
90
91
92
test incr-old-2.9 {incr errors} {
    set x +
    list [catch {incr x 1} msg] $msg
} {1 {expected integer but got "+"}}
test incr-old-2.10 {incr errors} {
    set x {20 x}
    list [catch {incr x 1} msg] $msg
} {1 {expected integer but got a list}}

# cleanup
::tcltest::cleanupTests
return
Changes to tests/incr.test.
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
    list [catch {incr x 1a} msg] $msg $::errorInfo
} {1 {expected integer but got "1a"} {expected integer but got "1a"
    (reading increment)
    invoked from within
"incr x 1a"}}
test incr-2.32 {incr command (compiled): bad pure list increment} {
    list [catch {incr x [list 1 2]} msg] $msg $::errorInfo
} {1 {expected integer but got "1 2"} {expected integer but got "1 2"
    (reading increment)
    invoked from within
"incr x [list 1 2]"}}
test incr-2.33 {incr command (compiled): bad pure dict increment} {
    list [catch {incr x [dict create 1 2]} msg] $msg $::errorInfo
} {1 {expected integer but got "1 2"} {expected integer but got "1 2"
    (reading increment)
    invoked from within
"incr x [dict create 1 2]"}}

test incr-3.1 {increment by wide amount: bytecode route} {
    set x 0
    incr x 123123123123







|





|







549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
    list [catch {incr x 1a} msg] $msg $::errorInfo
} {1 {expected integer but got "1a"} {expected integer but got "1a"
    (reading increment)
    invoked from within
"incr x 1a"}}
test incr-2.32 {incr command (compiled): bad pure list increment} {
    list [catch {incr x [list 1 2]} msg] $msg $::errorInfo
} {1 {expected integer but got a list} {expected integer but got a list
    (reading increment)
    invoked from within
"incr x [list 1 2]"}}
test incr-2.33 {incr command (compiled): bad pure dict increment} {
    list [catch {incr x [dict create 1 2]} msg] $msg $::errorInfo
} {1 {expected integer but got a list} {expected integer but got a list
    (reading increment)
    invoked from within
"incr x [dict create 1 2]"}}

test incr-3.1 {increment by wide amount: bytecode route} {
    set x 0
    incr x 123123123123
Changes to tests/info.test.
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
    proc t1 {a b} {set c 123; set d $c}
    t1 1 2
    info args t1
} {a b}
test info-1.7 {info args option} {
    catch {namespace delete test_ns_info2}
    namespace eval test_ns_info2 {
        namespace import ::test_ns_info1::*
        list [info args p] [info args q]
    }
} {x {y z}}

test info-2.1 {info body option} {
    proc t1 {} {body of t1}
    info body t1
} {body of t1}
test info-2.2 {info body option} -body {
    info body set
} -returnCodes error -result {"set" isn't a procedure}
test info-2.3 {info body option} -body {
    info args set 1
} -returnCodes error -result {wrong # args: should be "info args procname"}
test info-2.4 {info body option} {
    catch {namespace delete test_ns_info2}
    namespace eval test_ns_info2 {
        namespace import ::test_ns_info1::*
        list [info body p] [info body q]
    }
} {{return "x=$x"} {return "y=$y"}}
# Prior to 8.3.0 this would cause a crash because [info body]
# would return the bytecompiled version of foo, which the catch
# would then try and eval out of the foo context, accessing
# compiled local indices
test info-2.5 {info body option, returning bytecompiled bodies} -body {







|
|
















|
|







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
    proc t1 {a b} {set c 123; set d $c}
    t1 1 2
    info args t1
} {a b}
test info-1.7 {info args option} {
    catch {namespace delete test_ns_info2}
    namespace eval test_ns_info2 {
	namespace import ::test_ns_info1::*
	list [info args p] [info args q]
    }
} {x {y z}}

test info-2.1 {info body option} {
    proc t1 {} {body of t1}
    info body t1
} {body of t1}
test info-2.2 {info body option} -body {
    info body set
} -returnCodes error -result {"set" isn't a procedure}
test info-2.3 {info body option} -body {
    info args set 1
} -returnCodes error -result {wrong # args: should be "info args procname"}
test info-2.4 {info body option} {
    catch {namespace delete test_ns_info2}
    namespace eval test_ns_info2 {
	namespace import ::test_ns_info1::*
	list [info body p] [info body q]
    }
} {{return "x=$x"} {return "y=$y"}}
# Prior to 8.3.0 this would cause a crash because [info body]
# would return the bytecompiled version of foo, which the catch
# would then try and eval out of the foo context, accessing
# compiled local indices
test info-2.5 {info body option, returning bytecompiled bodies} -body {
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
} -returnCodes error -result {wrong # args: should be "info cmdcount"}

test info-4.1 {info commands option} -body {
    proc t1 {} {}
    proc t2 {} {}
    set x " [info commands] "
    list [string match {* t1 *} $x] [string match {* t2 *} $x] \
            [string match {* set *} $x] [string match {* list *} $x]
} -cleanup {unset x} -result {1 1 1 1}
test info-4.2 {info commands option} -body {
    proc t1 {} {}
    rename t1 {}
    string match {* t1 *} \
	[info comm]
} -result 0







|







128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
} -returnCodes error -result {wrong # args: should be "info cmdcount"}

test info-4.1 {info commands option} -body {
    proc t1 {} {}
    proc t2 {} {}
    set x " [info commands] "
    list [string match {* t1 *} $x] [string match {* t2 *} $x] \
	    [string match {* set *} $x] [string match {* list *} $x]
} -cleanup {unset x} -result {1 1 1 1}
test info-4.2 {info commands option} -body {
    proc t1 {} {}
    rename t1 {}
    string match {* t1 *} \
	[info comm]
} -result 0
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
    set a(0) 88
    proc t1 {{a 18} b} {}
    info default t1 a a
} -returnCodes error -result {can't set "a": variable is array}
test info-6.11 {info default option} {
    catch {namespace delete test_ns_info2}
    namespace eval test_ns_info2 {
        namespace import ::test_ns_info1::*
        list [info default p x foo] $foo [info default q y bar] $bar
    }
} {0 {} 1 27}

test info-7.1 {info exists option} -body {
    set value foo
    info exists value
} -cleanup {unset value} -result 1

test info-7.2 {info exists option} -setup {catch {unset _nonexistent_}} -body {
    info exists _nonexistent_
} -result 0
test info-7.3 {info exists option} {
    proc t1 {x} {return [info exists x]}
    t1 2
} 1
test info-7.4 {info exists option} -body {
    proc t1 {x} {
        global _nonexistent_
        return [info exists _nonexistent_]
    }
    t1 2
} -setup {unset -nocomplain _nonexistent_} -result 0
test info-7.5 {info exists option} {
    proc t1 {x} {
        set y 47
        return [info exists y]
    }
    t1 2
} 1
test info-7.6 {info exists option} {
    proc t1 {x} {return [info exists value]}
    t1 2
} 0







|
|

















|
|





|
|







225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
    set a(0) 88
    proc t1 {{a 18} b} {}
    info default t1 a a
} -returnCodes error -result {can't set "a": variable is array}
test info-6.11 {info default option} {
    catch {namespace delete test_ns_info2}
    namespace eval test_ns_info2 {
	namespace import ::test_ns_info1::*
	list [info default p x foo] $foo [info default q y bar] $bar
    }
} {0 {} 1 27}

test info-7.1 {info exists option} -body {
    set value foo
    info exists value
} -cleanup {unset value} -result 1

test info-7.2 {info exists option} -setup {catch {unset _nonexistent_}} -body {
    info exists _nonexistent_
} -result 0
test info-7.3 {info exists option} {
    proc t1 {x} {return [info exists x]}
    t1 2
} 1
test info-7.4 {info exists option} -body {
    proc t1 {x} {
	global _nonexistent_
	return [info exists _nonexistent_]
    }
    t1 2
} -setup {unset -nocomplain _nonexistent_} -result 0
test info-7.5 {info exists option} {
    proc t1 {x} {
	set y 47
	return [info exists y]
    }
    t1 2
} 1
test info-7.6 {info exists option} {
    proc t1 {x} {return [info exists value]}
    t1 2
} 0
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294

test info-8.1 {info globals option} -body {
    set x 1
    set y 2
    set value 23
    set a " [info globals] "
    list [string match {* x *} $a] [string match {* y *} $a] \
            [string match {* value *} $a] [string match {* _foobar_ *} $a]
} -cleanup {unset x y value a} -result {1 1 1 0}
test info-8.2 {info globals option} -body {
    set _xxx1 1
    set _xxx2 2
    lsort [info g _xxx*]
} -cleanup {unset _xxx1 _xxx2} -result {_xxx1 _xxx2}
test info-8.3 {info globals option} -returnCodes error -body {







|







280
281
282
283
284
285
286
287
288
289
290
291
292
293
294

test info-8.1 {info globals option} -body {
    set x 1
    set y 2
    set value 23
    set a " [info globals] "
    list [string match {* x *} $a] [string match {* y *} $a] \
	    [string match {* value *} $a] [string match {* _foobar_ *} $a]
} -cleanup {unset x y value a} -result {1 1 1 0}
test info-8.2 {info globals option} -body {
    set _xxx1 1
    set _xxx2 2
    lsort [info g _xxx*]
} -cleanup {unset _xxx1 _xxx2} -result {_xxx1 _xxx2}
test info-8.3 {info globals option} -returnCodes error -body {
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
}

test info-9.1 {info level option} {
    info level
} 0
test info-9.2 {info level option} {
    proc t1 {a b} {
        set x [info le]
        set y [info level 1]
        list $x $y
    }
    t1 146 testString
} {1 {t1 146 testString}}
test info-9.3 {info level option} {
    proc t1 {a b} {
        t2 [expr {$a*2}] $b
    }
    proc t2 {x y} {
        list [info level] [info level 1] [info level 2] [info level -1] \
                [info level 0]
    }
    t1 146 {a {b c} {{{c}}}}
} {2 {t1 146 {a {b c} {{{c}}}}} {t2 292 {a {b c} {{{c}}}}} {t1 146 {a {b c} {{{c}}}}} {t2 292 {a {b c} {{{c}}}}}}
test info-9.4 {info level option} {
    proc t1 {} {
        set x [info level]
        set y [info level 1]
        list $x $y
    }
    t1
} {1 t1}
test info-9.5 {info level option} -body {
    info level 1 2
} -returnCodes error -result {wrong # args: should be "info level ?number?"}
test info-9.6 {info level option} -body {







|
|
|





|


|
|





|
|
|







313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
}

test info-9.1 {info level option} {
    info level
} 0
test info-9.2 {info level option} {
    proc t1 {a b} {
	set x [info le]
	set y [info level 1]
	list $x $y
    }
    t1 146 testString
} {1 {t1 146 testString}}
test info-9.3 {info level option} {
    proc t1 {a b} {
	t2 [expr {$a*2}] $b
    }
    proc t2 {x y} {
	list [info level] [info level 1] [info level 2] [info level -1] \
		[info level 0]
    }
    t1 146 {a {b c} {{{c}}}}
} {2 {t1 146 {a {b c} {{{c}}}}} {t2 292 {a {b c} {{{c}}}}} {t1 146 {a {b c} {{{c}}}}} {t2 292 {a {b c} {{{c}}}}}}
test info-9.4 {info level option} {
    proc t1 {} {
	set x [info level]
	set y [info level 1]
	list $x $y
    }
    t1
} {1 t1}
test info-9.5 {info level option} -body {
    info level 1 2
} -returnCodes error -result {wrong # args: should be "info level ?number?"}
test info-9.6 {info level option} -body {
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
test info-11.2 {info loaded option} -body {
    info loaded {}; info loaded gorp
} -returnCodes error -result {could not find interpreter "gorp"}

test info-12.1 {info locals option} -body {
    set a 22
    proc t1 {x y} {
        set b 13
        set c testing
        global a
	global aa
	set aa 23
        return [info locals]
    }
    lsort [t1 23 24]
} -cleanup {unset a aa} -result {b c x y}
test info-12.2 {info locals option} {
    proc t1 {x y} {
        set xx1 2
        set xx2 3
        set y 4
        return [info loc x*]
    }
    lsort [t1 2 3]
} {x xx1 xx2}
test info-12.3 {info locals option} -body {
    info locals 1 2
} -returnCodes error -result {wrong # args: should be "info locals ?pattern?"}
test info-12.4 {info locals option} {
    info locals
} {}
test info-12.5 {info locals option} {
    proc t1 {} {return [info locals]}
    t1
} {}
test info-12.6 {info locals vs unset compiled locals} {
    proc t1 {lst} {
        foreach $lst $lst {}
        unset lst
        return [info locals]
    }
    lsort [t1 {a b c c d e f}]
} {a b c d e f}
test info-12.7 {info locals with temporary variables} {
    proc t1 {} {
        foreach a {b c} {}
        info locals
    }
    t1
} {a}

test info-13.1 {info nameofexecutable option} -returnCodes error -body {
    info nameofexecutable foo
} -result {wrong # args: should be "info nameofexecutable"}







|
|
|


|





|
|
|
|















|
|
|





|
|







402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
test info-11.2 {info loaded option} -body {
    info loaded {}; info loaded gorp
} -returnCodes error -result {could not find interpreter "gorp"}

test info-12.1 {info locals option} -body {
    set a 22
    proc t1 {x y} {
	set b 13
	set c testing
	global a
	global aa
	set aa 23
	return [info locals]
    }
    lsort [t1 23 24]
} -cleanup {unset a aa} -result {b c x y}
test info-12.2 {info locals option} {
    proc t1 {x y} {
	set xx1 2
	set xx2 3
	set y 4
	return [info loc x*]
    }
    lsort [t1 2 3]
} {x xx1 xx2}
test info-12.3 {info locals option} -body {
    info locals 1 2
} -returnCodes error -result {wrong # args: should be "info locals ?pattern?"}
test info-12.4 {info locals option} {
    info locals
} {}
test info-12.5 {info locals option} {
    proc t1 {} {return [info locals]}
    t1
} {}
test info-12.6 {info locals vs unset compiled locals} {
    proc t1 {lst} {
	foreach $lst $lst {}
	unset lst
	return [info locals]
    }
    lsort [t1 {a b c c d e f}]
} {a b c d e f}
test info-12.7 {info locals with temporary variables} {
    proc t1 {} {
	foreach a {b c} {}
	info locals
    }
    t1
} {a}

test info-13.1 {info nameofexecutable option} -returnCodes error -body {
    info nameofexecutable foo
} -result {wrong # args: should be "info nameofexecutable"}
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
} -returnCodes error -result {can't read "tcl_patchLevel": no such variable}

test info-15.1 {info procs option} -body {
    proc t1 {} {}
    proc t2 {} {}
    set x " [info procs] "
    list [string match {* t1 *} $x] [string match {* t2 *} $x] \
            [string match {* _undefined_ *} $x]
} -cleanup {unset x} -result {1 1 0}
test info-15.2 {info procs option} {
    proc _tt1 {} {}
    proc _tt2 {} {}
    lsort [info pr _tt*]
} {_tt1 _tt2}
catch {rename _tt1 {}}
catch {rename _tt2 {}}
test info-15.3 {info procs option} -body {
    info procs 2 3
} -returnCodes error -result {wrong # args: should be "info procs ?pattern?"}
test info-15.4 {info procs option} -setup {
    catch {namespace delete test_ns_info2}
} -body {
    namespace eval test_ns_info2 {
        namespace import ::test_ns_info1::*
        proc r {} {}
        list [lsort [info procs]] [info procs p*]
    }
} -result {{p q r} p}
test info-15.5 {info procs option with a proc in a namespace} -setup {
    catch {namespace delete test_ns_info2}
} -body {
    namespace eval test_ns_info2 {
	proc p1 { arg } {
	    puts cmd
	}
        proc p2 { arg } {
	    puts cmd
	}
    }
    info procs ::test_ns_info2::p1
} -result {::test_ns_info2::p1}
test info-15.6 {info procs option with a pattern in a namespace} -setup {
    catch {namespace delete test_ns_info2}
} -body {
    namespace eval test_ns_info2 {
	proc p1 { arg } {
	    puts cmd
	}
        proc p2 { arg } {
	    puts cmd
	}
    }
    lsort [info procs ::test_ns_info2::p*]
} -result [lsort [list ::test_ns_info2::p1 ::test_ns_info2::p2]]
test info-15.7 {info procs option with a global shadowing proc} -setup {
    catch {namespace delete test_ns_info2}
} -body {
    proc string_cmd { arg } {
        puts cmd
    }
    namespace eval test_ns_info2 {
	proc string_cmd { arg } {
	    puts cmd
	}
    }
    info procs test_ns_info2::string*
} -result {::test_ns_info2::string_cmd}
# This regression test is currently commented out because it requires
# that the implementation of "info procs" looks into the global namespace,
# which it does not (in contrast to "info commands")
test info-15.8 {info procs option with a global shadowing proc} -setup {
    catch {namespace delete test_ns_info2}
} -constraints knownBug -body {
    proc string_cmd { arg } {
        puts cmd
    }
    proc string_cmd2 { arg } {
        puts cmd
    }
    namespace eval test_ns_info2 {
	proc string_cmd { arg } {
	    puts cmd
	}
    }
    namespace eval test_ns_info2 {
        lsort [info procs string*]
    }
} -result [lsort [list string_cmd string_cmd2]]

test info-16.1 {info script option} -returnCodes error -body {
    info script x x
} -result {wrong # args: should be "info script ?filename?"}
test info-16.2 {info script option} {







|















|
|
|









|












|









|















|


|







|







471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
} -returnCodes error -result {can't read "tcl_patchLevel": no such variable}

test info-15.1 {info procs option} -body {
    proc t1 {} {}
    proc t2 {} {}
    set x " [info procs] "
    list [string match {* t1 *} $x] [string match {* t2 *} $x] \
	    [string match {* _undefined_ *} $x]
} -cleanup {unset x} -result {1 1 0}
test info-15.2 {info procs option} {
    proc _tt1 {} {}
    proc _tt2 {} {}
    lsort [info pr _tt*]
} {_tt1 _tt2}
catch {rename _tt1 {}}
catch {rename _tt2 {}}
test info-15.3 {info procs option} -body {
    info procs 2 3
} -returnCodes error -result {wrong # args: should be "info procs ?pattern?"}
test info-15.4 {info procs option} -setup {
    catch {namespace delete test_ns_info2}
} -body {
    namespace eval test_ns_info2 {
	namespace import ::test_ns_info1::*
	proc r {} {}
	list [lsort [info procs]] [info procs p*]
    }
} -result {{p q r} p}
test info-15.5 {info procs option with a proc in a namespace} -setup {
    catch {namespace delete test_ns_info2}
} -body {
    namespace eval test_ns_info2 {
	proc p1 { arg } {
	    puts cmd
	}
	proc p2 { arg } {
	    puts cmd
	}
    }
    info procs ::test_ns_info2::p1
} -result {::test_ns_info2::p1}
test info-15.6 {info procs option with a pattern in a namespace} -setup {
    catch {namespace delete test_ns_info2}
} -body {
    namespace eval test_ns_info2 {
	proc p1 { arg } {
	    puts cmd
	}
	proc p2 { arg } {
	    puts cmd
	}
    }
    lsort [info procs ::test_ns_info2::p*]
} -result [lsort [list ::test_ns_info2::p1 ::test_ns_info2::p2]]
test info-15.7 {info procs option with a global shadowing proc} -setup {
    catch {namespace delete test_ns_info2}
} -body {
    proc string_cmd { arg } {
	puts cmd
    }
    namespace eval test_ns_info2 {
	proc string_cmd { arg } {
	    puts cmd
	}
    }
    info procs test_ns_info2::string*
} -result {::test_ns_info2::string_cmd}
# This regression test is currently commented out because it requires
# that the implementation of "info procs" looks into the global namespace,
# which it does not (in contrast to "info commands")
test info-15.8 {info procs option with a global shadowing proc} -setup {
    catch {namespace delete test_ns_info2}
} -constraints knownBug -body {
    proc string_cmd { arg } {
	puts cmd
    }
    proc string_cmd2 { arg } {
	puts cmd
    }
    namespace eval test_ns_info2 {
	proc string_cmd { arg } {
	    puts cmd
	}
    }
    namespace eval test_ns_info2 {
	lsort [info procs string*]
    }
} -result [lsort [list string_cmd string_cmd2]]

test info-16.1 {info script option} -returnCodes error -body {
    info script x x
} -result {wrong # args: should be "info script ?filename?"}
test info-16.2 {info script option} {
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
    set tcl_version $t; unset t
} -result {can't read "tcl_version": no such variable}

test info-19.1 {info vars option} -body {
    set a 1
    set b 2
    proc t1 {x y} {
        global a b
        set c 33
        return [info vars]
    }
    lsort [t1 18 19]
} -cleanup {unset a b} -result {a b c x y}
test info-19.2 {info vars option} -body {
    set xxx1 1
    set xxx2 2
    proc t1 {xxa y} {
        global xxx1 xxx2
        set c 33
        return [info vars x*]
    }
    lsort [t1 18 19]
} -cleanup {unset xxx1 xxx2} -result {xxa xxx1 xxx2}
test info-19.3 {info vars option} {
    lsort [info vars]
} [lsort [info globals]]
test info-19.4 {info vars option} -returnCodes error -body {
    info vars a b
} -result {wrong # args: should be "info vars ?pattern?"}
test info-19.5 {info vars with temporary variables} {
    proc t1 {} {
        foreach a {b c} {}
        info vars
    }
    t1
} {a}
test info-19.6 {info vars: Bug 1072654} -setup {
    namespace eval :: unset -nocomplain foo
    catch {namespace delete x}
} -body {







|
|
|







|
|
|











|
|







613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
    set tcl_version $t; unset t
} -result {can't read "tcl_version": no such variable}

test info-19.1 {info vars option} -body {
    set a 1
    set b 2
    proc t1 {x y} {
	global a b
	set c 33
	return [info vars]
    }
    lsort [t1 18 19]
} -cleanup {unset a b} -result {a b c x y}
test info-19.2 {info vars option} -body {
    set xxx1 1
    set xxx2 2
    proc t1 {xxa y} {
	global xxx1 xxx2
	set c 33
	return [info vars x*]
    }
    lsort [t1 18 19]
} -cleanup {unset xxx1 xxx2} -result {xxa xxx1 xxx2}
test info-19.3 {info vars option} {
    lsort [info vars]
} [lsort [info globals]]
test info-19.4 {info vars option} -returnCodes error -body {
    info vars a b
} -result {wrong # args: should be "info vars ?pattern?"}
test info-19.5 {info vars with temporary variables} {
    proc t1 {} {
	foreach a {b c} {}
	info vars
    }
    t1
} {a}
test info-19.6 {info vars: Bug 1072654} -setup {
    namespace eval :: unset -nocomplain foo
    catch {namespace delete x}
} -body {
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
} {
type source line 1587 file info.test cmd {info frame 0} proc ::a level 0
type source line 1589 file info.test cmd {info frame 0} proc ::a level 0}

test info-30.17 {bs+nl in multi-body switch, direct} {
    switch -regexp -- {key    } \
	^key     { reduce [info frame 0] ;# 1601 } \
        \t###    { } \
        {[0-9]*} { }
} {type source line 1601 file info.test cmd {info frame 0} proc ::tcltest::RunTest}

test info-30.18 {bs+nl, literal word, uplevel through proc, appended, loss of primary tracking data} {
    proc abra {script} {
	append script "\n# end of script"
	uplevel 1 $script
    }







|
|







1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
} {
type source line 1587 file info.test cmd {info frame 0} proc ::a level 0
type source line 1589 file info.test cmd {info frame 0} proc ::a level 0}

test info-30.17 {bs+nl in multi-body switch, direct} {
    switch -regexp -- {key    } \
	^key     { reduce [info frame 0] ;# 1601 } \
	\t###    { } \
	{[0-9]*} { }
} {type source line 1601 file info.test cmd {info frame 0} proc ::tcltest::RunTest}

test info-30.18 {bs+nl, literal word, uplevel through proc, appended, loss of primary tracking data} {
    proc abra {script} {
	append script "\n# end of script"
	uplevel 1 $script
    }
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652

test info-30.20 {bs+nl in single-body switch, direct} {
    switch -regexp -- {key    } { \

	^key     { reduce \
		       [info frame 0] }
	\t###    { }
        {[0-9]*} { }
    }
} {type source line 1643 file info.test cmd {info frame 0} proc ::tcltest::RunTest}

test info-30.21 {bs+nl in if, full compiled} {
    proc a {value} {
	if {$value} \
	    {info frame 0} \







|







1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652

test info-30.20 {bs+nl in single-body switch, direct} {
    switch -regexp -- {key    } { \

	^key     { reduce \
		       [info frame 0] }
	\t###    { }
	{[0-9]*} { }
    }
} {type source line 1643 file info.test cmd {info frame 0} proc ::tcltest::RunTest}

test info-30.21 {bs+nl in if, full compiled} {
    proc a {value} {
	if {$value} \
	    {info frame 0} \
Changes to tests/init.test.
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
    tcl:::HistAdd
} -returnCodes error -cleanup {
    rename ::tcl::HistAdd {}
} -result {wrong # args: should be "tcl:::HistAdd event ?exec?"}

test init-3.0 {random stuff in the auto_index, should still work} {
    set auto_index(foo:::bar::blah) {
        namespace eval foo {namespace eval bar {proc blah {} {return 1}}}
    }
    foo:::bar::blah
} 1

# Tests that compare the error stack trace generated when autoloading with
# that generated when no autoloading is necessary.  Ideally they should be the
# same.

set count 0
foreach arg [subst -nocommands -novariables {
    c
    {argument
                which spans
                multiple lines}
    {argument which is all on one line but which is of such great length that the Tcl C library will truncate it when appending it onto the global error stack}
    {argument which spans multiple lines
                and is long enough to be truncated and
"               <- includes a false lead in the prune point search
                and must be longer still to force truncation}
                {contrived example: rare circumstance
		where the point at which to prune the
		error stack cannot be uniquely determined.
		foo bar foo
"}
    {contrived example: rare circumstance
		where the point at which to prune the
		error stack cannot be uniquely determined.







|












|
|


|

|
|







121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
    tcl:::HistAdd
} -returnCodes error -cleanup {
    rename ::tcl::HistAdd {}
} -result {wrong # args: should be "tcl:::HistAdd event ?exec?"}

test init-3.0 {random stuff in the auto_index, should still work} {
    set auto_index(foo:::bar::blah) {
	namespace eval foo {namespace eval bar {proc blah {} {return 1}}}
    }
    foo:::bar::blah
} 1

# Tests that compare the error stack trace generated when autoloading with
# that generated when no autoloading is necessary.  Ideally they should be the
# same.

set count 0
foreach arg [subst -nocommands -novariables {
    c
    {argument
		which spans
		multiple lines}
    {argument which is all on one line but which is of such great length that the Tcl C library will truncate it when appending it onto the global error stack}
    {argument which spans multiple lines
		and is long enough to be truncated and
"               <- includes a false lead in the prune point search
		and must be longer still to force truncation}
		{contrived example: rare circumstance
		where the point at which to prune the
		error stack cannot be uniquely determined.
		foo bar foo
"}
    {contrived example: rare circumstance
		where the point at which to prune the
		error stack cannot be uniquely determined.
Changes to tests/internals.tcl.
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
	set result
    } result opt]
    if {$pipe ne ""} { catch { close $pipe } }
    if {$ret && [dict get $opt -errorcode] eq "BYPASS-SKIPPED-TEST"} {
	return {*}$opt $result
    }
    if { ( [info exists in(-warn-on-code)] && $ret in $in(-warn-on-code) )
      || ( $ret && [info exists in(-warn-on-alloc-error)] && $in(-warn-on-alloc-error)
      	    && [regexp {\munable to (?:re)?alloc\M} $result] )
    } {
	tcltest::Warn "testWithLimit: wrong limit, result: $result"
	tcltest::Skip testWithLimit
    }
    return {*}$opt $result
}








|
|







74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
	set result
    } result opt]
    if {$pipe ne ""} { catch { close $pipe } }
    if {$ret && [dict get $opt -errorcode] eq "BYPASS-SKIPPED-TEST"} {
	return {*}$opt $result
    }
    if { ( [info exists in(-warn-on-code)] && $ret in $in(-warn-on-code) )
	|| ( $ret && [info exists in(-warn-on-alloc-error)] && $in(-warn-on-alloc-error)
	&& [regexp {\munable to (?:re)?alloc\M} $result] )
    } {
	tcltest::Warn "testWithLimit: wrong limit, result: $result"
	tcltest::Skip testWithLimit
    }
    return {*}$opt $result
}

Changes to tests/interp.test.
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
    interp delete a
    list $r $msg
} {0 91}
test interp-20.45 {interp hide vs namespaces} {
    catch {interp delete a}
    interp create a
    a eval {
        namespace eval foo {}
	proc foo::x {} {}
    }
    set l [list [catch {interp hide a foo::x} msg] $msg]
    interp delete a
    set l
} {1 {cannot use namespace qualifiers in hidden command token (rename)}}
test interp-20.46 {interp hide vs namespaces} {
    catch {interp delete a}
    interp create a
    a eval {
        namespace eval foo {}
	proc foo::x {} {}
    }
    set l [list [catch {interp hide a foo::x x} msg] $msg]
    interp delete a
    set l
} {1 {can only hide global namespace commands (use rename then hide)}}
test interp-20.47 {interp hide vs namespaces} {
    catch {interp delete a}
    interp create a
    a eval {
	proc x {} {}
    }
    set l [list [catch {interp hide a x foo::x} msg] $msg]
    interp delete a
    set l
} {1 {cannot use namespace qualifiers in hidden command token (rename)}}
test interp-20.48 {interp hide vs namespaces} {
    catch {interp delete a}
    interp create a
    a eval {
        namespace eval foo {}
	proc foo::x {} {}
    }
    set l [list [catch {interp hide a foo::x bar::x} msg] $msg]
    interp delete a
    set l
} {1 {cannot use namespace qualifiers in hidden command token (rename)}}
test interp-20.49 {interp invokehidden -namespace} -setup {







|










|




















|







1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
    interp delete a
    list $r $msg
} {0 91}
test interp-20.45 {interp hide vs namespaces} {
    catch {interp delete a}
    interp create a
    a eval {
	namespace eval foo {}
	proc foo::x {} {}
    }
    set l [list [catch {interp hide a foo::x} msg] $msg]
    interp delete a
    set l
} {1 {cannot use namespace qualifiers in hidden command token (rename)}}
test interp-20.46 {interp hide vs namespaces} {
    catch {interp delete a}
    interp create a
    a eval {
	namespace eval foo {}
	proc foo::x {} {}
    }
    set l [list [catch {interp hide a foo::x x} msg] $msg]
    interp delete a
    set l
} {1 {can only hide global namespace commands (use rename then hide)}}
test interp-20.47 {interp hide vs namespaces} {
    catch {interp delete a}
    interp create a
    a eval {
	proc x {} {}
    }
    set l [list [catch {interp hide a x foo::x} msg] $msg]
    interp delete a
    set l
} {1 {cannot use namespace qualifiers in hidden command token (rename)}}
test interp-20.48 {interp hide vs namespaces} {
    catch {interp delete a}
    interp create a
    a eval {
	namespace eval foo {}
	proc foo::x {} {}
    }
    set l [list [catch {interp hide a foo::x bar::x} msg] $msg]
    interp delete a
    set l
} {1 {cannot use namespace qualifiers in hidden command token (rename)}}
test interp-20.49 {interp invokehidden -namespace} -setup {
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
    proc MyTestAlias {interp args} {
	global aliasTrace
	lappend aliasTrace $args
	interp invokehidden $interp {*}$args
    }
    foreach c {return} {
	interp hide $interp  $c
        interp alias $interp $c {} MyTestAlias $interp $c
    }
    interp eval $interp {proc ret {code} {return -code $code ret$code}}
    set res {}
    set aliasTrace {}
    for {set code -1} {$code<=5} {incr code} {
	lappend res [catch {interp eval $interp ret $code} msg] $msg
    }







|







2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
    proc MyTestAlias {interp args} {
	global aliasTrace
	lappend aliasTrace $args
	interp invokehidden $interp {*}$args
    }
    foreach c {return} {
	interp hide $interp  $c
	interp alias $interp $c {} MyTestAlias $interp $c
    }
    interp eval $interp {proc ret {code} {return -code $code ret$code}}
    set res {}
    set aliasTrace {}
    for {set code -1} {$code<=5} {incr code} {
	lappend res [catch {interp eval $interp ret $code} msg] $msg
    }
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377

test interp-28.1 {getting fooled by child's namespace ?} -setup {
    set i [interp create -safe]
    proc parent {interp args} {interp hide $interp list}
} -body {
    $i alias parent parent $i
    set r [interp eval $i {
        namespace eval foo {
	    proc list {args} {
		return "dummy foo::list"
	    }
	    parent
	}
	info commands list
    }]







|







2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377

test interp-28.1 {getting fooled by child's namespace ?} -setup {
    set i [interp create -safe]
    proc parent {interp args} {interp hide $interp list}
} -body {
    $i alias parent parent $i
    set r [interp eval $i {
	namespace eval foo {
	    proc list {args} {
		return "dummy foo::list"
	    }
	    parent
	}
	info commands list
    }]
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
    }]
   interp delete $i
   set r
} {1 {too many nested evaluations (infinite loop?)} 49}
test interp-29.3.4 {recursion limit error reporting} {
    interp create child
    set r1 [child eval {
        catch { 		# nesting level 1
	    eval {		# 2
	        eval {		# 3
		    eval {	# 4
		        eval {	# 5
			     interp recursionlimit {} 5
			     set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {1 {falling back due to new recursion limit}}
test interp-29.3.5 {recursion limit error reporting} {
    interp create child
    set r1 [child eval {
        catch {			# nesting level 1
	    eval {		# 2
	        eval {		# 3
		    eval {	# 4
		        eval {	# 5
			    interp recursionlimit {} 4
			    set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {1 {falling back due to new recursion limit}}
test interp-29.3.6 {recursion limit error reporting} {
    interp create child
    set r1 [child eval {
        catch {			# nesting level 1
	    eval {		# 2
	        eval {		# 3
		    eval {	# 4
		        eval {	# 5
			    interp recursionlimit {} 6
			    set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {0 ok}
#
# Note that TEBC does not verify the interp's nesting level itself; the nesting
# level will only be verified when it invokes a non-bcc'd command.
#
test interp-29.3.7a {recursion limit error reporting} {
    interp create child
    after 0 {interp recursionlimit child 5}
    set r1 [child eval {
        catch { 		# nesting level 1
	    eval {		# 2
	        eval {		# 3
		    eval {	# 4
		        eval {	# 5
			    update
			    set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {0 ok}
test interp-29.3.7b {recursion limit error reporting} {
    interp create child
    after 0 {interp recursionlimit child 5}
    set r1 [child eval {
        catch { 		# nesting level 1
	    eval {		# 2
	        eval {		# 3
		    eval {	# 4
			update
		        eval {	# 5
			    set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {0 ok}
test interp-29.3.7c {recursion limit error reporting} {
    interp create child
    after 0 {interp recursionlimit child 5}
    set r1 [child eval {
        catch { 		# nesting level 1
	    eval {		# 2
	        eval {		# 3
		    eval {	# 4
		        eval {	# 5
			    update
			    set set set
			    $set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {1 {too many nested evaluations (infinite loop?)}}
test interp-29.3.8a {recursion limit error reporting} {
    interp create child
    after 0 {interp recursionlimit child 4}
    set r1 [child eval {
        catch { 		# nesting level 1
	    eval {		# 2
	        eval {		# 3
		    eval {	# 4
		        eval {	# 5
			    update
			    set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {0 ok}
test interp-29.3.8b {recursion limit error reporting} {
    interp create child
    after 0 {interp recursionlimit child 4}
    set r1 [child eval {
        catch { 		# nesting level 1
	    eval {		# 2
	        eval {		# 3
		    eval {	# 4
			update
		        eval {	# 5
			    set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {1 {too many nested evaluations (infinite loop?)}}
test interp-29.3.9a {recursion limit error reporting} {
    interp create child
    after 0 {interp recursionlimit child 6}
    set r1 [child eval {
        catch { 		# nesting level 1
	    eval {		# 2
	        eval {		# 3
		    eval {	# 4
		        eval {	# 5
			    update
			    set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {0 ok}
test interp-29.3.9b {recursion limit error reporting} {
    interp create child
    after 0 {interp recursionlimit child 6}
    set r1 [child eval {
        catch { 		# nesting level 1
	    eval {		# 2
	        eval {		# 3
		    eval {	# 4
		        eval {	# 5
			    set set set
			    $set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {0 ok}
test interp-29.3.10a {recursion limit error reporting} {
    interp create child
    after 0 {child recursionlimit 4}
    set r1 [child eval {
        catch { 		# nesting level 1
	    eval {		# 2
	        eval {		# 3
		    eval {	# 4
		        eval {	# 5
			     update
			     set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {0 ok}
test interp-29.3.10b {recursion limit error reporting} {
    interp create child
    after 0 {child recursionlimit 4}
    set r1 [child eval {
        catch { 		# nesting level 1
	    eval {		# 2
	        eval {		# 3
		    eval {	# 4
			update
		        eval {	# 5
			    set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {1 {too many nested evaluations (infinite loop?)}}
test interp-29.3.11a {recursion limit error reporting} {
    interp create child
    after 0 {child recursionlimit 5}
    set r1 [child eval {
        catch { 		# nesting level 1
	    eval {		# 2
	        eval {		# 3
		    eval {	# 4
		        eval {	# 5
			    update
			    set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {0 ok}
test interp-29.3.11b {recursion limit error reporting} {
    interp create child
    after 0 {child recursionlimit 5}
    set r1 [child eval {
        catch { 		# nesting level 1
	    eval {		# 2
	        eval {		# 3
		    eval {	# 4
		        eval {	# 5
			    update
			    set set set
			    $set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {1 {too many nested evaluations (infinite loop?)}}
test interp-29.3.12a {recursion limit error reporting} {
    interp create child
    after 0 {child recursionlimit 6}
    set r1 [child eval {
        catch { 		# nesting level 1
	    eval {		# 2
	        eval {		# 3
		    eval {	# 4
		        eval {	# 5
			    update
			    set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {0 ok}
test interp-29.3.12b {recursion limit error reporting} {
    interp create child
    after 0 {child recursionlimit 6}
    set r1 [child eval {
        catch { 		# nesting level 1
	    eval {		# 2
	        eval {		# 3
		    eval {	# 4
		        eval {	# 5
			    update
			    set set set
			    $set x ok
			}
		    }
		}
	    }







|

|

|















|

|

|















|

|

|




















|

|

|
















|

|


|















|

|

|

















|

|

|
















|

|


|















|

|

|
















|

|

|
















|

|

|
















|

|


|















|

|

|
















|

|

|

















|

|

|
















|

|

|







2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
    }]
   interp delete $i
   set r
} {1 {too many nested evaluations (infinite loop?)} 49}
test interp-29.3.4 {recursion limit error reporting} {
    interp create child
    set r1 [child eval {
	catch {			# nesting level 1
	    eval {		# 2
		eval {		# 3
		    eval {	# 4
			eval {	# 5
			     interp recursionlimit {} 5
			     set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {1 {falling back due to new recursion limit}}
test interp-29.3.5 {recursion limit error reporting} {
    interp create child
    set r1 [child eval {
	catch {			# nesting level 1
	    eval {		# 2
		eval {		# 3
		    eval {	# 4
			eval {	# 5
			    interp recursionlimit {} 4
			    set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {1 {falling back due to new recursion limit}}
test interp-29.3.6 {recursion limit error reporting} {
    interp create child
    set r1 [child eval {
	catch {			# nesting level 1
	    eval {		# 2
		eval {		# 3
		    eval {	# 4
			eval {	# 5
			    interp recursionlimit {} 6
			    set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {0 ok}
#
# Note that TEBC does not verify the interp's nesting level itself; the nesting
# level will only be verified when it invokes a non-bcc'd command.
#
test interp-29.3.7a {recursion limit error reporting} {
    interp create child
    after 0 {interp recursionlimit child 5}
    set r1 [child eval {
	catch {			# nesting level 1
	    eval {		# 2
		eval {		# 3
		    eval {	# 4
			eval {	# 5
			    update
			    set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {0 ok}
test interp-29.3.7b {recursion limit error reporting} {
    interp create child
    after 0 {interp recursionlimit child 5}
    set r1 [child eval {
	catch {			# nesting level 1
	    eval {		# 2
		eval {		# 3
		    eval {	# 4
			update
			eval {	# 5
			    set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {0 ok}
test interp-29.3.7c {recursion limit error reporting} {
    interp create child
    after 0 {interp recursionlimit child 5}
    set r1 [child eval {
	catch {			# nesting level 1
	    eval {		# 2
		eval {		# 3
		    eval {	# 4
			eval {	# 5
			    update
			    set set set
			    $set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {1 {too many nested evaluations (infinite loop?)}}
test interp-29.3.8a {recursion limit error reporting} {
    interp create child
    after 0 {interp recursionlimit child 4}
    set r1 [child eval {
	catch {			# nesting level 1
	    eval {		# 2
		eval {		# 3
		    eval {	# 4
			eval {	# 5
			    update
			    set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {0 ok}
test interp-29.3.8b {recursion limit error reporting} {
    interp create child
    after 0 {interp recursionlimit child 4}
    set r1 [child eval {
	catch {			# nesting level 1
	    eval {		# 2
		eval {		# 3
		    eval {	# 4
			update
			eval {	# 5
			    set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {1 {too many nested evaluations (infinite loop?)}}
test interp-29.3.9a {recursion limit error reporting} {
    interp create child
    after 0 {interp recursionlimit child 6}
    set r1 [child eval {
	catch {			# nesting level 1
	    eval {		# 2
		eval {		# 3
		    eval {	# 4
			eval {	# 5
			    update
			    set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {0 ok}
test interp-29.3.9b {recursion limit error reporting} {
    interp create child
    after 0 {interp recursionlimit child 6}
    set r1 [child eval {
	catch {			# nesting level 1
	    eval {		# 2
		eval {		# 3
		    eval {	# 4
			eval {	# 5
			    set set set
			    $set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {0 ok}
test interp-29.3.10a {recursion limit error reporting} {
    interp create child
    after 0 {child recursionlimit 4}
    set r1 [child eval {
	catch {			# nesting level 1
	    eval {		# 2
		eval {		# 3
		    eval {	# 4
			eval {	# 5
			     update
			     set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {0 ok}
test interp-29.3.10b {recursion limit error reporting} {
    interp create child
    after 0 {child recursionlimit 4}
    set r1 [child eval {
	catch {			# nesting level 1
	    eval {		# 2
		eval {		# 3
		    eval {	# 4
			update
			eval {	# 5
			    set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {1 {too many nested evaluations (infinite loop?)}}
test interp-29.3.11a {recursion limit error reporting} {
    interp create child
    after 0 {child recursionlimit 5}
    set r1 [child eval {
	catch {			# nesting level 1
	    eval {		# 2
		eval {		# 3
		    eval {	# 4
			eval {	# 5
			    update
			    set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {0 ok}
test interp-29.3.11b {recursion limit error reporting} {
    interp create child
    after 0 {child recursionlimit 5}
    set r1 [child eval {
	catch {			# nesting level 1
	    eval {		# 2
		eval {		# 3
		    eval {	# 4
			eval {	# 5
			    update
			    set set set
			    $set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {1 {too many nested evaluations (infinite loop?)}}
test interp-29.3.12a {recursion limit error reporting} {
    interp create child
    after 0 {child recursionlimit 6}
    set r1 [child eval {
	catch {			# nesting level 1
	    eval {		# 2
		eval {		# 3
		    eval {	# 4
			eval {	# 5
			    update
			    set x ok
			}
		    }
		}
	    }
	} msg
    }]
    set r2 [child eval { set msg }]
    interp delete child
    list $r1 $r2
} {0 ok}
test interp-29.3.12b {recursion limit error reporting} {
    interp create child
    after 0 {child recursionlimit 6}
    set r1 [child eval {
	catch {			# nesting level 1
	    eval {		# 2
		eval {		# 3
		    eval {	# 4
			eval {	# 5
			    update
			    set set set
			    $set x ok
			}
		    }
		}
	    }
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
} {1 {permission denied: safe interpreters cannot change recursion limit}}
test interp-29.6.9 {safe interpreter recursion limit} {
    interp create child -safe
    set result [
	child eval {
	    interp create child2 -safe
	    set n [catch {
	        interp recursionlimit child2 42
            } msg]
            list $n $msg
        }
    ]
    interp delete child
    set result
} {1 {permission denied: safe interpreters cannot change recursion limit}}
test interp-29.6.10 {safe interpreter recursion limit} {
    interp create child -safe
    set result [
        child eval {
	    interp create child2 -safe
	    set n [catch {
	        child2 recursionlimit 42
            } msg]
            list $n $msg
        }
    ]
    interp delete child
    set result
} {1 {permission denied: safe interpreters cannot change recursion limit}}


#    # Deep recursion (into interps when the regular one fails):







|
|
|
|







|


|
|
|
|







3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
} {1 {permission denied: safe interpreters cannot change recursion limit}}
test interp-29.6.9 {safe interpreter recursion limit} {
    interp create child -safe
    set result [
	child eval {
	    interp create child2 -safe
	    set n [catch {
		interp recursionlimit child2 42
	    } msg]
	    list $n $msg
	}
    ]
    interp delete child
    set result
} {1 {permission denied: safe interpreters cannot change recursion limit}}
test interp-29.6.10 {safe interpreter recursion limit} {
    interp create child -safe
    set result [
	child eval {
	    interp create child2 -safe
	    set n [catch {
		child2 recursionlimit 42
	    } msg]
	    list $n $msg
	}
    ]
    interp delete child
    set result
} {1 {permission denied: safe interpreters cannot change recursion limit}}


#    # Deep recursion (into interps when the regular one fails):
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
    lappend parent [pwd]
    set i [interp create]
    lappend child [$i eval pwd]
    cd ..
    file delete cwd_test
    interp delete $i
    expr {[string equal $parent $child] ? 1 :
             "\{$parent\} != \{$child\}"}
} -cleanup {
    cd [workingDirectory]
} -result 1

test interp-33.1 {refCounting for target words of alias [Bug 730244]} {
    # This test will panic if Bug 730244 is not fixed.
    set i [interp create]







|







3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
    lappend parent [pwd]
    set i [interp create]
    lappend child [$i eval pwd]
    cd ..
    file delete cwd_test
    interp delete $i
    expr {[string equal $parent $child] ? 1 :
	     "\{$parent\} != \{$child\}"}
} -cleanup {
    cd [workingDirectory]
} -result 1

test interp-33.1 {refCounting for target words of alias [Bug 730244]} {
    # This test will panic if Bug 730244 is not fixed.
    set i [interp create]
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
} -result {foo bar soom}
test interp-36.7 {ChildBgerror sets error handler of child [1999035]} -setup {
    interp create child
    child alias handler handler
    child bgerror handler
    variable result {untouched}
    proc handler {args} {
        variable result
        set result [lindex $args 0]
    }
} -body {
    child eval {
        variable done {}
        after 0 error foo
        after 10 [list ::set [namespace which -variable done] {}]
        vwait [namespace which -variable done]
    }
    set result
} -cleanup {
    variable result {}
    unset -nocomplain result
    interp delete child
} -result foo







|
|



|
|
|
|







3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
} -result {foo bar soom}
test interp-36.7 {ChildBgerror sets error handler of child [1999035]} -setup {
    interp create child
    child alias handler handler
    child bgerror handler
    variable result {untouched}
    proc handler {args} {
	variable result
	set result [lindex $args 0]
    }
} -body {
    child eval {
	variable done {}
	after 0 error foo
	after 10 [list ::set [namespace which -variable done] {}]
	vwait [namespace which -variable done]
    }
    set result
} -cleanup {
    variable result {}
    unset -nocomplain result
    interp delete child
} -result foo
Changes to tests/io.test.
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
    set sizes
} {19 19 19 19 19}

proc testreadwrite {size {mode ""} args} {
    set tmpfile [file join [temporaryDirectory] io-1.10.tmp]
    set w [string repeat A $size]
    try {
        set fd [open $tmpfile w$mode]
        try {
            if {[llength $args]} {
                fconfigure $fd {*}$args
            }
            puts -nonewline $fd $w
        } finally {
            close $fd
        }
        set fd [open $tmpfile r$mode]
        try {
            if {[llength $args]} {
                fconfigure $fd {*}$args
            }
            set r [read $fd]
        } finally {
            close $fd
        }
    } finally {
        file delete $tmpfile
    }
    string equal $w $r
}

test io-1.10 {WriteChars: large file (> INT_MAX). Bug 3d01d51bc4} -constraints {
    pointerIs64bit perf
} -body {







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|







197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
    set sizes
} {19 19 19 19 19}

proc testreadwrite {size {mode ""} args} {
    set tmpfile [file join [temporaryDirectory] io-1.10.tmp]
    set w [string repeat A $size]
    try {
	set fd [open $tmpfile w$mode]
	try {
	    if {[llength $args]} {
		fconfigure $fd {*}$args
	    }
	    puts -nonewline $fd $w
	} finally {
	    close $fd
	}
	set fd [open $tmpfile r$mode]
	try {
	    if {[llength $args]} {
		fconfigure $fd {*}$args
	    }
	    set r [read $fd]
	} finally {
	    close $fd
	}
    } finally {
	file delete $tmpfile
    }
    string equal $w $r
}

test io-1.10 {WriteChars: large file (> INT_MAX). Bug 3d01d51bc4} -constraints {
    pointerIs64bit perf
} -body {
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
	Should not produce a segmentation fault in a Tcl built with
	--enable-symbols and -DPURIFY
} -body  {
    variable done
    variable res
    after 0 [list coroutine c1 apply [list {} {
	variable done
        # Not a complete / correct channel implementation. Just enough
        # to exercise the crash - closing from a read handler
	set chan [chan create r {apply {{cmd chan args} {
	    switch $cmd {
		blocking - finalize {
		}
		watch {
		    lappend ::timers287 [after 0 chan postevent $chan read]
		}







|
|







2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
	Should not produce a segmentation fault in a Tcl built with
	--enable-symbols and -DPURIFY
} -body  {
    variable done
    variable res
    after 0 [list coroutine c1 apply [list {} {
	variable done
	# Not a complete / correct channel implementation. Just enough
	# to exercise the crash - closing from a read handler
	set chan [chan create r {apply {{cmd chan args} {
	    switch $cmd {
		blocking - finalize {
		}
		watch {
		    lappend ::timers287 [after 0 chan postevent $chan read]
		}
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
# event generation and the one in the bug report was not doing so.
test io-44.6 {FileEventProc procedure: write-only non-blocking channel} -setup {
} -constraints {stdio fileevent} -body {

    namespace eval refchan {
	namespace ensemble create
	namespace export *
        # Change to taste depending on how much CPU you want to hog
        variable delay 0

	proc finalize {chan args} {
            namespace upvar c_$chan timer timer
            catch {after cancel $timer}
	    namespace delete c_$chan
	}

	proc initialize {chan args} {
	    namespace eval c_$chan {}
	    namespace upvar c_$chan watching watching timer timer
	    set watching {}







|
|


|
|







6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
# event generation and the one in the bug report was not doing so.
test io-44.6 {FileEventProc procedure: write-only non-blocking channel} -setup {
} -constraints {stdio fileevent} -body {

    namespace eval refchan {
	namespace ensemble create
	namespace export *
	# Change to taste depending on how much CPU you want to hog
	variable delay 0

	proc finalize {chan args} {
	    namespace upvar c_$chan timer timer
	    catch {after cancel $timer}
	    namespace delete c_$chan
	}

	proc initialize {chan args} {
	    namespace eval c_$chan {}
	    namespace upvar c_$chan watching watching timer timer
	    set watching {}
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
		    write {
			if {$arg ni $watching} {
			    lappend watching $arg
			}
		    }
		}
	    }
            update $chan
	}

	proc write {chan args} {
	    return 1
	}

        # paraphrased from tcllib
        proc update {chan} {
            namespace upvar c_$chan watching watching timer timer
            variable delay
            catch {after cancel $timer}
            if {"write" in $watching} {
                set timer [after idle after $delay \
                               [namespace code [list post $chan]]]
            }
        }

        # paraphrased from tcllib
        proc post {chan} {
            variable delay
            namespace upvar c_$chan watching watching timer timer
            if {"write" in $watching} {
                set timer [after idle after $delay \
                               [namespace code [list post $chan]]]
                chan postevent $chan write
            }
        }
    }
    set f [chan create w [namespace which refchan]]
    chan configure $f -blocking 0
    set data "some data"
    set x 0
    chan event $f writable [namespace code {
	puts $f $data







|






|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|







6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
		    write {
			if {$arg ni $watching} {
			    lappend watching $arg
			}
		    }
		}
	    }
	    update $chan
	}

	proc write {chan args} {
	    return 1
	}

	# paraphrased from tcllib
	proc update {chan} {
	    namespace upvar c_$chan watching watching timer timer
	    variable delay
	    catch {after cancel $timer}
	    if {"write" in $watching} {
		set timer [after idle after $delay \
			       [namespace code [list post $chan]]]
	    }
	}

	# paraphrased from tcllib
	proc post {chan} {
	    variable delay
	    namespace upvar c_$chan watching watching timer timer
	    if {"write" in $watching} {
		set timer [after idle after $delay \
			       [namespace code [list post $chan]]]
		chan postevent $chan write
	    }
	}
    }
    set f [chan create w [namespace which refchan]]
    chan configure $f -blocking 0
    set data "some data"
    set x 0
    chan event $f writable [namespace code {
	puts $f $data
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
# Bug https://core.tcl-lang.org/tcl/info/67a5eabbd3d1 with a corrected
# refchan implementation. refchans that are not reentrant should use
# event loop to post events and the script in the bug report was not
# doing so.
test io-44.7 {refchan + coroutine yield error } -setup {
    set bghandler [interp bgerror {}]
    namespace eval schan {
        namespace ensemble create
        namespace export *
        proc open {} {
            set chan [chan create read [namespace current]]

        }
        proc initialize {chan mode} {
            return [list initialize finalize read watch]
        }
        proc finalize args {}
        proc read {chan count} {}
        proc watch {chan eventspec} {
            foreach event $eventspec {
                after idle after 0 chan postevent $chan $event
            }
        }
    }
} -cleanup {
    interp bgerror {} $bghandler
    unset -nocomplain ::io-44.7-result
    namespace delete schan
} -body {
    interp bgerror {} [list apply {{res opts} {
        set ::io-44.7-result [dict get $opts -errorinfo]
    }}]
    coroutine c1 apply [list {} {
        set chan [schan::open]
        chan event $chan readable [list [info coroutine]]
        yield
        close $chan
        set ::io-44.7-result success
    } [namespace current]]
    vwait ::io-44.7-result
    set ::io-44.7-result
} -result success

makeFile "foo bar" foo








|
|
|
|

|
|
|
|
|
|
|
|
|
|
|







|


|
|
|
|
|







6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
# Bug https://core.tcl-lang.org/tcl/info/67a5eabbd3d1 with a corrected
# refchan implementation. refchans that are not reentrant should use
# event loop to post events and the script in the bug report was not
# doing so.
test io-44.7 {refchan + coroutine yield error } -setup {
    set bghandler [interp bgerror {}]
    namespace eval schan {
	namespace ensemble create
	namespace export *
	proc open {} {
	    set chan [chan create read [namespace current]]

	}
	proc initialize {chan mode} {
	    return [list initialize finalize read watch]
	}
	proc finalize args {}
	proc read {chan count} {}
	proc watch {chan eventspec} {
	    foreach event $eventspec {
		after idle after 0 chan postevent $chan $event
	    }
	}
    }
} -cleanup {
    interp bgerror {} $bghandler
    unset -nocomplain ::io-44.7-result
    namespace delete schan
} -body {
    interp bgerror {} [list apply {{res opts} {
	set ::io-44.7-result [dict get $opts -errorinfo]
    }}]
    coroutine c1 apply [list {} {
	set chan [schan::open]
	chan event $chan readable [list [info coroutine]]
	yield
	close $chan
	set ::io-44.7-result success
    } [namespace current]]
    vwait ::io-44.7-result
    set ::io-44.7-result
} -result success

makeFile "foo bar" foo

8363
8364
8365
8366
8367
8368
8369
8370
8371
8372
8373
8374
8375
8376
8377
		puts stderr 2COPY
	    }
	    puts stderr ...
	}
	puts stderr SRV
	set l {}
	set srv [socket -server new -myaddr 127.0.0.1 0]
        set port [lindex [fconfigure $srv -sockname] 2]
	puts stderr WAITING
	fileevent stdin readable bye
	puts "OK $port"
	vwait forever
    }
    # wait for OK from server.
    lassign [gets $pipe] ok port







|







8363
8364
8365
8366
8367
8368
8369
8370
8371
8372
8373
8374
8375
8376
8377
		puts stderr 2COPY
	    }
	    puts stderr ...
	}
	puts stderr SRV
	set l {}
	set srv [socket -server new -myaddr 127.0.0.1 0]
	set port [lindex [fconfigure $srv -sockname] 2]
	puts stderr WAITING
	fileevent stdin readable bye
	puts "OK $port"
	vwait forever
    }
    # wait for OK from server.
    lassign [gets $pipe] ok port
9892
9893
9894
9895
9896
9897
9898
9899
9900
9901
9902
9903
9904
9905
9906
9907
9908
9909
9910
9911
9912
9913
9914
9915
9916
9917
9918
9919
9920
9921
9922
    Bad mode, would make channel inacessible. Channel: "*"}

# Encoding errors on pipeline
# Ensures fix for exec bug [0f1ddc0df7] does not affect open
# It should still fail unless -profile is explicitly set to replace
test io-77.1 {open pipe encoding mismatch} -setup {
    set scriptFile [makeFile {
        fconfigure stdout -translation binary
        puts -nonewline a\xe9b
        flush stdout
    } script]
} -cleanup {
    close $fd
    removeFile $scriptFile
} -body {
    set fd [open |[list [info nameofexecutable] $scriptFile r+]]
    fconfigure $fd -encoding utf-8
    list [catch {read $fd} result opts] [string match {error reading "*": invalid or incomplete multibyte or wide character} $result] [dict get $opts -errorcode]
} -result [list 1 1 {POSIX EILSEQ {invalid or incomplete multibyte or wide character}}]
test io-77.2 {open pipe encoding mismatch - use replace profile} -setup {
    set scriptFile [makeFile {
        fconfigure stdout -translation binary
        puts -nonewline a\xe9b
        flush stdout
    } script]
} -cleanup {
    close $fd
    removeFile $scriptFile
} -body {
    set fd [open |[list [info nameofexecutable] $scriptFile r+]]
    fconfigure $fd -encoding utf-8 -profile replace







|
|
|











|
|
|







9892
9893
9894
9895
9896
9897
9898
9899
9900
9901
9902
9903
9904
9905
9906
9907
9908
9909
9910
9911
9912
9913
9914
9915
9916
9917
9918
9919
9920
9921
9922
    Bad mode, would make channel inacessible. Channel: "*"}

# Encoding errors on pipeline
# Ensures fix for exec bug [0f1ddc0df7] does not affect open
# It should still fail unless -profile is explicitly set to replace
test io-77.1 {open pipe encoding mismatch} -setup {
    set scriptFile [makeFile {
	fconfigure stdout -translation binary
	puts -nonewline a\xe9b
	flush stdout
    } script]
} -cleanup {
    close $fd
    removeFile $scriptFile
} -body {
    set fd [open |[list [info nameofexecutable] $scriptFile r+]]
    fconfigure $fd -encoding utf-8
    list [catch {read $fd} result opts] [string match {error reading "*": invalid or incomplete multibyte or wide character} $result] [dict get $opts -errorcode]
} -result [list 1 1 {POSIX EILSEQ {invalid or incomplete multibyte or wide character}}]
test io-77.2 {open pipe encoding mismatch - use replace profile} -setup {
    set scriptFile [makeFile {
	fconfigure stdout -translation binary
	puts -nonewline a\xe9b
	flush stdout
    } script]
} -cleanup {
    close $fd
    removeFile $scriptFile
} -body {
    set fd [open |[list [info nameofexecutable] $scriptFile r+]]
    fconfigure $fd -encoding utf-8 -profile replace
Changes to tests/ioCmd.test.
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194

test iocmd-32.2 {delete interp of reflected chan} {
    # Bug 3034840
    # Run this test in an interp with memory debugging to panic
    # on the double free
    interp create child
    child eval {
        proc no-op args {}
        proc driver {sub args} {return {initialize finalize watch read}}
        chan event [chan create read driver] readable no-op
    }
    interp delete child
} {}

# 1st attempt without error in write, another with error in write:
foreach ::writeErr {0 1} {
test iocmd-32.3.$::writeErr {prevent copy-state against segfault by finalize, bug [79474c58800cdf94]} -setup {
    proc test_chan {args} {
      set rest [lassign $args mode chan]
      lappend ::ret $mode
      switch -exact $mode {
        read {puts $chan "Test" ; close $chan}
        write {if {$::writeErr} {return "boom"}; set data [lindex $rest 0]; string length $data}
        finalize {after 20 {set ::done done}}
        initialize {return "initialize watch finalize read write"}
      }
    }
    set clchlst {}
    set toev [after 5000 {set ::done tout}]
} -body {
    set ::ret {}
    set ch [chan create "read write" test_chan]







|
|
|











|
|
|
|







2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194

test iocmd-32.2 {delete interp of reflected chan} {
    # Bug 3034840
    # Run this test in an interp with memory debugging to panic
    # on the double free
    interp create child
    child eval {
	proc no-op args {}
	proc driver {sub args} {return {initialize finalize watch read}}
	chan event [chan create read driver] readable no-op
    }
    interp delete child
} {}

# 1st attempt without error in write, another with error in write:
foreach ::writeErr {0 1} {
test iocmd-32.3.$::writeErr {prevent copy-state against segfault by finalize, bug [79474c58800cdf94]} -setup {
    proc test_chan {args} {
      set rest [lassign $args mode chan]
      lappend ::ret $mode
      switch -exact $mode {
	read {puts $chan "Test" ; close $chan}
	write {if {$::writeErr} {return "boom"}; set data [lindex $rest 0]; string length $data}
	finalize {after 20 {set ::done done}}
	initialize {return "initialize watch finalize read write"}
      }
    }
    set clchlst {}
    set toev [after 5000 {set ::done tout}]
} -body {
    set ::ret {}
    set ch [chan create "read write" test_chan]
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
    foreachLine a b c d
} -result {wrong # args: should be "foreachLine varName filename body"}
test iocmd.foreachLine-1.3 "foreachLine procedure: basic errors" -setup {
    set f [makeFile "" foreachLine13.txt]
} -body {
    apply {filename {
	array set b {1 1}
        foreachLine b $filename {}
    }} $f
} -cleanup {
    removeFile $f
} -returnCodes error -result {can't set "line": variable is array}
set f [makeFile "" foreachLine14.txt]
removeFile $f
test iocmd.foreachLine-1.4 "foreachLine procedure: basic errors" -body {







|







4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
    foreachLine a b c d
} -result {wrong # args: should be "foreachLine varName filename body"}
test iocmd.foreachLine-1.3 "foreachLine procedure: basic errors" -setup {
    set f [makeFile "" foreachLine13.txt]
} -body {
    apply {filename {
	array set b {1 1}
	foreachLine b $filename {}
    }} $f
} -cleanup {
    removeFile $f
} -returnCodes error -result {can't set "line": variable is array}
set f [makeFile "" foreachLine14.txt]
removeFile $f
test iocmd.foreachLine-1.4 "foreachLine procedure: basic errors" -body {
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
} -cleanup {
    removeFile $f
} -result {a bb}
test iocmd.foreachLine-2.4 "foreachLine procedure: behaviour" -setup {
    set f [makeFile "a\nbb\nccc\ndd\ne" foreachLine24.txt]
} -body {
    apply {filename {
    	set lines {}
	foreachLine var $filename {
	    if {[string length $var] > 2} {
		return $var
	    }
	    lappend lines $var
	}
	return $lines







|







4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
} -cleanup {
    removeFile $f
} -result {a bb}
test iocmd.foreachLine-2.4 "foreachLine procedure: behaviour" -setup {
    set f [makeFile "a\nbb\nccc\ndd\ne" foreachLine24.txt]
} -body {
    apply {filename {
	set lines {}
	foreachLine var $filename {
	    if {[string length $var] > 2} {
		return $var
	    }
	    lappend lines $var
	}
	return $lines
Changes to tests/ioTrans.test.
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
    rename foo {}
} -result {{read rt* {test data
}} {}}

# Driver for a base channel that emits several short "files"
# with each terminated by a fleeting EOF
    proc driver {cmd args} {
        variable ::tcl::buffer
        variable ::tcl::index
        set chan [lindex $args 0]
        switch -- $cmd {
            initialize {
                set index($chan) 0
                set buffer($chan) .....
                return {initialize finalize watch read}
            }
            finalize {
                if {![info exists index($chan)]} {return}
                unset index($chan) buffer($chan)
		array unset index
		array unset buffer
                return
            }
            watch {}
            read {
                set n [lindex $args 1]
                if {![info exists index($chan)]} {
                    driver initialize $chan
                }
                set new [expr {$index($chan) + $n}]
                set result [string range $buffer($chan) $index($chan) $new-1]
                set index($chan) $new
                if {[string length $result] == 0} {
                    driver finalize $chan
                }
                return $result
            }
        }
    }



namespace eval reflector {
    proc initialize {_ chan mode} {
	return {initialize finalize watch read}







|
|
|
|
|
|
|
|
|
|
|
|


|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
    rename foo {}
} -result {{read rt* {test data
}} {}}

# Driver for a base channel that emits several short "files"
# with each terminated by a fleeting EOF
    proc driver {cmd args} {
	variable ::tcl::buffer
	variable ::tcl::index
	set chan [lindex $args 0]
	switch -- $cmd {
	    initialize {
		set index($chan) 0
		set buffer($chan) .....
		return {initialize finalize watch read}
	    }
	    finalize {
		if {![info exists index($chan)]} {return}
		unset index($chan) buffer($chan)
		array unset index
		array unset buffer
		return
	    }
	    watch {}
	    read {
		set n [lindex $args 1]
		if {![info exists index($chan)]} {
		    driver initialize $chan
		}
		set new [expr {$index($chan) + $n}]
		set result [string range $buffer($chan) $index($chan) $new-1]
		set index($chan) $new
		if {[string length $result] == 0} {
		    driver finalize $chan
		}
		return $result
	    }
	}
    }



namespace eval reflector {
    proc initialize {_ chan mode} {
	return {initialize finalize watch read}
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
}



# Channel read transform that is just the identity - pass all through
    proc idxform {cmd handle args} {
      switch -- $cmd {
        initialize {
            return {initialize finalize read}
        }
        finalize {
            return
        }
        read {
            lassign $args buffer
            return $buffer
        }
      }
    }

# Test that all EOFs pass through full xform stack.  Proper data boundaries.
# Check robustness against buffer sizes.
test iortrans-4.10 {[5adbc350683] chan read, handle fleeting EOF} -body {
    set chan [chan push [chan create read driver] idxform]
    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
        [read $chan] [eof $chan]
} -cleanup {
    close $chan
} -result {0 ..... 1 {} 0 ..... 1}
test iortrans-4.10.1 {[5adbc350683] chan read, handle fleeting EOF} -body {
    set chan [chan push [chan create read driver] idxform]
    chan configure $chan -buffersize 3
    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
        [read $chan] [eof $chan]
} -cleanup {
    close $chan
} -result {0 ..... 1 {} 0 ..... 1}
test iortrans-4.10.2 {[5adbc350683] chan read, handle fleeting EOF} -body {
    set chan [chan push [chan create read driver] idxform]
    chan configure $chan -buffersize 5
    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
        [read $chan] [eof $chan]
} -cleanup {
    close $chan
} -result {0 ..... 1 {} 0 ..... 1}

rename idxform {}

# Channel read transform that delays the data and always returns something
    proc delayxform {cmd handle args} {
      variable store
      switch -- $cmd {
        initialize {
	    set store($handle) {}
            return {initialize finalize read drain}
        }
        finalize {
	    unset store($handle)
            return
        }
        read {
            lassign $args buffer
	    if {$store($handle) eq {}} {
		set reply [string index $buffer 0]
		set store($handle) [string range $buffer 1 end]
	    } else {
		set reply $store($handle)
		set store($handle) $buffer
	    }
            return $reply
        }
	drain {
	    delayxform read $handle {}
	}
      }
    }

# Test that all EOFs pass through full xform stack.  Proper data boundaries.
# Check robustness against buffer sizes.
test iortrans-4.11 {[5adbc350683] chan read, handle fleeting EOF} -body {
    set chan [chan push [chan create read driver] delayxform]
    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
        [read $chan] [eof $chan]
} -cleanup {
    close $chan
} -result {0 ..... 1 {} 0 ..... 1}
test iortrans-4.11.1 {[5adbc350683] chan read, handle fleeting EOF} -body {
    set chan [chan push [chan create read driver] delayxform]
    chan configure $chan -buffersize 3
    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
        [read $chan] [eof $chan]
} -cleanup {
    close $chan
} -result {0 ..... 1 {} 0 ..... 1}
test iortrans-4.11.2 {[5adbc350683] chan read, handle fleeting EOF} -body {
    set chan [chan push [chan create read driver] delayxform]
    chan configure $chan -buffersize 5
    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
        [read $chan] [eof $chan]
} -cleanup {
    close $chan
} -result {0 ..... 1 {} 0 ..... 1}

    rename delayxform {}

# Channel read transform that delays the data and may return {}
    proc delay2xform {cmd handle args} {
      variable store
      switch -- $cmd {
        initialize {
	    set store($handle) {}
            return {initialize finalize read drain}
        }
        finalize {
	    unset store($handle)
            return
        }
        read {
            lassign $args buffer
		set reply $store($handle)
		set store($handle) $buffer
            return $reply
        }
	drain {
	    delay2xform read $handle {}
	}
      }
    }

test iortrans-4.12 {[5adbc350683] chan read, handle fleeting EOF} -body {
    set chan [chan push [chan create read driver] delay2xform]
    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
        [read $chan] [eof $chan]
} -cleanup {
    close $chan
} -result {0 ..... 1 {} 0 ..... 1}

    rename delay2xform {}
    rename driver {}








|
|
|
|
|
|
|
|
|
|








|







|







|










|

|
|
|

|
|
|
|







|
|











|







|







|










|

|
|
|

|
|
|
|


|
|









|







688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
}



# Channel read transform that is just the identity - pass all through
    proc idxform {cmd handle args} {
      switch -- $cmd {
	initialize {
	    return {initialize finalize read}
	}
	finalize {
	    return
	}
	read {
	    lassign $args buffer
	    return $buffer
	}
      }
    }

# Test that all EOFs pass through full xform stack.  Proper data boundaries.
# Check robustness against buffer sizes.
test iortrans-4.10 {[5adbc350683] chan read, handle fleeting EOF} -body {
    set chan [chan push [chan create read driver] idxform]
    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
	[read $chan] [eof $chan]
} -cleanup {
    close $chan
} -result {0 ..... 1 {} 0 ..... 1}
test iortrans-4.10.1 {[5adbc350683] chan read, handle fleeting EOF} -body {
    set chan [chan push [chan create read driver] idxform]
    chan configure $chan -buffersize 3
    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
	[read $chan] [eof $chan]
} -cleanup {
    close $chan
} -result {0 ..... 1 {} 0 ..... 1}
test iortrans-4.10.2 {[5adbc350683] chan read, handle fleeting EOF} -body {
    set chan [chan push [chan create read driver] idxform]
    chan configure $chan -buffersize 5
    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
	[read $chan] [eof $chan]
} -cleanup {
    close $chan
} -result {0 ..... 1 {} 0 ..... 1}

rename idxform {}

# Channel read transform that delays the data and always returns something
    proc delayxform {cmd handle args} {
      variable store
      switch -- $cmd {
	initialize {
	    set store($handle) {}
	    return {initialize finalize read drain}
	}
	finalize {
	    unset store($handle)
	    return
	}
	read {
	    lassign $args buffer
	    if {$store($handle) eq {}} {
		set reply [string index $buffer 0]
		set store($handle) [string range $buffer 1 end]
	    } else {
		set reply $store($handle)
		set store($handle) $buffer
	    }
	    return $reply
	}
	drain {
	    delayxform read $handle {}
	}
      }
    }

# Test that all EOFs pass through full xform stack.  Proper data boundaries.
# Check robustness against buffer sizes.
test iortrans-4.11 {[5adbc350683] chan read, handle fleeting EOF} -body {
    set chan [chan push [chan create read driver] delayxform]
    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
	[read $chan] [eof $chan]
} -cleanup {
    close $chan
} -result {0 ..... 1 {} 0 ..... 1}
test iortrans-4.11.1 {[5adbc350683] chan read, handle fleeting EOF} -body {
    set chan [chan push [chan create read driver] delayxform]
    chan configure $chan -buffersize 3
    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
	[read $chan] [eof $chan]
} -cleanup {
    close $chan
} -result {0 ..... 1 {} 0 ..... 1}
test iortrans-4.11.2 {[5adbc350683] chan read, handle fleeting EOF} -body {
    set chan [chan push [chan create read driver] delayxform]
    chan configure $chan -buffersize 5
    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
	[read $chan] [eof $chan]
} -cleanup {
    close $chan
} -result {0 ..... 1 {} 0 ..... 1}

    rename delayxform {}

# Channel read transform that delays the data and may return {}
    proc delay2xform {cmd handle args} {
      variable store
      switch -- $cmd {
	initialize {
	    set store($handle) {}
	    return {initialize finalize read drain}
	}
	finalize {
	    unset store($handle)
	    return
	}
	read {
	    lassign $args buffer
		set reply $store($handle)
		set store($handle) $buffer
	    return $reply
	}
	drain {
	    delay2xform read $handle {}
	}
      }
    }

test iortrans-4.12 {[5adbc350683] chan read, handle fleeting EOF} -body {
    set chan [chan push [chan create read driver] delay2xform]
    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
	[read $chan] [eof $chan]
} -cleanup {
    close $chan
} -result {0 ..... 1 {} 0 ..... 1}

    rename delay2xform {}
    rename driver {}

Changes to tests/iogt.test.
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
    close $fin
    set trail [list]
    set got [list]
    proc Done {args} {
	variable stop 1
    }
    proc Get {sock} {
        variable trail
        variable got
        if {[eof $sock]} {
            Done
            lappend trail "xxxxxxxxxxxxx"
            close $sock
            return
        }
        lappend trail "vvvvvvvvvvvvv"
        lappend trail "\tgot: [lappend got "\[\[[read $sock]\]\]"]"
        lappend trail "============="
        #puts stdout $__ ; flush stdout
        #read $sock
    }

} -constraints {testchannel knownBug} -body {
    fevent 1000 500 {20 20 20 10 1} {
	variable stop
	audit_flow trail -attach $sock
	rblocks_t rbuf trail 23 -attach $sock







|
|
|
|
|
|
|
|
|
|
|
|
|







649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
    close $fin
    set trail [list]
    set got [list]
    proc Done {args} {
	variable stop 1
    }
    proc Get {sock} {
	variable trail
	variable got
	if {[eof $sock]} {
	    Done
	    lappend trail "xxxxxxxxxxxxx"
	    close $sock
	    return
	}
	lappend trail "vvvvvvvvvvvvv"
	lappend trail "\tgot: [lappend got "\[\[[read $sock]\]\]"]"
	lappend trail "============="
	#puts stdout $__ ; flush stdout
	#read $sock
    }

} -constraints {testchannel knownBug} -body {
    fevent 1000 500 {20 20 20 10 1} {
	variable stop
	audit_flow trail -attach $sock
	rblocks_t rbuf trail 23 -attach $sock
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
    close $f
} -result {xxxghi}


# Driver for a base channel that emits several short "files"
# with each terminated by a fleeting EOF
    proc driver {cmd args} {
        variable buffer
        variable index
        set chan [lindex $args 0]
        switch -- $cmd {
            initialize {
                set index($chan) 0
                set buffer($chan) .....
                return {initialize finalize watch read}
            }
            finalize {
                if {![info exists index($chan)]} {return}
                unset index($chan) buffer($chan)
                return
            }
            watch {}
            read {
                set n [lindex $args 1]
                if {![info exists index($chan)]} {
                    driver initialize $chan
                }
                set new [expr {$index($chan) + $n}]
                set result [string range $buffer($chan) $index($chan) $new-1]
                set index($chan) $new
                if {[string length $result] == 0} {
                    driver finalize $chan
                }
                return $result
            }
        }
    }

test iogt-7.0 {Handle fleeting EOF} -constraints {testchannel} -body {
    set chan [chan create read [namespace which driver]]
    identity -attach $chan
    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
        [read $chan] [eof $chan]
} -cleanup {
    close $chan
} -result {0 ..... 1 {} 0 ..... 1}

proc delay {op data} {
    variable store
    switch -- $op {







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|






|







871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
    close $f
} -result {xxxghi}


# Driver for a base channel that emits several short "files"
# with each terminated by a fleeting EOF
    proc driver {cmd args} {
	variable buffer
	variable index
	set chan [lindex $args 0]
	switch -- $cmd {
	    initialize {
		set index($chan) 0
		set buffer($chan) .....
		return {initialize finalize watch read}
	    }
	    finalize {
		if {![info exists index($chan)]} {return}
		unset index($chan) buffer($chan)
		return
	    }
	    watch {}
	    read {
		set n [lindex $args 1]
		if {![info exists index($chan)]} {
		    driver initialize $chan
		}
		set new [expr {$index($chan) + $n}]
		set result [string range $buffer($chan) $index($chan) $new-1]
		set index($chan) $new
		if {[string length $result] == 0} {
		    driver finalize $chan
		}
		return $result
	    }
	}
    }

test iogt-7.0 {Handle fleeting EOF} -constraints {testchannel} -body {
    set chan [chan create read [namespace which driver]]
    identity -attach $chan
    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
	[read $chan] [eof $chan]
} -cleanup {
    close $chan
} -result {0 ..... 1 {} 0 ..... 1}

proc delay {op data} {
    variable store
    switch -- $op {
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
    }
}

test iogt-7.1 {Handle fleeting EOF} -constraints {testchannel} -body {
    set chan [chan create read [namespace which driver]]
    testchannel transform $chan -command [namespace code delay]
    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
        [read $chan] [eof $chan]
} -cleanup {
    close $chan
} -result {0 ..... 1 {} 0 ..... 1}

rename delay {}
rename driver {}








|







933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
    }
}

test iogt-7.1 {Handle fleeting EOF} -constraints {testchannel} -body {
    set chan [chan create read [namespace which driver]]
    testchannel transform $chan -command [namespace code delay]
    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
	[read $chan] [eof $chan]
} -cleanup {
    close $chan
} -result {0 ..... 1 {} 0 ..... 1}

rename delay {}
rename driver {}

Changes to tests/linsert.test.
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
} [list a b c]
test linsert-2.6 {syntax (TIP 323)} {
    linsert "a\nb\nc" 0
} [list a b c]

test linsert-3.1 {linsert won't modify shared argument objects} {
    proc p {} {
        linsert "a b c" 1 "x y"
        return "a b c"
    }
    p
} "a b c"
test linsert-3.2 {linsert won't modify shared argument objects} {
    catch {unset lis}
    set lis [format "a \"%s\" c" "b"]
    linsert $lis 0 [string length $lis]







|
|







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
} [list a b c]
test linsert-2.6 {syntax (TIP 323)} {
    linsert "a\nb\nc" 0
} [list a b c]

test linsert-3.1 {linsert won't modify shared argument objects} {
    proc p {} {
	linsert "a b c" 1 "x y"
	return "a b c"
    }
    p
} "a b c"
test linsert-3.2 {linsert won't modify shared argument objects} {
    catch {unset lis}
    set lis [format "a \"%s\" c" "b"]
    linsert $lis 0 [string length $lis]
Changes to tests/listObj.test.
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

test listobj-2.1 {Tcl_SetListObj, use in lappend} {
    catch {unset x}
    list [lappend x 1 abc def] [lappend x 1 ghi jkl] $x
} {{1 abc def} {1 abc def 1 ghi jkl} {1 abc def 1 ghi jkl}}
test listobj-2.2 {Tcl_SetListObj, use in ObjInterpProc} {
    proc return_args {args} {
        return $args
    }
    list [return_args] [return_args x] [return_args x y]
} {{} x {x y}}
test listobj-2.3 {Tcl_SetListObj, zero element count} {
    list
} {}








|







33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

test listobj-2.1 {Tcl_SetListObj, use in lappend} {
    catch {unset x}
    list [lappend x 1 abc def] [lappend x 1 ghi jkl] $x
} {{1 abc def} {1 abc def 1 ghi jkl} {1 abc def 1 ghi jkl}}
test listobj-2.2 {Tcl_SetListObj, use in ObjInterpProc} {
    proc return_args {args} {
	return $args
    }
    list [return_args] [return_args x] [return_args x y]
} {{} x {x y}}
test listobj-2.3 {Tcl_SetListObj, zero element count} {
    list
} {}

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
test listobj-3.4 {Tcl_ListObjAppend, error in conversion} {
    set x " \{"
    list [catch {lappend x abc def} msg] $msg
} {1 {unmatched open brace in list}}
test listobj-3.5 {Tcl_ListObjAppend, force internal rep array to grow} {
    set x ""
    list [lappend x 1 1] [lappend x 2 2] [lappend x 3 3] [lappend x 4 4] \
        [lappend x 5 5] [lappend x 6 6] [lappend x 7 7] [lappend x 8 8] $x
} {{1 1} {1 1 2 2} {1 1 2 2 3 3} {1 1 2 2 3 3 4 4} {1 1 2 2 3 3 4 4 5 5} {1 1 2 2 3 3 4 4 5 5 6 6} {1 1 2 2 3 3 4 4 5 5 6 6 7 7} {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8} {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8}}

test listobj-4.1 {Tcl_ListObjAppendElement, list conversion} {
    catch {unset x}
    list [lappend x 1] $x
} {1 1}
test listobj-4.2 {Tcl_ListObjAppendElement, list conversion} {







|







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
test listobj-3.4 {Tcl_ListObjAppend, error in conversion} {
    set x " \{"
    list [catch {lappend x abc def} msg] $msg
} {1 {unmatched open brace in list}}
test listobj-3.5 {Tcl_ListObjAppend, force internal rep array to grow} {
    set x ""
    list [lappend x 1 1] [lappend x 2 2] [lappend x 3 3] [lappend x 4 4] \
	[lappend x 5 5] [lappend x 6 6] [lappend x 7 7] [lappend x 8 8] $x
} {{1 1} {1 1 2 2} {1 1 2 2 3 3} {1 1 2 2 3 3 4 4} {1 1 2 2 3 3 4 4 5 5} {1 1 2 2 3 3 4 4 5 5 6 6} {1 1 2 2 3 3 4 4 5 5 6 6 7 7} {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8} {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8}}

test listobj-4.1 {Tcl_ListObjAppendElement, list conversion} {
    catch {unset x}
    list [lappend x 1] $x
} {1 1}
test listobj-4.2 {Tcl_ListObjAppendElement, list conversion} {
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
test listobj-4.4 {Tcl_ListObjAppendElement, error in conversion} {
    set x " \{"
    list [catch {lappend x abc} msg] $msg
} {1 {unmatched open brace in list}}
test listobj-4.5 {Tcl_ListObjAppendElement, force internal rep array to grow} {
    set x ""
    list [lappend x 1] [lappend x 2] [lappend x 3] [lappend x 4] \
        [lappend x 5] [lappend x 6] [lappend x 7] [lappend x 8] $x
} {1 {1 2} {1 2 3} {1 2 3 4} {1 2 3 4 5} {1 2 3 4 5 6} {1 2 3 4 5 6 7} {1 2 3 4 5 6 7 8} {1 2 3 4 5 6 7 8}}

test listobj-5.1 {Tcl_ListObjIndex, basic tests} {
    lindex {a b c} 0
} a
test listobj-5.2 {Tcl_ListObjIndex, basic tests} {
    lindex a 0







|







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
test listobj-4.4 {Tcl_ListObjAppendElement, error in conversion} {
    set x " \{"
    list [catch {lappend x abc} msg] $msg
} {1 {unmatched open brace in list}}
test listobj-4.5 {Tcl_ListObjAppendElement, force internal rep array to grow} {
    set x ""
    list [lappend x 1] [lappend x 2] [lappend x 3] [lappend x 4] \
	[lappend x 5] [lappend x 6] [lappend x 7] [lappend x 8] $x
} {1 {1 2} {1 2 3} {1 2 3 4} {1 2 3 4 5} {1 2 3 4 5 6} {1 2 3 4 5 6 7} {1 2 3 4 5 6 7 8} {1 2 3 4 5 6 7 8}}

test listobj-5.1 {Tcl_ListObjIndex, basic tests} {
    lindex {a b c} 0
} a
test listobj-5.2 {Tcl_ListObjIndex, basic tests} {
    lindex a 0
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
    list [llength $l] [lindex $l 2]
} {100 c}

# Stolen from dict.test
proc listobjmemcheck script {
    set end [lindex [split [memory info] \n] 3 3]
    for {set i 0} {$i < 5} {incr i} {
        uplevel 1 $script
        set tmp $end
        set end [lindex [split [memory info] \n] 3 3]
    }
    expr {$end - $tmp}
}

test listobj-12.1 {Tcl_ListObjIndex memory leaks for native lists} -constraints {
    testobj memory
} -body {
    list [listobjmemcheck {
        testobj set 1 [lrepeat 1000 x]
        set errorMessage [testlistobj indexmemcheck 1]
        testobj freeallvars
    }] $errorMessage
} -result {0 {}}
test listobj-12.2 {Tcl_ListObjIndex memory leaks for native lists with spans} -constraints {
    testobj memory
} -body {
    list [listobjmemcheck {
        testobj set 1 [testlistrep new 1000 100 100]
        set errorMessage [testlistobj indexmemcheck 1]
        testobj freeallvars
    }] $errorMessage
} -result {0 {}}
test listobj-12.3 {Tcl_ListObjIndex memory leaks for lseq} -constraints {
    testobj memory
} -body {
    list [listobjmemcheck {
        testobj set 1 [lseq 1000]
        set errorMessage [testlistobj indexmemcheck 1]
        testobj freeallvars
    }] $errorMessage
} -result {0 {}}

test listobj-13.1 {Tcl_ListObjGetElements memory leaks for native lists} -constraints {
    testobj memory
} -body {
    list [listobjmemcheck {
        testobj set 1 [lrepeat 1000 x]
        set errorMessage [testlistobj getelementsmemcheck 1]
        testobj freeallvars
    }] $errorMessage
} -result {0 {}}
test listobj-13.2 {Tcl_ListObjElements memory leaks for native lists with spans} -constraints {
    testobj memory
} -body {
    list [listobjmemcheck {
        testobj set 1 [testlistrep new 1000 100 100]
        set errorMessage [testlistobj getelementsmemcheck 1]
        testobj freeallvars
    }] $errorMessage
} -result {0 {}}
test listobj-13.3 {Tcl_ListObjElements memory leaks for lseq} -constraints {
    testobj memory
} -body {
    list [listobjmemcheck {
        testobj set 1 [lseq 1000]
        set errorMessage [testlistobj getelementsmemcheck 1]
        testobj freeallvars
    }] $errorMessage
} -result {0 {}}

# Tests for Tcl_ListObjIndex as sematics are different from lindex for
# out of bounds indices. Out of bounds should return a null pointer and
# not empty string.
test listobj-14.1 {Tcl_ListObjIndex out-of-bounds index for native lists} -constraints {







|
|
|








|
|
|






|
|
|






|
|
|







|
|
|






|
|
|






|
|
|







229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
    list [llength $l] [lindex $l 2]
} {100 c}

# Stolen from dict.test
proc listobjmemcheck script {
    set end [lindex [split [memory info] \n] 3 3]
    for {set i 0} {$i < 5} {incr i} {
	uplevel 1 $script
	set tmp $end
	set end [lindex [split [memory info] \n] 3 3]
    }
    expr {$end - $tmp}
}

test listobj-12.1 {Tcl_ListObjIndex memory leaks for native lists} -constraints {
    testobj memory
} -body {
    list [listobjmemcheck {
	testobj set 1 [lrepeat 1000 x]
	set errorMessage [testlistobj indexmemcheck 1]
	testobj freeallvars
    }] $errorMessage
} -result {0 {}}
test listobj-12.2 {Tcl_ListObjIndex memory leaks for native lists with spans} -constraints {
    testobj memory
} -body {
    list [listobjmemcheck {
	testobj set 1 [testlistrep new 1000 100 100]
	set errorMessage [testlistobj indexmemcheck 1]
	testobj freeallvars
    }] $errorMessage
} -result {0 {}}
test listobj-12.3 {Tcl_ListObjIndex memory leaks for lseq} -constraints {
    testobj memory
} -body {
    list [listobjmemcheck {
	testobj set 1 [lseq 1000]
	set errorMessage [testlistobj indexmemcheck 1]
	testobj freeallvars
    }] $errorMessage
} -result {0 {}}

test listobj-13.1 {Tcl_ListObjGetElements memory leaks for native lists} -constraints {
    testobj memory
} -body {
    list [listobjmemcheck {
	testobj set 1 [lrepeat 1000 x]
	set errorMessage [testlistobj getelementsmemcheck 1]
	testobj freeallvars
    }] $errorMessage
} -result {0 {}}
test listobj-13.2 {Tcl_ListObjElements memory leaks for native lists with spans} -constraints {
    testobj memory
} -body {
    list [listobjmemcheck {
	testobj set 1 [testlistrep new 1000 100 100]
	set errorMessage [testlistobj getelementsmemcheck 1]
	testobj freeallvars
    }] $errorMessage
} -result {0 {}}
test listobj-13.3 {Tcl_ListObjElements memory leaks for lseq} -constraints {
    testobj memory
} -body {
    list [listobjmemcheck {
	testobj set 1 [lseq 1000]
	set errorMessage [testlistobj getelementsmemcheck 1]
	testobj freeallvars
    }] $errorMessage
} -result {0 {}}

# Tests for Tcl_ListObjIndex as sematics are different from lindex for
# out of bounds indices. Out of bounds should return a null pointer and
# not empty string.
test listobj-14.1 {Tcl_ListObjIndex out-of-bounds index for native lists} -constraints {
Changes to tests/listRep.test.
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
testConstraint testlistrep [llength [info commands testlistrep]]

proc describe {l args} {dict get [testlistrep describe $l] {*}$args}

proc irange {first last} {
    set l {}
    while {$first <= $last} {
        lappend l $first
        incr first
    }
    return $l
}
proc leadSpace {l} {
    # Returns the leading space in a list store
    return [dict get [describe $l] store firstUsed]
}
proc tailSpace {l} {
    # Returns the trailing space in a list store
    array set rep [describe $l]
    dict with rep(store) {
        return [expr {$numAllocated - ($firstUsed + $numUsed)}]
    }
}
proc allocated {l} {
    # Returns the allocated space in a list store
    return [dict get [describe $l] store numAllocated]
}
proc repStoreRefCount {l} {







|
|











|







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
testConstraint testlistrep [llength [info commands testlistrep]]

proc describe {l args} {dict get [testlistrep describe $l] {*}$args}

proc irange {first last} {
    set l {}
    while {$first <= $last} {
	lappend l $first
	incr first
    }
    return $l
}
proc leadSpace {l} {
    # Returns the leading space in a list store
    return [dict get [describe $l] store firstUsed]
}
proc tailSpace {l} {
    # Returns the trailing space in a list store
    array set rep [describe $l]
    dict with rep(store) {
	return [expr {$numAllocated - ($firstUsed + $numUsed)}]
    }
}
proc allocated {l} {
    # Returns the allocated space in a list store
    return [dict get [describe $l] store numAllocated]
}
proc repStoreRefCount {l} {
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
    expr {$tailSpace > 0 && $tailSpace >= 2*[leadSpace $l]}
}
proc spaceEqual {l} {
    # 1 if lead and tail space shared (diff of 1 at most) and more than 0
    set leadSpace [leadSpace $l]
    set tailSpace [tailSpace $l]
    if {$leadSpace == 0 && $tailSpace == 0} {
        # At least one must be positive
        return 0
    }
    set diff [expr {$leadSpace - $tailSpace}]
    return [expr {$diff >= -1 && $diff <= 1}]
}
proc storeAddress {l} {
    return [describe $l store memoryAddress]
}
proc sameStore {l1 l2} {
    expr {[storeAddress $l1] == [storeAddress $l2]}
}
proc hasSpan {l args} {
    # Returns 1 if list has a span. If args are specified, they are checked with
    # span values (start and length)
    array set rep [describe $l]
    if {![info exists rep(span)]} {
        return 0
    }
    if {[llength $args] == 0} {
        return 1; # No need to check values
    }
    lassign $args start len
    if {[dict get $rep(span) spanStart] == $start &&
        [dict get $rep(span) spanLength] == $len} {
        return 1
    }
    return 0
}
proc checkListrep {l listLen numAllocated leadSpace tailSpace {refCount 0}} {
    # Checks if the internal representation of $l match
    # passed arguments. Return "" if yes, else error messages.
    array set rep [testlistrep describe $l]

    set rep(leadSpace) [dict get $rep(store) firstUsed]
    set rep(numAllocated) [dict get $rep(store) numAllocated]
    set rep(tailSpace) [expr {
                              $rep(numAllocated) - ($rep(leadSpace) + [dict get $rep(store) numUsed])
                          }]
    set rep(refCount) [dict get $rep(store) refCount]

    if {[info exists rep(span)]} {
        set rep(listLen) [dict get $rep(span) spanLength]
    } else {
        set rep(listLen) [dict get $rep(store) numUsed]
    }

    set errors [list]
    foreach arg {listLen numAllocated leadSpace tailSpace} {
        if {$rep($arg) != [set $arg]} {
            lappend errors "$arg in list representation ($rep($arg)) is not expected value ([set $arg])."
        }
    }
    # Check refCount only if caller has specified it as non-0
    if {$refCount && $refCount != $rep(refCount)} {
        lappend errors "refCount in list representation ($rep(refCount)) is not expected value ($refCount)."
    }
    return $errors
}

proc assertListrep {l listLen numAllocated leadSpace tailSpace {refCount 0}} {
    # Like check_listrep but raises error
    set errors [checkListrep $l $listLen $numAllocated $leadSpace $tailSpace $refCount]
    if {[llength $errors]} {
        error [join $errors \n]
    }
    return
}

# The default length should be large enough that doubling the allocation will
# clearly distinguish free space allocation difference between front and back.
# (difference in the two should at least be 2 else we cannot tell if front







|
|















|


|



|
|











|
|



|

|




|
|
|



|








|







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
    expr {$tailSpace > 0 && $tailSpace >= 2*[leadSpace $l]}
}
proc spaceEqual {l} {
    # 1 if lead and tail space shared (diff of 1 at most) and more than 0
    set leadSpace [leadSpace $l]
    set tailSpace [tailSpace $l]
    if {$leadSpace == 0 && $tailSpace == 0} {
	# At least one must be positive
	return 0
    }
    set diff [expr {$leadSpace - $tailSpace}]
    return [expr {$diff >= -1 && $diff <= 1}]
}
proc storeAddress {l} {
    return [describe $l store memoryAddress]
}
proc sameStore {l1 l2} {
    expr {[storeAddress $l1] == [storeAddress $l2]}
}
proc hasSpan {l args} {
    # Returns 1 if list has a span. If args are specified, they are checked with
    # span values (start and length)
    array set rep [describe $l]
    if {![info exists rep(span)]} {
	return 0
    }
    if {[llength $args] == 0} {
	return 1; # No need to check values
    }
    lassign $args start len
    if {[dict get $rep(span) spanStart] == $start &&
	[dict get $rep(span) spanLength] == $len} {
	return 1
    }
    return 0
}
proc checkListrep {l listLen numAllocated leadSpace tailSpace {refCount 0}} {
    # Checks if the internal representation of $l match
    # passed arguments. Return "" if yes, else error messages.
    array set rep [testlistrep describe $l]

    set rep(leadSpace) [dict get $rep(store) firstUsed]
    set rep(numAllocated) [dict get $rep(store) numAllocated]
    set rep(tailSpace) [expr {
			      $rep(numAllocated) - ($rep(leadSpace) + [dict get $rep(store) numUsed])
			  }]
    set rep(refCount) [dict get $rep(store) refCount]

    if {[info exists rep(span)]} {
	set rep(listLen) [dict get $rep(span) spanLength]
    } else {
	set rep(listLen) [dict get $rep(store) numUsed]
    }

    set errors [list]
    foreach arg {listLen numAllocated leadSpace tailSpace} {
	if {$rep($arg) != [set $arg]} {
	    lappend errors "$arg in list representation ($rep($arg)) is not expected value ([set $arg])."
	}
    }
    # Check refCount only if caller has specified it as non-0
    if {$refCount && $refCount != $rep(refCount)} {
	lappend errors "refCount in list representation ($rep(refCount)) is not expected value ($refCount)."
    }
    return $errors
}

proc assertListrep {l listLen numAllocated leadSpace tailSpace {refCount 0}} {
    # Like check_listrep but raises error
    set errors [checkListrep $l $listLen $numAllocated $leadSpace $tailSpace $refCount]
    if {[llength $errors]} {
	error [join $errors \n]
    }
    return
}

# The default length should be large enough that doubling the allocation will
# clearly distinguish free space allocation difference between front and back.
# (difference in the two should at least be 2 else we cannot tell if front
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
if {[testConstraint testlistrep]} {
    assertListrep [freeSpaceNone] 8 8 0 0 1
    assertListrep [freeSpaceLead] 8 11 3 0 1
    assertListrep [freeSpaceTail] 8 11 0 3 1
    assertListrep [freeSpaceBoth] 8 14 3 3 1
    assertListrep [zombieSample] 1000 1200 0 0 1
    if {![hasSpan [zombieSample]] || [dict get [testlistrep describe [zombieSample]] span spanStart] == 0} {
        error "zombieSample span missing or span start is at 0."
    }
}

# Define some variables for some indices because the Tcl compiler will do some
# operations completely in byte code if indices are literals
set zero 0
set one 1







|







168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
if {[testConstraint testlistrep]} {
    assertListrep [freeSpaceNone] 8 8 0 0 1
    assertListrep [freeSpaceLead] 8 11 3 0 1
    assertListrep [freeSpaceTail] 8 11 0 3 1
    assertListrep [freeSpaceBoth] 8 14 3 3 1
    assertListrep [zombieSample] 1000 1200 0 0 1
    if {![hasSpan [zombieSample]] || [dict get [testlistrep describe [zombieSample]] span spanStart] == 0} {
	error "zombieSample span missing or span start is at 0."
    }
}

# Define some variables for some indices because the Tcl compiler will do some
# operations completely in byte code if indices are literals
set zero 0
set one 1
Changes to tests/lmap.test.
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
	if {[string compare $i "b"] == 0} continue
	set i
    }
} {a c d}
test lmap-3.2 {continue tests} {
    set x 0
    list [lmap i {a b c d} {
    	incr x
    	if {[string compare $i "b"] != 0} continue
    	set i
    }] $x
} {b 4}
test lmap-3.3 {break tests} {
    set x 0
    list [lmap i {a b c d} {
	incr x
    	if {[string compare $i "c"] == 0} break
    	set i
    }] $x
} {{a b} 3}
# Check for bug similar to #406709
test lmap-3.4 {break tests} {
    set a 1
    lmap b b {list [concat a; break]; incr a}
    incr a







|
|
|






|
|







145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
	if {[string compare $i "b"] == 0} continue
	set i
    }
} {a c d}
test lmap-3.2 {continue tests} {
    set x 0
    list [lmap i {a b c d} {
	incr x
	if {[string compare $i "b"] != 0} continue
	set i
    }] $x
} {b 4}
test lmap-3.3 {break tests} {
    set x 0
    list [lmap i {a b c d} {
	incr x
	if {[string compare $i "c"] == 0} break
	set i
    }] $x
} {{a b} 3}
# Check for bug similar to #406709
test lmap-3.4 {break tests} {
    set a 1
    lmap b b {list [concat a; break]; incr a}
    incr a
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
	lmap a {} b {1 2 3} c {1 2} d {1 2 3 4} e {{1 2}} {
	    join [list $a $b $c $d $e] .
	}
    }}
} {{.1.1.1.1 2} .2.2.2. .3..3. ...4.}
test lmap-5.9 {lmap only sets vars if repeating loop} {
    apply {{} {
        set rgb {65535 0 0}
        lmap {r g b} [set rgb] {}
        return "r=$r, g=$g, b=$b"
    }}
} {r=65535, g=0, b=0}
test lmap-5.10 {lmap only supports local scalar variables} {
    apply {{} {
        lmap {a(3)} {1 2 3 4} {set {a(3)}}
    }}
} {1 2 3 4}

# "lmap" with "continue" and "break" (compiled)
test lmap-6.1 {continue tests} {
    apply {{} {
	lmap i {a b c d} {







|
|
|




|







289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
	lmap a {} b {1 2 3} c {1 2} d {1 2 3 4} e {{1 2}} {
	    join [list $a $b $c $d $e] .
	}
    }}
} {{.1.1.1.1 2} .2.2.2. .3..3. ...4.}
test lmap-5.9 {lmap only sets vars if repeating loop} {
    apply {{} {
	set rgb {65535 0 0}
	lmap {r g b} [set rgb] {}
	return "r=$r, g=$g, b=$b"
    }}
} {r=65535, g=0, b=0}
test lmap-5.10 {lmap only supports local scalar variables} {
    apply {{} {
	lmap {a(3)} {1 2 3 4} {set {a(3)}}
    }}
} {1 2 3 4}

# "lmap" with "continue" and "break" (compiled)
test lmap-6.1 {continue tests} {
    apply {{} {
	lmap i {a b c d} {
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375

# ----- Special cases and bugs -----------------------------------------------
test lmap-7.1 {compiled lmap backward jump works correctly} -setup {
    unset -nocomplain x
} -body {
    array set x {0 zero 1 one 2 two 3 three}
    lsort [apply {{arrayName} {
        upvar 1 $arrayName a
        lmap member [array names a] {
            list $member [set a($member)]
        }
    }} x]
} -result [lsort {{0 zero} {1 one} {2 two} {3 three}}]
test lmap-7.2 {noncompiled lmap and shared variable or value list objects that are converted to another type} -setup {
    unset -nocomplain x
} -body {
    lmap {12.0} {a b c} {
        set x 12.0
        set x [expr {$x + 1}]
    }
} -result {13.0 13.0 13.0}
# Test for incorrect "double evaluation" semantics
test lmap-7.3 {delayed substitution of body} {
    apply {{} {
       set a 0
       lmap a [list 1 2 3] "
           set x $a
       "
       return $x
    }}
} {0}
# Related to "foreach" test for [Bug 1189274]; crash on failure
test lmap-7.4 {empty list handling} {
    proc crash {} {







|
|
|
|






|
|







|







342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375

# ----- Special cases and bugs -----------------------------------------------
test lmap-7.1 {compiled lmap backward jump works correctly} -setup {
    unset -nocomplain x
} -body {
    array set x {0 zero 1 one 2 two 3 three}
    lsort [apply {{arrayName} {
	upvar 1 $arrayName a
	lmap member [array names a] {
	    list $member [set a($member)]
	}
    }} x]
} -result [lsort {{0 zero} {1 one} {2 two} {3 three}}]
test lmap-7.2 {noncompiled lmap and shared variable or value list objects that are converted to another type} -setup {
    unset -nocomplain x
} -body {
    lmap {12.0} {a b c} {
	set x 12.0
	set x [expr {$x + 1}]
    }
} -result {13.0 13.0 13.0}
# Test for incorrect "double evaluation" semantics
test lmap-7.3 {delayed substitution of body} {
    apply {{} {
       set a 0
       lmap a [list 1 2 3] "
	   set x $a
       "
       return $x
    }}
} {0}
# Related to "foreach" test for [Bug 1189274]; crash on failure
test lmap-7.4 {empty list handling} {
    proc crash {} {
Changes to tests/load.test.
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
    load -global [file join $testDir tcl9pkga$ext] Pkga
    load {} Pkga x
    info loaded x
} -cleanup {
    interp delete x
} -result [list [list [file join $testDir tcl9pkga$ext] Pkga]]

# On some platforms, like SunOS 4.1.3, these tests can't be run because
# they cause the process to exit.
#
# As of 2005, such ancient broken systems no longer matter.

test load-6.1 {errors loading file} [list $dll $loaded] {
    catch {load foo foo}
} {1}

test load-7.1 {Tcl_StaticLibrary procedure} [list teststaticlibrary] {
    set x "not loaded"
    teststaticlibrary Test 1 0







<
<
<
<
<







137
138
139
140
141
142
143





144
145
146
147
148
149
150
    load -global [file join $testDir tcl9pkga$ext] Pkga
    load {} Pkga x
    info loaded x
} -cleanup {
    interp delete x
} -result [list [list [file join $testDir tcl9pkga$ext] Pkga]]






test load-6.1 {errors loading file} [list $dll $loaded] {
    catch {load foo foo}
} {1}

test load-7.1 {Tcl_StaticLibrary procedure} [list teststaticlibrary] {
    set x "not loaded"
    teststaticlibrary Test 1 0
Changes to tests/lpop.test.
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137



test lpop-99.1 {performance} -constraints perf -body {
    set l [lrepeat 10000 x]
    set l2 $l
    set t1 [time {
        while {[llength $l] >= 2} {
            lpop l end
        }
    }]
    set l [lrepeat 30000 x]
    set l2 $l
    set t2 [time {
        while {[llength $l] >= 2} {
            lpop l end
        }
    }]
    regexp {\d+} $t1 ms1
    regexp {\d+} $t2 ms2
    set ratio [expr {double($ms2)/$ms1}]
    # Deleting from end should have linear performance
    expr {$ratio > 4 ? $ratio : 4}
} -result {4}

test lpop-99.2 {performance} -constraints perf -body {
    set l [lrepeat 10000 x]
    set l2 $l
    set t1 [time {
        while {[llength $l] >= 2} {
            lpop l 1
        }
    }]
    set l [lrepeat 30000 x]
    set l2 $l
    set t2 [time {
        while {[llength $l] >= 2} {
            lpop l 1
        }
    }]
    regexp {\d+} $t1 ms1
    regexp {\d+} $t2 ms2
    set ratio [expr {double($ms2)/$ms1}]
    expr {$ratio > 10 ? $ratio : 10}
} -result {10}








|
|
|




|
|
|












|
|
|




|
|
|







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137



test lpop-99.1 {performance} -constraints perf -body {
    set l [lrepeat 10000 x]
    set l2 $l
    set t1 [time {
	while {[llength $l] >= 2} {
	    lpop l end
	}
    }]
    set l [lrepeat 30000 x]
    set l2 $l
    set t2 [time {
	while {[llength $l] >= 2} {
	    lpop l end
	}
    }]
    regexp {\d+} $t1 ms1
    regexp {\d+} $t2 ms2
    set ratio [expr {double($ms2)/$ms1}]
    # Deleting from end should have linear performance
    expr {$ratio > 4 ? $ratio : 4}
} -result {4}

test lpop-99.2 {performance} -constraints perf -body {
    set l [lrepeat 10000 x]
    set l2 $l
    set t1 [time {
	while {[llength $l] >= 2} {
	    lpop l 1
	}
    }]
    set l [lrepeat 30000 x]
    set l2 $l
    set t2 [time {
	while {[llength $l] >= 2} {
	    lpop l 1
	}
    }]
    regexp {\d+} $t1 ms1
    regexp {\d+} $t2 ms2
    set ratio [expr {double($ms2)/$ms1}]
    expr {$ratio > 10 ? $ratio : 10}
} -result {10}

Changes to tests/lrange.test.
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
    set lss     {{} {a} {a b c} {a b c d}}
    set idxs    {-2 -1 0 1 2 3 end-3 end-2 end-1 end end+1 end+2}
    set lrange  lrange

    foreach ls $lss {
	foreach a $idxs {
	    foreach b $idxs {
                # Shared, uncompiled
                set ls2 $ls
                set expected [list [catch {$lrange $ls $a $b} m] $m]
                # Shared, compiled
                set tester [list lrange $ls $a $b]
                set script [list catch $tester m]
                set script "list \[$script\] \$m"
                test lrange-5.[incr n].1 {lrange shared compiled} -body \
			[list apply [list {} $script]] -result $expected
                # Unshared, uncompiled
                set tester [string map [list %l [list $ls] %a $a %b $b] {
                    [string cat l range] [lrange %l 0 end] %a %b
                }]
                set script [list catch $tester m]
                set script "list \[$script\] \$m"
                test lrange-5.$n.2 {lrange unshared uncompiled} -body \
			[list apply [list {} $script]] -result $expected
                # Unshared, compiled
                set tester [string map [list %l [list $ls] %a $a %b $b] {
                    lrange [lrange %l 0 end] %a %b
                }]
                set script [list catch $tester m]
                set script "list \[$script\] \$m"
                test lrange-5.$n.3 {lrange unshared compiled} -body \
			[list apply [list {} $script]] -result $expected
	    }
	}
    }
}}

# cleanup







|
|
|
|
|
|
|
|

|
|
|
|
|
|
|

|
|
|
|
|
|
|







214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
    set lss     {{} {a} {a b c} {a b c d}}
    set idxs    {-2 -1 0 1 2 3 end-3 end-2 end-1 end end+1 end+2}
    set lrange  lrange

    foreach ls $lss {
	foreach a $idxs {
	    foreach b $idxs {
		# Shared, uncompiled
		set ls2 $ls
		set expected [list [catch {$lrange $ls $a $b} m] $m]
		# Shared, compiled
		set tester [list lrange $ls $a $b]
		set script [list catch $tester m]
		set script "list \[$script\] \$m"
		test lrange-5.[incr n].1 {lrange shared compiled} -body \
			[list apply [list {} $script]] -result $expected
		# Unshared, uncompiled
		set tester [string map [list %l [list $ls] %a $a %b $b] {
		    [string cat l range] [lrange %l 0 end] %a %b
		}]
		set script [list catch $tester m]
		set script "list \[$script\] \$m"
		test lrange-5.$n.2 {lrange unshared uncompiled} -body \
			[list apply [list {} $script]] -result $expected
		# Unshared, compiled
		set tester [string map [list %l [list $ls] %a $a %b $b] {
		    lrange [lrange %l 0 end] %a %b
		}]
		set script [list catch $tester m]
		set script "list \[$script\] \$m"
		test lrange-5.$n.3 {lrange unshared compiled} -body \
			[list apply [list {} $script]] -result $expected
	    }
	}
    }
}}

# cleanup
Changes to tests/lreplace.test.
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
test lreplace-1.25 {lreplace command} {
    concat \"[lreplace {\}\     hello} end end]\"
} {"\}\ "}
test lreplace-1.26 {lreplace command} {
    catch {unset foo}
    set foo {a b}
    list [set foo [lreplace $foo end end]] \
        [set foo [lreplace $foo end end]] \
        [set foo [lreplace $foo end end]]
} {a {} {}}
test lreplace-1.27 {lreplace command} -body {
    lreplace x 1 1
} -result x
test lreplace-1.28 {lreplace command} -body {
    lreplace x 1 1 y
} -result {x y}







|
|







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
test lreplace-1.25 {lreplace command} {
    concat \"[lreplace {\}\     hello} end end]\"
} {"\}\ "}
test lreplace-1.26 {lreplace command} {
    catch {unset foo}
    set foo {a b}
    list [set foo [lreplace $foo end end]] \
	[set foo [lreplace $foo end end]] \
	[set foo [lreplace $foo end end]]
} {a {} {}}
test lreplace-1.27 {lreplace command} -body {
    lreplace x 1 1
} -result x
test lreplace-1.28 {lreplace command} -body {
    lreplace x 1 1 y
} -result {x y}
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
} -result {0 x}
test lreplace-2.7 {lreplace errors} -body {
    list [catch {lreplace x 2 2} msg] $msg
} -result {0 x}

test lreplace-3.1 {lreplace won't modify shared argument objects} {
    proc p {} {
        lreplace "a b c" 1 1 "x y"
        return "a b c"
    }
    p
} "a b c"

test lreplace-4.1 {Bug ccc2c2cc98: lreplace edge case} {
    lreplace {} 1 1
} {}







|
|







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
} -result {0 x}
test lreplace-2.7 {lreplace errors} -body {
    list [catch {lreplace x 2 2} msg] $msg
} -result {0 x}

test lreplace-3.1 {lreplace won't modify shared argument objects} {
    proc p {} {
	lreplace "a b c" 1 1 "x y"
	return "a b c"
    }
    p
} "a b c"

test lreplace-4.1 {Bug ccc2c2cc98: lreplace edge case} {
    lreplace {} 1 1
} {}
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
    set l {\}\     hello}
    concat \"[ledit l end end]\" $l
} {"\}\ " \}\ }
test ledit-1.26 {ledit command} {
    catch {unset foo}
    set foo {a b}
    list [ledit foo end end] $foo \
        [ledit foo end end] $foo \
        [ledit foo end end] $foo
} {a a {} {} {} {}}
test ledit-1.27 {lsubset command} -body {
    set l x
    list [ledit l 1 1] $l
} -result {x x}
test ledit-1.28 {ledit command} -body {
    set l x







|
|







337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
    set l {\}\     hello}
    concat \"[ledit l end end]\" $l
} {"\}\ " \}\ }
test ledit-1.26 {ledit command} {
    catch {unset foo}
    set foo {a b}
    list [ledit foo end end] $foo \
	[ledit foo end end] $foo \
	[ledit foo end end] $foo
} {a a {} {} {} {}}
test ledit-1.27 {lsubset command} -body {
    set l x
    list [ledit l 1 1] $l
} -result {x x}
test ledit-1.28 {ledit command} -body {
    set l x
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
    unset -nocomplain arr
    set arr(y) y
    ledit arr(x) 0 0 x
} -returnCodes error -result {can't read "arr(x)": no such element in array}

test ledit-3.1 {ledit won't modify shared argument objects} {
    proc p {} {
        set l "a b c"
        ledit l 1 1 "x y"
        # The literal in locals table should be unmodified
        return [list "a b c" $l]
    }
    p
} {{a b c} {a {x y} c}}

# Following bugs were in lreplace. Make sure ledit does not have them
test ledit-4.1 {Bug ccc2c2cc98: lreplace edge case} {
    set l {}







|
|
|
|







405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
    unset -nocomplain arr
    set arr(y) y
    ledit arr(x) 0 0 x
} -returnCodes error -result {can't read "arr(x)": no such element in array}

test ledit-3.1 {ledit won't modify shared argument objects} {
    proc p {} {
	set l "a b c"
	ledit l 1 1 "x y"
	# The literal in locals table should be unmodified
	return [list "a b c" $l]
    }
    p
} {{a b c} {a {x y} c}}

# Following bugs were in lreplace. Make sure ledit does not have them
test ledit-4.1 {Bug ccc2c2cc98: lreplace edge case} {
    set l {}
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
    apply {x {
	ledit x end 0 A
    }} {a b c}
} {a b A c}

test ledit-bug-a366c6efee {Bug [a366c6efee]} -body {
    apply {{} {
        set l { }
        string length [ledit l 1 1]; # Force string generation
        set result foo
        append result " " bar
    }}
} -result "foo bar"

# Testing for compiled behaviour. Far too many variations to check with
# spelt-out tests. Note that this *just* checks whether the compiled version
# and the interpreted version are the same, not whether the interpreted
# version is correct.







|
|
|
|







503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
    apply {x {
	ledit x end 0 A
    }} {a b c}
} {a b A c}

test ledit-bug-a366c6efee {Bug [a366c6efee]} -body {
    apply {{} {
	set l { }
	string length [ledit l 1 1]; # Force string generation
	set result foo
	append result " " bar
    }}
} -result "foo bar"

# Testing for compiled behaviour. Far too many variations to check with
# spelt-out tests. Note that this *just* checks whether the compiled version
# and the interpreted version are the same, not whether the interpreted
# version is correct.
Changes to tests/lseq.test.
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
testConstraint has64BitLengths [expr {$tcl_platform(pointerSize) == 8}]
testConstraint has32BitLengths [expr {$tcl_platform(pointerSize) == 4}]

proc memusage {} {
    set fd [open /proc/[pid]/statm]
    set line [gets $fd]
    if {[llength $line] != 7} {
        error "Unexpected /proc/pid/statm format"
    }
    return [lindex $line 5]
}
testConstraint hasMemUsage [expr {![catch {memusage}]}]

# Arg errors
test lseq-1.1 {error cases} -body {







|







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
testConstraint has64BitLengths [expr {$tcl_platform(pointerSize) == 8}]
testConstraint has32BitLengths [expr {$tcl_platform(pointerSize) == 4}]

proc memusage {} {
    set fd [open /proc/[pid]/statm]
    set line [gets $fd]
    if {[llength $line] != 7} {
	error "Unexpected /proc/pid/statm format"
    }
    return [lindex $line 5]
}
testConstraint hasMemUsage [expr {![catch {memusage}]}]

# Arg errors
test lseq-1.1 {error cases} -body {
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
    set srchlist {}
    for {set i 5} {$i < 25} {incr i} {
	lappend srchlist [lseq $i count 7 by 3]
    }
    set a [lsearch -all -inline -index 1 $srchlist 23]
    set b [lmap i $a {lindex [tcl::unsupported::representation $i] 3}]
    list [lindex [tcl::unsupported::representation $a] 3] $a $b \
        [lindex [tcl::unsupported::representation [lindex $srchlist 15]] 3]
} -cleanup {
    unset a b srchlist i
} -result {list {{20 23 26 29 32 35 38}} arithseries arithseries}


# lsearch -
#  -- should not shimmer lseq  list
#  -- should not leak lseq elements
test lseq-3.33 {lsearch nested lists of lseq} -constraints arithSeriesShimmer -body {
    set srchlist {}
    for {set i 5} {$i < 25} {incr i} {
	lappend srchlist [lseq $i count 7 by 3]
    }
    set a [lsearch -all -inline -index 1 $srchlist 23]
    set b [lmap i $a {lindex [tcl::unsupported::representation $i] 3}]
    list [lindex [tcl::unsupported::representation $a] 3] $a $b \
        [lindex [tcl::unsupported::representation [lindex $srchlist 15]] 3]
} -cleanup {
    unset srchlist i a b
} -result {list {{20 23 26 29 32 35 38}} arithseries arithseries}

test lseq-3.34 {"in" operator} -body {
    set seq [lseq 0.3 15e4 0.1]
    set inlist {}







|
















|







513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
    set srchlist {}
    for {set i 5} {$i < 25} {incr i} {
	lappend srchlist [lseq $i count 7 by 3]
    }
    set a [lsearch -all -inline -index 1 $srchlist 23]
    set b [lmap i $a {lindex [tcl::unsupported::representation $i] 3}]
    list [lindex [tcl::unsupported::representation $a] 3] $a $b \
	[lindex [tcl::unsupported::representation [lindex $srchlist 15]] 3]
} -cleanup {
    unset a b srchlist i
} -result {list {{20 23 26 29 32 35 38}} arithseries arithseries}


# lsearch -
#  -- should not shimmer lseq  list
#  -- should not leak lseq elements
test lseq-3.33 {lsearch nested lists of lseq} -constraints arithSeriesShimmer -body {
    set srchlist {}
    for {set i 5} {$i < 25} {incr i} {
	lappend srchlist [lseq $i count 7 by 3]
    }
    set a [lsearch -all -inline -index 1 $srchlist 23]
    set b [lmap i $a {lindex [tcl::unsupported::representation $i] 3}]
    list [lindex [tcl::unsupported::representation $a] 3] $a $b \
	[lindex [tcl::unsupported::representation [lindex $srchlist 15]] 3]
} -cleanup {
    unset srchlist i a b
} -result {list {{20 23 26 29 32 35 38}} arithseries arithseries}

test lseq-3.34 {"in" operator} -body {
    set seq [lseq 0.3 15e4 0.1]
    set inlist {}
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
} -cleanup {
    unset -nocomplain fred ginger
} -returnCodes 1 -result {bad index "fred": must be integer?[+-]integer? or end?[+-]integer?}

test lseq-4.9 {lrange empty/partial sets} -body {
    set res {}
    foreach {fred ginger} {7 8 4 9 0 15 9 9 4 2} {
        lappend res [lrange [lseq 1 5] $fred $ginger]
    }
    set res
} -cleanup {unset res fred ginger} -result {{} 5 {1 2 3 4 5} {} {}}

# Panic when using variable value?
test lseq-4.10 {panic using variable index} -body {
    set i 0







|







717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
} -cleanup {
    unset -nocomplain fred ginger
} -returnCodes 1 -result {bad index "fred": must be integer?[+-]integer? or end?[+-]integer?}

test lseq-4.9 {lrange empty/partial sets} -body {
    set res {}
    foreach {fred ginger} {7 8 4 9 0 15 9 9 4 2} {
	lappend res [lrange [lseq 1 5] $fred $ginger]
    }
    set res
} -cleanup {unset res fred ginger} -result {{} 5 {1 2 3 4 5} {} {}}

# Panic when using variable value?
test lseq-4.10 {panic using variable index} -body {
    set i 0
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
} -returnCodes 1 -result {max length of a Tcl list exceeded}

test lseq-4.13 {bug lseq} -constraints has64BitLengths -body {
    set l [lseq 0x7fffffffffffffff]
    list \
    [llength $l] \
    [lindex $l end] \
        [lindex $l 9223372036854775800]
} -cleanup {unset l} -result {9223372036854775807 9223372036854775806 9223372036854775800}


test lseq-4.14 {bug lseq - inconsistent rounding} {
    # using a non-integer increment, [lseq] rounding seems to be not consistent:
    lseq 4 40 0.1
} {4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 7.0 7.1 7.2 7.3 7.4 7.5 7.6 7.7 7.8 7.9 8.0 8.1 8.2 8.3 8.4 8.5 8.6 8.7 8.8 8.9 9.0 9.1 9.2 9.3 9.4 9.5 9.6 9.7 9.8 9.9 10.0 10.1 10.2 10.3 10.4 10.5 10.6 10.7 10.8 10.9 11.0 11.1 11.2 11.3 11.4 11.5 11.6 11.7 11.8 11.9 12.0 12.1 12.2 12.3 12.4 12.5 12.6 12.7 12.8 12.9 13.0 13.1 13.2 13.3 13.4 13.5 13.6 13.7 13.8 13.9 14.0 14.1 14.2 14.3 14.4 14.5 14.6 14.7 14.8 14.9 15.0 15.1 15.2 15.3 15.4 15.5 15.6 15.7 15.8 15.9 16.0 16.1 16.2 16.3 16.4 16.5 16.6 16.7 16.8 16.9 17.0 17.1 17.2 17.3 17.4 17.5 17.6 17.7 17.8 17.9 18.0 18.1 18.2 18.3 18.4 18.5 18.6 18.7 18.8 18.9 19.0 19.1 19.2 19.3 19.4 19.5 19.6 19.7 19.8 19.9 20.0 20.1 20.2 20.3 20.4 20.5 20.6 20.7 20.8 20.9 21.0 21.1 21.2 21.3 21.4 21.5 21.6 21.7 21.8 21.9 22.0 22.1 22.2 22.3 22.4 22.5 22.6 22.7 22.8 22.9 23.0 23.1 23.2 23.3 23.4 23.5 23.6 23.7 23.8 23.9 24.0 24.1 24.2 24.3 24.4 24.5 24.6 24.7 24.8 24.9 25.0 25.1 25.2 25.3 25.4 25.5 25.6 25.7 25.8 25.9 26.0 26.1 26.2 26.3 26.4 26.5 26.6 26.7 26.8 26.9 27.0 27.1 27.2 27.3 27.4 27.5 27.6 27.7 27.8 27.9 28.0 28.1 28.2 28.3 28.4 28.5 28.6 28.7 28.8 28.9 29.0 29.1 29.2 29.3 29.4 29.5 29.6 29.7 29.8 29.9 30.0 30.1 30.2 30.3 30.4 30.5 30.6 30.7 30.8 30.9 31.0 31.1 31.2 31.3 31.4 31.5 31.6 31.7 31.8 31.9 32.0 32.1 32.2 32.3 32.4 32.5 32.6 32.7 32.8 32.9 33.0 33.1 33.2 33.3 33.4 33.5 33.6 33.7 33.8 33.9 34.0 34.1 34.2 34.3 34.4 34.5 34.6 34.7 34.8 34.9 35.0 35.1 35.2 35.3 35.4 35.5 35.6 35.7 35.8 35.9 36.0 36.1 36.2 36.3 36.4 36.5 36.6 36.7 36.8 36.9 37.0 37.1 37.2 37.3 37.4 37.5 37.6 37.7 37.8 37.9 38.0 38.1 38.2 38.3 38.4 38.5 38.6 38.7 38.8 38.9 39.0 39.1 39.2 39.3 39.4 39.5 39.6 39.7 39.8 39.9 40.0}







|







745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
} -returnCodes 1 -result {max length of a Tcl list exceeded}

test lseq-4.13 {bug lseq} -constraints has64BitLengths -body {
    set l [lseq 0x7fffffffffffffff]
    list \
    [llength $l] \
    [lindex $l end] \
	[lindex $l 9223372036854775800]
} -cleanup {unset l} -result {9223372036854775807 9223372036854775806 9223372036854775800}


test lseq-4.14 {bug lseq - inconsistent rounding} {
    # using a non-integer increment, [lseq] rounding seems to be not consistent:
    lseq 4 40 0.1
} {4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 7.0 7.1 7.2 7.3 7.4 7.5 7.6 7.7 7.8 7.9 8.0 8.1 8.2 8.3 8.4 8.5 8.6 8.7 8.8 8.9 9.0 9.1 9.2 9.3 9.4 9.5 9.6 9.7 9.8 9.9 10.0 10.1 10.2 10.3 10.4 10.5 10.6 10.7 10.8 10.9 11.0 11.1 11.2 11.3 11.4 11.5 11.6 11.7 11.8 11.9 12.0 12.1 12.2 12.3 12.4 12.5 12.6 12.7 12.8 12.9 13.0 13.1 13.2 13.3 13.4 13.5 13.6 13.7 13.8 13.9 14.0 14.1 14.2 14.3 14.4 14.5 14.6 14.7 14.8 14.9 15.0 15.1 15.2 15.3 15.4 15.5 15.6 15.7 15.8 15.9 16.0 16.1 16.2 16.3 16.4 16.5 16.6 16.7 16.8 16.9 17.0 17.1 17.2 17.3 17.4 17.5 17.6 17.7 17.8 17.9 18.0 18.1 18.2 18.3 18.4 18.5 18.6 18.7 18.8 18.9 19.0 19.1 19.2 19.3 19.4 19.5 19.6 19.7 19.8 19.9 20.0 20.1 20.2 20.3 20.4 20.5 20.6 20.7 20.8 20.9 21.0 21.1 21.2 21.3 21.4 21.5 21.6 21.7 21.8 21.9 22.0 22.1 22.2 22.3 22.4 22.5 22.6 22.7 22.8 22.9 23.0 23.1 23.2 23.3 23.4 23.5 23.6 23.7 23.8 23.9 24.0 24.1 24.2 24.3 24.4 24.5 24.6 24.7 24.8 24.9 25.0 25.1 25.2 25.3 25.4 25.5 25.6 25.7 25.8 25.9 26.0 26.1 26.2 26.3 26.4 26.5 26.6 26.7 26.8 26.9 27.0 27.1 27.2 27.3 27.4 27.5 27.6 27.7 27.8 27.9 28.0 28.1 28.2 28.3 28.4 28.5 28.6 28.7 28.8 28.9 29.0 29.1 29.2 29.3 29.4 29.5 29.6 29.7 29.8 29.9 30.0 30.1 30.2 30.3 30.4 30.5 30.6 30.7 30.8 30.9 31.0 31.1 31.2 31.3 31.4 31.5 31.6 31.7 31.8 31.9 32.0 32.1 32.2 32.3 32.4 32.5 32.6 32.7 32.8 32.9 33.0 33.1 33.2 33.3 33.4 33.5 33.6 33.7 33.8 33.9 34.0 34.1 34.2 34.3 34.4 34.5 34.6 34.7 34.8 34.9 35.0 35.1 35.2 35.3 35.4 35.5 35.6 35.7 35.8 35.9 36.0 36.1 36.2 36.3 36.4 36.5 36.6 36.7 36.8 36.9 37.0 37.1 37.2 37.3 37.4 37.5 37.6 37.7 37.8 37.9 38.0 38.1 38.2 38.3 38.4 38.5 38.6 38.7 38.8 38.9 39.0 39.1 39.2 39.3 39.4 39.5 39.6 39.7 39.8 39.9 40.0}
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
#  -- lseq list should not shimmer
#  -- lseq elements should not leak
test lseq-4.17 {concat shimmer} -body {
    set rng [lseq 8 15 2]
    set pre [list A b C]
    set pst [list x Y z]
    list [concat $pre $rng $pst] \
         [lindex [tcl::unsupported::representation $pre] 3] \
         [lindex [tcl::unsupported::representation $rng] 3] \
         [lindex [tcl::unsupported::representation $pst] 3]
} -cleanup {unset rng pre pst} -result  {{A b C 8 10 12 14 x Y z} list arithseries list}

test lseq-4.18 {concat shimmer} -body {
    set rng [lseq 8 15 2]
    set pre [list A b C]
    set pst [list x Y z]
    list [concat $rng $pre $pst] \
         [lindex [tcl::unsupported::representation $rng] 3] \
         [lindex [tcl::unsupported::representation $pre] 3] \
         [lindex [tcl::unsupported::representation $pst] 3]
} -cleanup {unset rng pre pst} -result {{8 10 12 14 A b C x Y z} arithseries list list}

# Test lseq elements as var names
test lseq-4.19 {varnames} -body {
    set plist {}
    foreach v {auto_execok auto_load auto_qualify} {
	lappend plist proc $v [info args $v] [info body $v]







|
|
|







|
|
|







774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
#  -- lseq list should not shimmer
#  -- lseq elements should not leak
test lseq-4.17 {concat shimmer} -body {
    set rng [lseq 8 15 2]
    set pre [list A b C]
    set pst [list x Y z]
    list [concat $pre $rng $pst] \
	 [lindex [tcl::unsupported::representation $pre] 3] \
	 [lindex [tcl::unsupported::representation $rng] 3] \
	 [lindex [tcl::unsupported::representation $pst] 3]
} -cleanup {unset rng pre pst} -result  {{A b C 8 10 12 14 x Y z} list arithseries list}

test lseq-4.18 {concat shimmer} -body {
    set rng [lseq 8 15 2]
    set pre [list A b C]
    set pst [list x Y z]
    list [concat $rng $pre $pst] \
	 [lindex [tcl::unsupported::representation $rng] 3] \
	 [lindex [tcl::unsupported::representation $pre] 3] \
	 [lindex [tcl::unsupported::representation $pst] 3]
} -cleanup {unset rng pre pst} -result {{8 10 12 14 A b C x Y z} arithseries list list}

# Test lseq elements as var names
test lseq-4.19 {varnames} -body {
    set plist {}
    foreach v {auto_execok auto_load auto_qualify} {
	lappend plist proc $v [info args $v] [info body $v]
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
    lappend result $msg
    lappend result [lseq 3]
    lappend result [lseq 3.0]
    lappend result [lseq 5.1e1]
    lappend result [string compare [lseq 3] [lseq 3.0]]
    set result
} -result {1 {expected integer but got "3.1"} 0 {5 6 7} {0 1 2} {0 1 2} {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50} 0}
    
# cleanup
::tcltest::cleanupTests

return

# Local Variables:
# mode: tcl
# End:







|








860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
    lappend result $msg
    lappend result [lseq 3]
    lappend result [lseq 3.0]
    lappend result [lseq 5.1e1]
    lappend result [string compare [lseq 3] [lseq 3.0]]
    set result
} -result {1 {expected integer but got "3.1"} 0 {5 6 7} {0 1 2} {0 1 2} {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50} 0}

# cleanup
::tcltest::cleanupTests

return

# Local Variables:
# mode: tcl
# End:
Changes to tests/main.test.
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
	[llength [package provide tcl::test]]
	&& [package vsatisfies [package provide tcl::test] 8.5-]}]

    # Procedure to simulate interactive typing of commands, line by line
    proc type {chan script} {
	foreach line [split $script \n] {
	    if {[catch {
	        puts $chan $line
	        flush $chan
	    }]} {
		return
	    }
	    # Grrr... Behavior depends on this value.
	    after 1000
	}
    }







|
|







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
	[llength [package provide tcl::test]]
	&& [package vsatisfies [package provide tcl::test] 8.5-]}]

    # Procedure to simulate interactive typing of commands, line by line
    proc type {chan script} {
	foreach line [split $script \n] {
	    if {[catch {
		puts $chan $line
		flush $chan
	    }]} {
		return
	    }
	    # Grrr... Behavior depends on this value.
	    after 1000
	}
    }
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
	close $f
	file delete result
	removeFile rc
    } -result "application-specific initialization failed:\
	\nExit MainLoop\nIn exit\neven 0\n"

    test Tcl_Main-4.5 {
        Tcl_Main: Bug 1481986
    } -constraints {
        exec tcl::test
    } -setup {
        set rc [makeFile {
                testsetmainloop
                after 0 {puts "Event callback"}
        } rc]
    } -body {
        set f [open "|[list [interpreter] -appinitprocsetrcfile $rc]" w+]
        after 1000
        type $f {puts {Interactive output}
            exit
        }
        read $f
    } -cleanup {
        catch {close $f}
        removeFile rc
    } -result "Event callback\nInteractive output\n"

    # Tests Tcl_Main-5.*: interactive operations

    test Tcl_Main-5.1 {
	Tcl_Main: tcl_interactive must be boolean
    } -constraints {







|

|

|
|
|
|

|
|
|
|
|
|

|
|







542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
	close $f
	file delete result
	removeFile rc
    } -result "application-specific initialization failed:\
	\nExit MainLoop\nIn exit\neven 0\n"

    test Tcl_Main-4.5 {
	Tcl_Main: Bug 1481986
    } -constraints {
	exec tcl::test
    } -setup {
	set rc [makeFile {
		testsetmainloop
		after 0 {puts "Event callback"}
	} rc]
    } -body {
	set f [open "|[list [interpreter] -appinitprocsetrcfile $rc]" w+]
	after 1000
	type $f {puts {Interactive output}
	    exit
	}
	read $f
    } -cleanup {
	catch {close $f}
	removeFile rc
    } -result "Event callback\nInteractive output\n"

    # Tests Tcl_Main-5.*: interactive operations

    test Tcl_Main-5.1 {
	Tcl_Main: tcl_interactive must be boolean
    } -constraints {
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
    } -constraints {
	exec tcl::test
    } -setup {
	catch {set f [open "|[list [interpreter]]" w+]}
	catch {chan configure $f -blocking 0}
    } -body {
	type $f "testsetmainloop
	         after 2000 testexitmainloop
	         puts \{1 2"
	after 4000
	type $f "3 4\}"
	set code1 [catch {gets $f} line1]
	set code2 [catch {gets $f} line2]
	set code3 [catch {gets $f} line3]
	list $code1 $line1 $code2 $line2 $code3 $line3
    } -cleanup {







|
|







745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
    } -constraints {
	exec tcl::test
    } -setup {
	catch {set f [open "|[list [interpreter]]" w+]}
	catch {chan configure $f -blocking 0}
    } -body {
	type $f "testsetmainloop
		 after 2000 testexitmainloop
		 puts \{1 2"
	after 4000
	type $f "3 4\}"
	set code1 [catch {gets $f} line1]
	set code2 [catch {gets $f} line2]
	set code3 [catch {gets $f} line3]
	list $code1 $line1 $code2 $line2 $code3 $line3
    } -cleanup {
Changes to tests/mathop.test.
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# Shared / unshared arguments
# Original / imported
proc TestOp {op args} {
    set results {}

    # Non byte compiled version, shared args
    if {[catch {::tcl::mathop::$op {*}$args} res]} {
        append res " $::errorCode"
    }
    lappend results $res

    # Non byte compiled version, unshared args
    set cmd ::tcl::mathop::\$op
    foreach arg $args {
        append cmd " \[format %s [list $arg]\]"
    }
    if {[catch $cmd res]} {
        append res " $::errorCode"
    }
    lappend results $res

    # Non byte compiled imported
    if {[catch {::testmathop2::$op {*}$args} res]} {
        append res " $::errorCode"
    }
    lappend results [string map {testmathop2 tcl::mathop} $res]

    # BC version
    set argList1 {}
    set argList2 {}
    set argList3 {}
    for {set t 0} {$t < [llength $args]} {incr t} {
        lappend argList1 a$t
        lappend argList2 \$a$t
        lappend argList3 "\[format %s \$a$t\]"
    }
    # Shared args
    proc _TestOp  $argList1 "::tcl::mathop::$op [join $argList2]"
    # Unshared args
    proc _TestOp2 $argList1 "::tcl::mathop::$op [join $argList3]"
    # Imported
    proc _TestOp3 $argList1 "::testmathop2::$op [join $argList2]"

    set ::tcl_traceCompile 0  ;# Set to 2 to help with debug
    if {[catch {_TestOp {*}$args} res]} {
        append res " $::errorCode"
    }
    set ::tcl_traceCompile 0
    lappend results $res

    if {[catch {_TestOp2 {*}$args} res]} {
        append res " $::errorCode"
    }
    lappend results $res

    if {[catch {_TestOp3 {*}$args} res]} {
        append res " $::errorCode"
    }
    lappend results [string map {testmathop2 tcl::mathop} $res]

    # Check that they do the same
    set len [llength $results]
    for {set i 0} {$i < ($len - 1)} {incr i} {
        set res1 [lindex $results $i]
        set res2 [lindex $results $i+1]
        if {$res1 ne $res2} {
            return "$i:($res1 != $res2)"
        }
    }
    return [lindex $results 0]
}

# start of tests

namespace eval ::testmathop {







|






|


|





|








|
|
|










|





|




|






|
|
|
|
|







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# Shared / unshared arguments
# Original / imported
proc TestOp {op args} {
    set results {}

    # Non byte compiled version, shared args
    if {[catch {::tcl::mathop::$op {*}$args} res]} {
	append res " $::errorCode"
    }
    lappend results $res

    # Non byte compiled version, unshared args
    set cmd ::tcl::mathop::\$op
    foreach arg $args {
	append cmd " \[format %s [list $arg]\]"
    }
    if {[catch $cmd res]} {
	append res " $::errorCode"
    }
    lappend results $res

    # Non byte compiled imported
    if {[catch {::testmathop2::$op {*}$args} res]} {
	append res " $::errorCode"
    }
    lappend results [string map {testmathop2 tcl::mathop} $res]

    # BC version
    set argList1 {}
    set argList2 {}
    set argList3 {}
    for {set t 0} {$t < [llength $args]} {incr t} {
	lappend argList1 a$t
	lappend argList2 \$a$t
	lappend argList3 "\[format %s \$a$t\]"
    }
    # Shared args
    proc _TestOp  $argList1 "::tcl::mathop::$op [join $argList2]"
    # Unshared args
    proc _TestOp2 $argList1 "::tcl::mathop::$op [join $argList3]"
    # Imported
    proc _TestOp3 $argList1 "::testmathop2::$op [join $argList2]"

    set ::tcl_traceCompile 0  ;# Set to 2 to help with debug
    if {[catch {_TestOp {*}$args} res]} {
	append res " $::errorCode"
    }
    set ::tcl_traceCompile 0
    lappend results $res

    if {[catch {_TestOp2 {*}$args} res]} {
	append res " $::errorCode"
    }
    lappend results $res

    if {[catch {_TestOp3 {*}$args} res]} {
	append res " $::errorCode"
    }
    lappend results [string map {testmathop2 tcl::mathop} $res]

    # Check that they do the same
    set len [llength $results]
    for {set i 0} {$i < ($len - 1)} {incr i} {
	set res1 [lindex $results $i]
	set res2 [lindex $results $i+1]
	if {$res1 ne $res2} {
	    return "$i:($res1 != $res2)"
	}
    }
    return [lindex $results 0]
}

# start of tests

namespace eval ::testmathop {
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
    } {70720 70720}

    # TODO: % ** << >>  - /  == != < <= > >=  ne  in ni

    test mathop-13.100 {compiled -: argument processing order} -body {
      # Bytecode compilation known hard for 3+ arguments
      list [catch {
          - [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
      } msg] $msg $x
    } -result {1 expected 2}

    test mathop-14.100 {compiled /: argument processing order} -body {
      # Bytecode compilation known hard for 3+ arguments
      list [catch {
          / [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
      } msg] $msg $x
    } -result {1 expected 2}
}

test mathop-20.1 { zero args, return unit } {
    set res {}
    foreach op {+ * & ^ | ** < <= > >= == eq} {
        lappend res [TestOp $op]
    }
    set res
} {0 1 -1 0 0 1 1 1 1 1 1 1}
test mathop-20.2 { zero args, not allowed } {
    set exp {}
    foreach op {~ ! << >> % != ne in ni - /} {
        set res [TestOp $op]
        if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
            lappend exp 0
        } else {
            lappend exp $res
        }
    }
    set exp
} {0 0 0 0 0 0 0 0 0 0 0}
test mathop-20.3 { one arg } {
    set res {}
    foreach val {7 8.3} {
        foreach op {+ ** - * / < <= > >= == eq !} {
            lappend res [TestOp $op $val]
        }
    }
    set res
} [list 7   7   -7   7   [expr {1.0/7.0}] 1 1 1 1 1 1 0 \
        8.3 8.3 -8.3 8.3 [expr {1.0/8.3}] 1 1 1 1 1 1 0]
test mathop-20.4 { one arg, integer only ops } {
    set res {}
    foreach val {23} {
        foreach op {& | ^ ~} {
            lappend res [TestOp $op $val]
        }
    }
    set res
} [list 23 23 23 -24]
test mathop-20.5 { one arg, not allowed } {
    set exp {}
    foreach op {% != ne in ni << >>} {
        set res [TestOp $op 1]
        if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
            lappend exp 0
        } else {
            lappend exp $res
        }
    }
    set exp
} {0 0 0 0 0 0 0}
test mathop-20.6 { one arg, error } {
    set res {}
    set exp {}
    foreach vals {x {1 x} {1 1 x} {1 x 1}} {
        # skipping - for now, knownbug...
        foreach op {+ * / & | ^ **} {
            #lappend res [TestOp $op {*}$vals]
            #lappend exp "cannot use non-numeric string \"x\" as right operand of \"$op\"\
		#ARITH DOMAIN {non-numeric string}"
        }
    }
    foreach op {+ * / & | ^ **} {
	lappend res [TestOp $op NaN 1]
	lappend exp "cannot use non-numeric floating-point value \"NaN\" as left operand of \"$op\"\
	    ARITH DOMAIN {non-numeric floating-point value}"
    }
    expr {$res eq $exp ? 0 : "$res\n$exp"}
} 0
test mathop-20.7 { multi arg } {
    set res {}
    foreach vals {{1 2} {3 4 5} {4 3 2 1}} {
        foreach op {+ - * /} {
            lappend res [TestOp $op {*}$vals]
        }
    }
    set res
} [list 3 -1 2 0  12 -6 60 0  10 -2 24 0]
test mathop-20.8 { multi arg, double } {
    set res {}
    foreach vals {{1.0 2} {3.0 4 5} {4 3.0 2 1}
	    {1.0 -1.0 1e-18} {1.0 1.0 1e-18}} {
        foreach op {+ - * /} {
            lappend res [TestOp $op {*}$vals]
        }
    }
    set res
} [list 3.0 -1.0 2.0 0.5  12.0 -6.0 60.0 0.15  10.0 -2.0 24.0 [expr {2.0/3}] 1e-18 2.0 -1e-18 [expr {-1.0/1e-18}] 2.0 -1e-18 1e-18 [expr {1.0/1e-18}]]

test mathop-21.1 { unary ops, bitnot } {
    set res {}
    lappend res [TestOp ~ 7]







|






|







|






|
|
|
|
|
|






|
|
|



|



|
|
|






|
|
|
|
|
|







|
|
|
|

|











|
|
|







|
|
|







702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
    } {70720 70720}

    # TODO: % ** << >>  - /  == != < <= > >=  ne  in ni

    test mathop-13.100 {compiled -: argument processing order} -body {
      # Bytecode compilation known hard for 3+ arguments
      list [catch {
	  - [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
      } msg] $msg $x
    } -result {1 expected 2}

    test mathop-14.100 {compiled /: argument processing order} -body {
      # Bytecode compilation known hard for 3+ arguments
      list [catch {
	  / [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
      } msg] $msg $x
    } -result {1 expected 2}
}

test mathop-20.1 { zero args, return unit } {
    set res {}
    foreach op {+ * & ^ | ** < <= > >= == eq} {
	lappend res [TestOp $op]
    }
    set res
} {0 1 -1 0 0 1 1 1 1 1 1 1}
test mathop-20.2 { zero args, not allowed } {
    set exp {}
    foreach op {~ ! << >> % != ne in ni - /} {
	set res [TestOp $op]
	if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
	    lappend exp 0
	} else {
	    lappend exp $res
	}
    }
    set exp
} {0 0 0 0 0 0 0 0 0 0 0}
test mathop-20.3 { one arg } {
    set res {}
    foreach val {7 8.3} {
	foreach op {+ ** - * / < <= > >= == eq !} {
	    lappend res [TestOp $op $val]
	}
    }
    set res
} [list 7   7   -7   7   [expr {1.0/7.0}] 1 1 1 1 1 1 0 \
	8.3 8.3 -8.3 8.3 [expr {1.0/8.3}] 1 1 1 1 1 1 0]
test mathop-20.4 { one arg, integer only ops } {
    set res {}
    foreach val {23} {
	foreach op {& | ^ ~} {
	    lappend res [TestOp $op $val]
	}
    }
    set res
} [list 23 23 23 -24]
test mathop-20.5 { one arg, not allowed } {
    set exp {}
    foreach op {% != ne in ni << >>} {
	set res [TestOp $op 1]
	if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
	    lappend exp 0
	} else {
	    lappend exp $res
	}
    }
    set exp
} {0 0 0 0 0 0 0}
test mathop-20.6 { one arg, error } {
    set res {}
    set exp {}
    foreach vals {x {1 x} {1 1 x} {1 x 1}} {
	# skipping - for now, knownbug...
	foreach op {+ * / & | ^ **} {
	    #lappend res [TestOp $op {*}$vals]
	    #lappend exp "cannot use non-numeric string \"x\" as right operand of \"$op\"\
		#ARITH DOMAIN {non-numeric string}"
	}
    }
    foreach op {+ * / & | ^ **} {
	lappend res [TestOp $op NaN 1]
	lappend exp "cannot use non-numeric floating-point value \"NaN\" as left operand of \"$op\"\
	    ARITH DOMAIN {non-numeric floating-point value}"
    }
    expr {$res eq $exp ? 0 : "$res\n$exp"}
} 0
test mathop-20.7 { multi arg } {
    set res {}
    foreach vals {{1 2} {3 4 5} {4 3 2 1}} {
	foreach op {+ - * /} {
	    lappend res [TestOp $op {*}$vals]
	}
    }
    set res
} [list 3 -1 2 0  12 -6 60 0  10 -2 24 0]
test mathop-20.8 { multi arg, double } {
    set res {}
    foreach vals {{1.0 2} {3.0 4 5} {4 3.0 2 1}
	    {1.0 -1.0 1e-18} {1.0 1.0 1e-18}} {
	foreach op {+ - * /} {
	    lappend res [TestOp $op {*}$vals]
	}
    }
    set res
} [list 3.0 -1.0 2.0 0.5  12.0 -6.0 60.0 0.15  10.0 -2.0 24.0 [expr {2.0/3}] 1e-18 2.0 -1e-18 [expr {-1.0/1e-18}] 2.0 -1e-18 1e-18 [expr {1.0/1e-18}]]

test mathop-21.1 { unary ops, bitnot } {
    set res {}
    lappend res [TestOp ~ 7]
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
    lappend res [TestOp - -5]
    lappend res [TestOp - -2147483648]                  ;# -2**31
    lappend res [TestOp - -9223372036854775808]         ;# -2**63
    lappend res [TestOp -  354657483923456]             ;# wide
    lappend res [TestOp -  123456789123456789123456789] ;# big
    set res
} [list -7.2 5 2147483648 9223372036854775808 -354657483923456 \
           -123456789123456789123456789]
test mathop-21.4 { unary ops, inversion } {
    set res {}
    lappend res [TestOp / 1]
    lappend res [TestOp / 5]
    lappend res [TestOp / 5.6]
    lappend res [TestOp / -8]
    lappend res [TestOp /  354657483923456]             ;# wide
    lappend res [TestOp /  123456789123456789123456789] ;# big
    set res
} [list 1.0 0.2 0.17857142857142858 -0.125 \
           2.8196218755553604e-15 8.10000006561e-27]
test mathop-21.5 { unary ops, bad values } {
    set res {}
    set exp {}
    lappend res [TestOp / x]
    lappend exp "cannot use non-numeric string \"x\" as right operand of \"/\" ARITH DOMAIN {non-numeric string}"
    #lappend res [TestOp - x]
    #lappend exp "cannot use non-numeric string \"x\" as operand of \"-\" ARITH DOMAIN {non-numeric string}"
    lappend res [TestOp ~ x]
    lappend exp "cannot use non-numeric string \"x\" as operand of \"~\" ARITH DOMAIN {non-numeric string}"
    lappend res [TestOp ! x]
    lappend exp "cannot use non-numeric string \"x\" as operand of \"!\" ARITH DOMAIN {non-numeric string}"
    lappend res [TestOp ~ 5.0]
    lappend exp "cannot use floating-point value \"5.0\" as operand of \"~\" ARITH DOMAIN {floating-point value}"
    expr {$res eq $exp ? 0 : "$res\n$exp"}
} 0
test mathop-21.6 { unary ops, too many } {
    set exp {}
    foreach op {~ !} {
        set res [TestOp $op 7 8]
        if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
            lappend exp 0
        } else {
            lappend exp $res
        }
    }
    set exp
} {0 0}

test mathop-22.1 { bitwise ops } {
    set res {}
    foreach vals {5 {1 6} {1 2 3} {1 2 3 4}} {
        foreach op {& | ^} {
            lappend res [TestOp $op {*}$vals]
        }
    }
    set res
} [list 5 5 5  0 7 7  0 3 0  0 7 4]
test mathop-22.2 { bitwise ops on bignums } {
    set dig 50
    set a 0x[string repeat 5 $dig]
    set b 0x[string repeat 7 $dig]
    set c 0x[string repeat 9 $dig]
    set bn [expr {~$b}]
    set cn [expr {~$c}]

    set res {}
    foreach vals [list [list $a $b] [list $a $c] [list $b $c] \
                          [list $a $bn] [list $bn $c] [list $bn $cn]] {
        foreach op {& | ^} {
            lappend res [TestOp $op {*}$vals]
        }
    }
    set exp {}
    foreach d {5 7 2  1 D C  1 F E  0 -D -D  8 -9 -1  -0 -E E} {
        if {[string match "-*" $d]} {
            set d [format %X [expr {15-"0x[string range $d 1 end]"}]]
            set val [expr {-"0x[string repeat $d $dig]"-1}]
        } else {
            set val [expr {"0x[string repeat $d $dig]"}]
        }
        lappend exp $val
    }
    expr {$exp eq $res ? 1 : "($res != $exp"}
} 1
test mathop-22.3 { bitwise ops } {
    set big1      12135435435354435435342423948763867876
    set big2       2746237174783836746262564892918327847
    set wide1                             12345678912345
    set wide2                             87321847232215
    set small1                                     87345
    set small2                                     16753

    set res {}
    foreach op {& | ^} {
        lappend res [TestOp $op $big1   $big2]
        lappend res [TestOp $op $big1   $wide2]
        lappend res [TestOp $op $big1   $small2]
        lappend res [TestOp $op $wide1  $big2]
        lappend res [TestOp $op $wide1  $wide2]
        lappend res [TestOp $op $wide1  $small2]
        lappend res [TestOp $op $small1 $big2]
        lappend res [TestOp $op $small1 $wide2]
        lappend res [TestOp $op $small1 $small2]
    }
    set res
} [list \
           712439449294653815890598856501796 \
           78521450111684 \
           96 \
           2371422390785 \
           12275881497169 \
           16721 \
           33 \
           87057 \
           16689 \
           14880960170688977527789098242825693927 \
           12135435435354435435342432749160988407 \
           12135435435354435435342423948763884533 \
           2746237174783836746262574867174849407 \
           87391644647391 \
           12345678912377 \
           2746237174783836746262564892918415159 \
           87321847232503 \
           87409 \
           14880247731239682873973207643969192131 \
           12135435435354435435342354227710876723 \
           12135435435354435435342423948763884437 \
           2746237174783836746262572495752458622 \
           75115763150222 \
           12345678895656 \
           2746237174783836746262564892918415126 \
           87321847145446 \
           70720 \
          ]
test mathop-22.4 { unary ops, bad values } {
    set res {}
    set exp {}
    foreach op {& | ^} {
        lappend res [TestOp $op x 5]
        lappend exp "cannot use non-numeric string \"x\" as left operand of \"$op\" ARITH DOMAIN {non-numeric string}"
        lappend res [TestOp $op 5 x]
        lappend exp "cannot use non-numeric string \"x\" as right operand of \"$op\" ARITH DOMAIN {non-numeric string}"
    }
    expr {$res eq $exp ? 0 : "$res\n$exp"}
} 0

test mathop-23.1 { comparison ops, numerical } {
    set res {}
    set todo {5 {1 6} {1 2 2 3} {4 3 2 1} {5.0 5.0} {6 3 3 1} {5.0 5}}
    lappend todo [list 2342476234762482734623842342 234827463876473 3434]
    lappend todo [list 2653 453735910264536 453735910264537 2384762472634982746239847637]
    lappend todo [list 2653 2384762472634982746239847637]
    lappend todo [list 2653 -2384762472634982746239847637]
    lappend todo [list 3789253678212653 -2384762472634982746239847637]
    lappend todo [list 5.0 6 7.0 8 1e13 1945628567352654 1.1e20 \
                          6734253647589123456784564378 2.3e50]
    set a 7
    lappend todo [list $a $a] ;# Same object
    foreach vals $todo {
        foreach op {< <= > >= == eq} {
            lappend res [TestOp $op {*}$vals]
        }
    }
    set res
} [list 1 1 1 1 1 1 \
        1 1 0 0 0 0 \
        0 1 0 0 0 0 \
        0 0 1 1 0 0 \
        0 1 0 1 1 1 \
        0 0 0 1 0 0 \
        0 1 0 1 1 0 \
        0 0 1 1 0 0 \
        1 1 0 0 0 0 \
        1 1 0 0 0 0 \
        0 0 1 1 0 0 \
        0 0 1 1 0 0 \
        1 1 0 0 0 0 \
        0 1 0 1 1 1 \
       ]
test mathop-23.2 { comparison ops, string } {
    set res {}
    set todo {a {a b} {5 b b c} {d c b a} {xy xy} {gy ef ef ab}}
    set a x
    lappend todo [list $a $a]
    foreach vals $todo {
        foreach op {< <= > >= == eq} {
            lappend res [TestOp $op {*}$vals]
        }
    }
    set res
} [list 1 1 1 1 1 1 \
        1 1 0 0 0 0 \
        0 1 0 0 0 0 \
        0 0 1 1 0 0 \
        0 1 0 1 1 1 \
        0 0 0 1 0 0 \
        0 1 0 1 1 1 \
       ]
test mathop-23.3 { comparison ops, nonequal} {
    set res {}
    foreach vals {{a b} {17.0 0x11} {foo foo} {10 10}} {
        foreach op {!= ne} {
            lappend res [TestOp $op {*}$vals]
        }
    }
    set res
} [list 1 1  0 1  0 0  0 0 ]

test mathop-24.1 { binary ops } {
    set res {}
    foreach vals {{3 5} {17 7} {199 5} {293234675763434238476239486 17} \
                  {5 1} {0 7}} {
        foreach op {% << >> in ni} {
            lappend res [TestOp $op {*}$vals]
        }
    }
    set res
} [list 3 96 0 0 1  3 2176 0 0 1  4 6368 6 0 1 \
        14 38434855421664852505557661908992 2237203031642412097749 0 1 \
        0 10 2 0 1  0 0 0 0 1]
test mathop-24.2 { binary ops, modulo } {
    # Test different combinations to get all code paths
    set res {}

    set bigbig 14372423674564535234543545248972634923869
    set big       12135435435354435435342423948763867876
    set wide                              12345678912345







|










|


















|
|
|
|
|
|







|
|
|













|
|
|
|



|
|
|
|
|
|
|













|
|
|
|
|
|
|
|
|



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|




|
|
|
|













|



|
|
|



|
|
|
|
|
|
|
|
|
|
|
|
|







|
|
|



|
|
|
|
|
|




|
|
|







|
|
|
|



|
|







830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
    lappend res [TestOp - -5]
    lappend res [TestOp - -2147483648]                  ;# -2**31
    lappend res [TestOp - -9223372036854775808]         ;# -2**63
    lappend res [TestOp -  354657483923456]             ;# wide
    lappend res [TestOp -  123456789123456789123456789] ;# big
    set res
} [list -7.2 5 2147483648 9223372036854775808 -354657483923456 \
	   -123456789123456789123456789]
test mathop-21.4 { unary ops, inversion } {
    set res {}
    lappend res [TestOp / 1]
    lappend res [TestOp / 5]
    lappend res [TestOp / 5.6]
    lappend res [TestOp / -8]
    lappend res [TestOp /  354657483923456]             ;# wide
    lappend res [TestOp /  123456789123456789123456789] ;# big
    set res
} [list 1.0 0.2 0.17857142857142858 -0.125 \
	   2.8196218755553604e-15 8.10000006561e-27]
test mathop-21.5 { unary ops, bad values } {
    set res {}
    set exp {}
    lappend res [TestOp / x]
    lappend exp "cannot use non-numeric string \"x\" as right operand of \"/\" ARITH DOMAIN {non-numeric string}"
    #lappend res [TestOp - x]
    #lappend exp "cannot use non-numeric string \"x\" as operand of \"-\" ARITH DOMAIN {non-numeric string}"
    lappend res [TestOp ~ x]
    lappend exp "cannot use non-numeric string \"x\" as operand of \"~\" ARITH DOMAIN {non-numeric string}"
    lappend res [TestOp ! x]
    lappend exp "cannot use non-numeric string \"x\" as operand of \"!\" ARITH DOMAIN {non-numeric string}"
    lappend res [TestOp ~ 5.0]
    lappend exp "cannot use floating-point value \"5.0\" as operand of \"~\" ARITH DOMAIN {floating-point value}"
    expr {$res eq $exp ? 0 : "$res\n$exp"}
} 0
test mathop-21.6 { unary ops, too many } {
    set exp {}
    foreach op {~ !} {
	set res [TestOp $op 7 8]
	if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
	    lappend exp 0
	} else {
	    lappend exp $res
	}
    }
    set exp
} {0 0}

test mathop-22.1 { bitwise ops } {
    set res {}
    foreach vals {5 {1 6} {1 2 3} {1 2 3 4}} {
	foreach op {& | ^} {
	    lappend res [TestOp $op {*}$vals]
	}
    }
    set res
} [list 5 5 5  0 7 7  0 3 0  0 7 4]
test mathop-22.2 { bitwise ops on bignums } {
    set dig 50
    set a 0x[string repeat 5 $dig]
    set b 0x[string repeat 7 $dig]
    set c 0x[string repeat 9 $dig]
    set bn [expr {~$b}]
    set cn [expr {~$c}]

    set res {}
    foreach vals [list [list $a $b] [list $a $c] [list $b $c] \
			  [list $a $bn] [list $bn $c] [list $bn $cn]] {
	foreach op {& | ^} {
	    lappend res [TestOp $op {*}$vals]
	}
    }
    set exp {}
    foreach d {5 7 2  1 D C  1 F E  0 -D -D  8 -9 -1  -0 -E E} {
	if {[string match "-*" $d]} {
	    set d [format %X [expr {15-"0x[string range $d 1 end]"}]]
	    set val [expr {-"0x[string repeat $d $dig]"-1}]
	} else {
	    set val [expr {"0x[string repeat $d $dig]"}]
	}
	lappend exp $val
    }
    expr {$exp eq $res ? 1 : "($res != $exp"}
} 1
test mathop-22.3 { bitwise ops } {
    set big1      12135435435354435435342423948763867876
    set big2       2746237174783836746262564892918327847
    set wide1                             12345678912345
    set wide2                             87321847232215
    set small1                                     87345
    set small2                                     16753

    set res {}
    foreach op {& | ^} {
	lappend res [TestOp $op $big1   $big2]
	lappend res [TestOp $op $big1   $wide2]
	lappend res [TestOp $op $big1   $small2]
	lappend res [TestOp $op $wide1  $big2]
	lappend res [TestOp $op $wide1  $wide2]
	lappend res [TestOp $op $wide1  $small2]
	lappend res [TestOp $op $small1 $big2]
	lappend res [TestOp $op $small1 $wide2]
	lappend res [TestOp $op $small1 $small2]
    }
    set res
} [list \
	   712439449294653815890598856501796 \
	   78521450111684 \
	   96 \
	   2371422390785 \
	   12275881497169 \
	   16721 \
	   33 \
	   87057 \
	   16689 \
	   14880960170688977527789098242825693927 \
	   12135435435354435435342432749160988407 \
	   12135435435354435435342423948763884533 \
	   2746237174783836746262574867174849407 \
	   87391644647391 \
	   12345678912377 \
	   2746237174783836746262564892918415159 \
	   87321847232503 \
	   87409 \
	   14880247731239682873973207643969192131 \
	   12135435435354435435342354227710876723 \
	   12135435435354435435342423948763884437 \
	   2746237174783836746262572495752458622 \
	   75115763150222 \
	   12345678895656 \
	   2746237174783836746262564892918415126 \
	   87321847145446 \
	   70720 \
	  ]
test mathop-22.4 { unary ops, bad values } {
    set res {}
    set exp {}
    foreach op {& | ^} {
	lappend res [TestOp $op x 5]
	lappend exp "cannot use non-numeric string \"x\" as left operand of \"$op\" ARITH DOMAIN {non-numeric string}"
	lappend res [TestOp $op 5 x]
	lappend exp "cannot use non-numeric string \"x\" as right operand of \"$op\" ARITH DOMAIN {non-numeric string}"
    }
    expr {$res eq $exp ? 0 : "$res\n$exp"}
} 0

test mathop-23.1 { comparison ops, numerical } {
    set res {}
    set todo {5 {1 6} {1 2 2 3} {4 3 2 1} {5.0 5.0} {6 3 3 1} {5.0 5}}
    lappend todo [list 2342476234762482734623842342 234827463876473 3434]
    lappend todo [list 2653 453735910264536 453735910264537 2384762472634982746239847637]
    lappend todo [list 2653 2384762472634982746239847637]
    lappend todo [list 2653 -2384762472634982746239847637]
    lappend todo [list 3789253678212653 -2384762472634982746239847637]
    lappend todo [list 5.0 6 7.0 8 1e13 1945628567352654 1.1e20 \
			  6734253647589123456784564378 2.3e50]
    set a 7
    lappend todo [list $a $a] ;# Same object
    foreach vals $todo {
	foreach op {< <= > >= == eq} {
	    lappend res [TestOp $op {*}$vals]
	}
    }
    set res
} [list 1 1 1 1 1 1 \
	1 1 0 0 0 0 \
	0 1 0 0 0 0 \
	0 0 1 1 0 0 \
	0 1 0 1 1 1 \
	0 0 0 1 0 0 \
	0 1 0 1 1 0 \
	0 0 1 1 0 0 \
	1 1 0 0 0 0 \
	1 1 0 0 0 0 \
	0 0 1 1 0 0 \
	0 0 1 1 0 0 \
	1 1 0 0 0 0 \
	0 1 0 1 1 1 \
       ]
test mathop-23.2 { comparison ops, string } {
    set res {}
    set todo {a {a b} {5 b b c} {d c b a} {xy xy} {gy ef ef ab}}
    set a x
    lappend todo [list $a $a]
    foreach vals $todo {
	foreach op {< <= > >= == eq} {
	    lappend res [TestOp $op {*}$vals]
	}
    }
    set res
} [list 1 1 1 1 1 1 \
	1 1 0 0 0 0 \
	0 1 0 0 0 0 \
	0 0 1 1 0 0 \
	0 1 0 1 1 1 \
	0 0 0 1 0 0 \
	0 1 0 1 1 1 \
       ]
test mathop-23.3 { comparison ops, nonequal} {
    set res {}
    foreach vals {{a b} {17.0 0x11} {foo foo} {10 10}} {
	foreach op {!= ne} {
	    lappend res [TestOp $op {*}$vals]
	}
    }
    set res
} [list 1 1  0 1  0 0  0 0 ]

test mathop-24.1 { binary ops } {
    set res {}
    foreach vals {{3 5} {17 7} {199 5} {293234675763434238476239486 17} \
		  {5 1} {0 7}} {
	foreach op {% << >> in ni} {
	    lappend res [TestOp $op {*}$vals]
	}
    }
    set res
} [list 3 96 0 0 1  3 2176 0 0 1  4 6368 6 0 1 \
	14 38434855421664852505557661908992 2237203031642412097749 0 1 \
	0 10 2 0 1  0 0 0 0 1]
test mathop-24.2 { binary ops, modulo } {
    # Test different combinations to get all code paths
    set res {}

    set bigbig 14372423674564535234543545248972634923869
    set big       12135435435354435435342423948763867876
    set wide                              12345678912345
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
    lappend res [TestOp % $small   $big]
    lappend res [TestOp % $neg     $big]
    lappend res [TestOp % $small  $wide]
    lappend res [TestOp % $neg    $wide]
    lappend res [TestOp % $wide  $small]
    set res
} [list   4068119104883679098115293636215358685 \
                                 12345678912345 \
         12135435435354435435342411603084955531 \
                                              5 \
         12135435435354435435342423948763867871 \
                                              5 \
                                 12345678912340 \
                                              0 \
          ]
test mathop-24.3 { binary ops, bad values } {
    set res {}
    set exp {}
    foreach op {% << >>} {
        lappend res [TestOp $op x 1]
        lappend exp "cannot use non-numeric string \"x\" as left operand of \"$op\" ARITH DOMAIN {non-numeric string}"
        lappend res [TestOp $op 1 x]
        lappend exp "cannot use non-numeric string \"x\" as right operand of \"$op\" ARITH DOMAIN {non-numeric string}"
    }
    foreach op {% << >>} {
        lappend res [TestOp $op 5.0 1]
        lappend exp "cannot use floating-point value \"5.0\" as left operand of \"$op\" ARITH DOMAIN {floating-point value}"
        lappend res [TestOp $op 1 5.0]
        lappend exp "cannot use floating-point value \"5.0\" as right operand of \"$op\" ARITH DOMAIN {floating-point value}"
    }
    foreach op {in ni} {
        lappend res [TestOp $op 5 "a b \{ c"]
        lappend exp "unmatched open brace in list TCL VALUE LIST BRACE"
    }
    lappend res [TestOp % 5 0]
    lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
    lappend res [TestOp % 9838923468297346238478737647637375 0]
    lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
    lappend res [TestOp / 5 0]
    lappend exp "divide by zero ARITH DIVZERO {divide by zero}"







|
|
|
|
|
|
|
|




|
|
|
|


|
|
|
|


|
|







1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
    lappend res [TestOp % $small   $big]
    lappend res [TestOp % $neg     $big]
    lappend res [TestOp % $small  $wide]
    lappend res [TestOp % $neg    $wide]
    lappend res [TestOp % $wide  $small]
    set res
} [list   4068119104883679098115293636215358685 \
				 12345678912345 \
	 12135435435354435435342411603084955531 \
					      5 \
	 12135435435354435435342423948763867871 \
					      5 \
				 12345678912340 \
					      0 \
	  ]
test mathop-24.3 { binary ops, bad values } {
    set res {}
    set exp {}
    foreach op {% << >>} {
	lappend res [TestOp $op x 1]
	lappend exp "cannot use non-numeric string \"x\" as left operand of \"$op\" ARITH DOMAIN {non-numeric string}"
	lappend res [TestOp $op 1 x]
	lappend exp "cannot use non-numeric string \"x\" as right operand of \"$op\" ARITH DOMAIN {non-numeric string}"
    }
    foreach op {% << >>} {
	lappend res [TestOp $op 5.0 1]
	lappend exp "cannot use floating-point value \"5.0\" as left operand of \"$op\" ARITH DOMAIN {floating-point value}"
	lappend res [TestOp $op 1 5.0]
	lappend exp "cannot use floating-point value \"5.0\" as right operand of \"$op\" ARITH DOMAIN {floating-point value}"
    }
    foreach op {in ni} {
	lappend res [TestOp $op 5 "a b \{ c"]
	lappend exp "unmatched open brace in list TCL VALUE LIST BRACE"
    }
    lappend res [TestOp % 5 0]
    lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
    lappend res [TestOp % 9838923468297346238478737647637375 0]
    lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
    lappend res [TestOp / 5 0]
    lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
    set small                                          5
    set neg                                           -5

    lappend res [TestOp << $wide $small]
    lappend res [TestOp >> $wide $small]
    set res
} [list   395061725195040 \
             385802466010 \
          ]
test mathop-24.7 { binary ops, list search } {
    set res {}

    foreach op {in ni} {
        lappend res [TestOp $op 5 {7 5 8}]
        lappend res [TestOp $op hej {foo bar hej}]
        lappend res [TestOp $op 5 {7 0x5 8}]
    }
    set res
} [list 1 1 0  0 0 1]
test mathop-24.8 { binary ops, too many } {
    set exp {}
    foreach op {<< >> % != ne in ni ~ !} {
        set res [TestOp $op 7 8 9]
        if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
            lappend exp 0
        } else {
            lappend exp $res
        }
    }
    set exp
} {0 0 0 0 0 0 0 0 0}

test mathop-25.1  { exp operator } {TestOp **        } 1
test mathop-25.2  { exp operator } {TestOp **   0    } 0
test mathop-25.3  { exp operator } {TestOp **   0   5} 0







|
|




|
|
|






|
|
|
|
|
|







1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
    set small                                          5
    set neg                                           -5

    lappend res [TestOp << $wide $small]
    lappend res [TestOp >> $wide $small]
    set res
} [list   395061725195040 \
	     385802466010 \
	  ]
test mathop-24.7 { binary ops, list search } {
    set res {}

    foreach op {in ni} {
	lappend res [TestOp $op 5 {7 5 8}]
	lappend res [TestOp $op hej {foo bar hej}]
	lappend res [TestOp $op 5 {7 0x5 8}]
    }
    set res
} [list 1 1 0  0 0 1]
test mathop-24.8 { binary ops, too many } {
    set exp {}
    foreach op {<< >> % != ne in ni ~ !} {
	set res [TestOp $op 7 8 9]
	if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
	    lappend exp 0
	} else {
	    lappend exp $res
	}
    }
    set exp
} {0 0 0 0 0 0 0 0 0}

test mathop-25.1  { exp operator } {TestOp **        } 1
test mathop-25.2  { exp operator } {TestOp **   0    } 0
test mathop-25.3  { exp operator } {TestOp **   0   5} 0
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
    set wide1                             87321847232215
    set wide2                             12345678912345
    set small1                                     87345
    set small2                                     16753

    set res {}
    foreach op {+ * - /} {
        lappend res [TestOp $op $big1   $big2]
        lappend res [TestOp $op $big1   $wide2]
        lappend res [TestOp $op $big1   $small2]
        lappend res [TestOp $op $wide1  $big2]
        lappend res [TestOp $op $wide1  $wide2]
        lappend res [TestOp $op $wide1  $small2]
        lappend res [TestOp $op $small1 $big2]
        lappend res [TestOp $op $small1 $wide2]
        lappend res [TestOp $op $small1 $small2]
    }
    set res
} [list \
           14881672610138272181604988841682195723 \
           12135435435354435435342436294442780221 \
           12135435435354435435342423948763884629 \
           2746237174783836746262652214765560062 \
           99667526144560 \
           87321847248968 \
           2746237174783836746262564892918415192 \
           12345678999690 \
           104098 \
           33326783924759424684447891401270222910405366244661685890993770489959542972 \
           149820189346379518024969783068410988366610965329220 \
           203304949848492856848291628413641078526628 \
           239806503039903915972546163440347114360602909991105 \
           1078047487961768329845194175 \
           1462902906681297895 \
           239870086031494220602303730571951345796215 \
           1078333324598774025 \
           1463290785 \
           9389198260570598689079859055845540029 \
           12135435435354435435342411603084955531 \
           12135435435354435435342423948763851123 \
           -2746237174783836746262477571071095632 \
           74976168319870 \
           87321847215462 \
           -2746237174783836746262564892918240502 \
           -12345678825000 \
           70592 \
           4 \
           982970278225822587257201 \
           724373869477373332259441529801460 \
           0 \
           7 \
           5212311062 \
           0 \
           0 \
           5 \
          ]
test mathop-26.2 { misc ops, corner cases } {
    set res {}
    lappend res [TestOp - 0 -2147483648]                  ;# -2**31
    lappend res [TestOp - 0 -9223372036854775808]         ;# -2**63
    lappend res [TestOp / -9223372036854775808 -1]
    lappend res [TestOp * 2147483648 2]
    lappend res [TestOp * 9223372036854775808 2]







|
|
|
|
|
|
|
|
|



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
    set wide1                             87321847232215
    set wide2                             12345678912345
    set small1                                     87345
    set small2                                     16753

    set res {}
    foreach op {+ * - /} {
	lappend res [TestOp $op $big1   $big2]
	lappend res [TestOp $op $big1   $wide2]
	lappend res [TestOp $op $big1   $small2]
	lappend res [TestOp $op $wide1  $big2]
	lappend res [TestOp $op $wide1  $wide2]
	lappend res [TestOp $op $wide1  $small2]
	lappend res [TestOp $op $small1 $big2]
	lappend res [TestOp $op $small1 $wide2]
	lappend res [TestOp $op $small1 $small2]
    }
    set res
} [list \
	   14881672610138272181604988841682195723 \
	   12135435435354435435342436294442780221 \
	   12135435435354435435342423948763884629 \
	   2746237174783836746262652214765560062 \
	   99667526144560 \
	   87321847248968 \
	   2746237174783836746262564892918415192 \
	   12345678999690 \
	   104098 \
	   33326783924759424684447891401270222910405366244661685890993770489959542972 \
	   149820189346379518024969783068410988366610965329220 \
	   203304949848492856848291628413641078526628 \
	   239806503039903915972546163440347114360602909991105 \
	   1078047487961768329845194175 \
	   1462902906681297895 \
	   239870086031494220602303730571951345796215 \
	   1078333324598774025 \
	   1463290785 \
	   9389198260570598689079859055845540029 \
	   12135435435354435435342411603084955531 \
	   12135435435354435435342423948763851123 \
	   -2746237174783836746262477571071095632 \
	   74976168319870 \
	   87321847215462 \
	   -2746237174783836746262564892918240502 \
	   -12345678825000 \
	   70592 \
	   4 \
	   982970278225822587257201 \
	   724373869477373332259441529801460 \
	   0 \
	   7 \
	   5212311062 \
	   0 \
	   0 \
	   5 \
	  ]
test mathop-26.2 { misc ops, corner cases } {
    set res {}
    lappend res [TestOp - 0 -2147483648]                  ;# -2**31
    lappend res [TestOp - 0 -9223372036854775808]         ;# -2**63
    lappend res [TestOp / -9223372036854775808 -1]
    lappend res [TestOp * 2147483648 2]
    lappend res [TestOp * 9223372036854775808 2]
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
test mathop-30.8 {ge operator} {::tcl::mathop::ge a c b} 0
test mathop-30.9 {ge operator} {::tcl::mathop::ge 0x0 012} 1

if 0 {
    # Compare ops to expr bytecodes
    namespace import ::tcl::mathop::*
    proc _X {a b c} {
        set x [+ $a [- $b $c]]
        set y [expr {$a + ($b - $c)}]
        set z [< $a $b $c]
    }
    set ::tcl_traceCompile 2
    _X 3 4 5
    set ::tcl_traceCompile 0
}

# cleanup







|
|
|







1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
test mathop-30.8 {ge operator} {::tcl::mathop::ge a c b} 0
test mathop-30.9 {ge operator} {::tcl::mathop::ge 0x0 012} 1

if 0 {
    # Compare ops to expr bytecodes
    namespace import ::tcl::mathop::*
    proc _X {a b c} {
	set x [+ $a [- $b $c]]
	set y [expr {$a + ($b - $c)}]
	set z [< $a $b $c]
    }
    set ::tcl_traceCompile 2
    _X 3 4 5
    set ::tcl_traceCompile 0
}

# cleanup
Changes to tests/msgcat.test.
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
    } -body {
	namespace eval baz {::msgcat::mc con1}
    } -result con1baz

    test msgcat-2.5 {mcmset, global scope} -setup {
	namespace eval :: {
	    ::msgcat::mcmset  foo_BAR {
	        src1 trans1
	        src2 trans2
	    }
	}
	variable locale [mclocale]
	mclocale foo_BAR
    } -cleanup {
	mclocale $locale
    } -body {







|
|







255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
    } -body {
	namespace eval baz {::msgcat::mc con1}
    } -result con1baz

    test msgcat-2.5 {mcmset, global scope} -setup {
	namespace eval :: {
	    ::msgcat::mcmset  foo_BAR {
		src1 trans1
		src2 trans2
	    }
	}
	variable locale [mclocale]
	mclocale foo_BAR
    } -cleanup {
	mclocale $locale
    } -body {
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
    #     ov1 should resolve to foo in foo_BAR, foo_BAR_baz
    #     ov4 should be resolved in none, and call mcunknown
    #
    variable count 2
    variable result
    array set result {
	foo,ov0 ov0_ROOT foo,ov1 ov1_foo foo,ov2 ov2_foo
        foo,ov3 ov3_foo foo,ov4 ov4
	foo_BAR,ov0 ov0_ROOT foo_BAR,ov1 ov1_foo foo_BAR,ov2 ov2_foo_BAR
        foo_BAR,ov3 ov3_foo_BAR	foo_BAR,ov4 ov4
        foo_BAR_baz,ov0 ov0_ROOT foo_BAR_baz,ov1 ov1_foo
        foo_BAR_baz,ov2 ov2_foo_BAR
	foo_BAR_baz,ov3 ov3_foo_BAR_baz foo_BAR_baz,ov4 ov4
    }
    variable loc
    variable string
    foreach loc {foo foo_BAR foo_BAR_baz} {
	foreach string {ov0 ov1 ov2 ov3 ov4} {
	    test msgcat-3.$count {mcset, overlap} -setup {







|

|
|
|







317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
    #     ov1 should resolve to foo in foo_BAR, foo_BAR_baz
    #     ov4 should be resolved in none, and call mcunknown
    #
    variable count 2
    variable result
    array set result {
	foo,ov0 ov0_ROOT foo,ov1 ov1_foo foo,ov2 ov2_foo
	foo,ov3 ov3_foo foo,ov4 ov4
	foo_BAR,ov0 ov0_ROOT foo_BAR,ov1 ov1_foo foo_BAR,ov2 ov2_foo_BAR
	foo_BAR,ov3 ov3_foo_BAR	foo_BAR,ov4 ov4
	foo_BAR_baz,ov0 ov0_ROOT foo_BAR_baz,ov1 ov1_foo
	foo_BAR_baz,ov2 ov2_foo_BAR
	foo_BAR_baz,ov3 ov3_foo_BAR_baz foo_BAR_baz,ov4 ov4
    }
    variable loc
    variable string
    foreach loc {foo foo_BAR foo_BAR_baz} {
	foreach string {ov0 ov1 ov2 ov3 ov4} {
	    test msgcat-3.$count {mcset, overlap} -setup {
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
    } -body {
	mc unk2
    } -result unk2

    test msgcat-4.4 {mcunknown, overridden} -setup {
	rename ::msgcat::mcunknown SavedMcunknown
	proc ::msgcat::mcunknown {dom s} {
            return unknown:$dom:$s
	}
	mcset foo unk1 "unknown 1"
	variable locale [mclocale]
	mclocale foo
    } -cleanup {
	mclocale $locale
	rename ::msgcat::mcunknown {}
	rename SavedMcunknown ::msgcat::mcunknown
    } -body {
	mc unk1
    } -result {unknown 1}

    test msgcat-4.5 {mcunknown, overridden} -setup {
	rename ::msgcat::mcunknown SavedMcunknown
	proc ::msgcat::mcunknown {dom s} {
            return unknown:$dom:$s
	}
	mcset foo unk1 "unknown 1"
	variable locale [mclocale]
	mclocale foo
    } -cleanup {
	mclocale $locale
	rename ::msgcat::mcunknown {}
	rename SavedMcunknown ::msgcat::mcunknown
    } -body {
	mc unk2
    } -result {unknown:foo:unk2}

    test msgcat-4.6 {mcunknown, uplevel context} -setup {
	rename ::msgcat::mcunknown SavedMcunknown
	proc ::msgcat::mcunknown {dom s} {
            return "unknown:$dom:$s:[expr {[info level] - 1}]"
	}
	mcset foo unk1 "unknown 1"
	variable locale [mclocale]
	mclocale foo
    } -cleanup {
	mclocale $locale
	rename ::msgcat::mcunknown {}
	rename SavedMcunknown ::msgcat::mcunknown
    } -body {
	mc unk2
    } -result unknown:foo:unk2:[info level]

    # Tests msgcat-5.*: [mcload]

    variable locales {{} foo foo_BAR foo_BAR_baz}
    set msgdir [makeDirectory msgdir]
    foreach loc $locales {
	if { $loc eq {} } {
	    set msg ROOT
        } else {
	    set msg [string tolower $loc]
	}
	makeFile [list ::msgcat::mcset $loc abc abc-$loc] $msg.msg $msgdir
    }
    variable count 1
    foreach loc {foo foo_BAR foo_BAR_baz} {
	test msgcat-5.$count {mcload} -setup {







|















|















|



















|







376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
    } -body {
	mc unk2
    } -result unk2

    test msgcat-4.4 {mcunknown, overridden} -setup {
	rename ::msgcat::mcunknown SavedMcunknown
	proc ::msgcat::mcunknown {dom s} {
	    return unknown:$dom:$s
	}
	mcset foo unk1 "unknown 1"
	variable locale [mclocale]
	mclocale foo
    } -cleanup {
	mclocale $locale
	rename ::msgcat::mcunknown {}
	rename SavedMcunknown ::msgcat::mcunknown
    } -body {
	mc unk1
    } -result {unknown 1}

    test msgcat-4.5 {mcunknown, overridden} -setup {
	rename ::msgcat::mcunknown SavedMcunknown
	proc ::msgcat::mcunknown {dom s} {
	    return unknown:$dom:$s
	}
	mcset foo unk1 "unknown 1"
	variable locale [mclocale]
	mclocale foo
    } -cleanup {
	mclocale $locale
	rename ::msgcat::mcunknown {}
	rename SavedMcunknown ::msgcat::mcunknown
    } -body {
	mc unk2
    } -result {unknown:foo:unk2}

    test msgcat-4.6 {mcunknown, uplevel context} -setup {
	rename ::msgcat::mcunknown SavedMcunknown
	proc ::msgcat::mcunknown {dom s} {
	    return "unknown:$dom:$s:[expr {[info level] - 1}]"
	}
	mcset foo unk1 "unknown 1"
	variable locale [mclocale]
	mclocale foo
    } -cleanup {
	mclocale $locale
	rename ::msgcat::mcunknown {}
	rename SavedMcunknown ::msgcat::mcunknown
    } -body {
	mc unk2
    } -result unknown:foo:unk2:[info level]

    # Tests msgcat-5.*: [mcload]

    variable locales {{} foo foo_BAR foo_BAR_baz}
    set msgdir [makeDirectory msgdir]
    foreach loc $locales {
	if { $loc eq {} } {
	    set msg ROOT
	} else {
	    set msg [string tolower $loc]
	}
	makeFile [list ::msgcat::mcset $loc abc abc-$loc] $msg.msg $msgdir
    }
    variable count 1
    foreach loc {foo foo_BAR foo_BAR_baz} {
	test msgcat-5.$count {mcload} -setup {
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
	    mclocale foo
	    mcpackageconfig set mcfolder $msgdir
	} -result 2

    foreach loc $locales {
	if { $loc eq {} } {
	    set msg ROOT
        } else {
	    set msg [string tolower $loc]
	}
	removeFile $msg.msg $msgdir
    }
    removeDirectory msgdir

    # Tests msgcat-6.*: [mcset], [mc] namespace inheritance







|







548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
	    mclocale foo
	    mcpackageconfig set mcfolder $msgdir
	} -result 2

    foreach loc $locales {
	if { $loc eq {} } {
	    set msg ROOT
	} else {
	    set msg [string tolower $loc]
	}
	removeFile $msg.msg $msgdir
    }
    removeDirectory msgdir

    # Tests msgcat-6.*: [mcset], [mc] namespace inheritance
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
    interp bgerror {} [namespace code callbackproc]

    variable locale
    if {![info exist locale]} { set locale [mclocale] }

	test msgcat-14.1 {invocation loadcmd} -setup {
	    mcforgetpackage
    	    mclocale $locale
	    mclocale ""
	    mcloadedlocales clear
	    set resultvariable ""
	} -cleanup {
	    mcforgetpackage
	} -body {
	    mcpackageconfig set loadcmd [namespace code callbackproc]
	    mclocale foo_bar
	    lsort $resultvariable
	} -result {foo foo_bar}

	test msgcat-14.2 {invocation failed in loadcmd} -setup {
	    mcforgetpackage
    	    mclocale $locale
	    mclocale ""
	    mcloadedlocales clear
	} -cleanup {
	    mcforgetpackage
	    after cancel set [namespace current]::resultvariable timeout
	} -body {
	    mcpackageconfig set loadcmd [namespace code callbackfailproc]
	    mclocale foo_bar
	    # let the bgerror run
	    after 100 set [namespace current]::resultvariable timeout
	    vwait [namespace current]::resultvariable
	    lassign $resultvariable err errdict
	    list $err [dict get $errdict -code]
	} -result {fail 1}

	test msgcat-14.3 {invocation changecmd} -setup {
	    mcforgetpackage
    	    mclocale $locale
	    mclocale ""
	    set resultvariable ""
	} -cleanup {
	    mcforgetpackage
	} -body {
	    mcpackageconfig set changecmd [namespace code callbackproc]
	    mclocale foo_bar
	    set resultvariable
	} -result {foo_bar foo {}}

	test msgcat-14.4 {invocation unknowncmd} -setup {
	    mcforgetpackage
    	    mclocale $locale
	    mclocale ""
	    mcloadedlocales clear
	    set resultvariable ""
	} -cleanup {
	    mcforgetpackage
	} -body {
	    mcpackageconfig set unknowncmd [namespace code callbackproc]
	    mclocale foo_bar
	    mc k1 p1
	    set resultvariable
	} -result {foo_bar k1 p1}

	test msgcat-14.5 {disable global unknowncmd} -setup {
	    mcforgetpackage
    	    mclocale $locale
	    mclocale ""
	    mcloadedlocales clear
	    set resultvariable ""
	    rename ::msgcat::mcunknown SavedMcunknown
	    proc ::msgcat::mcunknown {dom s} {
		return unknown:$dom:$s
	    }
	} -cleanup {
	    mcforgetpackage
	    rename ::msgcat::mcunknown {}
	    rename SavedMcunknown ::msgcat::mcunknown
	} -body {
	    mcpackageconfig set unknowncmd ""
	    mclocale foo_bar
	    mc k1%s p1
	} -result {k1p1}

	test msgcat-14.6 {unknowncmd failing} -setup {
	    mcforgetpackage
    	    mclocale $locale
	    mclocale ""
	    mcloadedlocales clear
	    set resultvariable ""
	} -cleanup {
	    mcforgetpackage
	} -body {
	    mcpackageconfig set unknowncmd [namespace code callbackfailproc]







|













|

















|












|














|



















|







1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
    interp bgerror {} [namespace code callbackproc]

    variable locale
    if {![info exist locale]} { set locale [mclocale] }

	test msgcat-14.1 {invocation loadcmd} -setup {
	    mcforgetpackage
	    mclocale $locale
	    mclocale ""
	    mcloadedlocales clear
	    set resultvariable ""
	} -cleanup {
	    mcforgetpackage
	} -body {
	    mcpackageconfig set loadcmd [namespace code callbackproc]
	    mclocale foo_bar
	    lsort $resultvariable
	} -result {foo foo_bar}

	test msgcat-14.2 {invocation failed in loadcmd} -setup {
	    mcforgetpackage
	    mclocale $locale
	    mclocale ""
	    mcloadedlocales clear
	} -cleanup {
	    mcforgetpackage
	    after cancel set [namespace current]::resultvariable timeout
	} -body {
	    mcpackageconfig set loadcmd [namespace code callbackfailproc]
	    mclocale foo_bar
	    # let the bgerror run
	    after 100 set [namespace current]::resultvariable timeout
	    vwait [namespace current]::resultvariable
	    lassign $resultvariable err errdict
	    list $err [dict get $errdict -code]
	} -result {fail 1}

	test msgcat-14.3 {invocation changecmd} -setup {
	    mcforgetpackage
	    mclocale $locale
	    mclocale ""
	    set resultvariable ""
	} -cleanup {
	    mcforgetpackage
	} -body {
	    mcpackageconfig set changecmd [namespace code callbackproc]
	    mclocale foo_bar
	    set resultvariable
	} -result {foo_bar foo {}}

	test msgcat-14.4 {invocation unknowncmd} -setup {
	    mcforgetpackage
	    mclocale $locale
	    mclocale ""
	    mcloadedlocales clear
	    set resultvariable ""
	} -cleanup {
	    mcforgetpackage
	} -body {
	    mcpackageconfig set unknowncmd [namespace code callbackproc]
	    mclocale foo_bar
	    mc k1 p1
	    set resultvariable
	} -result {foo_bar k1 p1}

	test msgcat-14.5 {disable global unknowncmd} -setup {
	    mcforgetpackage
	    mclocale $locale
	    mclocale ""
	    mcloadedlocales clear
	    set resultvariable ""
	    rename ::msgcat::mcunknown SavedMcunknown
	    proc ::msgcat::mcunknown {dom s} {
		return unknown:$dom:$s
	    }
	} -cleanup {
	    mcforgetpackage
	    rename ::msgcat::mcunknown {}
	    rename SavedMcunknown ::msgcat::mcunknown
	} -body {
	    mcpackageconfig set unknowncmd ""
	    mclocale foo_bar
	    mc k1%s p1
	} -result {k1p1}

	test msgcat-14.6 {unknowncmd failing} -setup {
	    mcforgetpackage
	    mclocale $locale
	    mclocale ""
	    mcloadedlocales clear
	    set resultvariable ""
	} -cleanup {
	    mcforgetpackage
	} -body {
	    mcpackageconfig set unknowncmd [namespace code callbackfailproc]
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
	namespace eval bar {
	    ::msgcat::mcset foo_BAR con2 con2bar
	    oo::class create ClassCur
	    oo::define ClassCur method method1 {} {::msgcat::mc con2}
	}
	# full namespace is ::msgcat::test:baz
	namespace eval baz {
            set ObjCur [::msgcat::test::bar::ClassCur new]
	}
	variable locale [mclocale]
	mclocale foo_BAR
    } -cleanup {
	mclocale $locale
	namespace eval bar {::msgcat::mcforgetpackage}
	namespace delete bar baz







|







1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
	namespace eval bar {
	    ::msgcat::mcset foo_BAR con2 con2bar
	    oo::class create ClassCur
	    oo::define ClassCur method method1 {} {::msgcat::mc con2}
	}
	# full namespace is ::msgcat::test:baz
	namespace eval baz {
	    set ObjCur [::msgcat::test::bar::ClassCur new]
	}
	variable locale [mclocale]
	mclocale foo_BAR
    } -cleanup {
	mclocale $locale
	namespace eval bar {::msgcat::mcforgetpackage}
	namespace delete bar baz
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293

    test msgcat-16.3 {mcpackagenamespaceget in class} -setup {
	namespace eval bar {
	    oo::class create ClassCur
	    oo::define ClassCur method method1 {} {msgcat::mcpackagenamespaceget}
	}
	namespace eval baz {
            set ObjCur [::msgcat::test::bar::ClassCur new]
	}
    } -cleanup {
	namespace delete bar baz
    } -body {
	$baz::ObjCur method1
    } -result ::msgcat::test::bar








|







1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293

    test msgcat-16.3 {mcpackagenamespaceget in class} -setup {
	namespace eval bar {
	    oo::class create ClassCur
	    oo::define ClassCur method method1 {} {msgcat::mcpackagenamespaceget}
	}
	namespace eval baz {
	    set ObjCur [::msgcat::test::bar::ClassCur new]
	}
    } -cleanup {
	namespace delete bar baz
    } -body {
	$baz::ObjCur method1
    } -result ::msgcat::test::bar

Changes to tests/namespace-old.test.
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
test namespace-old-1.3 {usage for "namespace eval"} {
    list [catch {namespace eval} msg] $msg
} {1 {wrong # args: should be "namespace eval name arg ?arg...?"}}
test namespace-old-1.4 {create new namespaces} {
    list [lsort [namespace children :: test_ns_simple*]] \
	 [namespace eval test_ns_simple {}] \
	 [namespace eval test_ns_simple2 {}] \
         [lsort [namespace children :: test_ns_simple*]]
} {{} {} {} {::test_ns_simple ::test_ns_simple2}}
test namespace-old-1.5 {access a new namespace} {
    namespace eval test_ns_simple { namespace current }
} {::test_ns_simple}
test namespace-old-1.6 {usage for "namespace eval"} {
    list [catch {namespace eval} msg] $msg
} {1 {wrong # args: should be "namespace eval name arg ?arg...?"}}
test namespace-old-1.7 {usage for "namespace eval"} {
    list [catch {namespace eval test_ns_xyzzy} msg] $msg
} {1 {wrong # args: should be "namespace eval name arg ?arg...?"}}
test namespace-old-1.8 {command "namespace eval" concatenates args} {
    namespace eval test_ns_simple namespace current
} {::test_ns_simple}
test namespace-old-1.9 {add elements to a namespace} {
    namespace eval test_ns_simple {
        variable test_ns_x 0
        proc test {test_ns_x} {
            return "test: $test_ns_x"
        }
    }
} {}
namespace eval test_ns_simple {
    variable test_ns_x 0
    proc test {test_ns_x} {
	return "test: $test_ns_x"
    }
}
test namespace-old-1.10 {commands in a namespace} {
    namespace eval test_ns_simple { info commands [namespace current]::*}
} {::test_ns_simple::test}
test namespace-old-1.11 {variables in a namespace} {
    namespace eval test_ns_simple { info vars [namespace current]::* }
} {::test_ns_simple::test_ns_x}
test namespace-old-1.12 {global vars are separate from locals vars} {
    list [test_ns_simple::test 123] [set test_ns_simple::test_ns_x]
} {{test: 123} 0}
test namespace-old-1.13 {add to an existing namespace} {
    namespace eval test_ns_simple {
        variable test_ns_y 123
        proc _backdoor {cmd} {
            eval $cmd
        }
    }
} ""
namespace eval test_ns_simple {
    variable test_ns_y 123
    proc _backdoor {cmd} {
	eval $cmd
    }







|















|
|
|
|



















|
|
|
|







31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
test namespace-old-1.3 {usage for "namespace eval"} {
    list [catch {namespace eval} msg] $msg
} {1 {wrong # args: should be "namespace eval name arg ?arg...?"}}
test namespace-old-1.4 {create new namespaces} {
    list [lsort [namespace children :: test_ns_simple*]] \
	 [namespace eval test_ns_simple {}] \
	 [namespace eval test_ns_simple2 {}] \
	 [lsort [namespace children :: test_ns_simple*]]
} {{} {} {} {::test_ns_simple ::test_ns_simple2}}
test namespace-old-1.5 {access a new namespace} {
    namespace eval test_ns_simple { namespace current }
} {::test_ns_simple}
test namespace-old-1.6 {usage for "namespace eval"} {
    list [catch {namespace eval} msg] $msg
} {1 {wrong # args: should be "namespace eval name arg ?arg...?"}}
test namespace-old-1.7 {usage for "namespace eval"} {
    list [catch {namespace eval test_ns_xyzzy} msg] $msg
} {1 {wrong # args: should be "namespace eval name arg ?arg...?"}}
test namespace-old-1.8 {command "namespace eval" concatenates args} {
    namespace eval test_ns_simple namespace current
} {::test_ns_simple}
test namespace-old-1.9 {add elements to a namespace} {
    namespace eval test_ns_simple {
	variable test_ns_x 0
	proc test {test_ns_x} {
	    return "test: $test_ns_x"
	}
    }
} {}
namespace eval test_ns_simple {
    variable test_ns_x 0
    proc test {test_ns_x} {
	return "test: $test_ns_x"
    }
}
test namespace-old-1.10 {commands in a namespace} {
    namespace eval test_ns_simple { info commands [namespace current]::*}
} {::test_ns_simple::test}
test namespace-old-1.11 {variables in a namespace} {
    namespace eval test_ns_simple { info vars [namespace current]::* }
} {::test_ns_simple::test_ns_x}
test namespace-old-1.12 {global vars are separate from locals vars} {
    list [test_ns_simple::test 123] [set test_ns_simple::test_ns_x]
} {{test: 123} 0}
test namespace-old-1.13 {add to an existing namespace} {
    namespace eval test_ns_simple {
	variable test_ns_y 123
	proc _backdoor {cmd} {
	    eval $cmd
	}
    }
} ""
namespace eval test_ns_simple {
    variable test_ns_y 123
    proc _backdoor {cmd} {
	eval $cmd
    }
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
    list [catch "::test_ns_simple::_backdoor {return yes!}" msg] $msg
} {0 yes!}
test namespace-old-1.20 {variables in a namespace are hidden} {
    list [catch "set test_ns_x" msg] $msg [catch "set test_ns_y" msg] $msg
} {1 {can't read "test_ns_x": no such variable} 1 {can't read "test_ns_y": no such variable}}
test namespace-old-1.21 {using namespace qualifiers} {
    list [catch "set test_ns_simple::test_ns_x" msg] $msg \
         [catch "set test_ns_simple::test_ns_y" msg] $msg
} {0 0 0 123}
test namespace-old-1.22 {using absolute namespace qualifiers} {
    list [catch "set ::test_ns_simple::test_ns_x" msg] $msg \
         [catch "set ::test_ns_simple::test_ns_y" msg] $msg
} {0 0 0 123}
test namespace-old-1.23 {variables can be accessed within a namespace} {
    test_ns_simple::_backdoor {
        variable test_ns_x
        variable test_ns_y
        return "$test_ns_x $test_ns_y"
    }
} {0 123}
test namespace-old-1.24 {setting global variables} {
    test_ns_simple::_backdoor {variable test_ns_x;  set test_ns_x "new val"}
    namespace eval test_ns_simple {set test_ns_x}
} {new val}
test namespace-old-1.25 {qualified variables don't need a global declaration} {
    namespace eval test_ns_another { variable test_ns_x 456 }
    set cmd {set ::test_ns_another::test_ns_x}
    list [catch {test_ns_simple::_backdoor "$cmd some-value"} msg] $msg \
         [eval $cmd]
} {0 some-value some-value}
test namespace-old-1.26 {namespace qualifiers are okay after $'s} {
    namespace eval test_ns_simple { set test_ns_x 12; set test_ns_y 34 }
    set cmd {list $::test_ns_simple::test_ns_x $::test_ns_simple::test_ns_y}
    list [test_ns_simple::_backdoor $cmd] [eval $cmd]
} {{12 34} {12 34}}
test namespace-old-1.27 {can create commands with null names} {







|



|



|
|
|










|







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
    list [catch "::test_ns_simple::_backdoor {return yes!}" msg] $msg
} {0 yes!}
test namespace-old-1.20 {variables in a namespace are hidden} {
    list [catch "set test_ns_x" msg] $msg [catch "set test_ns_y" msg] $msg
} {1 {can't read "test_ns_x": no such variable} 1 {can't read "test_ns_y": no such variable}}
test namespace-old-1.21 {using namespace qualifiers} {
    list [catch "set test_ns_simple::test_ns_x" msg] $msg \
	 [catch "set test_ns_simple::test_ns_y" msg] $msg
} {0 0 0 123}
test namespace-old-1.22 {using absolute namespace qualifiers} {
    list [catch "set ::test_ns_simple::test_ns_x" msg] $msg \
	 [catch "set ::test_ns_simple::test_ns_y" msg] $msg
} {0 0 0 123}
test namespace-old-1.23 {variables can be accessed within a namespace} {
    test_ns_simple::_backdoor {
	variable test_ns_x
	variable test_ns_y
	return "$test_ns_x $test_ns_y"
    }
} {0 123}
test namespace-old-1.24 {setting global variables} {
    test_ns_simple::_backdoor {variable test_ns_x;  set test_ns_x "new val"}
    namespace eval test_ns_simple {set test_ns_x}
} {new val}
test namespace-old-1.25 {qualified variables don't need a global declaration} {
    namespace eval test_ns_another { variable test_ns_x 456 }
    set cmd {set ::test_ns_another::test_ns_x}
    list [catch {test_ns_simple::_backdoor "$cmd some-value"} msg] $msg \
	 [eval $cmd]
} {0 some-value some-value}
test namespace-old-1.26 {namespace qualifiers are okay after $'s} {
    namespace eval test_ns_simple { set test_ns_x 12; set test_ns_y 34 }
    set cmd {list $::test_ns_simple::test_ns_x $::test_ns_simple::test_ns_y}
    list [test_ns_simple::_backdoor $cmd] [eval $cmd]
} {{12 34} {12 34}}
test namespace-old-1.27 {can create commands with null names} {
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# TEST: namespace qualifiers, namespace tail
# -----------------------------------------------------------------------
test namespace-old-3.1 {usage for "namespace qualifiers"} {
    list [catch "namespace qualifiers" msg] $msg
} {1 {wrong # args: should be "namespace qualifiers string"}}
test namespace-old-3.2 {querying:  namespace qualifiers} {
    list [namespace qualifiers ""] \
         [namespace qualifiers ::] \
         [namespace qualifiers x] \
         [namespace qualifiers ::x] \
         [namespace qualifiers foo::x] \
         [namespace qualifiers ::foo::bar::xyz]
} {{} {} {} {} foo ::foo::bar}
test namespace-old-3.3 {usage for "namespace tail"} {
    list [catch "namespace tail" msg] $msg
} {1 {wrong # args: should be "namespace tail string"}}
test namespace-old-3.4 {querying:  namespace tail} {
    list [namespace tail ""] \
         [namespace tail ::] \
         [namespace tail x] \
         [namespace tail ::x] \
         [namespace tail foo::x] \
         [namespace tail ::foo::bar::xyz]
} {{} {} x x x xyz}

# -----------------------------------------------------------------------
# TEST: delete commands and namespaces
# -----------------------------------------------------------------------
test namespace-old-4.1 {define test namespaces} {
    namespace eval test_ns_delete {
        namespace eval ns1 {
            variable var1 1
            proc cmd1 {} {return "cmd1"}
        }
        namespace eval ns2 {
            variable var2 2
            proc cmd2 {} {return "cmd2"}
        }
        namespace eval another {}
        lsort [namespace children]
    }
} {::test_ns_delete::another ::test_ns_delete::ns1 ::test_ns_delete::ns2}
test namespace-old-4.2 {it's okay to invoke "namespace delete" with no args} {
    list [catch {namespace delete} msg] $msg
} {0 {}}
test namespace-old-4.3 {command "namespace delete" doesn't support patterns} {
    set cmd {
        namespace eval test_ns_delete {namespace delete ns*}
    }
    list [catch $cmd msg] $msg
} {1 {unknown namespace "ns*" in namespace delete command}}
namespace eval test_ns_delete {
    namespace eval ns1 {}
    namespace eval ns2 {}
    namespace eval another {}
}
test namespace-old-4.4 {command "namespace delete" handles multiple args} {
    set cmd {
        namespace eval test_ns_delete {
            namespace delete \
                {*}[namespace children [namespace current] ns?]
        }
    }
    list [catch $cmd msg] $msg [namespace children test_ns_delete]
} {0 {} ::test_ns_delete::another}

# -----------------------------------------------------------------------
# TEST: namespace hierarchy
# -----------------------------------------------------------------------
test namespace-old-5.1 {define nested namespaces} {
    set test_ns_var_global "var in ::"
    proc test_ns_cmd_global {} {return "cmd in ::"}
    namespace eval test_ns_hier1 {
        set test_ns_var_hier1 "particular to hier1"
        proc test_ns_cmd_hier1 {} {return "particular to hier1"}
        set test_ns_level 1
        proc test_ns_show {} {return "[namespace current]: 1"}
        namespace eval test_ns_hier2 {
            set test_ns_var_hier2 "particular to hier2"
            proc test_ns_cmd_hier2 {} {return "particular to hier2"}
            set test_ns_level 2
            proc test_ns_show {} {return "[namespace current]: 2"}
            namespace eval test_ns_hier3a {}
            namespace eval test_ns_hier3b {}
        }
        namespace eval test_ns_hier2a {}
        namespace eval test_ns_hier2b {}
    }
} {}
test namespace-old-5.2 {namespaces can be nested} {
    list [namespace eval test_ns_hier1 {namespace current}] \
         [namespace eval test_ns_hier1 {
              namespace eval test_ns_hier2 {namespace current}
          }]
} {::test_ns_hier1 ::test_ns_hier1::test_ns_hier2}
test namespace-old-5.3 {namespace qualifiers work in namespace command} {
    list [namespace eval ::test_ns_hier1 {namespace current}] \
         [namespace eval test_ns_hier1::test_ns_hier2 {namespace current}] \
         [namespace eval ::test_ns_hier1::test_ns_hier2 {namespace current}]
} {::test_ns_hier1 ::test_ns_hier1::test_ns_hier2 ::test_ns_hier1::test_ns_hier2}
set ::test_ns_var_global "var in ::"
proc test_ns_cmd_global {} {return "cmd in ::"}
namespace eval test_ns_hier1 {
    variable test_ns_var_hier1 "particular to hier1"
    proc test_ns_cmd_hier1 {} {return "particular to hier1"}
    variable test_ns_level 1
    proc test_ns_show {} {return "[namespace current]: 1"}
    namespace eval test_ns_hier2 {
	variable test_ns_var_hier2 "particular to hier2"
	proc test_ns_cmd_hier2 {} {return "particular to hier2"}
	variable test_ns_level 2
        proc test_ns_show {} {return "[namespace current]: 2"}
	namespace eval test_ns_hier3a {}
	namespace eval test_ns_hier3b {}
    }
    namespace eval test_ns_hier2a {}
    namespace eval test_ns_hier2b {}
}
# TIP 278: secondary lookup disabled for vars, tests disabled with #
test namespace-old-5.4 {nested namespaces can access global namespace} {
    list [namespace eval test_ns_hier1 {#set test_ns_var_global}] \
         [namespace eval test_ns_hier1 {test_ns_cmd_global}] \
         [namespace eval test_ns_hier1::test_ns_hier2 {#set test_ns_var_global}] \
         [namespace eval test_ns_hier1::test_ns_hier2 {test_ns_cmd_global}]
} {{} {cmd in ::} {} {cmd in ::}}
test namespace-old-5.5 {variables in different namespaces don't conflict} {
    list [set test_ns_hier1::test_ns_level] \
         [set test_ns_hier1::test_ns_hier2::test_ns_level]
} {1 2}
test namespace-old-5.6 {commands in different namespaces don't conflict} {
    list [test_ns_hier1::test_ns_show] \
         [test_ns_hier1::test_ns_hier2::test_ns_show]
} {{::test_ns_hier1: 1} {::test_ns_hier1::test_ns_hier2: 2}}
test namespace-old-5.7 {nested namespaces don't see variables in parent} {
    set cmd {
        namespace eval test_ns_hier1::test_ns_hier2 {set test_ns_var_hier1}
    }
    list [catch $cmd msg] $msg
} {1 {can't read "test_ns_var_hier1": no such variable}}
test namespace-old-5.8 {nested namespaces don't see commands in parent} {
    set cmd {
        namespace eval test_ns_hier1::test_ns_hier2 {test_ns_cmd_hier1}
    }
    list [catch $cmd msg] $msg
} {1 {invalid command name "test_ns_cmd_hier1"}}
test namespace-old-5.9 {usage for "namespace children"} {
    list [catch {namespace children test_ns_hier1 y z} msg] $msg
} {1 {wrong # args: should be "namespace children ?name? ?pattern?"}}
test namespace-old-5.10 {command "namespace children" must get valid namespace} -body {







|
|
|
|
|






|
|
|
|
|







|
|
|
|
|
|
|
|
|
|







|










|
|
|
|











|
|
|
|
|
|
|
|
|
|
|
|
|
|




|
|
|



|
|












|









|
|
|



|



|



|





|







178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# TEST: namespace qualifiers, namespace tail
# -----------------------------------------------------------------------
test namespace-old-3.1 {usage for "namespace qualifiers"} {
    list [catch "namespace qualifiers" msg] $msg
} {1 {wrong # args: should be "namespace qualifiers string"}}
test namespace-old-3.2 {querying:  namespace qualifiers} {
    list [namespace qualifiers ""] \
	 [namespace qualifiers ::] \
	 [namespace qualifiers x] \
	 [namespace qualifiers ::x] \
	 [namespace qualifiers foo::x] \
	 [namespace qualifiers ::foo::bar::xyz]
} {{} {} {} {} foo ::foo::bar}
test namespace-old-3.3 {usage for "namespace tail"} {
    list [catch "namespace tail" msg] $msg
} {1 {wrong # args: should be "namespace tail string"}}
test namespace-old-3.4 {querying:  namespace tail} {
    list [namespace tail ""] \
	 [namespace tail ::] \
	 [namespace tail x] \
	 [namespace tail ::x] \
	 [namespace tail foo::x] \
	 [namespace tail ::foo::bar::xyz]
} {{} {} x x x xyz}

# -----------------------------------------------------------------------
# TEST: delete commands and namespaces
# -----------------------------------------------------------------------
test namespace-old-4.1 {define test namespaces} {
    namespace eval test_ns_delete {
	namespace eval ns1 {
	    variable var1 1
	    proc cmd1 {} {return "cmd1"}
	}
	namespace eval ns2 {
	    variable var2 2
	    proc cmd2 {} {return "cmd2"}
	}
	namespace eval another {}
	lsort [namespace children]
    }
} {::test_ns_delete::another ::test_ns_delete::ns1 ::test_ns_delete::ns2}
test namespace-old-4.2 {it's okay to invoke "namespace delete" with no args} {
    list [catch {namespace delete} msg] $msg
} {0 {}}
test namespace-old-4.3 {command "namespace delete" doesn't support patterns} {
    set cmd {
	namespace eval test_ns_delete {namespace delete ns*}
    }
    list [catch $cmd msg] $msg
} {1 {unknown namespace "ns*" in namespace delete command}}
namespace eval test_ns_delete {
    namespace eval ns1 {}
    namespace eval ns2 {}
    namespace eval another {}
}
test namespace-old-4.4 {command "namespace delete" handles multiple args} {
    set cmd {
	namespace eval test_ns_delete {
	    namespace delete \
		{*}[namespace children [namespace current] ns?]
	}
    }
    list [catch $cmd msg] $msg [namespace children test_ns_delete]
} {0 {} ::test_ns_delete::another}

# -----------------------------------------------------------------------
# TEST: namespace hierarchy
# -----------------------------------------------------------------------
test namespace-old-5.1 {define nested namespaces} {
    set test_ns_var_global "var in ::"
    proc test_ns_cmd_global {} {return "cmd in ::"}
    namespace eval test_ns_hier1 {
	set test_ns_var_hier1 "particular to hier1"
	proc test_ns_cmd_hier1 {} {return "particular to hier1"}
	set test_ns_level 1
	proc test_ns_show {} {return "[namespace current]: 1"}
	namespace eval test_ns_hier2 {
	    set test_ns_var_hier2 "particular to hier2"
	    proc test_ns_cmd_hier2 {} {return "particular to hier2"}
	    set test_ns_level 2
	    proc test_ns_show {} {return "[namespace current]: 2"}
	    namespace eval test_ns_hier3a {}
	    namespace eval test_ns_hier3b {}
	}
	namespace eval test_ns_hier2a {}
	namespace eval test_ns_hier2b {}
    }
} {}
test namespace-old-5.2 {namespaces can be nested} {
    list [namespace eval test_ns_hier1 {namespace current}] \
	 [namespace eval test_ns_hier1 {
	      namespace eval test_ns_hier2 {namespace current}
	  }]
} {::test_ns_hier1 ::test_ns_hier1::test_ns_hier2}
test namespace-old-5.3 {namespace qualifiers work in namespace command} {
    list [namespace eval ::test_ns_hier1 {namespace current}] \
	 [namespace eval test_ns_hier1::test_ns_hier2 {namespace current}] \
	 [namespace eval ::test_ns_hier1::test_ns_hier2 {namespace current}]
} {::test_ns_hier1 ::test_ns_hier1::test_ns_hier2 ::test_ns_hier1::test_ns_hier2}
set ::test_ns_var_global "var in ::"
proc test_ns_cmd_global {} {return "cmd in ::"}
namespace eval test_ns_hier1 {
    variable test_ns_var_hier1 "particular to hier1"
    proc test_ns_cmd_hier1 {} {return "particular to hier1"}
    variable test_ns_level 1
    proc test_ns_show {} {return "[namespace current]: 1"}
    namespace eval test_ns_hier2 {
	variable test_ns_var_hier2 "particular to hier2"
	proc test_ns_cmd_hier2 {} {return "particular to hier2"}
	variable test_ns_level 2
	proc test_ns_show {} {return "[namespace current]: 2"}
	namespace eval test_ns_hier3a {}
	namespace eval test_ns_hier3b {}
    }
    namespace eval test_ns_hier2a {}
    namespace eval test_ns_hier2b {}
}
# TIP 278: secondary lookup disabled for vars, tests disabled with #
test namespace-old-5.4 {nested namespaces can access global namespace} {
    list [namespace eval test_ns_hier1 {#set test_ns_var_global}] \
	 [namespace eval test_ns_hier1 {test_ns_cmd_global}] \
	 [namespace eval test_ns_hier1::test_ns_hier2 {#set test_ns_var_global}] \
	 [namespace eval test_ns_hier1::test_ns_hier2 {test_ns_cmd_global}]
} {{} {cmd in ::} {} {cmd in ::}}
test namespace-old-5.5 {variables in different namespaces don't conflict} {
    list [set test_ns_hier1::test_ns_level] \
	 [set test_ns_hier1::test_ns_hier2::test_ns_level]
} {1 2}
test namespace-old-5.6 {commands in different namespaces don't conflict} {
    list [test_ns_hier1::test_ns_show] \
	 [test_ns_hier1::test_ns_hier2::test_ns_show]
} {{::test_ns_hier1: 1} {::test_ns_hier1::test_ns_hier2: 2}}
test namespace-old-5.7 {nested namespaces don't see variables in parent} {
    set cmd {
	namespace eval test_ns_hier1::test_ns_hier2 {set test_ns_var_hier1}
    }
    list [catch $cmd msg] $msg
} {1 {can't read "test_ns_var_hier1": no such variable}}
test namespace-old-5.8 {nested namespaces don't see commands in parent} {
    set cmd {
	namespace eval test_ns_hier1::test_ns_hier2 {test_ns_cmd_hier1}
    }
    list [catch $cmd msg] $msg
} {1 {invalid command name "test_ns_cmd_hier1"}}
test namespace-old-5.9 {usage for "namespace children"} {
    list [catch {namespace children test_ns_hier1 y z} msg] $msg
} {1 {wrong # args: should be "namespace children ?name? ?pattern?"}}
test namespace-old-5.10 {command "namespace children" must get valid namespace} -body {
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
    list [catch {namespace parent x y} msg] $msg
} {1 {wrong # args: should be "namespace parent ?name?"}}
test namespace-old-5.19 {command "namespace parent" must get valid namespace} -body {
    namespace parent xyzzy
} -returnCodes error -result {namespace "xyzzy" not found in "::"}
test namespace-old-5.20 {querying namespace parent} {
    list [namespace eval :: {namespace parent}] \
        [namespace eval test_ns_hier1 {namespace parent}] \
        [namespace eval test_ns_hier1::test_ns_hier2 {namespace parent}] \
        [namespace eval test_ns_hier1::test_ns_hier2::test_ns_hier3a {namespace parent}] \
} {{} :: ::test_ns_hier1 ::test_ns_hier1::test_ns_hier2}
test namespace-old-5.21 {querying namespace parent for explicit namespace} {
    list [namespace parent ::] \
         [namespace parent test_ns_hier1] \
         [namespace parent test_ns_hier1::test_ns_hier2] \
         [namespace parent test_ns_hier1::test_ns_hier2::test_ns_hier3a]
} {{} :: ::test_ns_hier1 ::test_ns_hier1::test_ns_hier2}

# -----------------------------------------------------------------------
# TEST: name resolution and caching
# -----------------------------------------------------------------------
set trigger {namespace eval test_ns_cache2 {namespace current}}
set trigger2 {namespace eval test_ns_cache2::test_ns_cache3 {namespace current}}
test namespace-old-6.1 {relative ns names only looked up in current ns} {
    namespace eval test_ns_cache1 {}
    namespace eval test_ns_cache2 {}
    namespace eval test_ns_cache2::test_ns_cache3 {}
    list [namespace eval test_ns_cache1 $trigger] \
         [namespace eval test_ns_cache1 $trigger2]
} {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
test namespace-old-6.2 {relative ns names only looked up in current ns} {
    namespace eval test_ns_cache1::test_ns_cache2 {}
    list [namespace eval test_ns_cache1 $trigger] \
         [namespace eval test_ns_cache1 $trigger2]
} {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
test namespace-old-6.3 {relative ns names only looked up in current ns} {
    namespace eval test_ns_cache1::test_ns_cache2::test_ns_cache3 {}
    list [namespace eval test_ns_cache1 $trigger] \
         [namespace eval test_ns_cache1 $trigger2]
} {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
namespace eval test_ns_cache1::test_ns_cache2 {}
test namespace-old-6.4 {relative ns names only looked up in current ns} {
    namespace delete test_ns_cache1::test_ns_cache2
    list [namespace eval test_ns_cache1 $trigger] \
         [namespace eval test_ns_cache1 $trigger2]
} {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
namespace eval test_ns_cache1 {
    proc trigger {} {test_ns_cache_cmd}
}
test namespace-old-6.5 {define test commands} {
    proc test_ns_cache_cmd {} {
        return "global version"
    }
    test_ns_cache1::trigger
} {global version}
test namespace-old-6.6 {one-level check for command shadowing} {
    proc test_ns_cache1::test_ns_cache_cmd {} {
        return "cache1 version"
    }
    test_ns_cache1::trigger
} {cache1 version}
proc test_ns_cache_cmd {} {
    return "global version"
}
test namespace-old-6.7 {renaming commands changes command epoch} -setup {
    proc test_ns_cache1::test_ns_cache_cmd {} {
        return "cache1 version"
    }
} -body {
    list [test_ns_cache1::trigger] \
	[namespace eval test_ns_cache1 {rename test_ns_cache_cmd test_ns_new}]\
	[test_ns_cache1::trigger]
} -result {{cache1 version} {} {global version}}
test namespace-old-6.8 {renaming back handles shadowing} -setup {
    proc test_ns_cache1::test_ns_new {} {
        return "cache1 version"
    }
} -body {
    list [test_ns_cache1::trigger] \
	[namespace eval test_ns_cache1 {rename test_ns_new test_ns_cache_cmd}]\
	[test_ns_cache1::trigger]
} -result {{global version} {} {cache1 version}}
test namespace-old-6.9 {deleting commands changes command epoch} -setup {
    proc test_ns_cache1::test_ns_cache_cmd {} {
        return "cache1 version"
    }
} -body {
    list [test_ns_cache1::trigger] \
	[namespace eval test_ns_cache1 {rename test_ns_cache_cmd ""}] \
	[test_ns_cache1::trigger]
} -result {{cache1 version} {} {global version}}
test namespace-old-6.10 {define test namespaces} {
    namespace eval test_ns_cache2 {
        proc test_ns_cache_cmd {} {
            return "global cache2 version"
        }
    }
    namespace eval test_ns_cache1 {
        proc trigger {} {
            test_ns_cache2::test_ns_cache_cmd
        }
    }
    namespace eval test_ns_cache1::test_ns_cache2 {
        proc trigger {} {
            test_ns_cache_cmd
        }
    }
    list [test_ns_cache1::trigger] [test_ns_cache1::test_ns_cache2::trigger]
} {{global cache2 version} {global version}}
namespace eval test_ns_cache1 {
    proc trigger {} { test_ns_cache2::test_ns_cache_cmd }
    namespace eval test_ns_cache2 {
	proc trigger {} { test_ns_cache_cmd }
    }
}
test namespace-old-6.11 {commands affect all parent namespaces} {
    proc test_ns_cache1::test_ns_cache2::test_ns_cache_cmd {} {
        return "cache2 version"
    }
    list [test_ns_cache1::trigger] [test_ns_cache1::test_ns_cache2::trigger]
} {{cache2 version} {cache2 version}}
# TIP 278: secondary lookup disabled, catch added, result changed from {global version}
test namespace-old-6.12 {define test variables} {
    variable test_ns_cache_var "global version"
    set trigger {set test_ns_cache_var}
    list [catch {namespace eval test_ns_cache1 $trigger} msg] $msg
} {1 {can't read "test_ns_cache_var": no such variable}}
    set trigger {set test_ns_cache_var}
test namespace-old-6.13 {one-level check for variable shadowing} {
    namespace eval test_ns_cache1 {
        variable test_ns_cache_var "cache1 version"
    }
    namespace eval test_ns_cache1 $trigger
} {cache1 version}
variable ::test_ns_cache_var "global version"
# TIP 278: secondary lookup disabled, catch added, result changed from {global version}
test namespace-old-6.14 {deleting variables changes variable epoch} {
    namespace eval test_ns_cache1 {
        variable test_ns_cache_var "cache1 version"
    }
    list [namespace eval test_ns_cache1 $trigger] \
	[namespace eval test_ns_cache1 {unset test_ns_cache_var}] \
	[catch {namespace eval test_ns_cache1 $trigger}]
} {{cache1 version} {} 1}
# TIP 278: secondary lookup disabled, catch added, result changed
test namespace-old-6.15 {define test namespaces} {
    namespace eval test_ns_cache2 {
        variable test_ns_cache_var "global cache2 version"
    }
    set trigger2 {set test_ns_cache2::test_ns_cache_var}
    catch {list [namespace eval test_ns_cache1 $trigger2] \
	       [namespace eval test_ns_cache1::test_ns_cache2 $trigger]}
} 1
set trigger2 {set test_ns_cache2::test_ns_cache_var}
test namespace-old-6.16 {public variables affect all parent namespaces} {
    variable test_ns_cache1::test_ns_cache2::test_ns_cache_var "cache2 version"
    list [namespace eval test_ns_cache1 $trigger2] \
         [namespace eval test_ns_cache1::test_ns_cache2 $trigger]
} {{cache2 version} {cache2 version}}
test namespace-old-6.17 {usage for "namespace which"} {
    list [catch "namespace which -baz x" msg] $msg
} {1 {wrong # args: should be "namespace which ?-command? ?-variable? name"}}
test namespace-old-6.18 {usage for "namespace which"} {
    # Presume no imported command called -command ;^)
    namespace which -command
} {}
test namespace-old-6.19 {querying:  namespace which -command} {
    proc test_ns_cache1::test_ns_cache_cmd {} {
        return "cache1 version"
    }
    list [namespace eval :: {namespace which test_ns_cache_cmd}] \
         [namespace eval test_ns_cache1 {namespace which test_ns_cache_cmd}] \
         [namespace eval :: {namespace which -command test_ns_cache_cmd}] \
         [namespace eval test_ns_cache1 {namespace which -command test_ns_cache_cmd}]
} {::test_ns_cache_cmd ::test_ns_cache1::test_ns_cache_cmd ::test_ns_cache_cmd ::test_ns_cache1::test_ns_cache_cmd}
test namespace-old-6.20 {command "namespace which" may not find commands} {
    namespace eval test_ns_cache1 {namespace which -command xyzzy}
} {}
variable test_ns_cache1::test_ns_cache2::test_ns_cache_var "cache2 version"
test namespace-old-6.21 {querying:  namespace which -variable} {
    namespace eval test_ns_cache1::test_ns_cache2 {
        namespace which -variable test_ns_cache_var
    }
} {::test_ns_cache1::test_ns_cache2::test_ns_cache_var}
test namespace-old-6.22 {command "namespace which" may not find variables} {
    namespace eval test_ns_cache1 {namespace which -variable xyzzy}
} {}

# -----------------------------------------------------------------------
# TEST: uplevel/upvar across namespace boundaries
# -----------------------------------------------------------------------
test namespace-old-7.1 {define test namespace} {
    namespace eval test_ns_uplevel {
        variable x 0
        variable y 1
        proc show_vars {num} {
            return [uplevel $num {info vars}]
        }
        proc test_uplevel {num} {
            set a 0
            set b 1
            namespace eval ::test_ns_uplevel " return \[show_vars $num\] "
        }
    }
} {}
namespace eval test_ns_uplevel {
    variable x 0
    variable y 1
    proc show_vars {num} {
	return [uplevel $num {info vars}]
    }
    proc test_uplevel {num} {
	set a 0
	set b 1
	namespace eval ::test_ns_uplevel " return \[show_vars $num\] "
    }
}
test namespace-old-7.2 {uplevel can access namespace call frame} {
    list [expr {"x" in [test_ns_uplevel::test_uplevel 1]}] \
         [expr {"y" in [test_ns_uplevel::test_uplevel 1]}]
} {1 1}
test namespace-old-7.3 {uplevel can go beyond namespace call frame} {
    lsort [test_ns_uplevel::test_uplevel 2]
} {a b num}
test namespace-old-7.4 {uplevel can go up to global context} {
    expr {[test_ns_uplevel::test_uplevel 3] == [info globals]}
} {1}
test namespace-old-7.5 {absolute call frame references work too} {
    list [expr {"x" in [test_ns_uplevel::test_uplevel #2]}] \
         [expr {"y" in [test_ns_uplevel::test_uplevel #2]}]
} {1 1}
test namespace-old-7.6 {absolute call frame references work too} {
    lsort [test_ns_uplevel::test_uplevel #1]
} {a b num}
test namespace-old-7.7 {absolute call frame references work too} {
    expr {[test_ns_uplevel::test_uplevel #0] == [info globals]}
} {1}
test namespace-old-7.8 {namespaces are included in the call stack} {
    namespace eval test_ns_upvar {
        variable scope "test_ns_upvar"
        proc show_val {var num} {
            upvar $num $var x
            return $x
        }
        proc test_upvar {num} {
            set scope "test_ns_upvar::test_upvar"
            namespace eval ::test_ns_upvar " return \[show_val scope $num\] "
        }
    }
} {}
namespace eval test_ns_upvar {
    variable scope "test_ns_upvar"
    proc show_val {var num} {
	upvar $num $var x
	return $x







|
|
|



|
|
|












|




|




|





|






|





|








|








|








|








|
|
|


|
|
|


|
|
|











|












|







|








|









|










|


|
|
|







|











|
|
|
|
|
|
|
|
|
|
















|









|









|
|
|
|
|
|
|
|
|







351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
    list [catch {namespace parent x y} msg] $msg
} {1 {wrong # args: should be "namespace parent ?name?"}}
test namespace-old-5.19 {command "namespace parent" must get valid namespace} -body {
    namespace parent xyzzy
} -returnCodes error -result {namespace "xyzzy" not found in "::"}
test namespace-old-5.20 {querying namespace parent} {
    list [namespace eval :: {namespace parent}] \
	[namespace eval test_ns_hier1 {namespace parent}] \
	[namespace eval test_ns_hier1::test_ns_hier2 {namespace parent}] \
	[namespace eval test_ns_hier1::test_ns_hier2::test_ns_hier3a {namespace parent}] \
} {{} :: ::test_ns_hier1 ::test_ns_hier1::test_ns_hier2}
test namespace-old-5.21 {querying namespace parent for explicit namespace} {
    list [namespace parent ::] \
	 [namespace parent test_ns_hier1] \
	 [namespace parent test_ns_hier1::test_ns_hier2] \
	 [namespace parent test_ns_hier1::test_ns_hier2::test_ns_hier3a]
} {{} :: ::test_ns_hier1 ::test_ns_hier1::test_ns_hier2}

# -----------------------------------------------------------------------
# TEST: name resolution and caching
# -----------------------------------------------------------------------
set trigger {namespace eval test_ns_cache2 {namespace current}}
set trigger2 {namespace eval test_ns_cache2::test_ns_cache3 {namespace current}}
test namespace-old-6.1 {relative ns names only looked up in current ns} {
    namespace eval test_ns_cache1 {}
    namespace eval test_ns_cache2 {}
    namespace eval test_ns_cache2::test_ns_cache3 {}
    list [namespace eval test_ns_cache1 $trigger] \
	 [namespace eval test_ns_cache1 $trigger2]
} {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
test namespace-old-6.2 {relative ns names only looked up in current ns} {
    namespace eval test_ns_cache1::test_ns_cache2 {}
    list [namespace eval test_ns_cache1 $trigger] \
	 [namespace eval test_ns_cache1 $trigger2]
} {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
test namespace-old-6.3 {relative ns names only looked up in current ns} {
    namespace eval test_ns_cache1::test_ns_cache2::test_ns_cache3 {}
    list [namespace eval test_ns_cache1 $trigger] \
	 [namespace eval test_ns_cache1 $trigger2]
} {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
namespace eval test_ns_cache1::test_ns_cache2 {}
test namespace-old-6.4 {relative ns names only looked up in current ns} {
    namespace delete test_ns_cache1::test_ns_cache2
    list [namespace eval test_ns_cache1 $trigger] \
	 [namespace eval test_ns_cache1 $trigger2]
} {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
namespace eval test_ns_cache1 {
    proc trigger {} {test_ns_cache_cmd}
}
test namespace-old-6.5 {define test commands} {
    proc test_ns_cache_cmd {} {
	return "global version"
    }
    test_ns_cache1::trigger
} {global version}
test namespace-old-6.6 {one-level check for command shadowing} {
    proc test_ns_cache1::test_ns_cache_cmd {} {
	return "cache1 version"
    }
    test_ns_cache1::trigger
} {cache1 version}
proc test_ns_cache_cmd {} {
    return "global version"
}
test namespace-old-6.7 {renaming commands changes command epoch} -setup {
    proc test_ns_cache1::test_ns_cache_cmd {} {
	return "cache1 version"
    }
} -body {
    list [test_ns_cache1::trigger] \
	[namespace eval test_ns_cache1 {rename test_ns_cache_cmd test_ns_new}]\
	[test_ns_cache1::trigger]
} -result {{cache1 version} {} {global version}}
test namespace-old-6.8 {renaming back handles shadowing} -setup {
    proc test_ns_cache1::test_ns_new {} {
	return "cache1 version"
    }
} -body {
    list [test_ns_cache1::trigger] \
	[namespace eval test_ns_cache1 {rename test_ns_new test_ns_cache_cmd}]\
	[test_ns_cache1::trigger]
} -result {{global version} {} {cache1 version}}
test namespace-old-6.9 {deleting commands changes command epoch} -setup {
    proc test_ns_cache1::test_ns_cache_cmd {} {
	return "cache1 version"
    }
} -body {
    list [test_ns_cache1::trigger] \
	[namespace eval test_ns_cache1 {rename test_ns_cache_cmd ""}] \
	[test_ns_cache1::trigger]
} -result {{cache1 version} {} {global version}}
test namespace-old-6.10 {define test namespaces} {
    namespace eval test_ns_cache2 {
	proc test_ns_cache_cmd {} {
	    return "global cache2 version"
	}
    }
    namespace eval test_ns_cache1 {
	proc trigger {} {
	    test_ns_cache2::test_ns_cache_cmd
	}
    }
    namespace eval test_ns_cache1::test_ns_cache2 {
	proc trigger {} {
	    test_ns_cache_cmd
	}
    }
    list [test_ns_cache1::trigger] [test_ns_cache1::test_ns_cache2::trigger]
} {{global cache2 version} {global version}}
namespace eval test_ns_cache1 {
    proc trigger {} { test_ns_cache2::test_ns_cache_cmd }
    namespace eval test_ns_cache2 {
	proc trigger {} { test_ns_cache_cmd }
    }
}
test namespace-old-6.11 {commands affect all parent namespaces} {
    proc test_ns_cache1::test_ns_cache2::test_ns_cache_cmd {} {
	return "cache2 version"
    }
    list [test_ns_cache1::trigger] [test_ns_cache1::test_ns_cache2::trigger]
} {{cache2 version} {cache2 version}}
# TIP 278: secondary lookup disabled, catch added, result changed from {global version}
test namespace-old-6.12 {define test variables} {
    variable test_ns_cache_var "global version"
    set trigger {set test_ns_cache_var}
    list [catch {namespace eval test_ns_cache1 $trigger} msg] $msg
} {1 {can't read "test_ns_cache_var": no such variable}}
    set trigger {set test_ns_cache_var}
test namespace-old-6.13 {one-level check for variable shadowing} {
    namespace eval test_ns_cache1 {
	variable test_ns_cache_var "cache1 version"
    }
    namespace eval test_ns_cache1 $trigger
} {cache1 version}
variable ::test_ns_cache_var "global version"
# TIP 278: secondary lookup disabled, catch added, result changed from {global version}
test namespace-old-6.14 {deleting variables changes variable epoch} {
    namespace eval test_ns_cache1 {
	variable test_ns_cache_var "cache1 version"
    }
    list [namespace eval test_ns_cache1 $trigger] \
	[namespace eval test_ns_cache1 {unset test_ns_cache_var}] \
	[catch {namespace eval test_ns_cache1 $trigger}]
} {{cache1 version} {} 1}
# TIP 278: secondary lookup disabled, catch added, result changed
test namespace-old-6.15 {define test namespaces} {
    namespace eval test_ns_cache2 {
	variable test_ns_cache_var "global cache2 version"
    }
    set trigger2 {set test_ns_cache2::test_ns_cache_var}
    catch {list [namespace eval test_ns_cache1 $trigger2] \
	       [namespace eval test_ns_cache1::test_ns_cache2 $trigger]}
} 1
set trigger2 {set test_ns_cache2::test_ns_cache_var}
test namespace-old-6.16 {public variables affect all parent namespaces} {
    variable test_ns_cache1::test_ns_cache2::test_ns_cache_var "cache2 version"
    list [namespace eval test_ns_cache1 $trigger2] \
	 [namespace eval test_ns_cache1::test_ns_cache2 $trigger]
} {{cache2 version} {cache2 version}}
test namespace-old-6.17 {usage for "namespace which"} {
    list [catch "namespace which -baz x" msg] $msg
} {1 {wrong # args: should be "namespace which ?-command? ?-variable? name"}}
test namespace-old-6.18 {usage for "namespace which"} {
    # Presume no imported command called -command ;^)
    namespace which -command
} {}
test namespace-old-6.19 {querying:  namespace which -command} {
    proc test_ns_cache1::test_ns_cache_cmd {} {
	return "cache1 version"
    }
    list [namespace eval :: {namespace which test_ns_cache_cmd}] \
	 [namespace eval test_ns_cache1 {namespace which test_ns_cache_cmd}] \
	 [namespace eval :: {namespace which -command test_ns_cache_cmd}] \
	 [namespace eval test_ns_cache1 {namespace which -command test_ns_cache_cmd}]
} {::test_ns_cache_cmd ::test_ns_cache1::test_ns_cache_cmd ::test_ns_cache_cmd ::test_ns_cache1::test_ns_cache_cmd}
test namespace-old-6.20 {command "namespace which" may not find commands} {
    namespace eval test_ns_cache1 {namespace which -command xyzzy}
} {}
variable test_ns_cache1::test_ns_cache2::test_ns_cache_var "cache2 version"
test namespace-old-6.21 {querying:  namespace which -variable} {
    namespace eval test_ns_cache1::test_ns_cache2 {
	namespace which -variable test_ns_cache_var
    }
} {::test_ns_cache1::test_ns_cache2::test_ns_cache_var}
test namespace-old-6.22 {command "namespace which" may not find variables} {
    namespace eval test_ns_cache1 {namespace which -variable xyzzy}
} {}

# -----------------------------------------------------------------------
# TEST: uplevel/upvar across namespace boundaries
# -----------------------------------------------------------------------
test namespace-old-7.1 {define test namespace} {
    namespace eval test_ns_uplevel {
	variable x 0
	variable y 1
	proc show_vars {num} {
	    return [uplevel $num {info vars}]
	}
	proc test_uplevel {num} {
	    set a 0
	    set b 1
	    namespace eval ::test_ns_uplevel " return \[show_vars $num\] "
	}
    }
} {}
namespace eval test_ns_uplevel {
    variable x 0
    variable y 1
    proc show_vars {num} {
	return [uplevel $num {info vars}]
    }
    proc test_uplevel {num} {
	set a 0
	set b 1
	namespace eval ::test_ns_uplevel " return \[show_vars $num\] "
    }
}
test namespace-old-7.2 {uplevel can access namespace call frame} {
    list [expr {"x" in [test_ns_uplevel::test_uplevel 1]}] \
	 [expr {"y" in [test_ns_uplevel::test_uplevel 1]}]
} {1 1}
test namespace-old-7.3 {uplevel can go beyond namespace call frame} {
    lsort [test_ns_uplevel::test_uplevel 2]
} {a b num}
test namespace-old-7.4 {uplevel can go up to global context} {
    expr {[test_ns_uplevel::test_uplevel 3] == [info globals]}
} {1}
test namespace-old-7.5 {absolute call frame references work too} {
    list [expr {"x" in [test_ns_uplevel::test_uplevel #2]}] \
	 [expr {"y" in [test_ns_uplevel::test_uplevel #2]}]
} {1 1}
test namespace-old-7.6 {absolute call frame references work too} {
    lsort [test_ns_uplevel::test_uplevel #1]
} {a b num}
test namespace-old-7.7 {absolute call frame references work too} {
    expr {[test_ns_uplevel::test_uplevel #0] == [info globals]}
} {1}
test namespace-old-7.8 {namespaces are included in the call stack} {
    namespace eval test_ns_upvar {
	variable scope "test_ns_upvar"
	proc show_val {var num} {
	    upvar $num $var x
	    return $x
	}
	proc test_upvar {num} {
	    set scope "test_ns_upvar::test_upvar"
	    namespace eval ::test_ns_upvar " return \[show_val scope $num\] "
	}
    }
} {}
namespace eval test_ns_upvar {
    variable scope "test_ns_upvar"
    proc show_val {var num} {
	upvar $num $var x
	return $x
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
} {test_ns_upvar::test_upvar}

# -----------------------------------------------------------------------
# TEST: variable traces across namespace boundaries
# -----------------------------------------------------------------------
test namespace-old-8.1 {traces work across namespace boundaries} {
    namespace eval test_ns_trace {
        namespace eval foo {
            variable x ""
        }
        variable status ""
        proc monitor {name1 name2 op} {
            variable status
            lappend status "$op: $name1"
        }
        trace add variable foo::x {read write unset} [namespace code monitor]
    }
    set test_ns_trace::foo::x "yes!"
    set test_ns_trace::foo::x
    unset test_ns_trace::foo::x
    namespace eval test_ns_trace { set status }
} {{write: test_ns_trace::foo::x} {read: test_ns_trace::foo::x} {unset: test_ns_trace::foo::x}}

# -----------------------------------------------------------------------
# TEST: imported commands
# -----------------------------------------------------------------------
test namespace-old-9.1 {empty "namespace export" list} {
    list [catch "namespace export" msg] $msg
} {0 {}}
test namespace-old-9.2 {usage for "namespace export" command} {
    list [catch "namespace export test_ns_trace::zzz" msg] $msg
} {1 {invalid export pattern "test_ns_trace::zzz": pattern can't specify a namespace}}
test namespace-old-9.3 {define test namespaces for import} {
    namespace eval test_ns_export {
        namespace export cmd1 cmd2 cmd3
        proc cmd1 {args} {return "cmd1: $args"}
        proc cmd2 {args} {return "cmd2: $args"}
        proc cmd3 {args} {return "cmd3: $args"}
        proc cmd4 {args} {return "cmd4: $args"}
        proc cmd5 {args} {return "cmd5: $args"}
        proc cmd6 {args} {return "cmd6: $args"}
    }
    lsort [info commands test_ns_export::*]
} {::test_ns_export::cmd1 ::test_ns_export::cmd2 ::test_ns_export::cmd3 ::test_ns_export::cmd4 ::test_ns_export::cmd5 ::test_ns_export::cmd6}
namespace eval test_ns_export {
    namespace export cmd1 cmd2 cmd3
    proc cmd1 {args} {return "cmd1: $args"}
    proc cmd2 {args} {return "cmd2: $args"}
    proc cmd3 {args} {return "cmd3: $args"}
    proc cmd4 {args} {return "cmd4: $args"}
    proc cmd5 {args} {return "cmd5: $args"}
    proc cmd6 {args} {return "cmd6: $args"}
}
test namespace-old-9.4 {check export status} {
    set x ""
    namespace eval test_ns_import {
        namespace export cmd1 cmd2
        namespace import ::test_ns_export::*
    }
    foreach cmd [lsort [info commands test_ns_import::*]] {
        lappend x $cmd
    }
    set x
} {::test_ns_import::cmd1 ::test_ns_import::cmd2 ::test_ns_import::cmd3}
namespace eval test_ns_import {
    namespace export cmd1 cmd2
    namespace import ::test_ns_export::*
}







|
|
|
|
|
|
|
|
|


















|
|
|
|
|
|
|















|
|


|







623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
} {test_ns_upvar::test_upvar}

# -----------------------------------------------------------------------
# TEST: variable traces across namespace boundaries
# -----------------------------------------------------------------------
test namespace-old-8.1 {traces work across namespace boundaries} {
    namespace eval test_ns_trace {
	namespace eval foo {
	    variable x ""
	}
	variable status ""
	proc monitor {name1 name2 op} {
	    variable status
	    lappend status "$op: $name1"
	}
	trace add variable foo::x {read write unset} [namespace code monitor]
    }
    set test_ns_trace::foo::x "yes!"
    set test_ns_trace::foo::x
    unset test_ns_trace::foo::x
    namespace eval test_ns_trace { set status }
} {{write: test_ns_trace::foo::x} {read: test_ns_trace::foo::x} {unset: test_ns_trace::foo::x}}

# -----------------------------------------------------------------------
# TEST: imported commands
# -----------------------------------------------------------------------
test namespace-old-9.1 {empty "namespace export" list} {
    list [catch "namespace export" msg] $msg
} {0 {}}
test namespace-old-9.2 {usage for "namespace export" command} {
    list [catch "namespace export test_ns_trace::zzz" msg] $msg
} {1 {invalid export pattern "test_ns_trace::zzz": pattern can't specify a namespace}}
test namespace-old-9.3 {define test namespaces for import} {
    namespace eval test_ns_export {
	namespace export cmd1 cmd2 cmd3
	proc cmd1 {args} {return "cmd1: $args"}
	proc cmd2 {args} {return "cmd2: $args"}
	proc cmd3 {args} {return "cmd3: $args"}
	proc cmd4 {args} {return "cmd4: $args"}
	proc cmd5 {args} {return "cmd5: $args"}
	proc cmd6 {args} {return "cmd6: $args"}
    }
    lsort [info commands test_ns_export::*]
} {::test_ns_export::cmd1 ::test_ns_export::cmd2 ::test_ns_export::cmd3 ::test_ns_export::cmd4 ::test_ns_export::cmd5 ::test_ns_export::cmd6}
namespace eval test_ns_export {
    namespace export cmd1 cmd2 cmd3
    proc cmd1 {args} {return "cmd1: $args"}
    proc cmd2 {args} {return "cmd2: $args"}
    proc cmd3 {args} {return "cmd3: $args"}
    proc cmd4 {args} {return "cmd4: $args"}
    proc cmd5 {args} {return "cmd5: $args"}
    proc cmd6 {args} {return "cmd6: $args"}
}
test namespace-old-9.4 {check export status} {
    set x ""
    namespace eval test_ns_import {
	namespace export cmd1 cmd2
	namespace import ::test_ns_export::*
    }
    foreach cmd [lsort [info commands test_ns_import::*]] {
	lappend x $cmd
    }
    set x
} {::test_ns_import::cmd1 ::test_ns_import::cmd2 ::test_ns_import::cmd3}
namespace eval test_ns_import {
    namespace export cmd1 cmd2
    namespace import ::test_ns_export::*
}
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
} {cmd1 cmd2}
namespace import test_ns_import::cmd*
test namespace-old-9.9 {imported commands work just the same as original} {
    list [cmd1 test 1 2 3] [test_ns_import::cmd1 test 4 5 6]
} {{cmd1: test 1 2 3} {cmd1: test 4 5 6}}
test namespace-old-9.10 {commands can be imported from many namespaces} {
    namespace eval test_ns_import2 {
        namespace export ncmd ncmd1 ncmd2
        proc ncmd  {args} {return "ncmd: $args"}
        proc ncmd1 {args} {return "ncmd1: $args"}
        proc ncmd2 {args} {return "ncmd2: $args"}
        proc ncmd3 {args} {return "ncmd3: $args"}
    }
    namespace import test_ns_import2::*
    lsort [concat [info commands cmd*] [info commands ncmd*]]
} {cmd1 cmd2 ncmd ncmd1 ncmd2}
namespace eval test_ns_import2 {
    namespace export ncmd ncmd1 ncmd2
    proc ncmd  {args} {return "ncmd: $args"}







|
|
|
|
|







713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
} {cmd1 cmd2}
namespace import test_ns_import::cmd*
test namespace-old-9.9 {imported commands work just the same as original} {
    list [cmd1 test 1 2 3] [test_ns_import::cmd1 test 4 5 6]
} {{cmd1: test 1 2 3} {cmd1: test 4 5 6}}
test namespace-old-9.10 {commands can be imported from many namespaces} {
    namespace eval test_ns_import2 {
	namespace export ncmd ncmd1 ncmd2
	proc ncmd  {args} {return "ncmd: $args"}
	proc ncmd1 {args} {return "ncmd1: $args"}
	proc ncmd2 {args} {return "ncmd2: $args"}
	proc ncmd3 {args} {return "ncmd3: $args"}
    }
    namespace import test_ns_import2::*
    lsort [concat [info commands cmd*] [info commands ncmd*]]
} {cmd1 cmd2 ncmd ncmd1 ncmd2}
namespace eval test_ns_import2 {
    namespace export ncmd ncmd1 ncmd2
    proc ncmd  {args} {return "ncmd: $args"}
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
} {cmd2 ncmd ncmd1 ncmd2}
catch { rename cmd1 "" }
test namespace-old-9.12 {command "namespace forget" checks for valid namespaces} {
    list [catch {namespace forget xyzzy::*} msg] $msg
} {1 {unknown namespace in namespace forget pattern "xyzzy::*"}}
test namespace-old-9.13 {command "namespace forget" ignores patterns that don't match} {
    list [catch {namespace forget test_ns_import::xy*zzy} msg] $msg \
         [lsort [info commands cmd?]]
} {0 {} cmd2}
test namespace-old-9.14 {imported commands can be removed} {
    namespace forget test_ns_import::cmd?
    list [lsort [info commands cmd?]] \
         [catch {cmd1 another test} msg] $msg
} {{} 1 {invalid command name "cmd1"}}
test namespace-old-9.15 {existing commands can't be overwritten} {
    proc cmd1 {x y} {
        return [expr {$x+$y}]
    }
    list [catch {namespace import test_ns_import::cmd?} msg] $msg \
         [cmd1 3 5]
} {1 {can't import command "cmd1": already exists} 8}
test namespace-old-9.16 {use "-force" option to override existing commands} {
    proc cmd1 {x y} { return [expr {$x+$y}] }
    list [cmd1 3 5] \
         [namespace import -force test_ns_import::cmd?] \
         [cmd1 3 5]
} {8 {} {cmd1: 3 5}}
test namespace-old-9.17 {commands can be imported into many namespaces} {
    namespace eval test_ns_import_use {
        namespace import ::test_ns_import::* ::test_ns_import2::ncmd?
        lsort [concat [info commands ::test_ns_import_use::cmd*] \
                      [info commands ::test_ns_import_use::ncmd*]]
    }
} {::test_ns_import_use::cmd1 ::test_ns_import_use::cmd2 ::test_ns_import_use::ncmd1 ::test_ns_import_use::ncmd2}
test namespace-old-9.18 {when command is deleted, imported commands go away} {
    namespace eval test_ns_import { rename cmd1 "" }
    list [info commands cmd1] \
         [namespace eval test_ns_import_use {info commands cmd1}]
} {{} {}}
test namespace-old-9.19 {when namesp is deleted, all imported commands go away} {
    namespace delete test_ns_import test_ns_import2
    list [info commands cmd*] \
         [info commands ncmd*] \
         [namespace eval test_ns_import_use {info commands cmd*}] \
         [namespace eval test_ns_import_use {info commands ncmd*}] \
} {{} {} {} {}}

# -----------------------------------------------------------------------
# TEST: scoped values
# -----------------------------------------------------------------------
test namespace-old-10.1 {define namespace for scope test} {
    namespace eval test_ns_inscope {
        variable x "x-value"
        proc show {args} {
            return "show: $args"
        }
        proc do {args} {
            return [eval $args]
        }
        list [set x] [show test]
    }
} {x-value {show: test}}
test namespace-old-10.2 {command "namespace code" requires one argument} {
    list [catch {namespace code} msg] $msg
} {1 {wrong # args: should be "namespace code arg"}}
test namespace-old-10.3 {command "namespace code" requires one argument} {
    list [catch {namespace code first "second arg" third} msg] $msg
} {1 {wrong # args: should be "namespace code arg"}}
test namespace-old-10.4 {command "namespace code" gets current namesp context} {
    namespace eval test_ns_inscope {
        namespace code {"1 2 3" "4 5" 6}
    }
} {::namespace inscope ::test_ns_inscope {"1 2 3" "4 5" 6}}
test namespace-old-10.5 {with one arg, first "scope" sticks} {
    set sval [namespace eval test_ns_inscope {namespace code {one two}}]
    namespace code $sval
} {::namespace inscope ::test_ns_inscope {one two}}
test namespace-old-10.6 {with many args, each "scope" adds new args} {







|




|



|


|




|
|



|
|
|





|




|
|
|







|
|
|
|
|
|
|
|










|







740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
} {cmd2 ncmd ncmd1 ncmd2}
catch { rename cmd1 "" }
test namespace-old-9.12 {command "namespace forget" checks for valid namespaces} {
    list [catch {namespace forget xyzzy::*} msg] $msg
} {1 {unknown namespace in namespace forget pattern "xyzzy::*"}}
test namespace-old-9.13 {command "namespace forget" ignores patterns that don't match} {
    list [catch {namespace forget test_ns_import::xy*zzy} msg] $msg \
	 [lsort [info commands cmd?]]
} {0 {} cmd2}
test namespace-old-9.14 {imported commands can be removed} {
    namespace forget test_ns_import::cmd?
    list [lsort [info commands cmd?]] \
	 [catch {cmd1 another test} msg] $msg
} {{} 1 {invalid command name "cmd1"}}
test namespace-old-9.15 {existing commands can't be overwritten} {
    proc cmd1 {x y} {
	return [expr {$x+$y}]
    }
    list [catch {namespace import test_ns_import::cmd?} msg] $msg \
	 [cmd1 3 5]
} {1 {can't import command "cmd1": already exists} 8}
test namespace-old-9.16 {use "-force" option to override existing commands} {
    proc cmd1 {x y} { return [expr {$x+$y}] }
    list [cmd1 3 5] \
	 [namespace import -force test_ns_import::cmd?] \
	 [cmd1 3 5]
} {8 {} {cmd1: 3 5}}
test namespace-old-9.17 {commands can be imported into many namespaces} {
    namespace eval test_ns_import_use {
	namespace import ::test_ns_import::* ::test_ns_import2::ncmd?
	lsort [concat [info commands ::test_ns_import_use::cmd*] \
		      [info commands ::test_ns_import_use::ncmd*]]
    }
} {::test_ns_import_use::cmd1 ::test_ns_import_use::cmd2 ::test_ns_import_use::ncmd1 ::test_ns_import_use::ncmd2}
test namespace-old-9.18 {when command is deleted, imported commands go away} {
    namespace eval test_ns_import { rename cmd1 "" }
    list [info commands cmd1] \
	 [namespace eval test_ns_import_use {info commands cmd1}]
} {{} {}}
test namespace-old-9.19 {when namesp is deleted, all imported commands go away} {
    namespace delete test_ns_import test_ns_import2
    list [info commands cmd*] \
	 [info commands ncmd*] \
	 [namespace eval test_ns_import_use {info commands cmd*}] \
	 [namespace eval test_ns_import_use {info commands ncmd*}] \
} {{} {} {} {}}

# -----------------------------------------------------------------------
# TEST: scoped values
# -----------------------------------------------------------------------
test namespace-old-10.1 {define namespace for scope test} {
    namespace eval test_ns_inscope {
	variable x "x-value"
	proc show {args} {
	    return "show: $args"
	}
	proc do {args} {
	    return [eval $args]
	}
	list [set x] [show test]
    }
} {x-value {show: test}}
test namespace-old-10.2 {command "namespace code" requires one argument} {
    list [catch {namespace code} msg] $msg
} {1 {wrong # args: should be "namespace code arg"}}
test namespace-old-10.3 {command "namespace code" requires one argument} {
    list [catch {namespace code first "second arg" third} msg] $msg
} {1 {wrong # args: should be "namespace code arg"}}
test namespace-old-10.4 {command "namespace code" gets current namesp context} {
    namespace eval test_ns_inscope {
	namespace code {"1 2 3" "4 5" 6}
    }
} {::namespace inscope ::test_ns_inscope {"1 2 3" "4 5" 6}}
test namespace-old-10.5 {with one arg, first "scope" sticks} {
    set sval [namespace eval test_ns_inscope {namespace code {one two}}]
    namespace code $sval
} {::namespace inscope ::test_ns_inscope {one two}}
test namespace-old-10.6 {with many args, each "scope" adds new args} {
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
    list [eval $cref "a" "b c" "d e f"]
} {{show: a b c d e f}}
namespace eval test_ns_inscope {
    variable x "x-value"
}
test namespace-old-10.8 {scoped commands execute in namespace context} {
    set cref [namespace eval test_ns_inscope {
        namespace code {set x "some new value"}
    }]
    list [set test_ns_inscope::x] [eval $cref] [set test_ns_inscope::x]
} {x-value {some new value} {some new value}}

foreach cmd [info commands test_ns_*] {
    rename $cmd ""
}







|







828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
    list [eval $cref "a" "b c" "d e f"]
} {{show: a b c d e f}}
namespace eval test_ns_inscope {
    variable x "x-value"
}
test namespace-old-10.8 {scoped commands execute in namespace context} {
    set cref [namespace eval test_ns_inscope {
	namespace code {set x "some new value"}
    }]
    list [set test_ns_inscope::x] [eval $cref] [set test_ns_inscope::x]
} {x-value {some new value} {some new value}}

foreach cmd [info commands test_ns_*] {
    rename $cmd ""
}
Changes to tests/namespace.test.
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
test namespace-1.1 {TclInitNamespaces, GetNamespaceFromObj, NamespaceChildrenCmd} {
    namespace children :: test_ns_*
} {}

catch {unset l}
test namespace-2.1 {Tcl_GetCurrentNamespace} {
    list [namespace current] [namespace eval {} {namespace current}] \
        [namespace eval {} {namespace current}]
} {:: :: ::}
test namespace-2.2 {Tcl_GetCurrentNamespace} {
    set l {}
    lappend l [namespace current]
    namespace eval test_ns_1 {
        lappend ::l [namespace current]
        namespace eval foo {
            lappend ::l [namespace current]
        }
    }
    lappend l [namespace current]
} {:: ::test_ns_1 ::test_ns_1::foo ::}

test namespace-3.1 {Tcl_GetGlobalNamespace} {
    namespace eval test_ns_1 {namespace eval foo {namespace eval bar {} } }
    # namespace children uses Tcl_GetGlobalNamespace
    namespace eval test_ns_1 {namespace children foo b*}
} {::test_ns_1::foo::bar}

test namespace-4.1 {Tcl_PushCallFrame with isProcCallFrame=1} {
    namespace eval test_ns_1 {
        variable v 123
        proc p {} {
            variable v
            return $v
        }
    }
    test_ns_1::p    ;# does Tcl_PushCallFrame to push p's namespace
} {123}
test namespace-4.2 {Tcl_PushCallFrame with isProcCallFrame=0} {
    namespace eval test_ns_1::baz {}  ;# does Tcl_PushCallFrame to create baz
    proc test_ns_1::baz::p {} {
        variable v
        set v 789
        set v}
    test_ns_1::baz::p
} {789}

test namespace-5.1 {Tcl_PopCallFrame, no vars} {
    namespace eval test_ns_1::blodge {}  ;# pushes then pops frame
} {}
test namespace-5.2 {Tcl_PopCallFrame, local vars must be deleted} -setup {
    namespace eval test_ns_1 {}
} -body {
    proc test_ns_1::r {} {
        set a 123
    }
    test_ns_1::r   ;# pushes then pop's r's frame
} -result {123}

test namespace-6.1 {Tcl_CreateNamespace} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    list [lsort [namespace children :: test_ns_*]] \
        [namespace eval test_ns_1 {namespace current}] \
	[namespace eval test_ns_2 {namespace current}] \
	[namespace eval ::test_ns_3 {namespace current}] \
	[namespace eval ::test_ns_4 \
            {namespace eval foo {namespace current}}] \
	[namespace eval ::test_ns_5 \
            {namespace eval ::test_ns_6 {namespace current}}] \
        [lsort [namespace children :: test_ns_*]]
} {{} ::test_ns_1 ::test_ns_2 ::test_ns_3 ::test_ns_4::foo ::test_ns_6 {::test_ns_1 ::test_ns_2 ::test_ns_3 ::test_ns_4 ::test_ns_5 ::test_ns_6}}
test namespace-6.2 {Tcl_CreateNamespace, odd number of :'s in name is okay} {
    list [namespace eval :::test_ns_1::::foo {namespace current}] \
         [namespace eval test_ns_2:::::foo {namespace current}]
} {::test_ns_1::foo ::test_ns_2::foo}
test namespace-6.3 {Tcl_CreateNamespace, trailing ::s in ns name are ignored} {
    list [catch {namespace eval test_ns_7::: {namespace current}} msg] $msg
} {0 ::test_ns_7}
test namespace-6.4 {Tcl_CreateNamespace, trailing ::s in ns name are ignored} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1:: {
        namespace eval test_ns_2:: {}
        namespace eval test_ns_3:: {}
    }
    lsort [namespace children ::test_ns_1]
} [lsort {::test_ns_1::test_ns_2 ::test_ns_1::test_ns_3}]
test namespace-6.5 {Tcl_CreateNamespace, relative ns names now only looked up in current ns} {
    set trigger {
        namespace eval test_ns_2 {namespace current}
    }
    set l {}
    lappend l [namespace eval test_ns_1 $trigger]
    namespace eval test_ns_1::test_ns_2 {}
    lappend l [namespace eval test_ns_1 $trigger]
} {::test_ns_1::test_ns_2 ::test_ns_1::test_ns_2}

test namespace-7.1 {Tcl_DeleteNamespace, active call frames in ns} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1 {
        proc p {} {
            namespace delete [namespace current]
            return [namespace current]
        }
    }
    list [test_ns_1::p] [catch {test_ns_1::p} msg] $msg
} {::test_ns_1 1 {invalid command name "test_ns_1::p"}}
test namespace-7.2 {Tcl_DeleteNamespace, no active call frames in ns} {
    namespace eval test_ns_2 {
        proc p {} {
            return [namespace current]
        }
    }
    list [test_ns_2::p] [namespace delete test_ns_2]
} {::test_ns_2 {}}
test namespace-7.3 {recursive Tcl_DeleteNamespace, active call frames in ns} {
    # [Bug 1355942]
    namespace eval test_ns_2 {
        set x 1
	trace add variable x unset "namespace delete [namespace current];#"
	namespace delete [namespace current]
    }
} {}
test namespace-7.4 {recursive Tcl_DeleteNamespace, active call frames in ns} {
    # [Bug 1355942]
    namespace eval test_ns_2 {
        proc x {} {}
	trace add command x delete "namespace delete [namespace current];#"
	namespace delete [namespace current]
    }
} {}
test namespace-7.5 {recursive Tcl_DeleteNamespace, no active call frames in ns} {
    # [Bug 1355942]
    namespace eval test_ns_2 {
        set x 1
	trace add variable x unset "namespace delete [namespace current];#"
    }
    namespace delete test_ns_2
} {}
test namespace-7.6 {recursive Tcl_DeleteNamespace, no active call frames in ns} {
    # [Bug 1355942]
    namespace eval test_ns_2 {
        proc x {} {}
	trace add command x delete "namespace delete [namespace current];#"
    }
    namespace delete test_ns_2
} {}
test namespace-7.7 {Bug 1655305} -setup {
    interp create child
    # Can't invoke through the ensemble, since deleting ::tcl







|





|
|
|
|












|
|
|
|
|






|
|
|










|







|



|

|
|



|







|
|





|










|
|
|
|





|
|
|






|







|







|







|







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
test namespace-1.1 {TclInitNamespaces, GetNamespaceFromObj, NamespaceChildrenCmd} {
    namespace children :: test_ns_*
} {}

catch {unset l}
test namespace-2.1 {Tcl_GetCurrentNamespace} {
    list [namespace current] [namespace eval {} {namespace current}] \
	[namespace eval {} {namespace current}]
} {:: :: ::}
test namespace-2.2 {Tcl_GetCurrentNamespace} {
    set l {}
    lappend l [namespace current]
    namespace eval test_ns_1 {
	lappend ::l [namespace current]
	namespace eval foo {
	    lappend ::l [namespace current]
	}
    }
    lappend l [namespace current]
} {:: ::test_ns_1 ::test_ns_1::foo ::}

test namespace-3.1 {Tcl_GetGlobalNamespace} {
    namespace eval test_ns_1 {namespace eval foo {namespace eval bar {} } }
    # namespace children uses Tcl_GetGlobalNamespace
    namespace eval test_ns_1 {namespace children foo b*}
} {::test_ns_1::foo::bar}

test namespace-4.1 {Tcl_PushCallFrame with isProcCallFrame=1} {
    namespace eval test_ns_1 {
	variable v 123
	proc p {} {
	    variable v
	    return $v
	}
    }
    test_ns_1::p    ;# does Tcl_PushCallFrame to push p's namespace
} {123}
test namespace-4.2 {Tcl_PushCallFrame with isProcCallFrame=0} {
    namespace eval test_ns_1::baz {}  ;# does Tcl_PushCallFrame to create baz
    proc test_ns_1::baz::p {} {
	variable v
	set v 789
	set v}
    test_ns_1::baz::p
} {789}

test namespace-5.1 {Tcl_PopCallFrame, no vars} {
    namespace eval test_ns_1::blodge {}  ;# pushes then pops frame
} {}
test namespace-5.2 {Tcl_PopCallFrame, local vars must be deleted} -setup {
    namespace eval test_ns_1 {}
} -body {
    proc test_ns_1::r {} {
	set a 123
    }
    test_ns_1::r   ;# pushes then pop's r's frame
} -result {123}

test namespace-6.1 {Tcl_CreateNamespace} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    list [lsort [namespace children :: test_ns_*]] \
	[namespace eval test_ns_1 {namespace current}] \
	[namespace eval test_ns_2 {namespace current}] \
	[namespace eval ::test_ns_3 {namespace current}] \
	[namespace eval ::test_ns_4 \
	    {namespace eval foo {namespace current}}] \
	[namespace eval ::test_ns_5 \
	    {namespace eval ::test_ns_6 {namespace current}}] \
	[lsort [namespace children :: test_ns_*]]
} {{} ::test_ns_1 ::test_ns_2 ::test_ns_3 ::test_ns_4::foo ::test_ns_6 {::test_ns_1 ::test_ns_2 ::test_ns_3 ::test_ns_4 ::test_ns_5 ::test_ns_6}}
test namespace-6.2 {Tcl_CreateNamespace, odd number of :'s in name is okay} {
    list [namespace eval :::test_ns_1::::foo {namespace current}] \
	 [namespace eval test_ns_2:::::foo {namespace current}]
} {::test_ns_1::foo ::test_ns_2::foo}
test namespace-6.3 {Tcl_CreateNamespace, trailing ::s in ns name are ignored} {
    list [catch {namespace eval test_ns_7::: {namespace current}} msg] $msg
} {0 ::test_ns_7}
test namespace-6.4 {Tcl_CreateNamespace, trailing ::s in ns name are ignored} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1:: {
	namespace eval test_ns_2:: {}
	namespace eval test_ns_3:: {}
    }
    lsort [namespace children ::test_ns_1]
} [lsort {::test_ns_1::test_ns_2 ::test_ns_1::test_ns_3}]
test namespace-6.5 {Tcl_CreateNamespace, relative ns names now only looked up in current ns} {
    set trigger {
	namespace eval test_ns_2 {namespace current}
    }
    set l {}
    lappend l [namespace eval test_ns_1 $trigger]
    namespace eval test_ns_1::test_ns_2 {}
    lappend l [namespace eval test_ns_1 $trigger]
} {::test_ns_1::test_ns_2 ::test_ns_1::test_ns_2}

test namespace-7.1 {Tcl_DeleteNamespace, active call frames in ns} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1 {
	proc p {} {
	    namespace delete [namespace current]
	    return [namespace current]
	}
    }
    list [test_ns_1::p] [catch {test_ns_1::p} msg] $msg
} {::test_ns_1 1 {invalid command name "test_ns_1::p"}}
test namespace-7.2 {Tcl_DeleteNamespace, no active call frames in ns} {
    namespace eval test_ns_2 {
	proc p {} {
	    return [namespace current]
	}
    }
    list [test_ns_2::p] [namespace delete test_ns_2]
} {::test_ns_2 {}}
test namespace-7.3 {recursive Tcl_DeleteNamespace, active call frames in ns} {
    # [Bug 1355942]
    namespace eval test_ns_2 {
	set x 1
	trace add variable x unset "namespace delete [namespace current];#"
	namespace delete [namespace current]
    }
} {}
test namespace-7.4 {recursive Tcl_DeleteNamespace, active call frames in ns} {
    # [Bug 1355942]
    namespace eval test_ns_2 {
	proc x {} {}
	trace add command x delete "namespace delete [namespace current];#"
	namespace delete [namespace current]
    }
} {}
test namespace-7.5 {recursive Tcl_DeleteNamespace, no active call frames in ns} {
    # [Bug 1355942]
    namespace eval test_ns_2 {
	set x 1
	trace add variable x unset "namespace delete [namespace current];#"
    }
    namespace delete test_ns_2
} {}
test namespace-7.6 {recursive Tcl_DeleteNamespace, no active call frames in ns} {
    # [Bug 1355942]
    namespace eval test_ns_2 {
	proc x {} {}
	trace add command x delete "namespace delete [namespace current];#"
    }
    namespace delete test_ns_2
} {}
test namespace-7.7 {Bug 1655305} -setup {
    interp create child
    # Can't invoke through the ensemble, since deleting ::tcl
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340



test namespace-8.1 {TclTeardownNamespace, delete global namespace} {
    catch {interp delete test_interp}
    interp create test_interp
    interp eval test_interp {
        namespace eval test_ns_1 {
            namespace export p
            proc p {} {
                return [namespace current]
            }
        }
        namespace eval test_ns_2 {
            namespace import ::test_ns_1::p
            variable v 27
            proc q {} {
                variable v
                return "[p] $v"
            }
        }
        set x [test_ns_2::q]
        catch {set xxxx}
    }
    list [interp eval test_interp {test_ns_2::q}] \
         [interp eval test_interp {namespace delete ::}] \
         [catch {interp eval test_interp {set a 123}} msg] $msg \
         [interp delete test_interp]
} {{::test_ns_1 27} {} 1 {invalid command name "set"} {}}
test namespace-8.2 {TclTeardownNamespace, remove deleted ns from parent} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1::test_ns_2::test_ns_3a {proc p {} {}}
    namespace eval test_ns_1::test_ns_2::test_ns_3b {proc q {} {}}
    list [namespace children test_ns_1] \
         [namespace delete test_ns_1::test_ns_2] \
         [namespace children test_ns_1]
} {::test_ns_1::test_ns_2 {} {}}
test namespace-8.3 {TclTeardownNamespace, delete child namespaces} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1::test_ns_2::test_ns_3a {proc p {} {}}
    namespace eval test_ns_1::test_ns_2::test_ns_3b {proc q {} {}}
    list [namespace children test_ns_1] \
         [namespace delete test_ns_1::test_ns_2] \
         [namespace children test_ns_1] \
         [catch {namespace children test_ns_1::test_ns_2} msg] $msg \
         [info commands test_ns_1::test_ns_2::test_ns_3a::*]
} {::test_ns_1::test_ns_2 {} {} 1 {namespace "test_ns_1::test_ns_2" not found in "::"} {}}
test namespace-8.4 {TclTeardownNamespace, cmds imported from deleted ns go away} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_export {
        namespace export cmd1 cmd2
        proc cmd1 {args} {return "cmd1: $args"}
        proc cmd2 {args} {return "cmd2: $args"}
    }
    namespace eval test_ns_import {
        namespace import ::test_ns_export::*
        proc p {} {return foo}
    }
    list [lsort [info commands test_ns_import::*]] \
         [namespace delete test_ns_export] \
         [info commands test_ns_import::*]
} [list [lsort {::test_ns_import::p ::test_ns_import::cmd1 ::test_ns_import::cmd2}] {} ::test_ns_import::p]
test namespace-8.5 {TclTeardownNamespace: preserve errorInfo; errorCode values} {
    interp create child
    child eval {trace add execution error leave {namespace delete :: ;#}}
    catch {child eval error foo bar baz}
    interp delete child
    set ::errorInfo







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|


|
|
|






|
|






|
|
|
|




|
|
|


|
|


|
|







273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340



test namespace-8.1 {TclTeardownNamespace, delete global namespace} {
    catch {interp delete test_interp}
    interp create test_interp
    interp eval test_interp {
	namespace eval test_ns_1 {
	    namespace export p
	    proc p {} {
		return [namespace current]
	    }
	}
	namespace eval test_ns_2 {
	    namespace import ::test_ns_1::p
	    variable v 27
	    proc q {} {
		variable v
		return "[p] $v"
	    }
	}
	set x [test_ns_2::q]
	catch {set xxxx}
    }
    list [interp eval test_interp {test_ns_2::q}] \
	 [interp eval test_interp {namespace delete ::}] \
	 [catch {interp eval test_interp {set a 123}} msg] $msg \
	 [interp delete test_interp]
} {{::test_ns_1 27} {} 1 {invalid command name "set"} {}}
test namespace-8.2 {TclTeardownNamespace, remove deleted ns from parent} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1::test_ns_2::test_ns_3a {proc p {} {}}
    namespace eval test_ns_1::test_ns_2::test_ns_3b {proc q {} {}}
    list [namespace children test_ns_1] \
	 [namespace delete test_ns_1::test_ns_2] \
	 [namespace children test_ns_1]
} {::test_ns_1::test_ns_2 {} {}}
test namespace-8.3 {TclTeardownNamespace, delete child namespaces} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1::test_ns_2::test_ns_3a {proc p {} {}}
    namespace eval test_ns_1::test_ns_2::test_ns_3b {proc q {} {}}
    list [namespace children test_ns_1] \
	 [namespace delete test_ns_1::test_ns_2] \
	 [namespace children test_ns_1] \
	 [catch {namespace children test_ns_1::test_ns_2} msg] $msg \
	 [info commands test_ns_1::test_ns_2::test_ns_3a::*]
} {::test_ns_1::test_ns_2 {} {} 1 {namespace "test_ns_1::test_ns_2" not found in "::"} {}}
test namespace-8.4 {TclTeardownNamespace, cmds imported from deleted ns go away} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_export {
	namespace export cmd1 cmd2
	proc cmd1 {args} {return "cmd1: $args"}
	proc cmd2 {args} {return "cmd2: $args"}
    }
    namespace eval test_ns_import {
	namespace import ::test_ns_export::*
	proc p {} {return foo}
    }
    list [lsort [info commands test_ns_import::*]] \
	 [namespace delete test_ns_export] \
	 [info commands test_ns_import::*]
} [list [lsort {::test_ns_import::p ::test_ns_import::cmd1 ::test_ns_import::cmd2}] {} ::test_ns_import::p]
test namespace-8.5 {TclTeardownNamespace: preserve errorInfo; errorCode values} {
    interp create child
    child eval {trace add execution error leave {namespace delete :: ;#}}
    catch {child eval error foo bar baz}
    interp delete child
    set ::errorInfo
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
} {1 {unknown namespace in import pattern "fred::x"}}
test namespace-9.3 {Tcl_Import, import ns == export ns} {
    list [catch {namespace eval test_ns_import {namespace import ::test_ns_import::puts}} msg] $msg
} {1 {import pattern "::test_ns_import::puts" tries to import from namespace "test_ns_import" into itself}}
test namespace-9.4 {Tcl_Import, simple import} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_export {
        namespace export cmd1
        proc cmd1 {args} {return "cmd1: $args"}
        proc cmd2 {args} {return "cmd2: $args"}
    }
    namespace eval test_ns_import {
        namespace import ::test_ns_export::*
        proc p {} {return [cmd1 123]}
    }
    test_ns_import::p
} {cmd1: 123}
test namespace-9.5 {Tcl_Import, RFE 1230597} -setup {
    namespace eval test_ns_import {}
    namespace eval test_ns_export {}
} -body {
    list [catch {namespace eval test_ns_import {namespace import ::test_ns_export::*}} msg] $msg
} -result {0 {}}
test namespace-9.6 {Tcl_Import, cmd redefinition ok if allowOverwrite!=0} -setup {
    namespace eval test_ns_import {}
    namespace eval ::test_ns_export {
        proc cmd1 {args} {return "cmd1: $args"}
	namespace export cmd1
    }
} -body {
    namespace eval test_ns_import {
        namespace import -force ::test_ns_export::*
        cmd1 555
    }
} -result {cmd1: 555}
test namespace-9.7 {Tcl_Import, links are preserved if cmd is redefined} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_export {
        namespace export cmd1
        proc cmd1 {args} {return "cmd1: $args"}
    }
    namespace eval test_ns_import {
        namespace import -force ::test_ns_export::*
    }
    list [test_ns_import::cmd1 a b c] \
         [test_ns_export::cmd1 d e f] \
         [proc test_ns_export::cmd1 {args} {return "new1: $args"}] \
         [namespace origin test_ns_import::cmd1] \
         [namespace origin test_ns_export::cmd1] \
         [test_ns_import::cmd1 g h i] \
         [test_ns_export::cmd1 j k l]
} {{cmd1: a b c} {cmd1: d e f} {} ::test_ns_export::cmd1 ::test_ns_export::cmd1 {new1: g h i} {new1: j k l}}
test namespace-9.8 {Tcl_Import: Bug 1017299} -setup {
    namespace eval one {
	namespace export cmd
	proc cmd {} {}
    }
    namespace eval two {







|
|
|


|
|












|




|
|





|
|


|


|
|
|
|
|
|







367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
} {1 {unknown namespace in import pattern "fred::x"}}
test namespace-9.3 {Tcl_Import, import ns == export ns} {
    list [catch {namespace eval test_ns_import {namespace import ::test_ns_import::puts}} msg] $msg
} {1 {import pattern "::test_ns_import::puts" tries to import from namespace "test_ns_import" into itself}}
test namespace-9.4 {Tcl_Import, simple import} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_export {
	namespace export cmd1
	proc cmd1 {args} {return "cmd1: $args"}
	proc cmd2 {args} {return "cmd2: $args"}
    }
    namespace eval test_ns_import {
	namespace import ::test_ns_export::*
	proc p {} {return [cmd1 123]}
    }
    test_ns_import::p
} {cmd1: 123}
test namespace-9.5 {Tcl_Import, RFE 1230597} -setup {
    namespace eval test_ns_import {}
    namespace eval test_ns_export {}
} -body {
    list [catch {namespace eval test_ns_import {namespace import ::test_ns_export::*}} msg] $msg
} -result {0 {}}
test namespace-9.6 {Tcl_Import, cmd redefinition ok if allowOverwrite!=0} -setup {
    namespace eval test_ns_import {}
    namespace eval ::test_ns_export {
	proc cmd1 {args} {return "cmd1: $args"}
	namespace export cmd1
    }
} -body {
    namespace eval test_ns_import {
	namespace import -force ::test_ns_export::*
	cmd1 555
    }
} -result {cmd1: 555}
test namespace-9.7 {Tcl_Import, links are preserved if cmd is redefined} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_export {
	namespace export cmd1
	proc cmd1 {args} {return "cmd1: $args"}
    }
    namespace eval test_ns_import {
	namespace import -force ::test_ns_export::*
    }
    list [test_ns_import::cmd1 a b c] \
	 [test_ns_export::cmd1 d e f] \
	 [proc test_ns_export::cmd1 {args} {return "new1: $args"}] \
	 [namespace origin test_ns_import::cmd1] \
	 [namespace origin test_ns_export::cmd1] \
	 [test_ns_import::cmd1 g h i] \
	 [test_ns_export::cmd1 j k l]
} {{cmd1: a b c} {cmd1: d e f} {} ::test_ns_export::cmd1 ::test_ns_export::cmd1 {new1: g h i} {new1: j k l}}
test namespace-9.8 {Tcl_Import: Bug 1017299} -setup {
    namespace eval one {
	namespace export cmd
	proc cmd {} {}
    }
    namespace eval two {
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497

test namespace-10.1 {Tcl_ForgetImport, check for valid namespaces} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    list [catch {namespace forget xyzzy::*} msg] $msg
} {1 {unknown namespace in namespace forget pattern "xyzzy::*"}}
test namespace-10.2 {Tcl_ForgetImport, ignores patterns that don't match} {
    namespace eval test_ns_export {
        namespace export cmd1
        proc cmd1 {args} {return "cmd1: $args"}
        proc cmd2 {args} {return "cmd2: $args"}
    }
    namespace eval test_ns_import {
        namespace forget ::test_ns_export::wombat
    }
} {}
test namespace-10.3 {Tcl_ForgetImport, deletes matching imported cmds} -setup {
    namespace eval test_ns_export {
        namespace export cmd1
        proc cmd1 {args} {return "cmd1: $args"}
        proc cmd2 {args} {return "cmd2: $args"}
    }
} -body {
    namespace eval test_ns_import {
        namespace import ::test_ns_export::*
        proc p {} {return [cmd1 123]}
        set l {}
        lappend l [lsort [info commands ::test_ns_import::*]]
        namespace forget ::test_ns_export::cmd1
        lappend l [info commands ::test_ns_import::*]
        lappend l [catch {cmd1 777} msg] $msg
    }
} -result [list [lsort {::test_ns_import::p ::test_ns_import::cmd1}] ::test_ns_import::p 1 {invalid command name "cmd1"}]
test namespace-10.4 {Tcl_ForgetImport: Bug 560297} -setup {
    namespace eval origin {
	namespace export cmd
	proc cmd {} {}
    }







|
|
|


|




|
|
|



|
|
|
|
|
|
|







461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497

test namespace-10.1 {Tcl_ForgetImport, check for valid namespaces} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    list [catch {namespace forget xyzzy::*} msg] $msg
} {1 {unknown namespace in namespace forget pattern "xyzzy::*"}}
test namespace-10.2 {Tcl_ForgetImport, ignores patterns that don't match} {
    namespace eval test_ns_export {
	namespace export cmd1
	proc cmd1 {args} {return "cmd1: $args"}
	proc cmd2 {args} {return "cmd2: $args"}
    }
    namespace eval test_ns_import {
	namespace forget ::test_ns_export::wombat
    }
} {}
test namespace-10.3 {Tcl_ForgetImport, deletes matching imported cmds} -setup {
    namespace eval test_ns_export {
	namespace export cmd1
	proc cmd1 {args} {return "cmd1: $args"}
	proc cmd2 {args} {return "cmd2: $args"}
    }
} -body {
    namespace eval test_ns_import {
	namespace import ::test_ns_export::*
	proc p {} {return [cmd1 123]}
	set l {}
	lappend l [lsort [info commands ::test_ns_import::*]]
	namespace forget ::test_ns_export::cmd1
	lappend l [info commands ::test_ns_import::*]
	lappend l [catch {cmd1 777} msg] $msg
    }
} -result [list [lsort {::test_ns_import::p ::test_ns_import::cmd1}] ::test_ns_import::p 1 {invalid command name "cmd1"}]
test namespace-10.4 {Tcl_ForgetImport: Bug 560297} -setup {
    namespace eval origin {
	namespace export cmd
	proc cmd {} {}
    }
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
    namespace delete origin link link2 my
} -returnCodes error -match glob -result *

test namespace-11.1 {TclGetOriginalCommand, check if not imported cmd} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_export {
        namespace export cmd1
        proc cmd1 {args} {return "cmd1: $args"}
    }
    list [namespace origin set] [namespace origin test_ns_export::cmd1]
} -result {::set ::test_ns_export::cmd1}
test namespace-11.2 {TclGetOriginalCommand, directly imported cmd} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_export {
        namespace export cmd1
        proc cmd1 {args} {return "cmd1: $args"}
    }
} -body {
    namespace eval test_ns_import1 {
        namespace import ::test_ns_export::*
        namespace export *
        proc p {} {namespace origin cmd1}
    }
    list [test_ns_import1::p] [namespace origin test_ns_import1::cmd1]
} -result {::test_ns_export::cmd1 ::test_ns_export::cmd1}
test namespace-11.3 {TclGetOriginalCommand, indirectly imported cmd} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_export {
        namespace export cmd1
        proc cmd1 {args} {return "cmd1: $args"}
    }
    namespace eval test_ns_import1 {
        namespace import ::test_ns_export::*
        namespace export *
        proc p {} {namespace origin cmd1}
    }
} -body {
    namespace eval test_ns_import2 {
        namespace import ::test_ns_import1::*
        proc q {} {return [cmd1 123]}
    }
    list [test_ns_import2::q] [namespace origin test_ns_import2::cmd1]
} -result {{cmd1: 123} ::test_ns_export::cmd1}

test namespace-12.1 {InvokeImportedCmd} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_export {
        namespace export cmd1
        proc cmd1 {args} {namespace current}
    }
    namespace eval test_ns_import {
        namespace import ::test_ns_export::*
    }
    list [test_ns_import::cmd1]
} {::test_ns_export}

test namespace-13.1 {DeleteImportedCmd, deletes imported cmds} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_export {
        namespace export cmd1
        proc cmd1 {args} {namespace current}
    }
    namespace eval test_ns_import {
        namespace import ::test_ns_export::*
    }
} -body {
    namespace eval test_ns_import {
        set l {}
        lappend l [info commands ::test_ns_import::*]
        namespace forget ::test_ns_export::cmd1
        lappend l [info commands ::test_ns_import::*]
    }
} -result {::test_ns_import::cmd1 {}}
test namespace-13.2 {DeleteImportedCmd, Bug a4494e28ed} {
    # Will panic if still buggy
    namespace eval src {namespace export foo; proc foo {} {}}
    namespace eval dst {namespace import [namespace parent]::src::foo}
    trace add command src::foo delete \
        "[list namespace delete [namespace current]::dst] ;#"
    proc src::foo {} {}
    namespace delete src
} {}

test namespace-14.1 {TclGetNamespaceForQualName, absolute names} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    variable v 10
    namespace eval test_ns_1::test_ns_2 {
        variable v 20
    }
    namespace eval test_ns_2 {
        variable v 30
    }
} -body {
    namespace eval test_ns_1 {
        list $::v $::test_ns_2::v $::test_ns_1::test_ns_2::v \
		[lsort [namespace children :: test_ns_*]]
    }
} -result [list 10 30 20 [lsort {::test_ns_1 ::test_ns_2}]]
test namespace-14.2 {TclGetNamespaceForQualName, invalid absolute names} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    variable v 10
    namespace eval test_ns_1::test_ns_2 {
        variable v 20
    }
    namespace eval test_ns_2 {
        variable v 30
    }
} -body {
    namespace eval test_ns_1 {
        list [catch {set ::test_ns_777::v} msg] $msg \
             [catch {namespace children test_ns_777} msg] $msg
    }
} -result {1 {can't read "::test_ns_777::v": no such variable} 1 {namespace "test_ns_777" not found in "::test_ns_1"}}

# TIP 278: secondary lookup disabled, results changed from {10 20}
test namespace-14.3 {TclGetNamespaceForQualName, relative names} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    variable v 10
    namespace eval test_ns_1::test_ns_2 {
        variable v 20
    }
    namespace eval test_ns_2 {
        variable v 30
    }
} -body {
    namespace eval test_ns_1 {
        # list $v $test_ns_2::v
        list [catch {set v} msg] $msg  [catch {set test_ns_2::v} msg] $msg
    }
} -result {1 {can't read "v": no such variable} 0 20}

test namespace-14.4 {TclGetNamespaceForQualName, relative ns names looked up only in current ns} {
    namespace eval test_ns_1::test_ns_2 {
        namespace eval foo {}
    }
    namespace eval test_ns_1 {
        list [namespace children test_ns_2] \
             [catch {namespace children test_ns_1} msg] $msg
    }
} {::test_ns_1::test_ns_2::foo 1 {namespace "test_ns_1" not found in "::test_ns_1"}}
test namespace-14.5 {TclGetNamespaceForQualName, relative ns names looked up only in current ns} {
    namespace eval ::test_ns_2 {
        namespace eval bar {}
    }
    namespace eval test_ns_1 {
        list [catch {namespace delete test_ns_2::bar} msg] $msg
    }
} {1 {unknown namespace "test_ns_2::bar" in namespace delete command}}
test namespace-14.6 {TclGetNamespaceForQualName, relative ns names looked up only in current ns} {
    namespace eval test_ns_1::test_ns_2 {
        namespace eval foo {}
    }
    namespace eval test_ns_1 {
        list [namespace children test_ns_2] \
             [catch {namespace children test_ns_1} msg] $msg
    }
} {::test_ns_1::test_ns_2::foo 1 {namespace "test_ns_1" not found in "::test_ns_1"}}
test namespace-14.7 {TclGetNamespaceForQualName, ignore extra :s if ns} -setup {
    namespace eval test_ns_1::test_ns_2::foo {}
} -body {
    namespace children test_ns_1:::
} -result {::test_ns_1::test_ns_2}







|
|






|
|



|
|
|






|
|


|
|
|



|
|







|
|


|







|
|


|



|
|
|
|







|








|


|



|







|


|



|
|








|


|



|
|





|


|
|




|


|




|


|
|







599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
    namespace delete origin link link2 my
} -returnCodes error -match glob -result *

test namespace-11.1 {TclGetOriginalCommand, check if not imported cmd} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_export {
	namespace export cmd1
	proc cmd1 {args} {return "cmd1: $args"}
    }
    list [namespace origin set] [namespace origin test_ns_export::cmd1]
} -result {::set ::test_ns_export::cmd1}
test namespace-11.2 {TclGetOriginalCommand, directly imported cmd} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_export {
	namespace export cmd1
	proc cmd1 {args} {return "cmd1: $args"}
    }
} -body {
    namespace eval test_ns_import1 {
	namespace import ::test_ns_export::*
	namespace export *
	proc p {} {namespace origin cmd1}
    }
    list [test_ns_import1::p] [namespace origin test_ns_import1::cmd1]
} -result {::test_ns_export::cmd1 ::test_ns_export::cmd1}
test namespace-11.3 {TclGetOriginalCommand, indirectly imported cmd} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_export {
	namespace export cmd1
	proc cmd1 {args} {return "cmd1: $args"}
    }
    namespace eval test_ns_import1 {
	namespace import ::test_ns_export::*
	namespace export *
	proc p {} {namespace origin cmd1}
    }
} -body {
    namespace eval test_ns_import2 {
	namespace import ::test_ns_import1::*
	proc q {} {return [cmd1 123]}
    }
    list [test_ns_import2::q] [namespace origin test_ns_import2::cmd1]
} -result {{cmd1: 123} ::test_ns_export::cmd1}

test namespace-12.1 {InvokeImportedCmd} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_export {
	namespace export cmd1
	proc cmd1 {args} {namespace current}
    }
    namespace eval test_ns_import {
	namespace import ::test_ns_export::*
    }
    list [test_ns_import::cmd1]
} {::test_ns_export}

test namespace-13.1 {DeleteImportedCmd, deletes imported cmds} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_export {
	namespace export cmd1
	proc cmd1 {args} {namespace current}
    }
    namespace eval test_ns_import {
	namespace import ::test_ns_export::*
    }
} -body {
    namespace eval test_ns_import {
	set l {}
	lappend l [info commands ::test_ns_import::*]
	namespace forget ::test_ns_export::cmd1
	lappend l [info commands ::test_ns_import::*]
    }
} -result {::test_ns_import::cmd1 {}}
test namespace-13.2 {DeleteImportedCmd, Bug a4494e28ed} {
    # Will panic if still buggy
    namespace eval src {namespace export foo; proc foo {} {}}
    namespace eval dst {namespace import [namespace parent]::src::foo}
    trace add command src::foo delete \
	"[list namespace delete [namespace current]::dst] ;#"
    proc src::foo {} {}
    namespace delete src
} {}

test namespace-14.1 {TclGetNamespaceForQualName, absolute names} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    variable v 10
    namespace eval test_ns_1::test_ns_2 {
	variable v 20
    }
    namespace eval test_ns_2 {
	variable v 30
    }
} -body {
    namespace eval test_ns_1 {
	list $::v $::test_ns_2::v $::test_ns_1::test_ns_2::v \
		[lsort [namespace children :: test_ns_*]]
    }
} -result [list 10 30 20 [lsort {::test_ns_1 ::test_ns_2}]]
test namespace-14.2 {TclGetNamespaceForQualName, invalid absolute names} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    variable v 10
    namespace eval test_ns_1::test_ns_2 {
	variable v 20
    }
    namespace eval test_ns_2 {
	variable v 30
    }
} -body {
    namespace eval test_ns_1 {
	list [catch {set ::test_ns_777::v} msg] $msg \
	     [catch {namespace children test_ns_777} msg] $msg
    }
} -result {1 {can't read "::test_ns_777::v": no such variable} 1 {namespace "test_ns_777" not found in "::test_ns_1"}}

# TIP 278: secondary lookup disabled, results changed from {10 20}
test namespace-14.3 {TclGetNamespaceForQualName, relative names} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    variable v 10
    namespace eval test_ns_1::test_ns_2 {
	variable v 20
    }
    namespace eval test_ns_2 {
	variable v 30
    }
} -body {
    namespace eval test_ns_1 {
	# list $v $test_ns_2::v
	list [catch {set v} msg] $msg  [catch {set test_ns_2::v} msg] $msg
    }
} -result {1 {can't read "v": no such variable} 0 20}

test namespace-14.4 {TclGetNamespaceForQualName, relative ns names looked up only in current ns} {
    namespace eval test_ns_1::test_ns_2 {
	namespace eval foo {}
    }
    namespace eval test_ns_1 {
	list [namespace children test_ns_2] \
	     [catch {namespace children test_ns_1} msg] $msg
    }
} {::test_ns_1::test_ns_2::foo 1 {namespace "test_ns_1" not found in "::test_ns_1"}}
test namespace-14.5 {TclGetNamespaceForQualName, relative ns names looked up only in current ns} {
    namespace eval ::test_ns_2 {
	namespace eval bar {}
    }
    namespace eval test_ns_1 {
	list [catch {namespace delete test_ns_2::bar} msg] $msg
    }
} {1 {unknown namespace "test_ns_2::bar" in namespace delete command}}
test namespace-14.6 {TclGetNamespaceForQualName, relative ns names looked up only in current ns} {
    namespace eval test_ns_1::test_ns_2 {
	namespace eval foo {}
    }
    namespace eval test_ns_1 {
	list [namespace children test_ns_2] \
	     [catch {namespace children test_ns_1} msg] $msg
    }
} {::test_ns_1::test_ns_2::foo 1 {namespace "test_ns_1" not found in "::test_ns_1"}}
test namespace-14.7 {TclGetNamespaceForQualName, ignore extra :s if ns} -setup {
    namespace eval test_ns_1::test_ns_2::foo {}
} -body {
    namespace children test_ns_1:::
} -result {::test_ns_1::test_ns_2}
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
} -result {1 {invalid command name "test_ns_1::test_ns_2::"} {{}: hello}}

# TIP 278: secondary lookup disabled, added catch, result changed from y
test namespace-14.12 {TclGetNamespaceForQualName, extra ::s are significant for vars} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1 {
        variable {}
        catch {set test_ns_1::(x) y} ::msg
    }
    list $::msg [catch {set test_ns_1::(x)} msg] $msg
} -result {{can't set "test_ns_1::(x)": parent namespace doesn't exist} 1 {can't read "test_ns_1::(x)": no such variable}}
test namespace-14.13 {TclGetNamespaceForQualName, namespace other than global ns can't have empty name} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -returnCodes error -body {
    namespace eval test_ns_1 {
	proc {} {} {}
	namespace eval {} {}
	{}
    }
} -result {can't create namespace "": only global namespace can have empty name}

test namespace-15.1 {Tcl_FindNamespace, absolute name found} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_delete {
        namespace eval test_ns_delete2 {}
        proc cmd {args} {namespace current}
    }
    list [namespace delete ::test_ns_delete::test_ns_delete2] \
         [namespace children ::test_ns_delete]
} -result {{} {}}
test namespace-15.2 {Tcl_FindNamespace, absolute name not found} -body {
    namespace delete ::test_ns_delete::test_ns_delete2
} -returnCodes error -result {unknown namespace "::test_ns_delete::test_ns_delete2" in namespace delete command}
test namespace-15.3 {Tcl_FindNamespace, relative name found} {
    namespace eval test_ns_delete {
        namespace eval test_ns_delete2 {}
        namespace eval test_ns_delete3 {}
        list [namespace delete test_ns_delete2] \
             [namespace children [namespace current]]
    }
} {{} ::test_ns_delete::test_ns_delete3}
test namespace-15.4 {Tcl_FindNamespace, relative name not found} {
    namespace eval test_ns_delete2 {}
    namespace eval test_ns_delete {
        list [catch {namespace delete test_ns_delete2} msg] $msg
    }
} {1 {unknown namespace "test_ns_delete2" in namespace delete command}}

test namespace-16.1 {Tcl_FindCommand, absolute name found} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1 {
        proc cmd {args} {return "[namespace current]::cmd: $args"}
        variable v "::test_ns_1::cmd"
        eval $v one
    }
} -result {::test_ns_1::cmd: one}
test namespace-16.2 {Tcl_FindCommand, absolute name found} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1 {
        proc cmd {args} {return "[namespace current]::cmd: $args"}
        variable v "::test_ns_1::cmd"
    }
} -body {
    eval $test_ns_1::v two
} -result {::test_ns_1::cmd: two}
test namespace-16.3 {Tcl_FindCommand, absolute name not found} {
    namespace eval test_ns_1 {
        variable v2 "::test_ns_1::ladidah"
        list [catch {eval $v2} msg] $msg
    }
} {1 {invalid command name "::test_ns_1::ladidah"}}

# save the "unknown" proc, which is redefined by the following two tests
catch {rename unknown unknown.old}
proc unknown {args} {
    return "unknown: $args"







|
|

















|
|


|






|
|
|
|





|







|
|
|





|
|






|
|







790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
} -result {1 {invalid command name "test_ns_1::test_ns_2::"} {{}: hello}}

# TIP 278: secondary lookup disabled, added catch, result changed from y
test namespace-14.12 {TclGetNamespaceForQualName, extra ::s are significant for vars} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1 {
	variable {}
	catch {set test_ns_1::(x) y} ::msg
    }
    list $::msg [catch {set test_ns_1::(x)} msg] $msg
} -result {{can't set "test_ns_1::(x)": parent namespace doesn't exist} 1 {can't read "test_ns_1::(x)": no such variable}}
test namespace-14.13 {TclGetNamespaceForQualName, namespace other than global ns can't have empty name} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -returnCodes error -body {
    namespace eval test_ns_1 {
	proc {} {} {}
	namespace eval {} {}
	{}
    }
} -result {can't create namespace "": only global namespace can have empty name}

test namespace-15.1 {Tcl_FindNamespace, absolute name found} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_delete {
	namespace eval test_ns_delete2 {}
	proc cmd {args} {namespace current}
    }
    list [namespace delete ::test_ns_delete::test_ns_delete2] \
	 [namespace children ::test_ns_delete]
} -result {{} {}}
test namespace-15.2 {Tcl_FindNamespace, absolute name not found} -body {
    namespace delete ::test_ns_delete::test_ns_delete2
} -returnCodes error -result {unknown namespace "::test_ns_delete::test_ns_delete2" in namespace delete command}
test namespace-15.3 {Tcl_FindNamespace, relative name found} {
    namespace eval test_ns_delete {
	namespace eval test_ns_delete2 {}
	namespace eval test_ns_delete3 {}
	list [namespace delete test_ns_delete2] \
	     [namespace children [namespace current]]
    }
} {{} ::test_ns_delete::test_ns_delete3}
test namespace-15.4 {Tcl_FindNamespace, relative name not found} {
    namespace eval test_ns_delete2 {}
    namespace eval test_ns_delete {
	list [catch {namespace delete test_ns_delete2} msg] $msg
    }
} {1 {unknown namespace "test_ns_delete2" in namespace delete command}}

test namespace-16.1 {Tcl_FindCommand, absolute name found} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1 {
	proc cmd {args} {return "[namespace current]::cmd: $args"}
	variable v "::test_ns_1::cmd"
	eval $v one
    }
} -result {::test_ns_1::cmd: one}
test namespace-16.2 {Tcl_FindCommand, absolute name found} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1 {
	proc cmd {args} {return "[namespace current]::cmd: $args"}
	variable v "::test_ns_1::cmd"
    }
} -body {
    eval $test_ns_1::v two
} -result {::test_ns_1::cmd: two}
test namespace-16.3 {Tcl_FindCommand, absolute name not found} {
    namespace eval test_ns_1 {
	variable v2 "::test_ns_1::ladidah"
	list [catch {eval $v2} msg] $msg
    }
} {1 {invalid command name "::test_ns_1::ladidah"}}

# save the "unknown" proc, which is redefined by the following two tests
catch {rename unknown unknown.old}
proc unknown {args} {
    return "unknown: $args"
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
# restore the "unknown" proc saved previously
catch {rename unknown {}}
catch {rename unknown.old unknown}

test namespace-16.8 {Tcl_FindCommand, relative name found} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1 {
        proc cmd {args} {return "[namespace current]::cmd: $args"}
    }
} -body {
    namespace eval test_ns_1 {
        cmd a b c
    }
} -result {::test_ns_1::cmd: a b c}
test namespace-16.9 {Tcl_FindCommand, relative name found} -body {
    proc cmd2 {args} {return "[namespace current]::cmd2: $args"}
    namespace eval test_ns_1 {
       cmd2 a b c
    }
} -cleanup {
    catch {rename cmd2 {}}
} -result {::::cmd2: a b c}
test namespace-16.10 {Tcl_FindCommand, relative name found, only look in current then global ns} -body {
    proc cmd2 {args} {return "[namespace current]::cmd2: $args"}
    namespace eval test_ns_1 {
        proc cmd2 {args} {
            return "[namespace current]::cmd2 in test_ns_1: $args"
        }
        namespace eval test_ns_12 {
            cmd2 a b c
        }
    }
} -cleanup {
    catch {rename cmd2 {}}
} -result {::::cmd2: a b c}
test namespace-16.11 {Tcl_FindCommand, relative name not found} -body {
    namespace eval test_ns_1 {
       cmd3 a b c
    }
} -returnCodes error -result {invalid command name "cmd3"}

unset -nocomplain x
test namespace-17.1 {Tcl_FindNamespaceVar, absolute name found} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    set x 314159
    namespace eval test_ns_1 {
        set ::x
    }
} -result {314159}
variable ::x 314159
test namespace-17.2 {Tcl_FindNamespaceVar, absolute name found} {
    namespace eval test_ns_1 {
        variable x 777
        set ::test_ns_1::x
    }
} {777}
test namespace-17.3 {Tcl_FindNamespaceVar, absolute name found} {
    namespace eval test_ns_1 {
        namespace eval test_ns_2 {
            variable x 1111
        }
        set ::test_ns_1::test_ns_2::x
    }
} {1111}
test namespace-17.4 {Tcl_FindNamespaceVar, absolute name not found} -body {
    namespace eval test_ns_1 {
        namespace eval test_ns_2 {
            variable x 1111
        }
        set ::test_ns_1::test_ns_2::y
    }
} -returnCodes error -result {can't read "::test_ns_1::test_ns_2::y": no such variable}
test namespace-17.5 {Tcl_FindNamespaceVar, absolute name and TCL_GLOBAL_ONLY} -setup {
    namespace eval ::test_ns_1::test_ns_2 {}
} -body {
    namespace eval test_ns_1 {
        namespace eval test_ns_3 {
            variable ::test_ns_1::test_ns_2::x 2222
        }
    }
    set ::test_ns_1::test_ns_2::x
} -result {2222}
test namespace-17.6 {Tcl_FindNamespaceVar, relative name found} -setup {
    namespace eval test_ns_1 {
        variable x 777
    }
} -body {
    namespace eval test_ns_1 {
        set x
    }
} -result {777}

# TIP 278: secondary lookup disabled, catch added, result changed from 314159
test namespace-17.7 {Tcl_FindNamespaceVar, relative name found} {
    namespace eval test_ns_1 {
	variable x 777
        unset x
        list [catch {set x} msg] $msg  ;# must not be global x now
    }
} {1 {can't read "x": no such variable}}
test namespace-17.8 {Tcl_FindNamespaceVar, relative name not found} -body {
    namespace eval test_ns_1 {
        set wuzzat
    }
} -returnCodes error -result {can't read "wuzzat": no such variable}
test namespace-17.9 {Tcl_FindNamespaceVar, relative name and TCL_GLOBAL_ONLY} {
    namespace eval test_ns_1 {
        variable a hello
    }
    set test_ns_1::a
} {hello}

# TIP 278: secondary lookup disabled, result changed from 1
test namespace-17.10 {Tcl_FindNamespaceVar, interference with cached varNames} -setup {
    namespace eval test_ns_1 {}







|



|













|
|
|
|
|
|
















|





|
|




|
|
|
|




|
|
|
|






|
|
|





|



|







|
|




|




|







882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
# restore the "unknown" proc saved previously
catch {rename unknown {}}
catch {rename unknown.old unknown}

test namespace-16.8 {Tcl_FindCommand, relative name found} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1 {
	proc cmd {args} {return "[namespace current]::cmd: $args"}
    }
} -body {
    namespace eval test_ns_1 {
	cmd a b c
    }
} -result {::test_ns_1::cmd: a b c}
test namespace-16.9 {Tcl_FindCommand, relative name found} -body {
    proc cmd2 {args} {return "[namespace current]::cmd2: $args"}
    namespace eval test_ns_1 {
       cmd2 a b c
    }
} -cleanup {
    catch {rename cmd2 {}}
} -result {::::cmd2: a b c}
test namespace-16.10 {Tcl_FindCommand, relative name found, only look in current then global ns} -body {
    proc cmd2 {args} {return "[namespace current]::cmd2: $args"}
    namespace eval test_ns_1 {
	proc cmd2 {args} {
	    return "[namespace current]::cmd2 in test_ns_1: $args"
	}
	namespace eval test_ns_12 {
	    cmd2 a b c
	}
    }
} -cleanup {
    catch {rename cmd2 {}}
} -result {::::cmd2: a b c}
test namespace-16.11 {Tcl_FindCommand, relative name not found} -body {
    namespace eval test_ns_1 {
       cmd3 a b c
    }
} -returnCodes error -result {invalid command name "cmd3"}

unset -nocomplain x
test namespace-17.1 {Tcl_FindNamespaceVar, absolute name found} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    set x 314159
    namespace eval test_ns_1 {
	set ::x
    }
} -result {314159}
variable ::x 314159
test namespace-17.2 {Tcl_FindNamespaceVar, absolute name found} {
    namespace eval test_ns_1 {
	variable x 777
	set ::test_ns_1::x
    }
} {777}
test namespace-17.3 {Tcl_FindNamespaceVar, absolute name found} {
    namespace eval test_ns_1 {
	namespace eval test_ns_2 {
	    variable x 1111
	}
	set ::test_ns_1::test_ns_2::x
    }
} {1111}
test namespace-17.4 {Tcl_FindNamespaceVar, absolute name not found} -body {
    namespace eval test_ns_1 {
	namespace eval test_ns_2 {
	    variable x 1111
	}
	set ::test_ns_1::test_ns_2::y
    }
} -returnCodes error -result {can't read "::test_ns_1::test_ns_2::y": no such variable}
test namespace-17.5 {Tcl_FindNamespaceVar, absolute name and TCL_GLOBAL_ONLY} -setup {
    namespace eval ::test_ns_1::test_ns_2 {}
} -body {
    namespace eval test_ns_1 {
	namespace eval test_ns_3 {
	    variable ::test_ns_1::test_ns_2::x 2222
	}
    }
    set ::test_ns_1::test_ns_2::x
} -result {2222}
test namespace-17.6 {Tcl_FindNamespaceVar, relative name found} -setup {
    namespace eval test_ns_1 {
	variable x 777
    }
} -body {
    namespace eval test_ns_1 {
	set x
    }
} -result {777}

# TIP 278: secondary lookup disabled, catch added, result changed from 314159
test namespace-17.7 {Tcl_FindNamespaceVar, relative name found} {
    namespace eval test_ns_1 {
	variable x 777
	unset x
	list [catch {set x} msg] $msg  ;# must not be global x now
    }
} {1 {can't read "x": no such variable}}
test namespace-17.8 {Tcl_FindNamespaceVar, relative name not found} -body {
    namespace eval test_ns_1 {
	set wuzzat
    }
} -returnCodes error -result {can't read "wuzzat": no such variable}
test namespace-17.9 {Tcl_FindNamespaceVar, relative name and TCL_GLOBAL_ONLY} {
    namespace eval test_ns_1 {
	variable a hello
    }
    set test_ns_1::a
} {hello}

# TIP 278: secondary lookup disabled, result changed from 1
test namespace-17.10 {Tcl_FindNamespaceVar, interference with cached varNames} -setup {
    namespace eval test_ns_1 {}
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
catch {unset l}
catch {rename foo {}}
test namespace-18.1 {TclResetShadowedCmdRefs, one-level check for command shadowing} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    proc foo {} {return "global foo"}
    namespace eval test_ns_1 {
        proc trigger {} {
            return [foo]
        }
    }
    set l ""
    lappend l [test_ns_1::trigger]
    namespace eval test_ns_1 {
        # force invalidation of cached ref to "foo" in proc trigger
        proc foo {} {return "foo in test_ns_1"}
    }
    lappend l [test_ns_1::trigger]
} -result {{global foo} {foo in test_ns_1}}
test namespace-18.2 {TclResetShadowedCmdRefs, multilevel check for command shadowing} {
    namespace eval test_ns_2 {
        proc foo {} {return "foo in ::test_ns_2"}
    }
    namespace eval test_ns_1 {
        namespace eval test_ns_2 {}
        proc trigger {} {
            return [test_ns_2::foo]
        }
    }
    set l ""
    lappend l [test_ns_1::trigger]
    namespace eval test_ns_1 {
        namespace eval test_ns_2 {
            # force invalidation of cached ref to "foo" in proc trigger
            proc foo {} {return "foo in ::test_ns_1::test_ns_2"}
        }
    }
    lappend l [test_ns_1::trigger]
} {{foo in ::test_ns_2} {foo in ::test_ns_1::test_ns_2}}
catch {unset l}
catch {rename foo {}}

test namespace-19.1 {GetNamespaceFromObj, global name found} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1::test_ns_2 {}
    namespace children ::test_ns_1
} -result {::test_ns_1::test_ns_2}
test namespace-19.2 {GetNamespaceFromObj, relative name found} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1::test_ns_2 {}
} -body {
    namespace eval test_ns_1 {
        namespace children test_ns_2
    }
} -result {}
test namespace-19.3 {GetNamespaceFromObj, name not found} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1 {
        namespace children test_ns_99
    }
} -returnCodes error -result {namespace "test_ns_99" not found in "::test_ns_1"}
test namespace-19.4 {GetNamespaceFromObj, invalidation of cached ns refs} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1::test_ns_2 {}
} -body {
    namespace eval test_ns_1 {
        proc foo {} {
            return [namespace children test_ns_2]
        }
        list [catch {namespace children test_ns_99} msg] $msg
    }
    set l {}
    lappend l [test_ns_1::foo]
    namespace delete test_ns_1::test_ns_2
    namespace eval test_ns_1::test_ns_2::test_ns_3 {}
    lappend l [test_ns_1::foo]
} -result {{} ::test_ns_1::test_ns_2::test_ns_3}







|
|
|




|
|





|


|
|
|
|




|
|
|
|

















|






|







|
|
|
|







1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
catch {unset l}
catch {rename foo {}}
test namespace-18.1 {TclResetShadowedCmdRefs, one-level check for command shadowing} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    proc foo {} {return "global foo"}
    namespace eval test_ns_1 {
	proc trigger {} {
	    return [foo]
	}
    }
    set l ""
    lappend l [test_ns_1::trigger]
    namespace eval test_ns_1 {
	# force invalidation of cached ref to "foo" in proc trigger
	proc foo {} {return "foo in test_ns_1"}
    }
    lappend l [test_ns_1::trigger]
} -result {{global foo} {foo in test_ns_1}}
test namespace-18.2 {TclResetShadowedCmdRefs, multilevel check for command shadowing} {
    namespace eval test_ns_2 {
	proc foo {} {return "foo in ::test_ns_2"}
    }
    namespace eval test_ns_1 {
	namespace eval test_ns_2 {}
	proc trigger {} {
	    return [test_ns_2::foo]
	}
    }
    set l ""
    lappend l [test_ns_1::trigger]
    namespace eval test_ns_1 {
	namespace eval test_ns_2 {
	    # force invalidation of cached ref to "foo" in proc trigger
	    proc foo {} {return "foo in ::test_ns_1::test_ns_2"}
	}
    }
    lappend l [test_ns_1::trigger]
} {{foo in ::test_ns_2} {foo in ::test_ns_1::test_ns_2}}
catch {unset l}
catch {rename foo {}}

test namespace-19.1 {GetNamespaceFromObj, global name found} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1::test_ns_2 {}
    namespace children ::test_ns_1
} -result {::test_ns_1::test_ns_2}
test namespace-19.2 {GetNamespaceFromObj, relative name found} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1::test_ns_2 {}
} -body {
    namespace eval test_ns_1 {
	namespace children test_ns_2
    }
} -result {}
test namespace-19.3 {GetNamespaceFromObj, name not found} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1 {
	namespace children test_ns_99
    }
} -returnCodes error -result {namespace "test_ns_99" not found in "::test_ns_1"}
test namespace-19.4 {GetNamespaceFromObj, invalidation of cached ns refs} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1::test_ns_2 {}
} -body {
    namespace eval test_ns_1 {
	proc foo {} {
	    return [namespace children test_ns_2]
	}
	list [catch {namespace children test_ns_99} msg] $msg
    }
    set l {}
    lappend l [test_ns_1::foo]
    namespace delete test_ns_1::test_ns_2
    namespace eval test_ns_1::test_ns_2::test_ns_3 {}
    lappend l [test_ns_1::foo]
} -result {{} ::test_ns_1::test_ns_2::test_ns_3}
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
    expr {"::test_ns_1" in [namespace children]}
} -result {1}
test namespace-21.2 {NamespaceChildrenCmd, no args} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1::test_ns_2 {}
} -body {
    namespace eval test_ns_1 {
        namespace children
    }
} -result {::test_ns_1::test_ns_2}
test namespace-21.3 {NamespaceChildrenCmd, ns name given} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1::test_ns_2 {}
} -body {
    namespace children ::test_ns_1
} -result {::test_ns_1::test_ns_2}
test namespace-21.4 {NamespaceChildrenCmd, ns name given} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1::test_ns_2 {}
} -body {
    namespace eval test_ns_1 {
        namespace children test_ns_2
    }
} -result {}
test namespace-21.5 {NamespaceChildrenCmd, too many args} {
    namespace eval test_ns_1 {
        list [catch {namespace children test_ns_2 xxx yyy} msg] $msg
    }
} {1 {wrong # args: should be "namespace children ?name? ?pattern?"}}
test namespace-21.6 {NamespaceChildrenCmd, glob-style pattern given} {
    namespace eval test_ns_1::test_ns_foo {}
    namespace children test_ns_1 *f*
} {::test_ns_1::test_ns_foo}
test namespace-21.7 {NamespaceChildrenCmd, glob-style pattern given} -setup {







|













|




|







1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
    expr {"::test_ns_1" in [namespace children]}
} -result {1}
test namespace-21.2 {NamespaceChildrenCmd, no args} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1::test_ns_2 {}
} -body {
    namespace eval test_ns_1 {
	namespace children
    }
} -result {::test_ns_1::test_ns_2}
test namespace-21.3 {NamespaceChildrenCmd, ns name given} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1::test_ns_2 {}
} -body {
    namespace children ::test_ns_1
} -result {::test_ns_1::test_ns_2}
test namespace-21.4 {NamespaceChildrenCmd, ns name given} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1::test_ns_2 {}
} -body {
    namespace eval test_ns_1 {
	namespace children test_ns_2
    }
} -result {}
test namespace-21.5 {NamespaceChildrenCmd, too many args} {
    namespace eval test_ns_1 {
	list [catch {namespace children test_ns_2 xxx yyy} msg] $msg
    }
} {1 {wrong # args: should be "namespace children ?name? ?pattern?"}}
test namespace-21.6 {NamespaceChildrenCmd, glob-style pattern given} {
    namespace eval test_ns_1::test_ns_foo {}
    namespace children test_ns_1 *f*
} {::test_ns_1::test_ns_foo}
test namespace-21.7 {NamespaceChildrenCmd, glob-style pattern given} -setup {
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
    namespace eval test_ns_1 {}
    namespace children [namespace current] [fq test_ns_1]
} [fq test_ns_1]

test namespace-22.1 {NamespaceCodeCmd, bad args} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    list [catch {namespace code} msg] $msg \
         [catch {namespace code xxx yyy} msg] $msg
} {1 {wrong # args: should be "namespace code arg"} 1 {wrong # args: should be "namespace code arg"}}
test namespace-22.2 {NamespaceCodeCmd, arg is already scoped value} {
    namespace eval test_ns_1 {
        proc cmd {} {return "test_ns_1::cmd"}
    }
    namespace code {::namespace inscope ::test_ns_1 cmd}
} {::namespace inscope ::test_ns_1 cmd}
test namespace-22.3 {NamespaceCodeCmd, arg is already scoped value} {
    namespace code {namespace     inscope     ::test_ns_1 cmd}
} {::namespace inscope :: {namespace     inscope     ::test_ns_1 cmd}}
test namespace-22.4 {NamespaceCodeCmd, in :: namespace} {
    namespace code unknown
} {::namespace inscope :: unknown}
test namespace-22.5 {NamespaceCodeCmd, in other namespace} {
    namespace eval test_ns_1 {
        namespace code cmd
    }
} {::namespace inscope ::test_ns_1 cmd}
test namespace-22.6 {NamespaceCodeCmd, in other namespace} {
    namespace eval test_ns_1 {
	variable v 42
    }
    namespace eval test_ns_2 {







|



|











|







1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
    namespace eval test_ns_1 {}
    namespace children [namespace current] [fq test_ns_1]
} [fq test_ns_1]

test namespace-22.1 {NamespaceCodeCmd, bad args} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    list [catch {namespace code} msg] $msg \
	 [catch {namespace code xxx yyy} msg] $msg
} {1 {wrong # args: should be "namespace code arg"} 1 {wrong # args: should be "namespace code arg"}}
test namespace-22.2 {NamespaceCodeCmd, arg is already scoped value} {
    namespace eval test_ns_1 {
	proc cmd {} {return "test_ns_1::cmd"}
    }
    namespace code {::namespace inscope ::test_ns_1 cmd}
} {::namespace inscope ::test_ns_1 cmd}
test namespace-22.3 {NamespaceCodeCmd, arg is already scoped value} {
    namespace code {namespace     inscope     ::test_ns_1 cmd}
} {::namespace inscope :: {namespace     inscope     ::test_ns_1 cmd}}
test namespace-22.4 {NamespaceCodeCmd, in :: namespace} {
    namespace code unknown
} {::namespace inscope :: unknown}
test namespace-22.5 {NamespaceCodeCmd, in other namespace} {
    namespace eval test_ns_1 {
	namespace code cmd
    }
} {::namespace inscope ::test_ns_1 cmd}
test namespace-22.6 {NamespaceCodeCmd, in other namespace} {
    namespace eval test_ns_1 {
	variable v 42
    }
    namespace eval test_ns_2 {
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
	::namespace code {namespace inscope foo}
    }
} [list ::namespace inscope [fq demo] {namespace inscope foo}]

test namespace-23.1 {NamespaceCurrentCmd, bad args} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    list [catch {namespace current xxx} msg] $msg \
         [catch {namespace current xxx yyy} msg] $msg
} {1 {wrong # args: should be "namespace current"} 1 {wrong # args: should be "namespace current"}}
test namespace-23.2 {NamespaceCurrentCmd, at global level} {
    namespace current
} {::}
test namespace-23.3 {NamespaceCurrentCmd, in nested ns} {
    namespace eval test_ns_1::test_ns_2 {
        namespace current
    }
} {::test_ns_1::test_ns_2}

test namespace-24.1 {NamespaceDeleteCmd, no args} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace delete
} {}







|






|







1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
	::namespace code {namespace inscope foo}
    }
} [list ::namespace inscope [fq demo] {namespace inscope foo}]

test namespace-23.1 {NamespaceCurrentCmd, bad args} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    list [catch {namespace current xxx} msg] $msg \
	 [catch {namespace current xxx yyy} msg] $msg
} {1 {wrong # args: should be "namespace current"} 1 {wrong # args: should be "namespace current"}}
test namespace-23.2 {NamespaceCurrentCmd, at global level} {
    namespace current
} {::}
test namespace-23.3 {NamespaceCurrentCmd, in nested ns} {
    namespace eval test_ns_1::test_ns_2 {
	namespace current
    }
} {::test_ns_1::test_ns_2}

test namespace-24.1 {NamespaceDeleteCmd, no args} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace delete
} {}
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
test namespace-25.2 {NamespaceEvalCmd, bad args} -body {
    namespace test_ns_1
} -returnCodes error -match glob -result {unknown or ambiguous subcommand "test_ns_1": must be *}
catch {unset v}
test namespace-25.3 {NamespaceEvalCmd, new namespace} {
    set v 123
    namespace eval test_ns_1 {
        variable v 314159
        proc p {} {
            variable v
            return $v
        }
    }
    test_ns_1::p
} {314159}
test namespace-25.4 {NamespaceEvalCmd, existing namespace} -setup {
    namespace eval test_ns_1 {
        variable v 314159
        proc p {} {
            variable v
            return $v
        }
    }
} -body {
    namespace eval test_ns_1 {
        proc q {} {return [expr {[p]+1}]}
    }
    test_ns_1::q
} -result {314160}
test namespace-25.5 {NamespaceEvalCmd, multiple args} -setup {
    namespace eval test_ns_1 {variable v 314159}
} -body {
    namespace eval test_ns_1 "set" "v"







|
|
|
|
|





|
|
|
|
|



|







1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
test namespace-25.2 {NamespaceEvalCmd, bad args} -body {
    namespace test_ns_1
} -returnCodes error -match glob -result {unknown or ambiguous subcommand "test_ns_1": must be *}
catch {unset v}
test namespace-25.3 {NamespaceEvalCmd, new namespace} {
    set v 123
    namespace eval test_ns_1 {
	variable v 314159
	proc p {} {
	    variable v
	    return $v
	}
    }
    test_ns_1::p
} {314159}
test namespace-25.4 {NamespaceEvalCmd, existing namespace} -setup {
    namespace eval test_ns_1 {
	variable v 314159
	proc p {} {
	    variable v
	    return $v
	}
    }
} -body {
    namespace eval test_ns_1 {
	proc q {} {return [expr {[p]+1}]}
    }
    test_ns_1::q
} -result {314160}
test namespace-25.5 {NamespaceEvalCmd, multiple args} -setup {
    namespace eval test_ns_1 {variable v 314159}
} -body {
    namespace eval test_ns_1 "set" "v"
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
    namespace export
} {}
test namespace-26.2 {NamespaceExportCmd, just -clear arg} {
    namespace export -clear
} {}
test namespace-26.3 {NamespaceExportCmd, pattern can't specify a namespace} {
    namespace eval test_ns_1 {
        list [catch {namespace export ::zzz} msg] $msg
    }
} {1 {invalid export pattern "::zzz": pattern can't specify a namespace}}
test namespace-26.4 {NamespaceExportCmd, one pattern} {
    namespace eval test_ns_1 {
        namespace export cmd1
        proc cmd1 {args} {return "cmd1: $args"}
        proc cmd2 {args} {return "cmd2: $args"}
        proc cmd3 {args} {return "cmd3: $args"}
        proc cmd4 {args} {return "cmd4: $args"}
    }
    namespace eval test_ns_2 {
        namespace import ::test_ns_1::*
    }
    list [info commands test_ns_2::*] [test_ns_2::cmd1 hello]
} {::test_ns_2::cmd1 {cmd1: hello}}
test namespace-26.5 {NamespaceExportCmd, sequence of patterns, patterns accumulate} -setup {
    catch {namespace delete {*}[namespace children test_ns_*]}
    namespace eval test_ns_1 {
        proc cmd1 {args} {return "cmd1: $args"}
        proc cmd2 {args} {return "cmd2: $args"}
        proc cmd3 {args} {return "cmd3: $args"}
        proc cmd4 {args} {return "cmd4: $args"}
        namespace export cmd1 cmd3
    }
} -body {
    namespace eval test_ns_2 {
        namespace import -force ::test_ns_1::*
    }
    list [lsort [info commands test_ns_2::*]] [test_ns_2::cmd3 hello]
} -result {{::test_ns_2::cmd1 ::test_ns_2::cmd3} {cmd3: hello}}
test namespace-26.6 {NamespaceExportCmd, no patterns means return uniq'ed export list} -setup {
    catch {namespace delete {*}[namespace children test_ns_*]}
    namespace eval test_ns_1 {
        proc cmd1 {args} {return "cmd1: $args"}
        proc cmd2 {args} {return "cmd2: $args"}
        proc cmd3 {args} {return "cmd3: $args"}
        proc cmd4 {args} {return "cmd4: $args"}
        namespace export cmd1 cmd3
    }
} -body {
    namespace eval test_ns_1 {
        namespace export
    }
} -result {cmd1 cmd3}
test namespace-26.7 {NamespaceExportCmd, -clear resets export list} -setup {
    catch {namespace delete {*}[namespace children test_ns_*]}
    namespace eval test_ns_1 {
        proc cmd1 {args} {return "cmd1: $args"}
        proc cmd2 {args} {return "cmd2: $args"}
        proc cmd3 {args} {return "cmd3: $args"}
        proc cmd4 {args} {return "cmd4: $args"}
    }
} -body {
    namespace eval test_ns_1 {
        namespace export cmd1 cmd3
    }
    namespace eval test_ns_2 {
        namespace import ::test_ns_1::*
    }
    namespace eval test_ns_1 {
        namespace export -clear cmd4
    }
    namespace eval test_ns_2 {
        namespace import ::test_ns_1::*
    }
    list [lsort [info commands test_ns_2::*]] [test_ns_2::cmd4 hello]
} -result [list [lsort {::test_ns_2::cmd4 ::test_ns_2::cmd1 ::test_ns_2::cmd3}] {cmd4: hello}]
test namespace-26.8 {NamespaceExportCmd, -clear resets export list} {
    catch {namespace delete foo}
    namespace eval foo {
	namespace export x







|




|
|
|
|
|


|






|
|
|
|
|



|






|
|
|
|
|



|





|
|
|
|



|


|


|


|







1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
    namespace export
} {}
test namespace-26.2 {NamespaceExportCmd, just -clear arg} {
    namespace export -clear
} {}
test namespace-26.3 {NamespaceExportCmd, pattern can't specify a namespace} {
    namespace eval test_ns_1 {
	list [catch {namespace export ::zzz} msg] $msg
    }
} {1 {invalid export pattern "::zzz": pattern can't specify a namespace}}
test namespace-26.4 {NamespaceExportCmd, one pattern} {
    namespace eval test_ns_1 {
	namespace export cmd1
	proc cmd1 {args} {return "cmd1: $args"}
	proc cmd2 {args} {return "cmd2: $args"}
	proc cmd3 {args} {return "cmd3: $args"}
	proc cmd4 {args} {return "cmd4: $args"}
    }
    namespace eval test_ns_2 {
	namespace import ::test_ns_1::*
    }
    list [info commands test_ns_2::*] [test_ns_2::cmd1 hello]
} {::test_ns_2::cmd1 {cmd1: hello}}
test namespace-26.5 {NamespaceExportCmd, sequence of patterns, patterns accumulate} -setup {
    catch {namespace delete {*}[namespace children test_ns_*]}
    namespace eval test_ns_1 {
	proc cmd1 {args} {return "cmd1: $args"}
	proc cmd2 {args} {return "cmd2: $args"}
	proc cmd3 {args} {return "cmd3: $args"}
	proc cmd4 {args} {return "cmd4: $args"}
	namespace export cmd1 cmd3
    }
} -body {
    namespace eval test_ns_2 {
	namespace import -force ::test_ns_1::*
    }
    list [lsort [info commands test_ns_2::*]] [test_ns_2::cmd3 hello]
} -result {{::test_ns_2::cmd1 ::test_ns_2::cmd3} {cmd3: hello}}
test namespace-26.6 {NamespaceExportCmd, no patterns means return uniq'ed export list} -setup {
    catch {namespace delete {*}[namespace children test_ns_*]}
    namespace eval test_ns_1 {
	proc cmd1 {args} {return "cmd1: $args"}
	proc cmd2 {args} {return "cmd2: $args"}
	proc cmd3 {args} {return "cmd3: $args"}
	proc cmd4 {args} {return "cmd4: $args"}
	namespace export cmd1 cmd3
    }
} -body {
    namespace eval test_ns_1 {
	namespace export
    }
} -result {cmd1 cmd3}
test namespace-26.7 {NamespaceExportCmd, -clear resets export list} -setup {
    catch {namespace delete {*}[namespace children test_ns_*]}
    namespace eval test_ns_1 {
	proc cmd1 {args} {return "cmd1: $args"}
	proc cmd2 {args} {return "cmd2: $args"}
	proc cmd3 {args} {return "cmd3: $args"}
	proc cmd4 {args} {return "cmd4: $args"}
    }
} -body {
    namespace eval test_ns_1 {
	namespace export cmd1 cmd3
    }
    namespace eval test_ns_2 {
	namespace import ::test_ns_1::*
    }
    namespace eval test_ns_1 {
	namespace export -clear cmd4
    }
    namespace eval test_ns_2 {
	namespace import ::test_ns_1::*
    }
    list [lsort [info commands test_ns_2::*]] [test_ns_2::cmd4 hello]
} -result [list [lsort {::test_ns_2::cmd4 ::test_ns_2::cmd1 ::test_ns_2::cmd3}] {cmd4: hello}]
test namespace-26.8 {NamespaceExportCmd, -clear resets export list} {
    catch {namespace delete foo}
    namespace eval foo {
	namespace export x
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
    namespace forget
} {}
test namespace-27.2 {NamespaceForgetCmd, args must be valid namespaces} {
    list [catch {namespace forget ::test_ns_1::xxx} msg] $msg
} {1 {unknown namespace in namespace forget pattern "::test_ns_1::xxx"}}
test namespace-27.3 {NamespaceForgetCmd, arg is forgotten} {
    namespace eval test_ns_1 {
        namespace export cmd*
        proc cmd1 {args} {return "cmd1: $args"}
        proc cmd2 {args} {return "cmd2: $args"}
    }
    namespace eval test_ns_2 {
        namespace import ::test_ns_1::*
        namespace forget ::test_ns_1::cmd1
    }
    info commands ::test_ns_2::*
} {::test_ns_2::cmd2}

test namespace-28.1 {NamespaceImportCmd, no args} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {







|
|
|


|
|







1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
    namespace forget
} {}
test namespace-27.2 {NamespaceForgetCmd, args must be valid namespaces} {
    list [catch {namespace forget ::test_ns_1::xxx} msg] $msg
} {1 {unknown namespace in namespace forget pattern "::test_ns_1::xxx"}}
test namespace-27.3 {NamespaceForgetCmd, arg is forgotten} {
    namespace eval test_ns_1 {
	namespace export cmd*
	proc cmd1 {args} {return "cmd1: $args"}
	proc cmd2 {args} {return "cmd2: $args"}
    }
    namespace eval test_ns_2 {
	namespace import ::test_ns_1::*
	namespace forget ::test_ns_1::cmd1
    }
    info commands ::test_ns_2::*
} {::test_ns_2::cmd2}

test namespace-28.1 {NamespaceImportCmd, no args} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -result {bar boo foo}
test namespace-28.2 {NamespaceImportCmd, no args and just "-force"} {
    namespace import -force
} {}
test namespace-28.3 {NamespaceImportCmd, arg is imported} {
    namespace eval test_ns_1 {
        namespace export cmd2
        proc cmd1 {args} {return "cmd1: $args"}
        proc cmd2 {args} {return "cmd2: $args"}
    }
    namespace eval test_ns_2 {
        namespace import ::test_ns_1::*
        namespace forget ::test_ns_1::cmd1
    }
    info commands test_ns_2::*
} {::test_ns_2::cmd2}

test namespace-29.1 {NamespaceInscopeCmd, bad args} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    list [catch {namespace inscope} msg] $msg
} {1 {wrong # args: should be "namespace inscope name arg ?arg...?"}}
test namespace-29.2 {NamespaceInscopeCmd, bad args} {
    list [catch {namespace inscope ::} msg] $msg
} {1 {wrong # args: should be "namespace inscope name arg ?arg...?"}}
test namespace-29.3 {NamespaceInscopeCmd, specified ns must exist} -body {
    namespace inscope test_ns_1 {set v}
} -returnCodes error -result {namespace "test_ns_1" not found in "::"}
test namespace-29.4 {NamespaceInscopeCmd, simple case} {
    namespace eval test_ns_1 {
        variable v 747
        proc cmd {args} {
            variable v
            return "[namespace current]::cmd: v=$v, args=$args"
        }
    }
    namespace inscope test_ns_1 cmd
} {::test_ns_1::cmd: v=747, args=}
test namespace-29.5 {NamespaceInscopeCmd, has lappend semantics} -setup {
    namespace eval test_ns_1 {
        variable v 747
        proc cmd {args} {
            variable v
            return "[namespace current]::cmd: v=$v, args=$args"
        }
    }
} -body {
    list [namespace inscope test_ns_1 cmd x y z] \
         [namespace eval test_ns_1 [concat cmd [list x y z]]]
} -result {{::test_ns_1::cmd: v=747, args=x y z} {::test_ns_1::cmd: v=747, args=x y z}}
test namespace-29.6 {NamespaceInscopeCmd, 1400572} -setup {
    namespace eval test_ns_1 {}
} -body {
    namespace inscope test_ns_1 {info level 0}
} -result {namespace inscope test_ns_1 {info level 0}}








|
|
|


|
|
















|
|
|
|
|





|
|
|
|
|



|







1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -result {bar boo foo}
test namespace-28.2 {NamespaceImportCmd, no args and just "-force"} {
    namespace import -force
} {}
test namespace-28.3 {NamespaceImportCmd, arg is imported} {
    namespace eval test_ns_1 {
	namespace export cmd2
	proc cmd1 {args} {return "cmd1: $args"}
	proc cmd2 {args} {return "cmd2: $args"}
    }
    namespace eval test_ns_2 {
	namespace import ::test_ns_1::*
	namespace forget ::test_ns_1::cmd1
    }
    info commands test_ns_2::*
} {::test_ns_2::cmd2}

test namespace-29.1 {NamespaceInscopeCmd, bad args} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    list [catch {namespace inscope} msg] $msg
} {1 {wrong # args: should be "namespace inscope name arg ?arg...?"}}
test namespace-29.2 {NamespaceInscopeCmd, bad args} {
    list [catch {namespace inscope ::} msg] $msg
} {1 {wrong # args: should be "namespace inscope name arg ?arg...?"}}
test namespace-29.3 {NamespaceInscopeCmd, specified ns must exist} -body {
    namespace inscope test_ns_1 {set v}
} -returnCodes error -result {namespace "test_ns_1" not found in "::"}
test namespace-29.4 {NamespaceInscopeCmd, simple case} {
    namespace eval test_ns_1 {
	variable v 747
	proc cmd {args} {
	    variable v
	    return "[namespace current]::cmd: v=$v, args=$args"
	}
    }
    namespace inscope test_ns_1 cmd
} {::test_ns_1::cmd: v=747, args=}
test namespace-29.5 {NamespaceInscopeCmd, has lappend semantics} -setup {
    namespace eval test_ns_1 {
	variable v 747
	proc cmd {args} {
	    variable v
	    return "[namespace current]::cmd: v=$v, args=$args"
	}
    }
} -body {
    list [namespace inscope test_ns_1 cmd x y z] \
	 [namespace eval test_ns_1 [concat cmd [list x y z]]]
} -result {{::test_ns_1::cmd: v=747, args=x y z} {::test_ns_1::cmd: v=747, args=x y z}}
test namespace-29.6 {NamespaceInscopeCmd, 1400572} -setup {
    namespace eval test_ns_1 {}
} -body {
    namespace inscope test_ns_1 {info level 0}
} -result {namespace inscope test_ns_1 {info level 0}}

1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
    list [catch {namespace origin fred} msg] $msg
} {1 {invalid command name "fred"}}
test namespace-30.4 {NamespaceOriginCmd, command isn't imported} {
    namespace origin set
} {::set}
test namespace-30.5 {NamespaceOriginCmd, imported command} {
    namespace eval test_ns_1 {
        namespace export cmd*
        proc cmd1 {args} {return "cmd1: $args"}
        proc cmd2 {args} {return "cmd2: $args"}
    }
    namespace eval test_ns_2 {
        namespace export *
        namespace import ::test_ns_1::*
        proc p {} {}
    }
    namespace eval test_ns_3 {
        namespace import ::test_ns_2::*
        list [namespace origin foreach] \
             [namespace origin p] \
             [namespace origin cmd1] \
             [namespace origin ::test_ns_2::cmd2]
    }
} {::foreach ::test_ns_2::p ::test_ns_1::cmd1 ::test_ns_1::cmd2}

test namespace-31.1 {NamespaceParentCmd, bad args} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    list [catch {namespace parent a b} msg] $msg
} {1 {wrong # args: should be "namespace parent ?name?"}}
test namespace-31.2 {NamespaceParentCmd, no args} {
    namespace parent
} {}
test namespace-31.3 {NamespaceParentCmd, namespace specified} {
    namespace eval test_ns_1 {
        namespace eval test_ns_2 {
            namespace eval test_ns_3 {}
        }
    }
    list [namespace parent ::] \
         [namespace parent test_ns_1::test_ns_2] \
         [namespace eval test_ns_1::test_ns_2::test_ns_3 {namespace parent ::test_ns_1::test_ns_2}]
} {{} ::test_ns_1 ::test_ns_1}
test namespace-31.4 {NamespaceParentCmd, bad namespace specified} -body {
    namespace parent test_ns_1::test_ns_foo
} -returnCodes error -result {namespace "test_ns_1::test_ns_foo" not found in "::"}

test namespace-32.1 {NamespaceQualifiersCmd, bad args} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}







|
|
|


|
|
|


|
|
|
|
|












|
|
|


|
|







1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
    list [catch {namespace origin fred} msg] $msg
} {1 {invalid command name "fred"}}
test namespace-30.4 {NamespaceOriginCmd, command isn't imported} {
    namespace origin set
} {::set}
test namespace-30.5 {NamespaceOriginCmd, imported command} {
    namespace eval test_ns_1 {
	namespace export cmd*
	proc cmd1 {args} {return "cmd1: $args"}
	proc cmd2 {args} {return "cmd2: $args"}
    }
    namespace eval test_ns_2 {
	namespace export *
	namespace import ::test_ns_1::*
	proc p {} {}
    }
    namespace eval test_ns_3 {
	namespace import ::test_ns_2::*
	list [namespace origin foreach] \
	     [namespace origin p] \
	     [namespace origin cmd1] \
	     [namespace origin ::test_ns_2::cmd2]
    }
} {::foreach ::test_ns_2::p ::test_ns_1::cmd1 ::test_ns_1::cmd2}

test namespace-31.1 {NamespaceParentCmd, bad args} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    list [catch {namespace parent a b} msg] $msg
} {1 {wrong # args: should be "namespace parent ?name?"}}
test namespace-31.2 {NamespaceParentCmd, no args} {
    namespace parent
} {}
test namespace-31.3 {NamespaceParentCmd, namespace specified} {
    namespace eval test_ns_1 {
	namespace eval test_ns_2 {
	    namespace eval test_ns_3 {}
	}
    }
    list [namespace parent ::] \
	 [namespace parent test_ns_1::test_ns_2] \
	 [namespace eval test_ns_1::test_ns_2::test_ns_3 {namespace parent ::test_ns_1::test_ns_2}]
} {{} ::test_ns_1 ::test_ns_1}
test namespace-31.4 {NamespaceParentCmd, bad namespace specified} -body {
    namespace parent test_ns_1::test_ns_foo
} -returnCodes error -result {namespace "test_ns_1::test_ns_foo" not found in "::"}

test namespace-32.1 {NamespaceQualifiersCmd, bad args} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
} {}
test namespace-34.4 {NamespaceWhichCmd, bad args} {
    list [catch {namespace which a b} msg] $msg
} {1 {wrong # args: should be "namespace which ?-command? ?-variable? name"}}
test namespace-34.5 {NamespaceWhichCmd, command lookup} -setup {
    catch {namespace delete {*}[namespace children test_ns_*]}
    namespace eval test_ns_1 {
        namespace export cmd*
        variable v1 111
        proc cmd1 {args} {return "cmd1: $args"}
        proc cmd2 {args} {return "cmd2: $args"}
    }
    namespace eval test_ns_2 {
        namespace export *
        namespace import ::test_ns_1::*
        variable v2 222
        proc p {} {}
    }
} -body {
    namespace eval test_ns_3 {
        namespace import ::test_ns_2::*
        variable v3 333
        list [namespace which -command foreach] \
             [namespace which -command p] \
             [namespace which -command cmd1] \
             [namespace which -command ::test_ns_2::cmd2] \
             [catch {namespace which -command ::test_ns_2::noSuchCmd} msg] $msg
    }
} -result {::foreach ::test_ns_3::p ::test_ns_3::cmd1 ::test_ns_2::cmd2 0 {}}
test namespace-34.6 {NamespaceWhichCmd, -command is default} -setup {
    catch {namespace delete {*}[namespace children test_ns_*]}
    namespace eval test_ns_1 {
        namespace export cmd*
        proc cmd1 {args} {return "cmd1: $args"}
        proc cmd2 {args} {return "cmd2: $args"}
    }
    namespace eval test_ns_2 {
        namespace export *
        namespace import ::test_ns_1::*
        proc p {} {}
    }
    namespace eval test_ns_3 {
        namespace import ::test_ns_2::*
    }
} -body {
    namespace eval test_ns_3 {
        list [namespace which foreach] \
             [namespace which p] \
             [namespace which cmd1] \
             [namespace which ::test_ns_2::cmd2]
    }
} -result {::foreach ::test_ns_3::p ::test_ns_3::cmd1 ::test_ns_2::cmd2}

# TIP 278: secondary lookup disabled, catch added, result changed
test namespace-34.7 {NamespaceWhichCmd, variable lookup} -setup {
    catch {namespace delete {*}[namespace children test_ns_*]}
    namespace eval test_ns_1 {
        namespace export cmd*
        proc cmd1 {args} {return "cmd1: $args"}
        proc cmd2 {args} {return "cmd2: $args"}
    }
    namespace eval test_ns_2 {
        namespace export *
        namespace import ::test_ns_1::*
        variable v2 222
        proc p {} {}
    }
    namespace eval test_ns_3 {
        variable v3 333
        namespace import ::test_ns_2::*
    }
} -body {
    namespace eval test_ns_3 {
        list [catch {namespace which -variable env } msg] $msg \
             [namespace which -variable v3] \
             [namespace which -variable ::test_ns_2::v2] \
             [catch {namespace which -variable ::test_ns_2::noSuchVar} msg] $msg
    }
} -result {0 {} ::test_ns_3::v3 ::test_ns_2::v2 0 {}}

test namespace-35.1 {FreeNsNameInternalRep, resulting ref count > 0} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1 {
        proc p {} {
            namespace delete [namespace current]
            return [namespace current]
        }
    }
    test_ns_1::p
} -result {::test_ns_1}
test namespace-35.2 {FreeNsNameInternalRep, resulting ref count == 0} {
    namespace eval test_ns_1 {
        proc q {} {
            return [namespace current]
        }
    }
    list [test_ns_1::q] \
         [namespace delete test_ns_1] \
         [catch {test_ns_1::q} msg] $msg
} {::test_ns_1 {} 1 {invalid command name "test_ns_1::q"}}

catch {unset x}
catch {unset y}
test namespace-36.1 {DupNsNameInternalRep} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1 {}
    set x "::test_ns_1"
    list [namespace parent $x] [set y $x] [namespace parent $y]
} {:: ::test_ns_1 ::}
catch {unset x}
catch {unset y}

test namespace-37.1 {SetNsNameFromAny, ns name found} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1::test_ns_2 {}
    namespace eval test_ns_1 {
        namespace children ::test_ns_1
    }
} {::test_ns_1::test_ns_2}
test namespace-37.2 {SetNsNameFromAny, ns name not found} -body {
    namespace eval test_ns_1 {
        namespace children ::test_ns_1::test_ns_foo
    }
} -returnCodes error -result {namespace "::test_ns_1::test_ns_foo" not found}

test namespace-38.1 {UpdateStringOfNsName} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    ;# Tcl_NamespaceObjCmd calls UpdateStringOfNsName to get subcmd name
    list [namespace eval {} {namespace current}] \
         [namespace eval {} {namespace current}]
} {:: ::}

test namespace-39.1 {NamespaceExistsCmd} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval ::test_ns_z::test_me { variable foo }
    list [namespace exists ::] \
	    [namespace exists ::bogus_namespace] \







|
|
|
|


|
|
|
|



|
|
|
|
|
|
|





|
|
|


|
|
|


|



|
|
|
|







|
|
|


|
|
|
|


|
|



|
|
|
|







|
|
|
|





|
|
|


|
|

















|




|







|







1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
} {}
test namespace-34.4 {NamespaceWhichCmd, bad args} {
    list [catch {namespace which a b} msg] $msg
} {1 {wrong # args: should be "namespace which ?-command? ?-variable? name"}}
test namespace-34.5 {NamespaceWhichCmd, command lookup} -setup {
    catch {namespace delete {*}[namespace children test_ns_*]}
    namespace eval test_ns_1 {
	namespace export cmd*
	variable v1 111
	proc cmd1 {args} {return "cmd1: $args"}
	proc cmd2 {args} {return "cmd2: $args"}
    }
    namespace eval test_ns_2 {
	namespace export *
	namespace import ::test_ns_1::*
	variable v2 222
	proc p {} {}
    }
} -body {
    namespace eval test_ns_3 {
	namespace import ::test_ns_2::*
	variable v3 333
	list [namespace which -command foreach] \
	     [namespace which -command p] \
	     [namespace which -command cmd1] \
	     [namespace which -command ::test_ns_2::cmd2] \
	     [catch {namespace which -command ::test_ns_2::noSuchCmd} msg] $msg
    }
} -result {::foreach ::test_ns_3::p ::test_ns_3::cmd1 ::test_ns_2::cmd2 0 {}}
test namespace-34.6 {NamespaceWhichCmd, -command is default} -setup {
    catch {namespace delete {*}[namespace children test_ns_*]}
    namespace eval test_ns_1 {
	namespace export cmd*
	proc cmd1 {args} {return "cmd1: $args"}
	proc cmd2 {args} {return "cmd2: $args"}
    }
    namespace eval test_ns_2 {
	namespace export *
	namespace import ::test_ns_1::*
	proc p {} {}
    }
    namespace eval test_ns_3 {
	namespace import ::test_ns_2::*
    }
} -body {
    namespace eval test_ns_3 {
	list [namespace which foreach] \
	     [namespace which p] \
	     [namespace which cmd1] \
	     [namespace which ::test_ns_2::cmd2]
    }
} -result {::foreach ::test_ns_3::p ::test_ns_3::cmd1 ::test_ns_2::cmd2}

# TIP 278: secondary lookup disabled, catch added, result changed
test namespace-34.7 {NamespaceWhichCmd, variable lookup} -setup {
    catch {namespace delete {*}[namespace children test_ns_*]}
    namespace eval test_ns_1 {
	namespace export cmd*
	proc cmd1 {args} {return "cmd1: $args"}
	proc cmd2 {args} {return "cmd2: $args"}
    }
    namespace eval test_ns_2 {
	namespace export *
	namespace import ::test_ns_1::*
	variable v2 222
	proc p {} {}
    }
    namespace eval test_ns_3 {
	variable v3 333
	namespace import ::test_ns_2::*
    }
} -body {
    namespace eval test_ns_3 {
	list [catch {namespace which -variable env } msg] $msg \
	     [namespace which -variable v3] \
	     [namespace which -variable ::test_ns_2::v2] \
	     [catch {namespace which -variable ::test_ns_2::noSuchVar} msg] $msg
    }
} -result {0 {} ::test_ns_3::v3 ::test_ns_2::v2 0 {}}

test namespace-35.1 {FreeNsNameInternalRep, resulting ref count > 0} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1 {
	proc p {} {
	    namespace delete [namespace current]
	    return [namespace current]
	}
    }
    test_ns_1::p
} -result {::test_ns_1}
test namespace-35.2 {FreeNsNameInternalRep, resulting ref count == 0} {
    namespace eval test_ns_1 {
	proc q {} {
	    return [namespace current]
	}
    }
    list [test_ns_1::q] \
	 [namespace delete test_ns_1] \
	 [catch {test_ns_1::q} msg] $msg
} {::test_ns_1 {} 1 {invalid command name "test_ns_1::q"}}

catch {unset x}
catch {unset y}
test namespace-36.1 {DupNsNameInternalRep} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1 {}
    set x "::test_ns_1"
    list [namespace parent $x] [set y $x] [namespace parent $y]
} {:: ::test_ns_1 ::}
catch {unset x}
catch {unset y}

test namespace-37.1 {SetNsNameFromAny, ns name found} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval test_ns_1::test_ns_2 {}
    namespace eval test_ns_1 {
	namespace children ::test_ns_1
    }
} {::test_ns_1::test_ns_2}
test namespace-37.2 {SetNsNameFromAny, ns name not found} -body {
    namespace eval test_ns_1 {
	namespace children ::test_ns_1::test_ns_foo
    }
} -returnCodes error -result {namespace "::test_ns_1::test_ns_foo" not found}

test namespace-38.1 {UpdateStringOfNsName} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    ;# Tcl_NamespaceObjCmd calls UpdateStringOfNsName to get subcmd name
    list [namespace eval {} {namespace current}] \
	 [namespace eval {} {namespace current}]
} {:: ::}

test namespace-39.1 {NamespaceExistsCmd} {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    namespace eval ::test_ns_z::test_me { variable foo }
    list [namespace exists ::] \
	    [namespace exists ::bogus_namespace] \
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939

test namespace-42.11 {
	ensembles: prefix matching segmentation fault

	issue ccc448a6bfd59cbd
} -body {
    namespace eval n1 {
        namespace ensemble create
        namespace export *
        proc p1 args {error success}
    }
    # segmentation fault only occurs in the non-byte-compiled path, so avoid
    # byte compilation
    set cmd {namespace eva n1 {[namespace parent]::n1 p1}}
    {*}$cmd
} -returnCodes error -result success








|
|
|







1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939

test namespace-42.11 {
	ensembles: prefix matching segmentation fault

	issue ccc448a6bfd59cbd
} -body {
    namespace eval n1 {
	namespace ensemble create
	namespace export *
	proc p1 args {error success}
    }
    # segmentation fault only occurs in the non-byte-compiled path, so avoid
    # byte compilation
    set cmd {namespace eva n1 {[namespace parent]::n1 p1}}
    {*}$cmd
} -returnCodes error -result success

3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
    0 {x1 x1 x1 x1 x1}}
test namespace-53.8 {ensemble: unknown handler changing -parameters} -setup {
    namespace eval ns {
	namespace export x*
	proc x1 {a1} {list 1 $a1}
	proc Magic {ensemble subcmd args} {
	    namespace ensemble configure $ensemble\
              -parameters [lrange p1 [llength [
                namespace ensemble configure $ensemble -parameters
              ]] 0]
            list
	}
	namespace ensemble create -unknown ::ns::Magic
    }
} -body {
    set result {}
    lappend result [catch {ns x1 x2} msg] $msg [namespace ensemble configure ns -parameters]
    lappend result [catch {ns x2 x1} msg] $msg [namespace ensemble configure ns -parameters]







|
|
|
|







3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
    0 {x1 x1 x1 x1 x1}}
test namespace-53.8 {ensemble: unknown handler changing -parameters} -setup {
    namespace eval ns {
	namespace export x*
	proc x1 {a1} {list 1 $a1}
	proc Magic {ensemble subcmd args} {
	    namespace ensemble configure $ensemble\
	      -parameters [lrange p1 [llength [
		namespace ensemble configure $ensemble -parameters
	      ]] 0]
	    list
	}
	namespace ensemble create -unknown ::ns::Magic
    }
} -body {
    set result {}
    lappend result [catch {ns x1 x2} msg] $msg [namespace ensemble configure ns -parameters]
    lappend result [catch {ns x2 x1} msg] $msg [namespace ensemble configure ns -parameters]
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
test namespace-53.9 {ensemble: unknown handler changing -parameters,\
  thereby eating all args} -setup {
    namespace eval ns {
	namespace export x*
	proc x1 {args} {list 1 $args}
	proc Magic {ensemble subcmd args} {
	    namespace ensemble configure $ensemble\
              -parameters {p1 p2 p3 p4 p5}
            list
	}
	namespace ensemble create -unknown ::ns::Magic
    }
} -body {
    set result {}
    lappend result [catch {ns x1 x2} msg] $msg [namespace ensemble configure ns -parameters]
    lappend result [catch {ns x2 x1} msg] $msg [namespace ensemble configure ns -parameters]







|
|







3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
test namespace-53.9 {ensemble: unknown handler changing -parameters,\
  thereby eating all args} -setup {
    namespace eval ns {
	namespace export x*
	proc x1 {args} {list 1 $args}
	proc Magic {ensemble subcmd args} {
	    namespace ensemble configure $ensemble\
	      -parameters {p1 p2 p3 p4 p5}
	    list
	}
	namespace ensemble create -unknown ::ns::Magic
    }
} -body {
    set result {}
    lappend result [catch {ns x1 x2} msg] $msg [namespace ensemble configure ns -parameters]
    lappend result [catch {ns x2 x1} msg] $msg [namespace ensemble configure ns -parameters]
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
    info class [format %s constructor] oo::object
} ""

test namespace-55.2 {compiled ensembles inside safe interpreters (for safe sub-commands), bug [1095bf7f756f9aed]} -setup {
    interp create -safe si
    set code {
	proc test_comp_dict d { dict for {k v} $d {expr $v} }
    	regexp -inline {Command 1:(?:[^\n]*\n){1,5}} [::tcl::unsupported::disassemble proc test_comp_dict]
    }
} -body {
    set a [   eval $code]
    set b [si eval $code]
    list [expr {$a eq $b}] [regexp { dictFirst } $a] [regexp { dictFirst } $b] $a $b
} -cleanup {
    rename test_comp_dict {}







|







3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
    info class [format %s constructor] oo::object
} ""

test namespace-55.2 {compiled ensembles inside safe interpreters (for safe sub-commands), bug [1095bf7f756f9aed]} -setup {
    interp create -safe si
    set code {
	proc test_comp_dict d { dict for {k v} $d {expr $v} }
	regexp -inline {Command 1:(?:[^\n]*\n){1,5}} [::tcl::unsupported::disassemble proc test_comp_dict]
    }
} -body {
    set a [   eval $code]
    set b [si eval $code]
    list [expr {$a eq $b}] [regexp { dictFirst } $a] [regexp { dictFirst } $b] $a $b
} -cleanup {
    rename test_comp_dict {}
Changes to tests/obj.test.
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
    foreach {t} {
	bytecode
	cmdName
	dict
	regexp
	string
    } {
        set first [string first $t [testobj types]]
        set r [expr {$r && ($first >= 0)}]
    }
    set result $r
} {1}

test obj-2.1 {Tcl_GetObjType error} testobj {
    list [testintobj set 1 0] [catch {testobj convert 1 foo} msg] $msg
} {0 1 {no type foo found}}







|
|







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
    foreach {t} {
	bytecode
	cmdName
	dict
	regexp
	string
    } {
	set first [string first $t [testobj types]]
	set r [expr {$r && ($first >= 0)}]
    }
    set result $r
} {1}

test obj-2.1 {Tcl_GetObjType error} testobj {
    list [testintobj set 1 0] [catch {testobj convert 1 foo} msg] $msg
} {0 1 {no type foo found}}
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
    lappend result [testdoubleobj set 1 3.14159]
    lappend result [testbooleanobj not 1]    ;# converts with SetBooleanFromAny
    lappend result [testobj type 1]
} {3.14159 0 int}
test obj-13.3 {SetBooleanFromAny, special case strings representing booleans} testobj {
    set result ""
    foreach s {yes no true false on off} {
        teststringobj set 1 $s
        lappend result [testbooleanobj not 1]
    }
    lappend result [testobj type 1]
} {0 1 0 1 0 1 int}
test obj-13.4 {SetBooleanFromAny, recompute string rep then parse it} testobj {
    set result ""
    lappend result [testintobj set 1 456]
    lappend result [testintobj div10 1]







|
|







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
    lappend result [testdoubleobj set 1 3.14159]
    lappend result [testbooleanobj not 1]    ;# converts with SetBooleanFromAny
    lappend result [testobj type 1]
} {3.14159 0 int}
test obj-13.3 {SetBooleanFromAny, special case strings representing booleans} testobj {
    set result ""
    foreach s {yes no true false on off} {
	teststringobj set 1 $s
	lappend result [testbooleanobj not 1]
    }
    lappend result [testobj type 1]
} {0 1 0 1 0 1 int}
test obj-13.4 {SetBooleanFromAny, recompute string rep then parse it} testobj {
    set result ""
    lappend result [testintobj set 1 456]
    lappend result [testintobj div10 1]
Changes to tests/oo.test.
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
	package require tcl::oo
	namespace delete ::
    }
    interp delete $i
} {}
test oo-0.3 {basic test of OO's ability to clean up its initial state} -body {
    leaktest {
        [oo::object new] destroy
    }
} -constraints memory -result 0
test oo-0.4 {basic test of OO's ability to clean up its initial state} -body {
    leaktest {
	oo::class create foo
	foo new
	foo destroy







|







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
	package require tcl::oo
	namespace delete ::
    }
    interp delete $i
} {}
test oo-0.3 {basic test of OO's ability to clean up its initial state} -body {
    leaktest {
	[oo::object new] destroy
    }
} -constraints memory -result 0
test oo-0.4 {basic test of OO's ability to clean up its initial state} -body {
    leaktest {
	oo::class create foo
	foo new
	foo destroy
387
388
389
390
391
392
393














































394
395
396
397
398
399
400
	    lappend x [info object class $initial]
	}
	return $x
    }] {lsort [lsearch -all -not -inline $x *::delegate]}
} -cleanup {
    interp delete $fresh
} -result {{} {::oo::Slot ::oo::abstract ::oo::class ::oo::configurable ::oo::configuresupport::configurable ::oo::object ::oo::singleton} {::oo::configuresupport::objreadableproperties ::oo::configuresupport::objwritableproperties ::oo::configuresupport::readableproperties ::oo::configuresupport::writableproperties ::oo::define::filter ::oo::define::mixin ::oo::define::superclass ::oo::define::variable ::oo::objdefine::filter ::oo::objdefine::mixin ::oo::objdefine::variable} {::oo::Slot ::oo::class ::oo::configuresupport::configurable} {::oo::abstract ::oo::configurable ::oo::singleton} {} {} {} {} {} ::oo::object ::oo::object ::oo::class ::oo::class ::oo::class}















































test oo-2.1 {basic test of OO functionality: constructor} -setup {
    # This is a bit complex because it needs to run in a sub-interp as
    # we're modifying the root object class's constructor
    interp create subinterp
    subinterp eval {
	package require tcl::oo







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
	    lappend x [info object class $initial]
	}
	return $x
    }] {lsort [lsearch -all -not -inline $x *::delegate]}
} -cleanup {
    interp delete $fresh
} -result {{} {::oo::Slot ::oo::abstract ::oo::class ::oo::configurable ::oo::configuresupport::configurable ::oo::object ::oo::singleton} {::oo::configuresupport::objreadableproperties ::oo::configuresupport::objwritableproperties ::oo::configuresupport::readableproperties ::oo::configuresupport::writableproperties ::oo::define::filter ::oo::define::mixin ::oo::define::superclass ::oo::define::variable ::oo::objdefine::filter ::oo::objdefine::mixin ::oo::objdefine::variable} {::oo::Slot ::oo::class ::oo::configuresupport::configurable} {::oo::abstract ::oo::configurable ::oo::singleton} {} {} {} {} {} ::oo::object ::oo::object ::oo::class ::oo::class ::oo::class}
test oo-1.22 {basic test of OO functionality: nested ownership destruction order} -setup {
    oo::class create parent
} -body {
    oo::class create abc {
	superclass parent
	variable n
	constructor {} {set n 0}
	method make {i} {set n $i; [self class] create xyz}
	destructor {lappend ::deathOrder $n}
    }
    apply {n {
	set ::deathOrder {}
	# Make some "nested" objects
	set base [abc new]
	for {set i 1; set obj $base} {$i < $n} {incr i} {
	     set obj [$obj make $i]
	}
	# Kill them all in one go; should come apart in right order!
	$base destroy
	return $::deathOrder
    }} 5
} -cleanup {
    parent destroy
} -result {1 2 3 4 0}
test oo-1.23 {basic test of OO functionality: deep nested ownership} -setup {
    oo::class create parent
} -constraints knownBug -body {
    oo::class create abc {
	superclass parent
	method make {} {[self class] create xyz}
	destructor {incr ::count}
    }
    apply {n {
	set ::count 0
	# Make a lot of "nested" objects
	set base [abc new]
	for {set i 1; set obj $base} {$i < $n} {incr i} {
	     set obj [$obj make]
	}
	# Kill them all in one go; should not crash!
	$base destroy
	return [expr {$n - $::count}]
    }} 10000
} -cleanup {
    parent destroy
} -result 0

test oo-2.1 {basic test of OO functionality: constructor} -setup {
    # This is a bit complex because it needs to run in a sub-interp as
    # we're modifying the root object class's constructor
    interp create subinterp
    subinterp eval {
	package require tcl::oo
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
	oo::class create spong {superclass boo}
	return
    }
} -result {}
test oo-7.10 {OO: next after object deletion, bug [135804138e]} -setup {
    set ::result ""
    oo::class create c1 {
        method m1 {} {
           lappend ::result c1::m1
        }
    }
    oo::class create c2 {
        superclass c1
        destructor {
            lappend ::result c2::destructor
            my m1
            lappend ::result /c2::destructor
        }
        method m1 {} {
            lappend ::result c2::m1
            rename [self] {}
            lappend ::result no-self
            next
            lappend ::result /c2::m1
        }
    }
} -body {
    c2 create o
    lappend ::result [catch {o m1} msg] $msg
} -cleanup {
    c1 destroy
    unset ::result







|
|
|


|
|
|
|
|
|
|
|
|
|
|
|
|







1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
	oo::class create spong {superclass boo}
	return
    }
} -result {}
test oo-7.10 {OO: next after object deletion, bug [135804138e]} -setup {
    set ::result ""
    oo::class create c1 {
	method m1 {} {
	   lappend ::result c1::m1
	}
    }
    oo::class create c2 {
	superclass c1
	destructor {
	    lappend ::result c2::destructor
	    my m1
	    lappend ::result /c2::destructor
	}
	method m1 {} {
	    lappend ::result c2::m1
	    rename [self] {}
	    lappend ::result no-self
	    next
	    lappend ::result /c2::m1
	}
    }
} -body {
    c2 create o
    lappend ::result [catch {o m1} msg] $msg
} -cleanup {
    c1 destroy
    unset ::result
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
	method dummy {} {}
    }
    set result {}
} -body {
    oo::define foo {
	variable x
	constructor {} {
            trace add variable x unset [list apply {{self ns args} {
		global result
		lappend result [info object isa object $self]
		lappend result [namespace exists $ns]
		# Method dispatch fails; too much gone in this case
		catch {$self dummy} msg
		lappend result $msg
	    }} [self] [self namespace]]







|







1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
	method dummy {} {}
    }
    set result {}
} -body {
    oo::define foo {
	variable x
	constructor {} {
	    trace add variable x unset [list apply {{self ns args} {
		global result
		lappend result [info object isa object $self]
		lappend result [namespace exists $ns]
		# Method dispatch fails; too much gone in this case
		catch {$self dummy} msg
		lappend result $msg
	    }} [self] [self namespace]]
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
"self {error foobar}"
    (in definition script for class "::bar" line 1)
    invoked from within
"oo::define foo {rename ::foo ::bar; self {error foobar}}"}
test oo-18.9 {OO: define/self command support} -setup {
    oo::class create parent
    set c [oo::class create now_this_is_a_very_very_long_class_name_indeed {
        superclass parent
    }]
} -body {
    catch {oo::define $c {error err}} msg opt
    dict get $opt -errorinfo
} -cleanup {
    parent destroy
} -result {err







|







3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
"self {error foobar}"
    (in definition script for class "::bar" line 1)
    invoked from within
"oo::define foo {rename ::foo ::bar; self {error foobar}}"}
test oo-18.9 {OO: define/self command support} -setup {
    oo::class create parent
    set c [oo::class create now_this_is_a_very_very_long_class_name_indeed {
	superclass parent
    }]
} -body {
    catch {oo::define $c {error err}} msg opt
    dict get $opt -errorinfo
} -cleanup {
    parent destroy
} -result {err
Changes to tests/ooProp.test.
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
    oo::class create parent
    unset -nocomplain result
    set result {}
} -body {
    oo::configurable create Point {
	superclass parent
	property x y
        constructor args {
            my configure -x 0 -y 0 {*}$args
        }
        variable x y
        method report {} {
            lappend ::result "x=$x, y=$y"
        }
    }
    set pt [Point new -x 3]
    $pt report
    $pt configure -y 4
    $pt report
    lappend result [$pt configure -x],[$pt configure -y] [$pt configure]
} -cleanup {
    parent destroy
} -result {{x=3, y=0} {x=3, y=4} 3,4 {-x 3 -y 4}}
test ooProp-2.2 {TIP 558: properties: configurable class system} -setup {
    oo::class create parent
} -body {
    oo::configurable create Point {
	superclass parent
	property x y
        constructor args {
            my configure -x 0 -y 0 {*}$args
        }
    }
    oo::configurable create 3DPoint {
	superclass Point
	property z
	constructor args {
	    next -z 0 {*}$args
	}
    }
    set pt [3DPoint new -x 3 -y 4 -z 5]
    list [$pt configure -x],[$pt configure -y],[$pt configure -z] \
	[$pt configure]
} -cleanup {
    parent destroy
} -result {3,4,5 {-x 3 -y 4 -z 5}}
test ooProp-2.3 {TIP 558: properties: configurable class system} -setup {
    oo::class create parent
} -body {
    oo::configurable create Point {
	superclass parent
	property x y
        constructor args {
            my configure -x 0 -y 0 {*}$args
        }
    }
    set pt [Point new -x 3 -y 4]
    oo::objdefine $pt property z
    $pt configure -z 5
    list [$pt configure -x],[$pt configure -y],[$pt configure -z] \
	[$pt configure]
} -cleanup {
    parent destroy
} -result {3,4,5 {-x 3 -y 4 -z 5}}
test ooProp-2.4 {TIP 558: properties: configurable class system} -setup {
    oo::class create parent
} -body {
    oo::configurable create Point {
	superclass parent
	property x y
        constructor args {
            my configure -x 0 -y 0 {*}$args
        }
    }
    [Point new] configure gorp
} -returnCodes error -cleanup {
    parent destroy
} -result {bad property "gorp": must be -x or -y}
test ooProp-2.5 {TIP 558: properties: configurable class system} -setup {
    oo::class create parent
} -body {
    oo::configurable create Point {
	superclass parent
	property x y
        constructor args {
            my configure -x 0 -y 0 {*}$args
        }
    }
    oo::configurable create 3DPoint {
	superclass Point
	property z
	constructor args {
	    next -z 0 {*}$args
	}
    }
    [3DPoint new] configure gorp
} -returnCodes error -cleanup {
    parent destroy
} -result {bad property "gorp": must be -x, -y, or -z}
test ooProp-2.6 {TIP 558: properties: configurable class system} -setup {
    oo::class create parent
} -body {
    oo::configurable create Point {
	superclass parent
	property x y
        constructor args {
            my configure -x 0 -y 0 {*}$args
        }
    }
    [Point create p] configure -x 1 -y
} -returnCodes error -cleanup {
    parent destroy
} -result {wrong # args: should be "::p configure ?-option value ...?"}
test ooProp-2.7 {TIP 558: properties: configurable class system} -setup {
    oo::class create parent
    unset -nocomplain msg
} -body {
    oo::configurable create Point {
	superclass parent
	property x y -kind writable
        constructor args {
            my configure -x 0 -y 0 {*}$args
        }
    }
    Point create p
    list [p configure -y ok] [catch {p configure -y} msg] $msg
} -cleanup {
    parent destroy
} -result {{} 1 {property "-y" is write only}}
test ooProp-2.8 {TIP 558: properties: configurable class system} -setup {
    oo::class create parent
    unset -nocomplain msg
} -body {
    oo::configurable create Point {
	superclass parent
	property x y -kind readable
        constructor args {
            my configure -x 0 {*}$args
	    variable y 123
        }
    }
    Point create p
    list [p configure] [p configure -y] [catch {p configure -y foo} msg] $msg
} -cleanup {
    parent destroy
} -result {{-x 0 -y 123} 123 1 {property "-y" is read only}}








|
|
|
|
|
|
|















|
|
|




















|
|
|















|
|
|











|
|
|


















|
|
|












|
|
|













|
|

|







236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
    oo::class create parent
    unset -nocomplain result
    set result {}
} -body {
    oo::configurable create Point {
	superclass parent
	property x y
	constructor args {
	    my configure -x 0 -y 0 {*}$args
	}
	variable x y
	method report {} {
	    lappend ::result "x=$x, y=$y"
	}
    }
    set pt [Point new -x 3]
    $pt report
    $pt configure -y 4
    $pt report
    lappend result [$pt configure -x],[$pt configure -y] [$pt configure]
} -cleanup {
    parent destroy
} -result {{x=3, y=0} {x=3, y=4} 3,4 {-x 3 -y 4}}
test ooProp-2.2 {TIP 558: properties: configurable class system} -setup {
    oo::class create parent
} -body {
    oo::configurable create Point {
	superclass parent
	property x y
	constructor args {
	    my configure -x 0 -y 0 {*}$args
	}
    }
    oo::configurable create 3DPoint {
	superclass Point
	property z
	constructor args {
	    next -z 0 {*}$args
	}
    }
    set pt [3DPoint new -x 3 -y 4 -z 5]
    list [$pt configure -x],[$pt configure -y],[$pt configure -z] \
	[$pt configure]
} -cleanup {
    parent destroy
} -result {3,4,5 {-x 3 -y 4 -z 5}}
test ooProp-2.3 {TIP 558: properties: configurable class system} -setup {
    oo::class create parent
} -body {
    oo::configurable create Point {
	superclass parent
	property x y
	constructor args {
	    my configure -x 0 -y 0 {*}$args
	}
    }
    set pt [Point new -x 3 -y 4]
    oo::objdefine $pt property z
    $pt configure -z 5
    list [$pt configure -x],[$pt configure -y],[$pt configure -z] \
	[$pt configure]
} -cleanup {
    parent destroy
} -result {3,4,5 {-x 3 -y 4 -z 5}}
test ooProp-2.4 {TIP 558: properties: configurable class system} -setup {
    oo::class create parent
} -body {
    oo::configurable create Point {
	superclass parent
	property x y
	constructor args {
	    my configure -x 0 -y 0 {*}$args
	}
    }
    [Point new] configure gorp
} -returnCodes error -cleanup {
    parent destroy
} -result {bad property "gorp": must be -x or -y}
test ooProp-2.5 {TIP 558: properties: configurable class system} -setup {
    oo::class create parent
} -body {
    oo::configurable create Point {
	superclass parent
	property x y
	constructor args {
	    my configure -x 0 -y 0 {*}$args
	}
    }
    oo::configurable create 3DPoint {
	superclass Point
	property z
	constructor args {
	    next -z 0 {*}$args
	}
    }
    [3DPoint new] configure gorp
} -returnCodes error -cleanup {
    parent destroy
} -result {bad property "gorp": must be -x, -y, or -z}
test ooProp-2.6 {TIP 558: properties: configurable class system} -setup {
    oo::class create parent
} -body {
    oo::configurable create Point {
	superclass parent
	property x y
	constructor args {
	    my configure -x 0 -y 0 {*}$args
	}
    }
    [Point create p] configure -x 1 -y
} -returnCodes error -cleanup {
    parent destroy
} -result {wrong # args: should be "::p configure ?-option value ...?"}
test ooProp-2.7 {TIP 558: properties: configurable class system} -setup {
    oo::class create parent
    unset -nocomplain msg
} -body {
    oo::configurable create Point {
	superclass parent
	property x y -kind writable
	constructor args {
	    my configure -x 0 -y 0 {*}$args
	}
    }
    Point create p
    list [p configure -y ok] [catch {p configure -y} msg] $msg
} -cleanup {
    parent destroy
} -result {{} 1 {property "-y" is write only}}
test ooProp-2.8 {TIP 558: properties: configurable class system} -setup {
    oo::class create parent
    unset -nocomplain msg
} -body {
    oo::configurable create Point {
	superclass parent
	property x y -kind readable
	constructor args {
	    my configure -x 0 {*}$args
	    variable y 123
	}
    }
    Point create p
    list [p configure] [p configure -y] [catch {p configure -y foo} msg] $msg
} -cleanup {
    parent destroy
} -result {{-x 0 -y 123} 123 1 {property "-y" is read only}}

Changes to tests/ooUtil.test.
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
}

test ooUtil-1.1 {TIP 478: classmethod} -setup {
    oo::class create parent
} -body {
    oo::class create ActiveRecord {
	superclass parent
        classmethod find args {
	    return "[self] called with arguments: $args"
	}
    }
    oo::class create Table {
        superclass ActiveRecord
    }
    Table find foo bar
} -cleanup {
    parent destroy
} -result {::Table called with arguments: foo bar}
test ooUtil-1.2 {TIP 478: classmethod in namespace} -setup {
    namespace eval ::testns {}







|




|







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
}

test ooUtil-1.1 {TIP 478: classmethod} -setup {
    oo::class create parent
} -body {
    oo::class create ActiveRecord {
	superclass parent
	classmethod find args {
	    return "[self] called with arguments: $args"
	}
    }
    oo::class create Table {
	superclass ActiveRecord
    }
    Table find foo bar
} -cleanup {
    parent destroy
} -result {::Table called with arguments: foo bar}
test ooUtil-1.2 {TIP 478: classmethod in namespace} -setup {
    namespace eval ::testns {}
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
} -cleanup {
    namespace delete ::testns
} -result {::testns::Table called with arguments: foo bar}
test ooUtil-1.3 {TIP 478: classmethod must not interfere with constructor signatures} -setup {
    oo::class create parent
} -body {
    oo::class create TestClass {
        superclass oo::class parent
        self method create {name ignore body} {
            next $name $body
        }
    }
    TestClass create okay {} {}
} -cleanup {
    parent destroy
} -result {::okay}
test ooUtil-1.4 {TIP 478: classmethod with several inheritance levels} -setup {
    oo::class create parent
} -body {
    oo::class create ActiveRecord {
	superclass parent
        classmethod find args {
	    return "[self] called with arguments: $args"
	}
    }
    oo::class create Table {
        superclass ActiveRecord
    }
    oo::class create SubTable {
        superclass Table
    }
    SubTable find foo bar
} -cleanup {
    parent destroy
} -result {::SubTable called with arguments: foo bar}
test ooUtil-1.5 {TIP 478: classmethod and instances} -setup {
    oo::class create parent
} -body {
    oo::class create ActiveRecord {
	superclass parent
        classmethod find args {
	    return "[self] called with arguments: $args"
	}
    }
    oo::class create Table {
	superclass ActiveRecord
    }
    set t [Table new]
    $t find 1 2 3
} -cleanup {
    parent destroy
} -result {::Table called with arguments: 1 2 3}
test ooUtil-1.6 {TIP 478: classmethod and instances} -setup {
    oo::class create parent
} -body {
    oo::class create ActiveRecord {
	superclass parent
        classmethod find args {
	    return "[self] called with arguments: $args"
	}
    }
    oo::class create Table {
	superclass ActiveRecord
	unexport find
    }
    set t [Table new]
    $t find 1 2 3
} -returnCodes error -cleanup {
    parent destroy
} -match glob -result {unknown method "find": must be *}
test ooUtil-1.7 {} -setup {
    oo::class create parent
} -body {
    oo::class create Foo {
	superclass parent
        classmethod bar {} {
            puts "This is in the class; self is [self]"
            my meee
        }
        classmethod meee {} {
            puts "This is meee"
        }
    }
    oo::class create Grill {
        superclass Foo
        classmethod meee {} {
            puts "This is meee 2"
        }
    }
    list [Foo bar] [Grill bar] [[Foo new] bar] [[Grill new] bar]
} -cleanup {
    parent destroy
} -result {{} {} {} {}} -output "This is in the class; self is ::Foo\nThis is meee\nThis is in the class; self is ::Grill\nThis is meee 2\nThis is in the class; self is ::Foo\nThis is meee\nThis is in the class; self is ::Grill\nThis is meee 2\n"
# Two tests to confirm that we correctly initialise the scripted part of TclOO
# in child interpreters. This is slightly tricky at the implementation level







|
|
|
|










|




|


|










|
















|

















|
|
|
|
|
|
|


|
|
|
|







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
} -cleanup {
    namespace delete ::testns
} -result {::testns::Table called with arguments: foo bar}
test ooUtil-1.3 {TIP 478: classmethod must not interfere with constructor signatures} -setup {
    oo::class create parent
} -body {
    oo::class create TestClass {
	superclass oo::class parent
	self method create {name ignore body} {
	    next $name $body
	}
    }
    TestClass create okay {} {}
} -cleanup {
    parent destroy
} -result {::okay}
test ooUtil-1.4 {TIP 478: classmethod with several inheritance levels} -setup {
    oo::class create parent
} -body {
    oo::class create ActiveRecord {
	superclass parent
	classmethod find args {
	    return "[self] called with arguments: $args"
	}
    }
    oo::class create Table {
	superclass ActiveRecord
    }
    oo::class create SubTable {
	superclass Table
    }
    SubTable find foo bar
} -cleanup {
    parent destroy
} -result {::SubTable called with arguments: foo bar}
test ooUtil-1.5 {TIP 478: classmethod and instances} -setup {
    oo::class create parent
} -body {
    oo::class create ActiveRecord {
	superclass parent
	classmethod find args {
	    return "[self] called with arguments: $args"
	}
    }
    oo::class create Table {
	superclass ActiveRecord
    }
    set t [Table new]
    $t find 1 2 3
} -cleanup {
    parent destroy
} -result {::Table called with arguments: 1 2 3}
test ooUtil-1.6 {TIP 478: classmethod and instances} -setup {
    oo::class create parent
} -body {
    oo::class create ActiveRecord {
	superclass parent
	classmethod find args {
	    return "[self] called with arguments: $args"
	}
    }
    oo::class create Table {
	superclass ActiveRecord
	unexport find
    }
    set t [Table new]
    $t find 1 2 3
} -returnCodes error -cleanup {
    parent destroy
} -match glob -result {unknown method "find": must be *}
test ooUtil-1.7 {} -setup {
    oo::class create parent
} -body {
    oo::class create Foo {
	superclass parent
	classmethod bar {} {
	    puts "This is in the class; self is [self]"
	    my meee
	}
	classmethod meee {} {
	    puts "This is meee"
	}
    }
    oo::class create Grill {
	superclass Foo
	classmethod meee {} {
	    puts "This is meee 2"
	}
    }
    list [Foo bar] [Grill bar] [[Foo new] bar] [[Grill new] bar]
} -cleanup {
    parent destroy
} -result {{} {} {} {}} -output "This is in the class; self is ::Foo\nThis is meee\nThis is in the class; self is ::Grill\nThis is meee 2\nThis is in the class; self is ::Foo\nThis is meee\nThis is in the class; self is ::Grill\nThis is meee 2\n"
# Two tests to confirm that we correctly initialise the scripted part of TclOO
# in child interpreters. This is slightly tricky at the implementation level
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
    oo::class create parent
} -body {
    ::oo::class create A {
	superclass parent
    }
    ::oo::class create B {
	superclass ::oo::class parent
    	constructor {{definitionScript ""}} {
	    next $definitionScript
	    next {superclass ::A}
	}
    }
    B create C {
	superclass A
    }







|







545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
    oo::class create parent
} -body {
    ::oo::class create A {
	superclass parent
    }
    ::oo::class create B {
	superclass ::oo::class parent
	constructor {{definitionScript ""}} {
	    next $definitionScript
	    next {superclass ::A}
	}
    }
    B create C {
	superclass A
    }
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
    }
} -cleanup {
    namespace delete ooutiltest
    rename animal {}
} -result {::ooutiltest::dog}
test ooUtil-tcllib-ticket-fe7a0e0a3a {classmethod must not interfere with constructor signatures} -setup {
    oo::class create TestClass {
        superclass oo::class
        self method create {name ignore body} {
            next $name $body
        }
    }
} -body {
    TestClass create okay {} {}
} -cleanup {
    rename TestClass {}
} -result {::okay}








|
|
|
|







574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
    }
} -cleanup {
    namespace delete ooutiltest
    rename animal {}
} -result {::ooutiltest::dog}
test ooUtil-tcllib-ticket-fe7a0e0a3a {classmethod must not interfere with constructor signatures} -setup {
    oo::class create TestClass {
	superclass oo::class
	self method create {name ignore body} {
	    next $name $body
	}
    }
} -body {
    TestClass create okay {} {}
} -cleanup {
    rename TestClass {}
} -result {::okay}

Changes to tests/package.test.
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
} -result {1.3}
test pkg-3.53 {Tcl_PkgRequire procedure, picking best stable version} -constraints testpreferstable -setup {
    testpreferstable
    package forget t
    set x xxx
} -body {
    foreach i {1.2b1 1.1} {
        package ifneeded t $i "set x $i; package provide t $i"
    }
    package require t
    set x
} -result {1.1}
test package-3.54 {Tcl_PkgRequire procedure, coroutine support} -setup {
    package forget t
} -body {







|







616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
} -result {1.3}
test pkg-3.53 {Tcl_PkgRequire procedure, picking best stable version} -constraints testpreferstable -setup {
    testpreferstable
    package forget t
    set x xxx
} -body {
    foreach i {1.2b1 1.1} {
	package ifneeded t $i "set x $i; package provide t $i"
    }
    package require t
    set x
} -result {1.1}
test package-3.54 {Tcl_PkgRequire procedure, coroutine support} -setup {
    package forget t
} -body {
Changes to tests/parse.test.
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
    rename ::foo {}
    rename ::unknown {}
    rename unknown.save ::unknown
    set ::info
} [subst {[set level 2; incr level [info level]] global 1 global 1 global}]
test parse-8.12 {Tcl_EvalObjv procedure, TCL_EVAL_INVOKE} {
    set ::auto_index(noSuchCommand) {
        proc noSuchCommand {} {lappend ::info global}
    }
    set ::auto_index(::[string trimleft [namespace current]::test_ns_1::noSuchCommand :]) [list \
        proc [namespace current]::test_ns_1::noSuchCommand {} {
            lappend ::info ns
        }]
    catch {rename ::noSuchCommand {}}
    set ::child [interp create]
    $::child alias bar noSuchCommand
    set ::info {}
    namespace eval test_ns_1 {
        $::child eval bar
    }
    namespace delete test_ns_1
    interp delete $::child
    catch {rename ::noSuchCommand {}}
    set ::info
} global








|


|
|
|





|







418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
    rename ::foo {}
    rename ::unknown {}
    rename unknown.save ::unknown
    set ::info
} [subst {[set level 2; incr level [info level]] global 1 global 1 global}]
test parse-8.12 {Tcl_EvalObjv procedure, TCL_EVAL_INVOKE} {
    set ::auto_index(noSuchCommand) {
	proc noSuchCommand {} {lappend ::info global}
    }
    set ::auto_index(::[string trimleft [namespace current]::test_ns_1::noSuchCommand :]) [list \
	proc [namespace current]::test_ns_1::noSuchCommand {} {
	    lappend ::info ns
	}]
    catch {rename ::noSuchCommand {}}
    set ::child [interp create]
    $::child alias bar noSuchCommand
    set ::info {}
    namespace eval test_ns_1 {
	$::child eval bar
    }
    namespace delete test_ns_1
    interp delete $::child
    catch {rename ::noSuchCommand {}}
    set ::info
} global

Changes to tests/parseExpr.test.
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
    testexprparser "1  + 2" -1
} {- {} 0 subexpr {1  + 2} 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
test parseExpr-1.3 {Tcl_ParseExpr procedure, error getting initial lexeme} testexprparser {
    testexprparser 12345678901234567890 -1
} {- {} 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-1.4 {Tcl_ParseExpr procedure, error in conditional expression} \
    -constraints testexprparser -body {
        testexprparser {foo+} -1
    } -match glob -returnCodes error -result *
test parseExpr-1.5 {Tcl_ParseExpr procedure, lexemes after the expression} -constraints testexprparser -body {
    testexprparser {1+2 345} -1
} -returnCodes error -match glob -result *

test parseExpr-2.1 {ParseCondExpr procedure, valid test subexpr} testexprparser {
    testexprparser {2>3? 1 : 0} -1
} {- {} 0 subexpr {2>3? 1 : 0} 11 operator ? 0 subexpr 2>3 5 operator > 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-2.2 {ParseCondExpr procedure, error in test subexpr} \
	-constraints testexprparser -body {
            testexprparser {0 || foo} -1
    } -match glob -returnCodes error -result *
test parseExpr-2.3 {ParseCondExpr procedure, next lexeme isn't "?"} testexprparser {
    testexprparser {1+2} -1
} {- {} 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
test parseExpr-2.4 {ParseCondExpr procedure, next lexeme is "?"} testexprparser {
    testexprparser {1+2 ? 3 : 4} -1
} {- {} 0 subexpr {1+2 ? 3 : 4} 11 operator ? 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-2.5 {ParseCondExpr procedure, bad lexeme after "?"} testexprparser {
    testexprparser {1+2 ? 12345678901234567890 : 0} -1
} {- {} 0 subexpr {1+2 ? 12345678901234567890 : 0} 11 operator ? 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 subexpr 0 1 text 0 0 {}}
test parseExpr-2.6 {ParseCondExpr procedure, valid "then" subexpression} testexprparser {
    testexprparser {1? 3 : 4} -1
} {- {} 0 subexpr {1? 3 : 4} 7 operator ? 0 subexpr 1 1 text 1 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-2.7 {ParseCondExpr procedure, error in "then" subexpression} \
    -constraints testexprparser -body {
        testexprparser {1? fred : martha} -1
    } -match glob -returnCodes error -result *
test parseExpr-2.8 {ParseCondExpr procedure, lexeme after "then" subexpr isn't ":"} -constraints testexprparser -body {
    testexprparser {1? 2 martha 3} -1
} -returnCodes error -match glob -result *
test parseExpr-2.9 {ParseCondExpr procedure, valid "else" subexpression} testexprparser {
    testexprparser {27||3? 3 : 4&&9} -1
} {- {} 0 subexpr {27||3? 3 : 4&&9} 15 operator ? 0 subexpr 27||3 5 operator || 0 subexpr 27 1 text 27 0 subexpr 3 1 text 3 0 subexpr 3 1 text 3 0 subexpr 4&&9 5 operator && 0 subexpr 4 1 text 4 0 subexpr 9 1 text 9 0 {}}
test parseExpr-2.10 {ParseCondExpr procedure, error in "else" subexpression} \
    -constraints testexprparser -body {
        testexprparser {1? 2 : martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-3.1 {ParseLorExpr procedure, valid logical and subexpr} testexprparser {
    testexprparser {1&&2 || 3} -1
} {- {} 0 subexpr {1&&2 || 3} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-3.2 {ParseLorExpr procedure, error in logical and subexpr} \
    -constraints testexprparser -body {
        testexprparser {1&&foo || 3} -1
    } -match glob -returnCodes error -result *
test parseExpr-3.3 {ParseLorExpr procedure, next lexeme isn't "||"} testexprparser {
    testexprparser {1&&2? 1 : 0} -1
} {- {} 0 subexpr {1&&2? 1 : 0} 11 operator ? 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-3.4 {ParseLorExpr procedure, next lexeme is "||"} testexprparser {
    testexprparser {1&&2 || 3} -1
} {- {} 0 subexpr {1&&2 || 3} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-3.5 {ParseLorExpr procedure, bad lexeme after "||"} testexprparser {
    testexprparser {1&&2 || 12345678901234567890} -1
} {- {} 0 subexpr {1&&2 || 12345678901234567890} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-3.6 {ParseLorExpr procedure, valid RHS subexpression} testexprparser {
    testexprparser {1&&2 || 3 || 4} -1
} {- {} 0 subexpr {1&&2 || 3 || 4} 13 operator || 0 subexpr {1&&2 || 3} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-3.7 {ParseLorExpr procedure, error in RHS subexpression} \
    -constraints testexprparser -body {
        testexprparser {1&&2 || 3 || martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-4.1 {ParseLandExpr procedure, valid LHS "|" subexpr} testexprparser {
    testexprparser {1|2 && 3} -1
} {- {} 0 subexpr {1|2 && 3} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-4.2 {ParseLandExpr procedure, error in LHS "|" subexpr} \
    -constraints testexprparser -body {
        testexprparser {1&&foo && 3} -1
    } -match glob -returnCodes error -result *
test parseExpr-4.3 {ParseLandExpr procedure, next lexeme isn't "&&"} testexprparser {
    testexprparser {1|2? 1 : 0} -1
} {- {} 0 subexpr {1|2? 1 : 0} 11 operator ? 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-4.4 {ParseLandExpr procedure, next lexeme is "&&"} testexprparser {
    testexprparser {1|2 && 3} -1
} {- {} 0 subexpr {1|2 && 3} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-4.5 {ParseLandExpr procedure, bad lexeme after "&&"} testexprparser {
    testexprparser {1|2 && 12345678901234567890} -1
} {- {} 0 subexpr {1|2 && 12345678901234567890} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-4.6 {ParseLandExpr procedure, valid RHS subexpression} testexprparser {
    testexprparser {1|2 && 3 && 4} -1
} {- {} 0 subexpr {1|2 && 3 && 4} 13 operator && 0 subexpr {1|2 && 3} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-4.7 {ParseLandExpr procedure, error in RHS subexpression} \
    -constraints testexprparser -body {
        testexprparser {1|2 && 3 && martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-5.1 {ParseBitOrExpr procedure, valid LHS "^" subexpr} testexprparser {
    testexprparser {1^2 | 3} -1
} {- {} 0 subexpr {1^2 | 3} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-5.2 {ParseBitOrExpr procedure, error in LHS "^" subexpr} \
    -constraints testexprparser -body {
        testexprparser {1|foo | 3} -1
    } -match glob -returnCodes error -result *
test parseExpr-5.3 {ParseBitOrExpr procedure, next lexeme isn't "|"} testexprparser {
    testexprparser {1^2? 1 : 0} -1
} {- {} 0 subexpr {1^2? 1 : 0} 11 operator ? 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-5.4 {ParseBitOrExpr procedure, next lexeme is "|"} testexprparser {
    testexprparser {1^2 | 3} -1
} {- {} 0 subexpr {1^2 | 3} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-5.5 {ParseBitOrExpr procedure, bad lexeme after "|"} testexprparser {
    testexprparser {1^2 | 12345678901234567890} -1
} {- {} 0 subexpr {1^2 | 12345678901234567890} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-5.6 {ParseBitOrExpr procedure, valid RHS subexpression} testexprparser {
    testexprparser {1^2 | 3 | 4} -1
} {- {} 0 subexpr {1^2 | 3 | 4} 13 operator | 0 subexpr {1^2 | 3} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-5.7 {ParseBitOrExpr procedure, error in RHS subexpression} \
    -constraints testexprparser -body {
        testexprparser {1^2 | 3 | martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-6.1 {ParseBitXorExpr procedure, valid LHS "&" subexpr} testexprparser {
    testexprparser {1&2 ^ 3} -1
} {- {} 0 subexpr {1&2 ^ 3} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-6.2 {ParseBitXorExpr procedure, error in LHS "&" subexpr} \
    -constraints testexprparser -body {
        testexprparser {1^foo ^ 3} -1
    } -match glob -returnCodes error -result *
test parseExpr-6.3 {ParseBitXorExpr procedure, next lexeme isn't "^"} testexprparser {
    testexprparser {1&2? 1 : 0} -1
} {- {} 0 subexpr {1&2? 1 : 0} 11 operator ? 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-6.4 {ParseBitXorExpr procedure, next lexeme is "^"} testexprparser {
    testexprparser {1&2 ^ 3} -1
} {- {} 0 subexpr {1&2 ^ 3} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-6.5 {ParseBitXorExpr procedure, bad lexeme after "^"} testexprparser {
    testexprparser {1&2 ^ 12345678901234567890} -1
} {- {} 0 subexpr {1&2 ^ 12345678901234567890} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-6.6 {ParseBitXorExpr procedure, valid RHS subexpression} testexprparser {
    testexprparser {1&2 ^ 3 ^ 4} -1
} {- {} 0 subexpr {1&2 ^ 3 ^ 4} 13 operator ^ 0 subexpr {1&2 ^ 3} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-6.7 {ParseBitXorExpr procedure, error in RHS subexpression} \
    -constraints testexprparser -body {
        testexprparser {1&2 ^ 3 ^ martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-7.1 {ParseBitAndExpr procedure, valid LHS equality subexpr} testexprparser {
    testexprparser {1==2 & 3} -1
} {- {} 0 subexpr {1==2 & 3} 9 operator & 0 subexpr 1==2 5 operator == 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-7.2 {ParseBitAndExpr procedure, error in LHS equality subexpr} \
    -constraints testexprparser -body {
        testexprparser {1!=foo & 3} -1
    } -match glob -returnCodes error -result *
test parseExpr-7.3 {ParseBitAndExpr procedure, next lexeme isn't "&"} testexprparser {
    testexprparser {1==2? 1 : 0} -1
} {- {} 0 subexpr {1==2? 1 : 0} 11 operator ? 0 subexpr 1==2 5 operator == 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-7.4 {ParseBitAndExpr procedure, next lexeme is "&"} testexprparser {
    testexprparser {1>2 & 3} -1
} {- {} 0 subexpr {1>2 & 3} 9 operator & 0 subexpr 1>2 5 operator > 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-7.5 {ParseBitAndExpr procedure, bad lexeme after "&"} {testexprparser} {
    testexprparser {1==2 & 12345678901234567890} -1
} {- {} 0 subexpr {1==2 & 12345678901234567890} 9 operator & 0 subexpr 1==2 5 operator == 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-7.6 {ParseBitAndExpr procedure, valid RHS subexpression} testexprparser {
    testexprparser {1<2 & 3 & 4} -1
} {- {} 0 subexpr {1<2 & 3 & 4} 13 operator & 0 subexpr {1<2 & 3} 9 operator & 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-7.7 {ParseBitAndExpr procedure, error in RHS subexpression} \
    -constraints testexprparser -body {
        testexprparser {1==2 & 3>2 & martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-8.1 {ParseEqualityExpr procedure, valid LHS relational subexpr} testexprparser {
    testexprparser {1<2 == 3} -1
} {- {} 0 subexpr {1<2 == 3} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-8.2 {ParseEqualityExpr procedure, error in LHS relational subexpr} \
    -constraints testexprparser -body {
        testexprparser {1>=foo == 3} -1
    } -match glob -returnCodes error -result *
test parseExpr-8.3 {ParseEqualityExpr procedure, next lexeme isn't "==" or "!="} testexprparser {
    testexprparser {1<2? 1 : 0} -1
} {- {} 0 subexpr {1<2? 1 : 0} 11 operator ? 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-8.4 {ParseEqualityExpr procedure, next lexeme is "==" or "!="} testexprparser {
    testexprparser {1<2 == 3} -1
} {- {} 0 subexpr {1<2 == 3} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-8.5 {ParseEqualityExpr procedure, next lexeme is "==" or "!="} testexprparser {
    testexprparser {1<2 != 3} -1
} {- {} 0 subexpr {1<2 != 3} 9 operator != 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-8.6 {ParseEqualityExpr procedure, bad lexeme after "==" or "!="} testexprparser {
    testexprparser {1<2 == 12345678901234567890} -1
} {- {} 0 subexpr {1<2 == 12345678901234567890} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-8.7 {ParseEqualityExpr procedure, valid RHS subexpression} testexprparser {
    testexprparser {1<2 == 3 == 4} -1
} {- {} 0 subexpr {1<2 == 3 == 4} 13 operator == 0 subexpr {1<2 == 3} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-8.8 {ParseEqualityExpr procedure, error in RHS subexpression} \
    -constraints testexprparser -body {
        testexprparser {1<2 == 3 != martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-9.1 {ParseRelationalExpr procedure, valid LHS shift subexpr} testexprparser {
    testexprparser {1<<2 < 3} -1
} {- {} 0 subexpr {1<<2 < 3} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-9.2 {ParseRelationalExpr procedure, error in LHS shift subexpr} \
    -constraints testexprparser -body {
        testexprparser {1>=foo < 3} -1
    } -match glob -returnCodes error -result *
test parseExpr-9.3 {ParseRelationalExpr procedure, next lexeme isn't relational op} testexprparser {
    testexprparser {1<<2? 1 : 0} -1
} {- {} 0 subexpr {1<<2? 1 : 0} 11 operator ? 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-9.4 {ParseRelationalExpr procedure, next lexeme is relational op} testexprparser {
    testexprparser {1<<2 < 3} -1
} {- {} 0 subexpr {1<<2 < 3} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}







|










|















|









|







|















|







|















|







|















|







|















|







|















|







|


















|







|







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
    testexprparser "1  + 2" -1
} {- {} 0 subexpr {1  + 2} 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
test parseExpr-1.3 {Tcl_ParseExpr procedure, error getting initial lexeme} testexprparser {
    testexprparser 12345678901234567890 -1
} {- {} 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-1.4 {Tcl_ParseExpr procedure, error in conditional expression} \
    -constraints testexprparser -body {
	testexprparser {foo+} -1
    } -match glob -returnCodes error -result *
test parseExpr-1.5 {Tcl_ParseExpr procedure, lexemes after the expression} -constraints testexprparser -body {
    testexprparser {1+2 345} -1
} -returnCodes error -match glob -result *

test parseExpr-2.1 {ParseCondExpr procedure, valid test subexpr} testexprparser {
    testexprparser {2>3? 1 : 0} -1
} {- {} 0 subexpr {2>3? 1 : 0} 11 operator ? 0 subexpr 2>3 5 operator > 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-2.2 {ParseCondExpr procedure, error in test subexpr} \
	-constraints testexprparser -body {
	    testexprparser {0 || foo} -1
    } -match glob -returnCodes error -result *
test parseExpr-2.3 {ParseCondExpr procedure, next lexeme isn't "?"} testexprparser {
    testexprparser {1+2} -1
} {- {} 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
test parseExpr-2.4 {ParseCondExpr procedure, next lexeme is "?"} testexprparser {
    testexprparser {1+2 ? 3 : 4} -1
} {- {} 0 subexpr {1+2 ? 3 : 4} 11 operator ? 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-2.5 {ParseCondExpr procedure, bad lexeme after "?"} testexprparser {
    testexprparser {1+2 ? 12345678901234567890 : 0} -1
} {- {} 0 subexpr {1+2 ? 12345678901234567890 : 0} 11 operator ? 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 subexpr 0 1 text 0 0 {}}
test parseExpr-2.6 {ParseCondExpr procedure, valid "then" subexpression} testexprparser {
    testexprparser {1? 3 : 4} -1
} {- {} 0 subexpr {1? 3 : 4} 7 operator ? 0 subexpr 1 1 text 1 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-2.7 {ParseCondExpr procedure, error in "then" subexpression} \
    -constraints testexprparser -body {
	testexprparser {1? fred : martha} -1
    } -match glob -returnCodes error -result *
test parseExpr-2.8 {ParseCondExpr procedure, lexeme after "then" subexpr isn't ":"} -constraints testexprparser -body {
    testexprparser {1? 2 martha 3} -1
} -returnCodes error -match glob -result *
test parseExpr-2.9 {ParseCondExpr procedure, valid "else" subexpression} testexprparser {
    testexprparser {27||3? 3 : 4&&9} -1
} {- {} 0 subexpr {27||3? 3 : 4&&9} 15 operator ? 0 subexpr 27||3 5 operator || 0 subexpr 27 1 text 27 0 subexpr 3 1 text 3 0 subexpr 3 1 text 3 0 subexpr 4&&9 5 operator && 0 subexpr 4 1 text 4 0 subexpr 9 1 text 9 0 {}}
test parseExpr-2.10 {ParseCondExpr procedure, error in "else" subexpression} \
    -constraints testexprparser -body {
	testexprparser {1? 2 : martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-3.1 {ParseLorExpr procedure, valid logical and subexpr} testexprparser {
    testexprparser {1&&2 || 3} -1
} {- {} 0 subexpr {1&&2 || 3} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-3.2 {ParseLorExpr procedure, error in logical and subexpr} \
    -constraints testexprparser -body {
	testexprparser {1&&foo || 3} -1
    } -match glob -returnCodes error -result *
test parseExpr-3.3 {ParseLorExpr procedure, next lexeme isn't "||"} testexprparser {
    testexprparser {1&&2? 1 : 0} -1
} {- {} 0 subexpr {1&&2? 1 : 0} 11 operator ? 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-3.4 {ParseLorExpr procedure, next lexeme is "||"} testexprparser {
    testexprparser {1&&2 || 3} -1
} {- {} 0 subexpr {1&&2 || 3} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-3.5 {ParseLorExpr procedure, bad lexeme after "||"} testexprparser {
    testexprparser {1&&2 || 12345678901234567890} -1
} {- {} 0 subexpr {1&&2 || 12345678901234567890} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-3.6 {ParseLorExpr procedure, valid RHS subexpression} testexprparser {
    testexprparser {1&&2 || 3 || 4} -1
} {- {} 0 subexpr {1&&2 || 3 || 4} 13 operator || 0 subexpr {1&&2 || 3} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-3.7 {ParseLorExpr procedure, error in RHS subexpression} \
    -constraints testexprparser -body {
	testexprparser {1&&2 || 3 || martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-4.1 {ParseLandExpr procedure, valid LHS "|" subexpr} testexprparser {
    testexprparser {1|2 && 3} -1
} {- {} 0 subexpr {1|2 && 3} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-4.2 {ParseLandExpr procedure, error in LHS "|" subexpr} \
    -constraints testexprparser -body {
	testexprparser {1&&foo && 3} -1
    } -match glob -returnCodes error -result *
test parseExpr-4.3 {ParseLandExpr procedure, next lexeme isn't "&&"} testexprparser {
    testexprparser {1|2? 1 : 0} -1
} {- {} 0 subexpr {1|2? 1 : 0} 11 operator ? 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-4.4 {ParseLandExpr procedure, next lexeme is "&&"} testexprparser {
    testexprparser {1|2 && 3} -1
} {- {} 0 subexpr {1|2 && 3} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-4.5 {ParseLandExpr procedure, bad lexeme after "&&"} testexprparser {
    testexprparser {1|2 && 12345678901234567890} -1
} {- {} 0 subexpr {1|2 && 12345678901234567890} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-4.6 {ParseLandExpr procedure, valid RHS subexpression} testexprparser {
    testexprparser {1|2 && 3 && 4} -1
} {- {} 0 subexpr {1|2 && 3 && 4} 13 operator && 0 subexpr {1|2 && 3} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-4.7 {ParseLandExpr procedure, error in RHS subexpression} \
    -constraints testexprparser -body {
	testexprparser {1|2 && 3 && martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-5.1 {ParseBitOrExpr procedure, valid LHS "^" subexpr} testexprparser {
    testexprparser {1^2 | 3} -1
} {- {} 0 subexpr {1^2 | 3} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-5.2 {ParseBitOrExpr procedure, error in LHS "^" subexpr} \
    -constraints testexprparser -body {
	testexprparser {1|foo | 3} -1
    } -match glob -returnCodes error -result *
test parseExpr-5.3 {ParseBitOrExpr procedure, next lexeme isn't "|"} testexprparser {
    testexprparser {1^2? 1 : 0} -1
} {- {} 0 subexpr {1^2? 1 : 0} 11 operator ? 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-5.4 {ParseBitOrExpr procedure, next lexeme is "|"} testexprparser {
    testexprparser {1^2 | 3} -1
} {- {} 0 subexpr {1^2 | 3} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-5.5 {ParseBitOrExpr procedure, bad lexeme after "|"} testexprparser {
    testexprparser {1^2 | 12345678901234567890} -1
} {- {} 0 subexpr {1^2 | 12345678901234567890} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-5.6 {ParseBitOrExpr procedure, valid RHS subexpression} testexprparser {
    testexprparser {1^2 | 3 | 4} -1
} {- {} 0 subexpr {1^2 | 3 | 4} 13 operator | 0 subexpr {1^2 | 3} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-5.7 {ParseBitOrExpr procedure, error in RHS subexpression} \
    -constraints testexprparser -body {
	testexprparser {1^2 | 3 | martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-6.1 {ParseBitXorExpr procedure, valid LHS "&" subexpr} testexprparser {
    testexprparser {1&2 ^ 3} -1
} {- {} 0 subexpr {1&2 ^ 3} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-6.2 {ParseBitXorExpr procedure, error in LHS "&" subexpr} \
    -constraints testexprparser -body {
	testexprparser {1^foo ^ 3} -1
    } -match glob -returnCodes error -result *
test parseExpr-6.3 {ParseBitXorExpr procedure, next lexeme isn't "^"} testexprparser {
    testexprparser {1&2? 1 : 0} -1
} {- {} 0 subexpr {1&2? 1 : 0} 11 operator ? 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-6.4 {ParseBitXorExpr procedure, next lexeme is "^"} testexprparser {
    testexprparser {1&2 ^ 3} -1
} {- {} 0 subexpr {1&2 ^ 3} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-6.5 {ParseBitXorExpr procedure, bad lexeme after "^"} testexprparser {
    testexprparser {1&2 ^ 12345678901234567890} -1
} {- {} 0 subexpr {1&2 ^ 12345678901234567890} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-6.6 {ParseBitXorExpr procedure, valid RHS subexpression} testexprparser {
    testexprparser {1&2 ^ 3 ^ 4} -1
} {- {} 0 subexpr {1&2 ^ 3 ^ 4} 13 operator ^ 0 subexpr {1&2 ^ 3} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-6.7 {ParseBitXorExpr procedure, error in RHS subexpression} \
    -constraints testexprparser -body {
	testexprparser {1&2 ^ 3 ^ martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-7.1 {ParseBitAndExpr procedure, valid LHS equality subexpr} testexprparser {
    testexprparser {1==2 & 3} -1
} {- {} 0 subexpr {1==2 & 3} 9 operator & 0 subexpr 1==2 5 operator == 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-7.2 {ParseBitAndExpr procedure, error in LHS equality subexpr} \
    -constraints testexprparser -body {
	testexprparser {1!=foo & 3} -1
    } -match glob -returnCodes error -result *
test parseExpr-7.3 {ParseBitAndExpr procedure, next lexeme isn't "&"} testexprparser {
    testexprparser {1==2? 1 : 0} -1
} {- {} 0 subexpr {1==2? 1 : 0} 11 operator ? 0 subexpr 1==2 5 operator == 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-7.4 {ParseBitAndExpr procedure, next lexeme is "&"} testexprparser {
    testexprparser {1>2 & 3} -1
} {- {} 0 subexpr {1>2 & 3} 9 operator & 0 subexpr 1>2 5 operator > 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-7.5 {ParseBitAndExpr procedure, bad lexeme after "&"} {testexprparser} {
    testexprparser {1==2 & 12345678901234567890} -1
} {- {} 0 subexpr {1==2 & 12345678901234567890} 9 operator & 0 subexpr 1==2 5 operator == 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-7.6 {ParseBitAndExpr procedure, valid RHS subexpression} testexprparser {
    testexprparser {1<2 & 3 & 4} -1
} {- {} 0 subexpr {1<2 & 3 & 4} 13 operator & 0 subexpr {1<2 & 3} 9 operator & 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-7.7 {ParseBitAndExpr procedure, error in RHS subexpression} \
    -constraints testexprparser -body {
	testexprparser {1==2 & 3>2 & martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-8.1 {ParseEqualityExpr procedure, valid LHS relational subexpr} testexprparser {
    testexprparser {1<2 == 3} -1
} {- {} 0 subexpr {1<2 == 3} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-8.2 {ParseEqualityExpr procedure, error in LHS relational subexpr} \
    -constraints testexprparser -body {
	testexprparser {1>=foo == 3} -1
    } -match glob -returnCodes error -result *
test parseExpr-8.3 {ParseEqualityExpr procedure, next lexeme isn't "==" or "!="} testexprparser {
    testexprparser {1<2? 1 : 0} -1
} {- {} 0 subexpr {1<2? 1 : 0} 11 operator ? 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-8.4 {ParseEqualityExpr procedure, next lexeme is "==" or "!="} testexprparser {
    testexprparser {1<2 == 3} -1
} {- {} 0 subexpr {1<2 == 3} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-8.5 {ParseEqualityExpr procedure, next lexeme is "==" or "!="} testexprparser {
    testexprparser {1<2 != 3} -1
} {- {} 0 subexpr {1<2 != 3} 9 operator != 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-8.6 {ParseEqualityExpr procedure, bad lexeme after "==" or "!="} testexprparser {
    testexprparser {1<2 == 12345678901234567890} -1
} {- {} 0 subexpr {1<2 == 12345678901234567890} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-8.7 {ParseEqualityExpr procedure, valid RHS subexpression} testexprparser {
    testexprparser {1<2 == 3 == 4} -1
} {- {} 0 subexpr {1<2 == 3 == 4} 13 operator == 0 subexpr {1<2 == 3} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-8.8 {ParseEqualityExpr procedure, error in RHS subexpression} \
    -constraints testexprparser -body {
	testexprparser {1<2 == 3 != martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-9.1 {ParseRelationalExpr procedure, valid LHS shift subexpr} testexprparser {
    testexprparser {1<<2 < 3} -1
} {- {} 0 subexpr {1<<2 < 3} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-9.2 {ParseRelationalExpr procedure, error in LHS shift subexpr} \
    -constraints testexprparser -body {
	testexprparser {1>=foo < 3} -1
    } -match glob -returnCodes error -result *
test parseExpr-9.3 {ParseRelationalExpr procedure, next lexeme isn't relational op} testexprparser {
    testexprparser {1<<2? 1 : 0} -1
} {- {} 0 subexpr {1<<2? 1 : 0} 11 operator ? 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-9.4 {ParseRelationalExpr procedure, next lexeme is relational op} testexprparser {
    testexprparser {1<<2 < 3} -1
} {- {} 0 subexpr {1<<2 < 3} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
    testexprparser {1<<2 < 12345678901234567890} -1
} {- {} 0 subexpr {1<<2 < 12345678901234567890} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-9.9 {ParseRelationalExpr procedure, valid RHS subexpression} testexprparser {
    testexprparser {1<<2 < 3 < 4} -1
} {- {} 0 subexpr {1<<2 < 3 < 4} 13 operator < 0 subexpr {1<<2 < 3} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-9.10 {ParseRelationalExpr procedure, error in RHS subexpression} \
    -constraints testexprparser -body {
        testexprparser {1<<2 < 3 > martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-10.1 {ParseShiftExpr procedure, valid LHS add subexpr} testexprparser {
    testexprparser {1+2 << 3} -1
} {- {} 0 subexpr {1+2 << 3} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-10.2 {ParseShiftExpr procedure, error in LHS add subexpr} \
    -constraints testexprparser -body {
        testexprparser {1-foo << 3} -1
    } -match glob -returnCodes error -result *
test parseExpr-10.3 {ParseShiftExpr procedure, next lexeme isn't "<<" or ">>"} testexprparser {
    testexprparser {1+2? 1 : 0} -1
} {- {} 0 subexpr {1+2? 1 : 0} 11 operator ? 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-10.4 {ParseShiftExpr procedure, next lexeme is "<<" or ">>"} testexprparser {
    testexprparser {1+2 << 3} -1
} {- {} 0 subexpr {1+2 << 3} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-10.5 {ParseShiftExpr procedure, next lexeme is "<<" or ">>"} testexprparser {
    testexprparser {1+2 >> 3} -1
} {- {} 0 subexpr {1+2 >> 3} 9 operator >> 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-10.6 {ParseShiftExpr procedure, bad lexeme after "<<" or ">>"} testexprparser {
    testexprparser {1+2 << 12345678901234567890} -1
} {- {} 0 subexpr {1+2 << 12345678901234567890} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-10.7 {ParseShiftExpr procedure, valid RHS subexpression} testexprparser {
    testexprparser {1+2 << 3 << 4} -1
} {- {} 0 subexpr {1+2 << 3 << 4} 13 operator << 0 subexpr {1+2 << 3} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-10.8 {ParseShiftExpr procedure, error in RHS subexpression} \
    -constraints testexprparser -body {
        testexprparser {1+2 << 3 >> martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-11.1 {ParseAddExpr procedure, valid LHS multiply subexpr} testexprparser {
    testexprparser {1*2 + 3} -1
} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-11.2 {ParseAddExpr procedure, error in LHS multiply subexpr} \
    -constraints testexprparser -body {
        testexprparser {1/foo + 3} -1
    } -match glob -returnCodes error -result *
test parseExpr-11.3 {ParseAddExpr procedure, next lexeme isn't "+" or "-"} testexprparser {
    testexprparser {1*2? 1 : 0} -1
} {- {} 0 subexpr {1*2? 1 : 0} 11 operator ? 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-11.4 {ParseAddExpr procedure, next lexeme is "+" or "-"} testexprparser {
    testexprparser {1*2 + 3} -1
} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-11.5 {ParseAddExpr procedure, next lexeme is "+" or "-"} testexprparser {
    testexprparser {1*2 - 3} -1
} {- {} 0 subexpr {1*2 - 3} 9 operator - 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-11.6 {ParseAddExpr procedure, bad lexeme after "+" or "-"} testexprparser {
    testexprparser {1*2 + 12345678901234567890} -1
} {- {} 0 subexpr {1*2 + 12345678901234567890} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-11.7 {ParseAddExpr procedure, valid RHS subexpression} testexprparser {
    testexprparser {1*2 + 3 + 4} -1
} {- {} 0 subexpr {1*2 + 3 + 4} 13 operator + 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-11.8 {ParseAddExpr procedure, error in RHS subexpression} \
    -constraints testexprparser -body {
        testexprparser {1*2 + 3 - martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-12.1 {ParseAddExpr procedure, valid LHS multiply subexpr} testexprparser {
    testexprparser {1*2 + 3} -1
} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-12.2 {ParseAddExpr procedure, error in LHS multiply subexpr} \
    -constraints testexprparser -body {
        testexprparser {1/foo + 3} -1
    } -match glob -returnCodes error -result *
test parseExpr-12.3 {ParseAddExpr procedure, next lexeme isn't "+" or "-"} testexprparser {
    testexprparser {1*2? 1 : 0} -1
} {- {} 0 subexpr {1*2? 1 : 0} 11 operator ? 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-12.4 {ParseAddExpr procedure, next lexeme is "+" or "-"} testexprparser {
    testexprparser {1*2 + 3} -1
} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-12.5 {ParseAddExpr procedure, next lexeme is "+" or "-"} testexprparser {
    testexprparser {1*2 - 3} -1
} {- {} 0 subexpr {1*2 - 3} 9 operator - 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-12.6 {ParseAddExpr procedure, bad lexeme after "+" or "-"} testexprparser {
    testexprparser {1*2 + 12345678901234567890} -1
} {- {} 0 subexpr {1*2 + 12345678901234567890} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-12.7 {ParseAddExpr procedure, valid RHS subexpression} testexprparser {
    testexprparser {1*2 + 3 + 4} -1
} {- {} 0 subexpr {1*2 + 3 + 4} 13 operator + 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-12.8 {ParseAddExpr procedure, error in RHS subexpression} \
    -constraints testexprparser -body {
        testexprparser {1*2 + 3 - martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-13.1 {ParseMultiplyExpr procedure, valid LHS unary subexpr} testexprparser {
    testexprparser {+2 * 3} -1
} {- {} 0 subexpr {+2 * 3} 7 operator * 0 subexpr +2 3 operator + 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-13.2 {ParseMultiplyExpr procedure, error in LHS unary subexpr} testexprparser {
    testexprparser {-12345678901234567890 * 3} -1







|







|


















|







|


















|







|


















|







308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
    testexprparser {1<<2 < 12345678901234567890} -1
} {- {} 0 subexpr {1<<2 < 12345678901234567890} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-9.9 {ParseRelationalExpr procedure, valid RHS subexpression} testexprparser {
    testexprparser {1<<2 < 3 < 4} -1
} {- {} 0 subexpr {1<<2 < 3 < 4} 13 operator < 0 subexpr {1<<2 < 3} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-9.10 {ParseRelationalExpr procedure, error in RHS subexpression} \
    -constraints testexprparser -body {
	testexprparser {1<<2 < 3 > martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-10.1 {ParseShiftExpr procedure, valid LHS add subexpr} testexprparser {
    testexprparser {1+2 << 3} -1
} {- {} 0 subexpr {1+2 << 3} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-10.2 {ParseShiftExpr procedure, error in LHS add subexpr} \
    -constraints testexprparser -body {
	testexprparser {1-foo << 3} -1
    } -match glob -returnCodes error -result *
test parseExpr-10.3 {ParseShiftExpr procedure, next lexeme isn't "<<" or ">>"} testexprparser {
    testexprparser {1+2? 1 : 0} -1
} {- {} 0 subexpr {1+2? 1 : 0} 11 operator ? 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-10.4 {ParseShiftExpr procedure, next lexeme is "<<" or ">>"} testexprparser {
    testexprparser {1+2 << 3} -1
} {- {} 0 subexpr {1+2 << 3} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-10.5 {ParseShiftExpr procedure, next lexeme is "<<" or ">>"} testexprparser {
    testexprparser {1+2 >> 3} -1
} {- {} 0 subexpr {1+2 >> 3} 9 operator >> 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-10.6 {ParseShiftExpr procedure, bad lexeme after "<<" or ">>"} testexprparser {
    testexprparser {1+2 << 12345678901234567890} -1
} {- {} 0 subexpr {1+2 << 12345678901234567890} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-10.7 {ParseShiftExpr procedure, valid RHS subexpression} testexprparser {
    testexprparser {1+2 << 3 << 4} -1
} {- {} 0 subexpr {1+2 << 3 << 4} 13 operator << 0 subexpr {1+2 << 3} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-10.8 {ParseShiftExpr procedure, error in RHS subexpression} \
    -constraints testexprparser -body {
	testexprparser {1+2 << 3 >> martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-11.1 {ParseAddExpr procedure, valid LHS multiply subexpr} testexprparser {
    testexprparser {1*2 + 3} -1
} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-11.2 {ParseAddExpr procedure, error in LHS multiply subexpr} \
    -constraints testexprparser -body {
	testexprparser {1/foo + 3} -1
    } -match glob -returnCodes error -result *
test parseExpr-11.3 {ParseAddExpr procedure, next lexeme isn't "+" or "-"} testexprparser {
    testexprparser {1*2? 1 : 0} -1
} {- {} 0 subexpr {1*2? 1 : 0} 11 operator ? 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-11.4 {ParseAddExpr procedure, next lexeme is "+" or "-"} testexprparser {
    testexprparser {1*2 + 3} -1
} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-11.5 {ParseAddExpr procedure, next lexeme is "+" or "-"} testexprparser {
    testexprparser {1*2 - 3} -1
} {- {} 0 subexpr {1*2 - 3} 9 operator - 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-11.6 {ParseAddExpr procedure, bad lexeme after "+" or "-"} testexprparser {
    testexprparser {1*2 + 12345678901234567890} -1
} {- {} 0 subexpr {1*2 + 12345678901234567890} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-11.7 {ParseAddExpr procedure, valid RHS subexpression} testexprparser {
    testexprparser {1*2 + 3 + 4} -1
} {- {} 0 subexpr {1*2 + 3 + 4} 13 operator + 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-11.8 {ParseAddExpr procedure, error in RHS subexpression} \
    -constraints testexprparser -body {
	testexprparser {1*2 + 3 - martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-12.1 {ParseAddExpr procedure, valid LHS multiply subexpr} testexprparser {
    testexprparser {1*2 + 3} -1
} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-12.2 {ParseAddExpr procedure, error in LHS multiply subexpr} \
    -constraints testexprparser -body {
	testexprparser {1/foo + 3} -1
    } -match glob -returnCodes error -result *
test parseExpr-12.3 {ParseAddExpr procedure, next lexeme isn't "+" or "-"} testexprparser {
    testexprparser {1*2? 1 : 0} -1
} {- {} 0 subexpr {1*2? 1 : 0} 11 operator ? 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-12.4 {ParseAddExpr procedure, next lexeme is "+" or "-"} testexprparser {
    testexprparser {1*2 + 3} -1
} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-12.5 {ParseAddExpr procedure, next lexeme is "+" or "-"} testexprparser {
    testexprparser {1*2 - 3} -1
} {- {} 0 subexpr {1*2 - 3} 9 operator - 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-12.6 {ParseAddExpr procedure, bad lexeme after "+" or "-"} testexprparser {
    testexprparser {1*2 + 12345678901234567890} -1
} {- {} 0 subexpr {1*2 + 12345678901234567890} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-12.7 {ParseAddExpr procedure, valid RHS subexpression} testexprparser {
    testexprparser {1*2 + 3 + 4} -1
} {- {} 0 subexpr {1*2 + 3 + 4} 13 operator + 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-12.8 {ParseAddExpr procedure, error in RHS subexpression} \
    -constraints testexprparser -body {
	testexprparser {1*2 + 3 - martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-13.1 {ParseMultiplyExpr procedure, valid LHS unary subexpr} testexprparser {
    testexprparser {+2 * 3} -1
} {- {} 0 subexpr {+2 * 3} 7 operator * 0 subexpr +2 3 operator + 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-13.2 {ParseMultiplyExpr procedure, error in LHS unary subexpr} testexprparser {
    testexprparser {-12345678901234567890 * 3} -1
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
    testexprparser {--++5 / 12345678901234567890} -1
} {- {} 0 subexpr {--++5 / 12345678901234567890} 13 operator / 0 subexpr --++5 9 operator - 0 subexpr -++5 7 operator - 0 subexpr ++5 5 operator + 0 subexpr +5 3 operator + 0 subexpr 5 1 text 5 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-13.8 {ParseMultiplyExpr procedure, valid RHS subexpression} testexprparser {
    testexprparser {-2 / 3 % 4} -1
} {- {} 0 subexpr {-2 / 3 % 4} 11 operator % 0 subexpr {-2 / 3} 7 operator / 0 subexpr -2 3 operator - 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-13.9 {ParseMultiplyExpr procedure, error in RHS subexpression} \
    -constraints testexprparser -body {
        testexprparser {++2 / 3 * martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-14.1 {ParseUnaryExpr procedure, first token is unary operator} testexprparser {
    testexprparser {+2} -1
} {- {} 0 subexpr +2 3 operator + 0 subexpr 2 1 text 2 0 {}}
test parseExpr-14.2 {ParseUnaryExpr procedure, first token is unary operator} testexprparser {
    testexprparser {-2} -1







|







418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
    testexprparser {--++5 / 12345678901234567890} -1
} {- {} 0 subexpr {--++5 / 12345678901234567890} 13 operator / 0 subexpr --++5 9 operator - 0 subexpr -++5 7 operator - 0 subexpr ++5 5 operator + 0 subexpr +5 3 operator + 0 subexpr 5 1 text 5 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-13.8 {ParseMultiplyExpr procedure, valid RHS subexpression} testexprparser {
    testexprparser {-2 / 3 % 4} -1
} {- {} 0 subexpr {-2 / 3 % 4} 11 operator % 0 subexpr {-2 / 3} 7 operator / 0 subexpr -2 3 operator - 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-13.9 {ParseMultiplyExpr procedure, error in RHS subexpression} \
    -constraints testexprparser -body {
	testexprparser {++2 / 3 * martha} -1
    } -match glob -returnCodes error -result *

test parseExpr-14.1 {ParseUnaryExpr procedure, first token is unary operator} testexprparser {
    testexprparser {+2} -1
} {- {} 0 subexpr +2 3 operator + 0 subexpr 2 1 text 2 0 {}}
test parseExpr-14.2 {ParseUnaryExpr procedure, first token is unary operator} testexprparser {
    testexprparser {-2} -1
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
    testexprparser {foo(123)} -1
} {- {} 0 subexpr foo(123) 3 operator foo 0 subexpr 123 1 text 123 0 {}}
test parseExpr-15.23 {ParsePrimaryExpr procedure, bad lexeme after function name} -constraints testexprparser -body {
    testexprparser {foo 12345678901234567890 123)} -1
} -returnCodes error -match glob -result *
test parseExpr-15.24 {ParsePrimaryExpr procedure, lexeme after function name isn't "("} \
    -constraints testexprparser -body {
        testexprparser {foo 27.4 123)} -1
    } -match glob -returnCodes error -result *
test parseExpr-15.25 {ParsePrimaryExpr procedure, bad lexeme after "("} testexprparser {
    testexprparser {foo(12345678901234567890)} -1
} {- {} 0 subexpr foo(12345678901234567890) 3 operator foo 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-15.26 {ParsePrimaryExpr procedure, function call, one arg} testexprparser {
    testexprparser {foo(27*4)} -1
} {- {} 0 subexpr foo(27*4) 7 operator foo 0 subexpr 27*4 5 operator * 0 subexpr 27 1 text 27 0 subexpr 4 1 text 4 0 {}}







|







530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
    testexprparser {foo(123)} -1
} {- {} 0 subexpr foo(123) 3 operator foo 0 subexpr 123 1 text 123 0 {}}
test parseExpr-15.23 {ParsePrimaryExpr procedure, bad lexeme after function name} -constraints testexprparser -body {
    testexprparser {foo 12345678901234567890 123)} -1
} -returnCodes error -match glob -result *
test parseExpr-15.24 {ParsePrimaryExpr procedure, lexeme after function name isn't "("} \
    -constraints testexprparser -body {
	testexprparser {foo 27.4 123)} -1
    } -match glob -returnCodes error -result *
test parseExpr-15.25 {ParsePrimaryExpr procedure, bad lexeme after "("} testexprparser {
    testexprparser {foo(12345678901234567890)} -1
} {- {} 0 subexpr foo(12345678901234567890) 3 operator foo 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
test parseExpr-15.26 {ParsePrimaryExpr procedure, function call, one arg} testexprparser {
    testexprparser {foo(27*4)} -1
} {- {} 0 subexpr foo(27*4) 7 operator foo 0 subexpr 27*4 5 operator * 0 subexpr 27 1 text 27 0 subexpr 4 1 text 4 0 {}}
Changes to tests/parseOld.test.
1
2
3
4
5
6
7
8
9
10
# Commands covered:  set (plus basic command syntax).  Also tests the
# procedures in the file tclOldParse.c.  This set of tests is an old
# one that predates the new parser in Tcl 8.1.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright © 1991-1993 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
|
<
|







1

2
3
4
5
6
7
8
9
# Commands covered:  set (plus basic command syntax).  This set

# of tests is an old one that predates the parser in Tcl 8.1.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright © 1991-1993 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
    while executing
"$x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000..."
    ("eval" body line 1)
    invoked from within
"eval \$x[format "%01000d" 0]("}}
test parseOld-10.15 {syntax errors, missplaced braces} {
    catch {
        proc misplaced_end_brace {} {
            set what foo
            set when [expr ${what}size - [set off$what]}]
    } msg
    set msg
} {extra characters after close-brace}
test parseOld-10.16 {syntax errors, missplaced braces} {
    catch {
        set a {
            set what foo
            set when [expr ${what}size - [set off$what]}]
    } msg
    set msg
} {extra characters after close-brace}
test parseOld-10.17 {syntax errors, unusual spacing} {
    list [catch {return [ [1]]} msg] $msg
} {1 {invalid command name "1"}}
# Long values (stressing storage management)







|
|
|





|
|
|







358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
    while executing
"$x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000..."
    ("eval" body line 1)
    invoked from within
"eval \$x[format "%01000d" 0]("}}
test parseOld-10.15 {syntax errors, missplaced braces} {
    catch {
	proc misplaced_end_brace {} {
	    set what foo
	    set when [expr ${what}size - [set off$what]}]
    } msg
    set msg
} {extra characters after close-brace}
test parseOld-10.16 {syntax errors, missplaced braces} {
    catch {
	set a {
	    set what foo
	    set when [expr ${what}size - [set off$what]}]
    } msg
    set msg
} {extra characters after close-brace}
test parseOld-10.17 {syntax errors, unusual spacing} {
    list [catch {return [ [1]]} msg] $msg
} {1 {invalid command name "1"}}
# Long values (stressing storage management)
Changes to tests/proc-old.test.
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
"tproc2"} none}
test proc-old-7.15 {return with special completion code} {
    list [catch {return -badOption foo message} msg] $msg
} {2 message}

test proc-old-8.1 {unset and undefined local arrays} {
    proc t1 {} {
        foreach v {xxx, yyy} {
            catch {unset $v}
        }
        set yyy(foo) bar
    }
    t1
} bar

test proc-old-9.1 {empty command name} {
    catch {rename {} ""}
    proc t1 {args} {
        return
    }
    set v [t1]
    catch {$v}
} 1

test proc-old-10.1 {ByteCode epoch change during recursive proc execution} {
    proc t1 x {
        set y 20
        rename expr expr.old
        rename expr.old expr
        if {$x} then {t1 0} ;# recursive call after foo's code is invalidated
        return 20
    }
    t1 1
} 20

# cleanup
catch {rename t1 ""}
catch {rename foo ""}







|
|
|
|







|







|
|
|
|
|







478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
"tproc2"} none}
test proc-old-7.15 {return with special completion code} {
    list [catch {return -badOption foo message} msg] $msg
} {2 message}

test proc-old-8.1 {unset and undefined local arrays} {
    proc t1 {} {
	foreach v {xxx, yyy} {
	    catch {unset $v}
	}
	set yyy(foo) bar
    }
    t1
} bar

test proc-old-9.1 {empty command name} {
    catch {rename {} ""}
    proc t1 {args} {
	return
    }
    set v [t1]
    catch {$v}
} 1

test proc-old-10.1 {ByteCode epoch change during recursive proc execution} {
    proc t1 x {
	set y 20
	rename expr expr.old
	rename expr.old expr
	if {$x} then {t1 0} ;# recursive call after foo's code is invalidated
	return 20
    }
    t1 1
} 20

# cleanup
catch {rename t1 ""}
catch {rename foo ""}
Changes to tests/proc.test.
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
catch {rename {} ""}
catch {unset msg}

test proc-1.1 {Tcl_ProcObjCmd, put proc in namespace specified in name, if any} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1 {
        namespace eval baz {}
    }
    proc test_ns_1::baz::p {} {
        return "p in [namespace current]"
    }
    list [test_ns_1::baz::p] \
         [namespace eval test_ns_1 {baz::p}] \
         [info commands test_ns_1::baz::*]
} -result {{p in ::test_ns_1::baz} {p in ::test_ns_1::baz} ::test_ns_1::baz::p}
test proc-1.2 {Tcl_ProcObjCmd, namespace specified in proc name must exist} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -returnCodes error -body {
    proc test_ns_1::baz::p {} {}
} -result {can't create procedure "test_ns_1::baz::p": unknown namespace}
test proc-1.3 {Tcl_ProcObjCmd, empty proc name} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    proc :: {} {
        return "empty called"
    }
    list [::] \
         [info body {}]
} -result {{empty called} {
        return "empty called"
    }}
test proc-1.4 {Tcl_ProcObjCmd, simple proc name and proc defined in namespace} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1 {
        namespace eval baz {
            proc p {} {
                return "p in [namespace current]"
            }
        }
    }
    list [test_ns_1::baz::p] \
         [info commands test_ns_1::baz::*]
} -result {{p in ::test_ns_1::baz} ::test_ns_1::baz::p}
test proc-1.5 {Tcl_ProcObjCmd, qualified proc name and proc defined in namespace} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1::baz {}
    namespace eval test_ns_1 {
        proc baz::p {} {
            return "p in [namespace current]"
        }
    }
    list [test_ns_1::baz::p] \
         [info commands test_ns_1::baz::*] \
         [namespace eval test_ns_1::baz {namespace which p}]
} -result {{p in ::test_ns_1::baz} ::test_ns_1::baz::p ::test_ns_1::baz::p}
test proc-1.6 {Tcl_ProcObjCmd, namespace code ignores single ":"s in middle or end of command names} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1 {
        proc q: {} {return "q:"}
        proc value:at: {} {return "value:at:"}
    }
    list [namespace eval test_ns_1 {q:}] \
         [namespace eval test_ns_1 {value:at:}] \
         [test_ns_1::q:] \
         [test_ns_1::value:at:] \
         [lsort [info commands test_ns_1::*]] \
         [namespace eval test_ns_1 {namespace which q:}] \
         [namespace eval test_ns_1 {namespace which value:at:}]
} -result {q: value:at: q: value:at: {::test_ns_1::q: ::test_ns_1::value:at:} ::test_ns_1::q: ::test_ns_1::value:at:}
test proc-1.7 {Tcl_ProcObjCmd, check that formal parameter names are not array elements} -setup {
    catch {rename p ""}
} -returnCodes error -body {
    proc p {a(1) a(2)} {
	set z [expr {$a(1)+$a(2)}]
	puts "$z=z, $a(1)=$a(1)"







|


|


|
|










|


|

|





|
|
|
|
|


|






|
|
|


|
|





|
|


|
|
|
|
|
|







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
catch {rename {} ""}
catch {unset msg}

test proc-1.1 {Tcl_ProcObjCmd, put proc in namespace specified in name, if any} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1 {
	namespace eval baz {}
    }
    proc test_ns_1::baz::p {} {
	return "p in [namespace current]"
    }
    list [test_ns_1::baz::p] \
	 [namespace eval test_ns_1 {baz::p}] \
	 [info commands test_ns_1::baz::*]
} -result {{p in ::test_ns_1::baz} {p in ::test_ns_1::baz} ::test_ns_1::baz::p}
test proc-1.2 {Tcl_ProcObjCmd, namespace specified in proc name must exist} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -returnCodes error -body {
    proc test_ns_1::baz::p {} {}
} -result {can't create procedure "test_ns_1::baz::p": unknown namespace}
test proc-1.3 {Tcl_ProcObjCmd, empty proc name} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    proc :: {} {
	return "empty called"
    }
    list [::] \
	 [info body {}]
} -result {{empty called} {
	return "empty called"
    }}
test proc-1.4 {Tcl_ProcObjCmd, simple proc name and proc defined in namespace} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1 {
	namespace eval baz {
	    proc p {} {
		return "p in [namespace current]"
	    }
	}
    }
    list [test_ns_1::baz::p] \
	 [info commands test_ns_1::baz::*]
} -result {{p in ::test_ns_1::baz} ::test_ns_1::baz::p}
test proc-1.5 {Tcl_ProcObjCmd, qualified proc name and proc defined in namespace} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1::baz {}
    namespace eval test_ns_1 {
	proc baz::p {} {
	    return "p in [namespace current]"
	}
    }
    list [test_ns_1::baz::p] \
	 [info commands test_ns_1::baz::*] \
	 [namespace eval test_ns_1::baz {namespace which p}]
} -result {{p in ::test_ns_1::baz} ::test_ns_1::baz::p ::test_ns_1::baz::p}
test proc-1.6 {Tcl_ProcObjCmd, namespace code ignores single ":"s in middle or end of command names} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1 {
	proc q: {} {return "q:"}
	proc value:at: {} {return "value:at:"}
    }
    list [namespace eval test_ns_1 {q:}] \
	 [namespace eval test_ns_1 {value:at:}] \
	 [test_ns_1::q:] \
	 [test_ns_1::value:at:] \
	 [lsort [info commands test_ns_1::*]] \
	 [namespace eval test_ns_1 {namespace which q:}] \
	 [namespace eval test_ns_1 {namespace which value:at:}]
} -result {q: value:at: q: value:at: {::test_ns_1::q: ::test_ns_1::value:at:} ::test_ns_1::q: ::test_ns_1::value:at:}
test proc-1.7 {Tcl_ProcObjCmd, check that formal parameter names are not array elements} -setup {
    catch {rename p ""}
} -returnCodes error -body {
    proc p {a(1) a(2)} {
	set z [expr {$a(1)+$a(2)}]
	puts "$z=z, $a(1)=$a(1)"
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
    proc p {} {return "p in [namespace current]"}
    info body p
} -result {return "p in [namespace current]"}
test proc-2.2 {TclFindProc, simple proc name and proc defined in namespace} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1 {
        namespace eval baz {
            proc p {} {return "p in [namespace current]"}
        }
    }
    namespace eval test_ns_1::baz {info body p}
} -result {return "p in [namespace current]"}
test proc-2.3 {TclFindProc, qualified proc name and proc defined in namespace} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1::baz {}
    namespace eval test_ns_1 {
        proc baz::p {} {return "p in [namespace current]"}
    }
    namespace eval test_ns_1 {info body baz::p}
} -result {return "p in [namespace current]"}
test proc-2.4 {TclFindProc, global proc and executing in namespace} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {rename p ""}
} -body {







|
|
|








|







127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
    proc p {} {return "p in [namespace current]"}
    info body p
} -result {return "p in [namespace current]"}
test proc-2.2 {TclFindProc, simple proc name and proc defined in namespace} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1 {
	namespace eval baz {
	    proc p {} {return "p in [namespace current]"}
	}
    }
    namespace eval test_ns_1::baz {info body p}
} -result {return "p in [namespace current]"}
test proc-2.3 {TclFindProc, qualified proc name and proc defined in namespace} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1::baz {}
    namespace eval test_ns_1 {
	proc baz::p {} {return "p in [namespace current]"}
    }
    namespace eval test_ns_1 {info body baz::p}
} -result {return "p in [namespace current]"}
test proc-2.4 {TclFindProc, global proc and executing in namespace} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {rename p ""}
} -body {
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
    proc p {} {return "p in [namespace current]"}
    p
} -result {p in ::}
test proc-3.2 {TclObjInterpProc, proc defined and executing in same namespace} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1::baz {
        proc p {} {return "p in [namespace current]"}
        p
    }
} -result {p in ::test_ns_1::baz}
test proc-3.3 {TclObjInterpProc, proc defined and executing in different namespaces} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {rename p ""}
} -body {
    proc p {} {return "p in [namespace current]"}
    namespace eval test_ns_1::baz {
        p
    }
} -result {p in ::}
test proc-3.4 {TclObjInterpProc, procs execute in the namespace in which they were defined unless renamed into new namespace} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {rename p ""}
} -body {
    namespace eval test_ns_1::baz {
        proc p {} {return "p in [namespace current]"}
        rename ::test_ns_1::baz::p ::p
        list [p] [namespace which p]
    }
} -result {{p in ::} ::p}
test proc-3.5 {TclObjInterpProc, any old result is reset before appending error msg about missing arguments} -body {
    proc p {x} {info commands 3m}
    p
} -returnCodes error -result {wrong # args: should be "p x"}
test proc-3.6 {TclObjInterpProc, proper quoting of proc name, Bug 942757} -body {







|
|








|







|
|
|







160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
    proc p {} {return "p in [namespace current]"}
    p
} -result {p in ::}
test proc-3.2 {TclObjInterpProc, proc defined and executing in same namespace} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
} -body {
    namespace eval test_ns_1::baz {
	proc p {} {return "p in [namespace current]"}
	p
    }
} -result {p in ::test_ns_1::baz}
test proc-3.3 {TclObjInterpProc, proc defined and executing in different namespaces} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {rename p ""}
} -body {
    proc p {} {return "p in [namespace current]"}
    namespace eval test_ns_1::baz {
	p
    }
} -result {p in ::}
test proc-3.4 {TclObjInterpProc, procs execute in the namespace in which they were defined unless renamed into new namespace} -setup {
    catch {namespace delete {*}[namespace children :: test_ns_*]}
    catch {rename p ""}
} -body {
    namespace eval test_ns_1::baz {
	proc p {} {return "p in [namespace current]"}
	rename ::test_ns_1::baz::p ::p
	list [p] [namespace which p]
    }
} -result {{p in ::} ::p}
test proc-3.5 {TclObjInterpProc, any old result is reset before appending error msg about missing arguments} -body {
    proc p {x} {info commands 3m}
    p
} -returnCodes error -result {wrong # args: should be "p x"}
test proc-3.6 {TclObjInterpProc, proper quoting of proc name, Bug 942757} -body {
Changes to tests/process.test.
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
test process-4.1 {exec one child} -body {
    tcl::process autopurge 0
    set pid [exec [interpreter] $path(exit) 0 &]
    set list [tcl::process list]
    set statuses [tcl::process status -wait]
    set status [lindex [tcl::process status $pid] 1]
    expr {
           [llength $list] eq 1
        && [lindex $list 0] eq $pid
        && [dict size $statuses] eq 1
        && [dict get $statuses $pid] eq $status
        && $status eq 0
    }
} -result {1} -cleanup {
    tcl::process purge
    tcl::process autopurge 1
}
# - Two children
test process-4.2 {exec two children in parallel} -body {
    tcl::process autopurge 0
    set pid1 [exec [interpreter] $path(exit) 0 &]
    set pid2 [exec [interpreter] $path(exit) 0 &]
    set list [tcl::process list]
    set statuses [tcl::process status -wait]
    set status1 [lindex [tcl::process status $pid1] 1]
    set status2 [lindex [tcl::process status $pid2] 1]
    expr {
           [llength $list] eq 2
        && [lsearch $list $pid1] >= 0
        && [lsearch $list $pid2] >= 0
        && [dict size $statuses] eq 2
        && [dict get $statuses $pid1] eq $status1
        && [dict get $statuses $pid2] eq $status2
        && $status1 eq 0
        && $status2 eq 0
    }
} -result {1} -cleanup {
    tcl::process purge
    tcl::process autopurge 1
}
# - 3-stage pipe
test process-4.3 {exec 3-stage pipe} -body {
    tcl::process autopurge 0
    set pids [exec \
          [interpreter] $path(exit) 0 \
        | [interpreter] $path(exit) 0 \
        | [interpreter] $path(exit) 0 \
    &]
    lassign $pids pid1 pid2 pid3
    set list [tcl::process list]
    set statuses [tcl::process status -wait]
    set status1 [lindex [tcl::process status $pid1] 1]
    set status2 [lindex [tcl::process status $pid2] 1]
    set status3 [lindex [tcl::process status $pid3] 1]
    expr {
           [llength $pids] eq 3
        && [llength $list] eq 3
        && [lsearch $list $pid1] >= 0
        && [lsearch $list $pid2] >= 0
        && [lsearch $list $pid3] >= 0
        && [dict size $statuses] eq 3
        && [dict get $statuses $pid1] eq $status1
        && [dict get $statuses $pid2] eq $status2
        && [dict get $statuses $pid3] eq $status3
        && $status1 eq 0
        && $status2 eq 0
        && $status3 eq 0
    }
} -result {1} -cleanup {
    tcl::process purge
    tcl::process autopurge 1
}

# Spawn subprocesses using [open "|"]
# - One child
test process-5.1 {exec one child} -body {
    tcl::process autopurge 0
    set f [open "|\"[interpreter]\" \"$path(exit)\" 0"]
    set pid [pid $f]
    set list [tcl::process list]
    set statuses [tcl::process status -wait]
    set status [lindex [tcl::process status $pid] 1]
    expr {
           [llength $list] eq 1
        && [lindex $list 0] eq $pid
        && [dict size $statuses] eq 1
        && [dict get $statuses $pid] eq $status
        && $status eq 0
    }
} -result {1} -cleanup {
    close $f
    tcl::process purge
    tcl::process autopurge 1
}
# - Two children
test process-5.2 {exec two children in parallel} -body {
    tcl::process autopurge 0
    set f1 [open "|\"[interpreter]\" \"$path(exit)\" 0"]
    set f2 [open "|\"[interpreter]\" \"$path(exit)\" 0"]
    set pid1 [pid $f1]
    set pid2 [pid $f2]
    set list [tcl::process list]
    set statuses [tcl::process status -wait]
    set status1 [lindex [tcl::process status $pid1] 1]
    set status2 [lindex [tcl::process status $pid2] 1]
    expr {
           [llength $list] eq 2
        && [lsearch $list $pid1] >= 0
        && [lsearch $list $pid2] >= 0
        && [dict size $statuses] eq 2
        && [dict get $statuses $pid1] eq $status1
        && [dict get $statuses $pid2] eq $status2
        && $status1 eq 0
        && $status2 eq 0
    }
} -result {1} -cleanup {
    close $f1
    close $f2
    tcl::process purge
    tcl::process autopurge 1
}
# - 3-stage pipe
test process-5.3 {exec 3-stage pipe} -body {
    tcl::process autopurge 0
    set f [open "|
          \"[interpreter]\" \"$path(exit)\" 0
        | \"[interpreter]\" \"$path(exit)\" 0
        | \"[interpreter]\" \"$path(exit)\" 0
    "]
    set pids [pid $f]
    lassign $pids pid1 pid2 pid3
    set list [tcl::process list]
    set statuses [tcl::process status -wait]
    set status1 [lindex [tcl::process status $pid1] 1]
    set status2 [lindex [tcl::process status $pid2] 1]
    set status3 [lindex [tcl::process status $pid3] 1]
    expr {
           [llength $pids] eq 3
        && [llength $list] eq 3
        && [lsearch $list $pid1] >= 0
        && [lsearch $list $pid2] >= 0
        && [lsearch $list $pid3] >= 0
        && [dict size $statuses] eq 3
        && [dict get $statuses $pid1] eq $status1
        && [dict get $statuses $pid2] eq $status2
        && [dict get $statuses $pid3] eq $status3
        && $status1 eq 0
        && $status2 eq 0
        && $status3 eq 0
    }
} -result {1} -cleanup {
    close $f
    tcl::process purge
    tcl::process autopurge 1
}

# Async child status
test process-6.1 {async status} -setup {
    signal_exit $path(test-signalfile) 0; # clean signal-file
} -body {
    tcl::process autopurge 0
    set pid [exec [interpreter] $path(sleep) 1 $path(test-signalfile) &]
    set status1 [lindex [tcl::process status $pid] 1]
    signal_exit $path(test-signalfile); # signal exit (stop sleep)
    set status2 [lindex [tcl::process status -wait $pid] 1]
    expr {
           $status1 eq {}
        && $status2 eq 0
    }
} -result {1} -cleanup {
    tcl::process purge
    tcl::process autopurge 1
}
test process-6.2 {selective wait} -setup {
    signal_exit $path(test-signalfile)  0; # clean signal-files







|
|
|
|
|















|
|
|
|
|
|
|
|









|
|
|








|
|
|
|
|
|
|
|
|
|
|
|
















|
|
|
|
|


















|
|
|
|
|
|
|
|











|
|
|









|
|
|
|
|
|
|
|
|
|
|
|

















|
|







103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
test process-4.1 {exec one child} -body {
    tcl::process autopurge 0
    set pid [exec [interpreter] $path(exit) 0 &]
    set list [tcl::process list]
    set statuses [tcl::process status -wait]
    set status [lindex [tcl::process status $pid] 1]
    expr {
	   [llength $list] eq 1
	&& [lindex $list 0] eq $pid
	&& [dict size $statuses] eq 1
	&& [dict get $statuses $pid] eq $status
	&& $status eq 0
    }
} -result {1} -cleanup {
    tcl::process purge
    tcl::process autopurge 1
}
# - Two children
test process-4.2 {exec two children in parallel} -body {
    tcl::process autopurge 0
    set pid1 [exec [interpreter] $path(exit) 0 &]
    set pid2 [exec [interpreter] $path(exit) 0 &]
    set list [tcl::process list]
    set statuses [tcl::process status -wait]
    set status1 [lindex [tcl::process status $pid1] 1]
    set status2 [lindex [tcl::process status $pid2] 1]
    expr {
	   [llength $list] eq 2
	&& [lsearch $list $pid1] >= 0
	&& [lsearch $list $pid2] >= 0
	&& [dict size $statuses] eq 2
	&& [dict get $statuses $pid1] eq $status1
	&& [dict get $statuses $pid2] eq $status2
	&& $status1 eq 0
	&& $status2 eq 0
    }
} -result {1} -cleanup {
    tcl::process purge
    tcl::process autopurge 1
}
# - 3-stage pipe
test process-4.3 {exec 3-stage pipe} -body {
    tcl::process autopurge 0
    set pids [exec \
	  [interpreter] $path(exit) 0 \
	| [interpreter] $path(exit) 0 \
	| [interpreter] $path(exit) 0 \
    &]
    lassign $pids pid1 pid2 pid3
    set list [tcl::process list]
    set statuses [tcl::process status -wait]
    set status1 [lindex [tcl::process status $pid1] 1]
    set status2 [lindex [tcl::process status $pid2] 1]
    set status3 [lindex [tcl::process status $pid3] 1]
    expr {
	   [llength $pids] eq 3
	&& [llength $list] eq 3
	&& [lsearch $list $pid1] >= 0
	&& [lsearch $list $pid2] >= 0
	&& [lsearch $list $pid3] >= 0
	&& [dict size $statuses] eq 3
	&& [dict get $statuses $pid1] eq $status1
	&& [dict get $statuses $pid2] eq $status2
	&& [dict get $statuses $pid3] eq $status3
	&& $status1 eq 0
	&& $status2 eq 0
	&& $status3 eq 0
    }
} -result {1} -cleanup {
    tcl::process purge
    tcl::process autopurge 1
}

# Spawn subprocesses using [open "|"]
# - One child
test process-5.1 {exec one child} -body {
    tcl::process autopurge 0
    set f [open "|\"[interpreter]\" \"$path(exit)\" 0"]
    set pid [pid $f]
    set list [tcl::process list]
    set statuses [tcl::process status -wait]
    set status [lindex [tcl::process status $pid] 1]
    expr {
	   [llength $list] eq 1
	&& [lindex $list 0] eq $pid
	&& [dict size $statuses] eq 1
	&& [dict get $statuses $pid] eq $status
	&& $status eq 0
    }
} -result {1} -cleanup {
    close $f
    tcl::process purge
    tcl::process autopurge 1
}
# - Two children
test process-5.2 {exec two children in parallel} -body {
    tcl::process autopurge 0
    set f1 [open "|\"[interpreter]\" \"$path(exit)\" 0"]
    set f2 [open "|\"[interpreter]\" \"$path(exit)\" 0"]
    set pid1 [pid $f1]
    set pid2 [pid $f2]
    set list [tcl::process list]
    set statuses [tcl::process status -wait]
    set status1 [lindex [tcl::process status $pid1] 1]
    set status2 [lindex [tcl::process status $pid2] 1]
    expr {
	   [llength $list] eq 2
	&& [lsearch $list $pid1] >= 0
	&& [lsearch $list $pid2] >= 0
	&& [dict size $statuses] eq 2
	&& [dict get $statuses $pid1] eq $status1
	&& [dict get $statuses $pid2] eq $status2
	&& $status1 eq 0
	&& $status2 eq 0
    }
} -result {1} -cleanup {
    close $f1
    close $f2
    tcl::process purge
    tcl::process autopurge 1
}
# - 3-stage pipe
test process-5.3 {exec 3-stage pipe} -body {
    tcl::process autopurge 0
    set f [open "|
	  \"[interpreter]\" \"$path(exit)\" 0
	| \"[interpreter]\" \"$path(exit)\" 0
	| \"[interpreter]\" \"$path(exit)\" 0
    "]
    set pids [pid $f]
    lassign $pids pid1 pid2 pid3
    set list [tcl::process list]
    set statuses [tcl::process status -wait]
    set status1 [lindex [tcl::process status $pid1] 1]
    set status2 [lindex [tcl::process status $pid2] 1]
    set status3 [lindex [tcl::process status $pid3] 1]
    expr {
	   [llength $pids] eq 3
	&& [llength $list] eq 3
	&& [lsearch $list $pid1] >= 0
	&& [lsearch $list $pid2] >= 0
	&& [lsearch $list $pid3] >= 0
	&& [dict size $statuses] eq 3
	&& [dict get $statuses $pid1] eq $status1
	&& [dict get $statuses $pid2] eq $status2
	&& [dict get $statuses $pid3] eq $status3
	&& $status1 eq 0
	&& $status2 eq 0
	&& $status3 eq 0
    }
} -result {1} -cleanup {
    close $f
    tcl::process purge
    tcl::process autopurge 1
}

# Async child status
test process-6.1 {async status} -setup {
    signal_exit $path(test-signalfile) 0; # clean signal-file
} -body {
    tcl::process autopurge 0
    set pid [exec [interpreter] $path(sleep) 1 $path(test-signalfile) &]
    set status1 [lindex [tcl::process status $pid] 1]
    signal_exit $path(test-signalfile); # signal exit (stop sleep)
    set status2 [lindex [tcl::process status -wait $pid] 1]
    expr {
	   $status1 eq {}
	&& $status2 eq 0
    }
} -result {1} -cleanup {
    tcl::process purge
    tcl::process autopurge 1
}
test process-6.2 {selective wait} -setup {
    signal_exit $path(test-signalfile)  0; # clean signal-files
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
    set status2_1 [lindex [tcl::process status -wait $pid1] 1]
    set status2_2 [lindex [tcl::process status $pid2] 1]
    # Wait until child 2 termination
    signal_exit $path(test-signalfile2); # signal exit for pid2 (stop sleep)
    set status3_2 [lindex [tcl::process status -wait $pid2] 1]
    set status3_1 [lindex [tcl::process status $pid1] 1]
    expr {
           $status1_1 eq {}
        && $status1_2 eq {}
        && $status2_1 eq 0
        && $status2_2 eq {}
        && $status3_1 eq 0
        && $status3_2 eq 0
    }
} -result {1} -cleanup {
    tcl::process purge
    tcl::process autopurge 1
}

# Error codes







|
|
|
|
|
|







290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
    set status2_1 [lindex [tcl::process status -wait $pid1] 1]
    set status2_2 [lindex [tcl::process status $pid2] 1]
    # Wait until child 2 termination
    signal_exit $path(test-signalfile2); # signal exit for pid2 (stop sleep)
    set status3_2 [lindex [tcl::process status -wait $pid2] 1]
    set status3_1 [lindex [tcl::process status $pid1] 1]
    expr {
	   $status1_1 eq {}
	&& $status1_2 eq {}
	&& $status2_1 eq 0
	&& $status2_2 eq {}
	&& $status3_1 eq 0
	&& $status3_2 eq 0
    }
} -result {1} -cleanup {
    tcl::process purge
    tcl::process autopurge 1
}

# Error codes
Changes to tests/registry.test.
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
    lsort [registry values HKEY_CURRENT_USER\\TclFoobar b*]
} -cleanup {
    registry delete HKEY_CURRENT_USER\\TclFoobar
} -result {{baz bar} blat}

test registry-8.1 {OpenSubKey} -constraints {win reg nonPortable english} \
    -body {
        # This test will only succeed if the current user does not have
        # registry access on the specified machine.
        registry keys {\\mom\HKEY_LOCAL_MACHINE}
    } -returnCodes error -result "unable to open key: Access is denied."
test registry-8.2 {OpenSubKey} -constraints {win reg} -setup {
    registry delete HKEY_CURRENT_USER\\TclFoobar
    registry set HKEY_CURRENT_USER\\TclFoobar
} -body {
    registry keys HKEY_CURRENT_USER TclFoobar
} -cleanup {







|
|
|







570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
    lsort [registry values HKEY_CURRENT_USER\\TclFoobar b*]
} -cleanup {
    registry delete HKEY_CURRENT_USER\\TclFoobar
} -result {{baz bar} blat}

test registry-8.1 {OpenSubKey} -constraints {win reg nonPortable english} \
    -body {
	# This test will only succeed if the current user does not have
	# registry access on the specified machine.
	registry keys {\\mom\HKEY_LOCAL_MACHINE}
    } -returnCodes error -result "unable to open key: Access is denied."
test registry-8.2 {OpenSubKey} -constraints {win reg} -setup {
    registry delete HKEY_CURRENT_USER\\TclFoobar
    registry set HKEY_CURRENT_USER\\TclFoobar
} -body {
    registry keys HKEY_CURRENT_USER TclFoobar
} -cleanup {
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
    registry delete HKEY_CURRENT_USER\\TclFoobar\\test2\\test4
} -cleanup {
    registry delete HKEY_CURRENT_USER\\TclFoobar
} -result {}

test registry-11.1 {SetValue: recursive creation} \
    -constraints {win reg} -setup {
        registry delete HKEY_CURRENT_USER\\TclFoobar
    } -body {
        registry set HKEY_CURRENT_USER\\TclFoobar\\baz blat foobar
        set result [registry get HKEY_CURRENT_USER\\TclFoobar\\baz blat]
    } -result {foobar}
test registry-11.2 {SetValue: modification} -constraints {win reg} \
    -setup {
        registry delete HKEY_CURRENT_USER\\TclFoobar
    } -body {
        registry set HKEY_CURRENT_USER\\TclFoobar\\baz blat foobar
        registry set HKEY_CURRENT_USER\\TclFoobar\\baz blat frob
        set result [registry get HKEY_CURRENT_USER\\TclFoobar\\baz blat]
    } -result {frob}
test registry-11.3 {SetValue: failure} \
    -constraints {win reg nonPortable english} \
    -body {
        # This test will only succeed if the current user does not have
        # registry access on the specified machine.
        registry set {\\mom\HKEY_CURRENT_USER\TclFoobar} bar foobar
    } -returnCodes error -result {unable to open key: Access is denied.}

test registry-12.1 {BroadcastValue} -constraints {win reg} -body {
    registry broadcast
} -returnCodes error -result "wrong # args: should be \"registry broadcast keyName ?-timeout milliseconds?\""
test registry-12.2 {BroadcastValue} -constraints {win reg} -body {
    registry broadcast "" -time







|

|
|



|

|
|
|




|
|
|







640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
    registry delete HKEY_CURRENT_USER\\TclFoobar\\test2\\test4
} -cleanup {
    registry delete HKEY_CURRENT_USER\\TclFoobar
} -result {}

test registry-11.1 {SetValue: recursive creation} \
    -constraints {win reg} -setup {
	registry delete HKEY_CURRENT_USER\\TclFoobar
    } -body {
	registry set HKEY_CURRENT_USER\\TclFoobar\\baz blat foobar
	set result [registry get HKEY_CURRENT_USER\\TclFoobar\\baz blat]
    } -result {foobar}
test registry-11.2 {SetValue: modification} -constraints {win reg} \
    -setup {
	registry delete HKEY_CURRENT_USER\\TclFoobar
    } -body {
	registry set HKEY_CURRENT_USER\\TclFoobar\\baz blat foobar
	registry set HKEY_CURRENT_USER\\TclFoobar\\baz blat frob
	set result [registry get HKEY_CURRENT_USER\\TclFoobar\\baz blat]
    } -result {frob}
test registry-11.3 {SetValue: failure} \
    -constraints {win reg nonPortable english} \
    -body {
	# This test will only succeed if the current user does not have
	# registry access on the specified machine.
	registry set {\\mom\HKEY_CURRENT_USER\TclFoobar} bar foobar
    } -returnCodes error -result {unable to open key: Access is denied.}

test registry-12.1 {BroadcastValue} -constraints {win reg} -body {
    registry broadcast
} -returnCodes error -result "wrong # args: should be \"registry broadcast keyName ?-timeout milliseconds?\""
test registry-12.2 {BroadcastValue} -constraints {win reg} -body {
    registry broadcast "" -time
Changes to tests/rename.test.
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179

catch {rename unknown unknown.old}

set SAVED_UNKNOWN "proc unknown "
append SAVED_UNKNOWN [list [info args unknown.old] [info body unknown.old]]
test rename-5.1 {repeated rename deletion and redefinition of same command} {
    for {set i 0} {$i < 10} {incr i} {
        eval $SAVED_UNKNOWN
        tcl_wordBreakBefore "" 0
        rename tcl_wordBreakBefore {}
        rename unknown {}
    }
} {}

catch {rename unknown {}}
catch {rename unknown.old unknown}

test rename-6.1 {old code invalidated (epoch incremented) when cmd with compile proc is renamed} -body {
    proc x {} {
        set a 123
        set b [incr a]
    }
    x
    rename incr incr.old
    proc incr {} {puts "new incr called!"}
    x
} -cleanup {
    rename incr {}







|
|
|
|








|
|







152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179

catch {rename unknown unknown.old}

set SAVED_UNKNOWN "proc unknown "
append SAVED_UNKNOWN [list [info args unknown.old] [info body unknown.old]]
test rename-5.1 {repeated rename deletion and redefinition of same command} {
    for {set i 0} {$i < 10} {incr i} {
	eval $SAVED_UNKNOWN
	tcl_wordBreakBefore "" 0
	rename tcl_wordBreakBefore {}
	rename unknown {}
    }
} {}

catch {rename unknown {}}
catch {rename unknown.old unknown}

test rename-6.1 {old code invalidated (epoch incremented) when cmd with compile proc is renamed} -body {
    proc x {} {
	set a 123
	set b [incr a]
    }
    x
    rename incr incr.old
    proc incr {} {puts "new incr called!"}
    x
} -cleanup {
    rename incr {}
Changes to tests/result.test.
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
    proc foo {} {catch {return -level 2}; testreturn}
    foo
} -cleanup {
    rename foo {}
} -result {}
test result-6.2 {Bug 1649062} -setup {
    proc foo {} {
        if {[catch {
            return -code error -errorinfo custom -errorcode CUSTOM foo
        } err]} {
            return [list $err $::errorCode $::errorInfo]
        }
    }
    set ::errorInfo {}
    set ::errorCode {}
} -body {
    foo
} -cleanup {
    rename foo {}







|
|
|
|
|







115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
    proc foo {} {catch {return -level 2}; testreturn}
    foo
} -cleanup {
    rename foo {}
} -result {}
test result-6.2 {Bug 1649062} -setup {
    proc foo {} {
	if {[catch {
	    return -code error -errorinfo custom -errorcode CUSTOM foo
	} err]} {
	    return [list $err $::errorCode $::errorInfo]
	}
    }
    set ::errorInfo {}
    set ::errorCode {}
} -body {
    foo
} -cleanup {
    rename foo {}
Changes to tests/safe-stock.test.
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
lappend PathMapp [file join [info library] $pkgOptDir] TCLLIB/OPTDIR
lappend PathMapp [file join [info library] $pkgJarDir] TCLLIB/JARDIR
lappend PathMapp $tcl_library TCLLIB $TestsDir TESTSDIR

proc mapList {map listIn} {
    set listOut {}
    foreach element $listIn {
        lappend listOut [string map $map $element]
    }
    return $listOut
}
proc mapAndSortList {map listIn} {
    set listOut {}
    foreach element $listIn {
        lappend listOut [string map $map $element]
    }
    lsort $listOut
}

# Force actual loading of the safe package because we use unexported (and
# thus unautoindexed) APIs in this test result arguments:
catch {safe::interpConfigure}

testConstraint AutoSyncDefined 1

# high level general test
test safe-stock-7.1 {tests that everything works at high level with conventional AutoPathSync, use pkg opt} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    }
    set i [safe::interpCreate]
} -body {
    # no error shall occur:
    # (because the default access_path shall include 1st level sub dirs so
    #  package require in a child works like in the parent)
    set v [interp eval $i {package require opt}]
    # no error shall occur:
    interp eval $i {::tcl::Lempty {a list}}
    set v
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result 0.4.*
test safe-stock-7.2 {tests specific path and interpFind/AddToAccessPath with conventional AutoPathSync, use pkg opt} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    } else {
        set SyncVal_TMP 1
    }
} -body {
    set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
    # should not add anything (p0)
    set token1 [safe::interpAddToAccessPath $i [info library]]
    # should add as p* (not p1 if parent has a module path)
    set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
    # an error shall occur (opt is not anymore in the secure 0-level
    # provided deep path)
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    list $token1 $token2 -- \
	    [catch {interp eval $i {package require opt}} msg] $msg -- \
	    $mappA -- [safe::interpDelete $i]
} -cleanup {
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result "{\$p(:0:)} {\$p(:*:)} -- 1 {$pkgOptErrMsg} --\
        {TCLLIB */dummy/unixlike/test/path} -- {}"
test safe-stock-7.4 {tests specific path and positive search with conventional AutoPathSync, use pkg opt} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    } else {
        set SyncVal_TMP 1
    }
} -body {
    set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
    # should not add anything (p0)
    set token1 [safe::interpAddToAccessPath $i [info library]]
    # should add as p* (not p1 if parent has a module path)
    set token2 [safe::interpAddToAccessPath $i [file join [info library] $pkgOptDir]]
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    # this time, unlike test safe-stock-7.2, opt should be found
    list $token1 $token2 -- \
            [catch {interp eval $i {package require opt}} msg] $msg -- \
            $mappA -- [safe::interpDelete $i]
    # Note that the glob match elides directories (those from the module path)
    # other than the first and last in the access path.
} -cleanup {
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:0:)} {$p(:*:)} -- 0 0.4.* --\
        {TCLLIB * TCLLIB/OPTDIR} -- {}}
test safe-stock-7.5 {tests positive and negative module loading with conventional AutoPathSync} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    }
    set i [safe::interpCreate]
    interp eval $i {
        package forget platform::shell
        package forget platform
        catch {namespace delete ::platform}
    }
} -body {
    # Should raise an error (module ancestor directory issue)
    set code1 [catch {interp eval $i {package require shell}} msg1]
    # Should not raise an error
    set code2 [catch {interp eval $i {package require platform::shell}} msg2]
    return [list $code1 $msg1 $code2]
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {1 {can't find package shell} 0}

# The following test checks whether the definition of tcl_endOfWord can be
# obtained from auto_loading.  It was previously test "safe-5.1".
test safe-stock-9.8 {test auto-loading in safe interpreters, was safe-5.1} -setup {
    catch {safe::interpDelete a}
    safe::interpCreate a
} -body {
    interp eval a {tcl_endOfWord "" 0}
} -cleanup {
    safe::interpDelete a
} -result -1
test safe-stock-9.11 {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement with conventional AutoPathSync, uses pkg opt and tcl::idna} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    }
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library \
                                            [file join $tcl_library $pkgOptDir] \
                                            [file join $tcl_library $pkgJarDir]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgOptDir]]
    set path2 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgJarDir]]

    # Load pkgIndex.tcl data.
    catch {interp eval $i {package require NOEXIST}}

    # Rearrange access path.  Swap tokens {$p(:1:)} and {$p(:2:)}.
    # This has no effect because the records in Pkg of these directories were from access as children of {$p(:0:)}.
    safe::interpConfigure $i -accessPath [list $tcl_library \
                                           [file join $tcl_library $pkgJarDir] \
                                           [file join $tcl_library $pkgOptDir]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path3 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgOptDir]]
    set path4 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgJarDir]]

    # Try to load the packages and run a command from each one.
    set code3 [catch {interp eval $i {package require tcl::idna}} msg3]
    set code4 [catch {interp eval $i {package require opt}} msg4]
    set code5 [catch {interp eval $i {::tcl::Lempty {a list}}} msg5]
    set code6 [catch {interp eval $i {::tcl::idna::IDNAencode example.com}} msg6]

    list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- \
         $mappA -- $mappB -- $code5 $msg5 $code6 $msg6
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} -- 0 1.* 0 0.4.* --\
        {TCLLIB TCLLIB/OPTDIR TCLLIB/JARDIR*} --\
        {TCLLIB TCLLIB/JARDIR TCLLIB/OPTDIR*} --\
        0 0 0 example.com}
test safe-stock-9.13 {interpConfigure change the access path; pkgIndex.tcl packages fail if directory de-listed with conventional AutoPathSync, uses pkg opt and tcl::idna} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    }
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library \
                                            [file join $tcl_library $pkgOptDir] \
                                            [file join $tcl_library $pkgJarDir]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgOptDir]]
    set path2 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgJarDir]]

    # Load pkgIndex.tcl data.







|






|














|
|













|





|
|

|
















|


|



|
|

|











|
|




|


|



|
|



|
|
|










|
















|
|



|
|












|
|













|



|


|
|
|



|
|



|
|







81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
lappend PathMapp [file join [info library] $pkgOptDir] TCLLIB/OPTDIR
lappend PathMapp [file join [info library] $pkgJarDir] TCLLIB/JARDIR
lappend PathMapp $tcl_library TCLLIB $TestsDir TESTSDIR

proc mapList {map listIn} {
    set listOut {}
    foreach element $listIn {
	lappend listOut [string map $map $element]
    }
    return $listOut
}
proc mapAndSortList {map listIn} {
    set listOut {}
    foreach element $listIn {
	lappend listOut [string map $map $element]
    }
    lsort $listOut
}

# Force actual loading of the safe package because we use unexported (and
# thus unautoindexed) APIs in this test result arguments:
catch {safe::interpConfigure}

testConstraint AutoSyncDefined 1

# high level general test
test safe-stock-7.1 {tests that everything works at high level with conventional AutoPathSync, use pkg opt} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    }
    set i [safe::interpCreate]
} -body {
    # no error shall occur:
    # (because the default access_path shall include 1st level sub dirs so
    #  package require in a child works like in the parent)
    set v [interp eval $i {package require opt}]
    # no error shall occur:
    interp eval $i {::tcl::Lempty {a list}}
    set v
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result 0.4.*
test safe-stock-7.2 {tests specific path and interpFind/AddToAccessPath with conventional AutoPathSync, use pkg opt} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    } else {
	set SyncVal_TMP 1
    }
} -body {
    set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
    # should not add anything (p0)
    set token1 [safe::interpAddToAccessPath $i [info library]]
    # should add as p* (not p1 if parent has a module path)
    set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
    # an error shall occur (opt is not anymore in the secure 0-level
    # provided deep path)
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    list $token1 $token2 -- \
	    [catch {interp eval $i {package require opt}} msg] $msg -- \
	    $mappA -- [safe::interpDelete $i]
} -cleanup {
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result "{\$p(:0:)} {\$p(:*:)} -- 1 {$pkgOptErrMsg} --\
	{TCLLIB */dummy/unixlike/test/path} -- {}"
test safe-stock-7.4 {tests specific path and positive search with conventional AutoPathSync, use pkg opt} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    } else {
	set SyncVal_TMP 1
    }
} -body {
    set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
    # should not add anything (p0)
    set token1 [safe::interpAddToAccessPath $i [info library]]
    # should add as p* (not p1 if parent has a module path)
    set token2 [safe::interpAddToAccessPath $i [file join [info library] $pkgOptDir]]
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    # this time, unlike test safe-stock-7.2, opt should be found
    list $token1 $token2 -- \
	    [catch {interp eval $i {package require opt}} msg] $msg -- \
	    $mappA -- [safe::interpDelete $i]
    # Note that the glob match elides directories (those from the module path)
    # other than the first and last in the access path.
} -cleanup {
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:0:)} {$p(:*:)} -- 0 0.4.* --\
	{TCLLIB * TCLLIB/OPTDIR} -- {}}
test safe-stock-7.5 {tests positive and negative module loading with conventional AutoPathSync} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    }
    set i [safe::interpCreate]
    interp eval $i {
	package forget platform::shell
	package forget platform
	catch {namespace delete ::platform}
    }
} -body {
    # Should raise an error (module ancestor directory issue)
    set code1 [catch {interp eval $i {package require shell}} msg1]
    # Should not raise an error
    set code2 [catch {interp eval $i {package require platform::shell}} msg2]
    return [list $code1 $msg1 $code2]
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {1 {can't find package shell} 0}

# The following test checks whether the definition of tcl_endOfWord can be
# obtained from auto_loading.  It was previously test "safe-5.1".
test safe-stock-9.8 {test auto-loading in safe interpreters, was safe-5.1} -setup {
    catch {safe::interpDelete a}
    safe::interpCreate a
} -body {
    interp eval a {tcl_endOfWord "" 0}
} -cleanup {
    safe::interpDelete a
} -result -1
test safe-stock-9.11 {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement with conventional AutoPathSync, uses pkg opt and tcl::idna} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    }
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library \
					    [file join $tcl_library $pkgOptDir] \
					    [file join $tcl_library $pkgJarDir]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgOptDir]]
    set path2 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgJarDir]]

    # Load pkgIndex.tcl data.
    catch {interp eval $i {package require NOEXIST}}

    # Rearrange access path.  Swap tokens {$p(:1:)} and {$p(:2:)}.
    # This has no effect because the records in Pkg of these directories were from access as children of {$p(:0:)}.
    safe::interpConfigure $i -accessPath [list $tcl_library \
					   [file join $tcl_library $pkgJarDir] \
					   [file join $tcl_library $pkgOptDir]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path3 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgOptDir]]
    set path4 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgJarDir]]

    # Try to load the packages and run a command from each one.
    set code3 [catch {interp eval $i {package require tcl::idna}} msg3]
    set code4 [catch {interp eval $i {package require opt}} msg4]
    set code5 [catch {interp eval $i {::tcl::Lempty {a list}}} msg5]
    set code6 [catch {interp eval $i {::tcl::idna::IDNAencode example.com}} msg6]

    list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- \
	 $mappA -- $mappB -- $code5 $msg5 $code6 $msg6
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} -- 0 1.* 0 0.4.* --\
	{TCLLIB TCLLIB/OPTDIR TCLLIB/JARDIR*} --\
	{TCLLIB TCLLIB/JARDIR TCLLIB/OPTDIR*} --\
	0 0 0 example.com}
test safe-stock-9.13 {interpConfigure change the access path; pkgIndex.tcl packages fail if directory de-listed with conventional AutoPathSync, uses pkg opt and tcl::idna} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    }
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library \
					    [file join $tcl_library $pkgOptDir] \
					    [file join $tcl_library $pkgJarDir]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgOptDir]]
    set path2 [::safe::interpFindInAccessPath $i [file join $tcl_library $pkgJarDir]]

    # Load pkgIndex.tcl data.
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
    set code5 [catch {::safe::interpFindInAccessPath $i [file join $tcl_library $pkgJarDir]} path5]

    # Try to load the packages.
    set code3 [catch {interp eval $i {package require opt}} msg3]
    set code6 [catch {interp eval $i {package require tcl::idna}} msg6]

    list $path1 $path2 -- $code4 $path4 -- $code5 $path5 -- $code3 $code6 -- \
            $mappA -- $mappB
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- 1 {* not found in access path} --\
        1 {* not found in access path} -- 1 1 --\
        {TCLLIB TCLLIB/OPTDIR TCLLIB/JARDIR*} -- {TCLLIB*}}

test safe-stock-18.1 {cf. safe-stock-7.1opt - tests that everything works at high level without conventional AutoPathSync, use pkg opt} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    # Without AutoPathSync, we need a more complete auto_path,
    # because the child will use the same value.
    set lib1        [info library]
    set lib2        [file dirname $lib1]
    set ::auto_TMP  $::auto_path
    set ::auto_path [list $lib1 $lib2]







|



|


|
|




|
|

|







291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
    set code5 [catch {::safe::interpFindInAccessPath $i [file join $tcl_library $pkgJarDir]} path5]

    # Try to load the packages.
    set code3 [catch {interp eval $i {package require opt}} msg3]
    set code6 [catch {interp eval $i {package require tcl::idna}} msg6]

    list $path1 $path2 -- $code4 $path4 -- $code5 $path5 -- $code3 $code6 -- \
	    $mappA -- $mappB
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- 1 {* not found in access path} --\
	1 {* not found in access path} -- 1 1 --\
	{TCLLIB TCLLIB/OPTDIR TCLLIB/JARDIR*} -- {TCLLIB*}}

test safe-stock-18.1 {cf. safe-stock-7.1opt - tests that everything works at high level without conventional AutoPathSync, use pkg opt} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    # Without AutoPathSync, we need a more complete auto_path,
    # because the child will use the same value.
    set lib1        [info library]
    set lib2        [file dirname $lib1]
    set ::auto_TMP  $::auto_path
    set ::auto_path [list $lib1 $lib2]
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
    set v [interp eval $i {package require opt}]
    # no error shall occur:
    interp eval $i {::tcl::Lempty {a list}}
    set v
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result 0.4.*
test safe-stock-18.2 {cf. safe-stock-7.2opt - tests specific path and interpFind/AddToAccessPath without conventional AutoPathSync, use pkg opt} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
    set auto1 [interp eval $i {set ::auto_path}]
    # This will differ from the value -autoPath {}
    interp eval $i {set ::auto_path [list {$p(:0:)}]}
    # should not add anything (p0)
    set token1 [safe::interpAddToAccessPath $i [info library]]
    # should add as p* (not p1 if parent has a module path)
    set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
    # an error shall occur (opt is not anymore in the secure 0-level
    # provided deep path)
    list $auto1 $token1 $token2 \
	    [catch {interp eval $i {package require opt}} msg] $msg \
	    [safe::interpConfigure $i]\
	    [safe::interpDelete $i]
} -cleanup {
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result "{} {\$p(:0:)} {\$p(:*:)} 1 {$pkgOptErrMsg}\
        {-accessPath {[list $tcl_library */dummy/unixlike/test/path]}\
        -statics 0 -nested 1 -deleteHook {} -autoPath {}} {}"
test safe-stock-18.4 {cf. safe-stock-7.4opt - tests specific path and positive search and auto_path without conventional AutoPathSync, use pkg opt} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]

    # should not have been set by Safe Base:
    set auto1 [interp eval $i {set ::auto_path}]








|





|
|

|


















|


|
|



|
|

|







329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
    set v [interp eval $i {package require opt}]
    # no error shall occur:
    interp eval $i {::tcl::Lempty {a list}}
    set v
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result 0.4.*
test safe-stock-18.2 {cf. safe-stock-7.2opt - tests specific path and interpFind/AddToAccessPath without conventional AutoPathSync, use pkg opt} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
    set auto1 [interp eval $i {set ::auto_path}]
    # This will differ from the value -autoPath {}
    interp eval $i {set ::auto_path [list {$p(:0:)}]}
    # should not add anything (p0)
    set token1 [safe::interpAddToAccessPath $i [info library]]
    # should add as p* (not p1 if parent has a module path)
    set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
    # an error shall occur (opt is not anymore in the secure 0-level
    # provided deep path)
    list $auto1 $token1 $token2 \
	    [catch {interp eval $i {package require opt}} msg] $msg \
	    [safe::interpConfigure $i]\
	    [safe::interpDelete $i]
} -cleanup {
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result "{} {\$p(:0:)} {\$p(:*:)} 1 {$pkgOptErrMsg}\
	{-accessPath {[list $tcl_library */dummy/unixlike/test/path]}\
	-statics 0 -nested 1 -deleteHook {} -autoPath {}} {}"
test safe-stock-18.4 {cf. safe-stock-7.4opt - tests specific path and positive search and auto_path without conventional AutoPathSync, use pkg opt} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]

    # should not have been set by Safe Base:
    set auto1 [interp eval $i {set ::auto_path}]

398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
	    [safe::interpConfigure $i]\
	    [safe::interpDelete $i]
} -cleanup {
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result "{} {{\$p(:0:)}} {\$p(:0:)} {\$p(:*:)} 0 0.4.*\
        {-accessPath {[list $tcl_library *$tcl_library/$pkgOptDir]}\
        -statics 0 -nested 1 -deleteHook {} -autoPath {}} {}"
test safe-stock-18.5 {cf. safe-stock-7.5 - tests positive and negative module loading without conventional AutoPathSync} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate]
    interp eval $i {
        package forget platform::shell
        package forget platform
        catch {namespace delete ::platform}
    }
} -body {
    # Should raise an error (tests module ancestor directory rule)
    set code1 [catch {interp eval $i {package require shell}} msg1]
    # Should not raise an error
    set code2 [catch {interp eval $i {package require platform::shell}} msg2]
    return [list $code1 $msg1 $code2]
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {1 {can't find package shell} 0}

set ::auto_path $SaveAutoPath
unset pkgOptErrMsg pkgOptDir pkgJarDir SaveAutoPath TestsDir PathMapp
rename mapList {}
rename mapAndSortList {}







|
|



|
|

|



|
|
|










|







398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
	    [safe::interpConfigure $i]\
	    [safe::interpDelete $i]
} -cleanup {
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result "{} {{\$p(:0:)}} {\$p(:0:)} {\$p(:*:)} 0 0.4.*\
	{-accessPath {[list $tcl_library *$tcl_library/$pkgOptDir]}\
	-statics 0 -nested 1 -deleteHook {} -autoPath {}} {}"
test safe-stock-18.5 {cf. safe-stock-7.5 - tests positive and negative module loading without conventional AutoPathSync} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate]
    interp eval $i {
	package forget platform::shell
	package forget platform
	catch {namespace delete ::platform}
    }
} -body {
    # Should raise an error (tests module ancestor directory rule)
    set code1 [catch {interp eval $i {package require shell}} msg1]
    # Should not raise an error
    set code2 [catch {interp eval $i {package require platform::shell}} msg2]
    return [list $code1 $msg1 $code2]
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {1 {can't find package shell} 0}

set ::auto_path $SaveAutoPath
unset pkgOptErrMsg pkgOptDir pkgJarDir SaveAutoPath TestsDir PathMapp
rename mapList {}
rename mapAndSortList {}
Changes to tests/safe-zipfs.test.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
# this file, and for a DISCLAIMER OF ALL WARRANTIES.


apply [list {} {
    global auto_path
    global tcl_library
    if {"::tcltest" ni [namespace children]} {
        package require tcltest 2.5
        namespace import -force ::tcltest::*
    }

    foreach i [interp children] {
        interp delete $i
    }

    set SaveAutoPath $::auto_path
    set ::auto_path [info library]
    set TestsDir [file normalize [file dirname [info script]]]

    set ZipMountPoint [zipfs root]auto-files
    zipfs mount [file join $TestsDir auto-files.zip] $ZipMountPoint

    set PathMapp {}
    lappend PathMapp $tcl_library TCLLIB $TestsDir TESTSDIR $ZipMountPoint ZIPDIR

    proc mapList {map listIn} {
        set listOut {}
        foreach element $listIn {
            lappend listOut [string map $map $element]
        }
        return $listOut
    }
    proc mapAndSortList {map listIn} {
        set listOut {}
        foreach element $listIn {
            lappend listOut [string map $map $element]
        }
        lsort $listOut
    }

    # Force actual loading of the safe package because we use un-exported (and
    # thus un-autoindexed) APIs in this test result arguments:
    catch {safe::interpConfigure}

    testConstraint AutoSyncDefined 1

    # Tests 5.* test the example files before using them to test safe interpreters.

    test safe-zipfs-5.1 {example tclIndex commands, test in parent interpreter; zipfs} -setup {
        set tmpAutoPath $::auto_path
        lappend ::auto_path [file join $ZipMountPoint auto0 auto1] [file join $ZipMountPoint auto0 auto2]
    } -body {
        # Try to load the commands.
        set code3 [catch report1 msg3]
        set code4 [catch report2 msg4]
        list $code3 $msg3 $code4 $msg4
    } -cleanup {
        catch {rename report1 {}}
        catch {rename report2 {}}
        set ::auto_path $tmpAutoPath
        auto_reset
    } -match glob -result {0 ok1 0 ok2}
    test safe-zipfs-5.2 {example tclIndex commands, negative test in parent interpreter; zipfs} -setup {
        set tmpAutoPath $::auto_path
        lappend ::auto_path [file join $ZipMountPoint auto0]
    } -body {
        # Try to load the commands.
        set code3 [catch report1 msg3]
        set code4 [catch report2 msg4]
        list $code3 $msg3 $code4 $msg4
    } -cleanup {
        catch {rename report1 {}}
        catch {rename report2 {}}
        set ::auto_path $tmpAutoPath
        auto_reset
    } -match glob -result {1 {invalid command name "report1"} 1 {invalid command name "report2"}}
    test safe-zipfs-5.3 {example pkgIndex.tcl packages, test in parent interpreter, child directories; zipfs} -setup {
        set tmpAutoPath $::auto_path
        lappend ::auto_path [file join $ZipMountPoint auto0]
    } -body {
        # Try to load the packages and run a command from each one.
        set code3 [catch {package require SafeTestPackage1} msg3]
        set code4 [catch {package require SafeTestPackage2} msg4]
        set code5 [catch HeresPackage1 msg5]
        set code6 [catch HeresPackage2 msg6]
        list $code3 $msg3 $code4 $msg4 $code5 $msg5 $code6 $msg6
    } -cleanup {
        set ::auto_path $tmpAutoPath
        catch {package forget SafeTestPackage1}
        catch {package forget SafeTestPackage2}
        catch {rename HeresPackage1 {}}
        catch {rename HeresPackage2 {}}
    } -match glob -result {0 1.2.3 0 2.3.4 0 OK1 0 OK2}
    test safe-zipfs-5.4 {example pkgIndex.tcl packages, test in parent interpreter, main directories; zipfs} -setup {
        set tmpAutoPath $::auto_path
        lappend ::auto_path [file join $ZipMountPoint auto0 auto1]  [file join $ZipMountPoint auto0 auto2]
    } -body {
        # Try to load the packages and run a command from each one.
        set code3 [catch {package require SafeTestPackage1} msg3]
        set code4 [catch {package require SafeTestPackage2} msg4]
        set code5 [catch HeresPackage1 msg5]
        set code6 [catch HeresPackage2 msg6]
        list $code3 $msg3 $code4 $msg4 $code5 $msg5 $code6 $msg6
    } -cleanup {
        set ::auto_path $tmpAutoPath
        catch {package forget SafeTestPackage1}
        catch {package forget SafeTestPackage2}
        catch {rename HeresPackage1 {}}
        catch {rename HeresPackage2 {}}
    } -match glob -result {0 1.2.3 0 2.3.4 0 OK1 0 OK2}
    test safe-zipfs-5.5 {example modules packages, test in parent interpreter, replace path; zipfs} -setup {
        set oldTm [tcl::tm::path list]
        foreach path $oldTm {
            tcl::tm::path remove $path
        }
        tcl::tm::path add [file join $ZipMountPoint auto0 modules]
    } -body {
        # Try to load the modules and run a command from each one.
        set code0 [catch {package require test0} msg0]
        set code1 [catch {package require mod1::test1} msg1]
        set code2 [catch {package require mod2::test2} msg2]
        set out0  [test0::try0]
        set out1  [mod1::test1::try1]
        set out2  [mod2::test2::try2]
        list $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $out0 $out1 $out2
    } -cleanup {
        tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
        foreach path [lreverse $oldTm] {
            tcl::tm::path add $path
        }
        catch {package forget test0}
        catch {package forget mod1::test1}
        catch {package forget mod2::test2}
        catch {namespace delete ::test0}
        catch {namespace delete ::mod1}
    } -match glob -result {0 0.5 0 1.0 0 2.0 -- res0 res1 res2}
    test safe-zipfs-5.6 {example modules packages, test in parent interpreter, append to path; zipfs} -setup {
        tcl::tm::path add [file join $ZipMountPoint auto0 modules]
    } -body {
        # Try to load the modules and run a command from each one.
        set code0 [catch {package require test0} msg0]
        set code1 [catch {package require mod1::test1} msg1]
        set code2 [catch {package require mod2::test2} msg2]
        set out0  [test0::try0]
        set out1  [mod1::test1::try1]
        set out2  [mod2::test2::try2]
        list $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $out0 $out1 $out2
    } -cleanup {
        tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
        catch {package forget test0}
        catch {package forget mod1::test1}
        catch {package forget mod2::test2}
        catch {namespace delete ::test0}
        catch {namespace delete ::mod1}
    } -match glob -result {0 0.5 0 1.0 0 2.0 -- res0 res1 res2}

    # high level general test
    # Use zipped example packages not http1.0 etc
    test safe-zipfs-7.1 {tests that everything works at high level with conventional AutoPathSync; zipfs} -setup {
        set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
        if {$SyncExists} {
            set SyncVal_TMP [safe::setSyncMode]
            safe::setSyncMode 1
        }
        set tmpAutoPath $::auto_path
        lappend ::auto_path [file join $ZipMountPoint auto0]
        set i [safe::interpCreate]
        set ::auto_path $tmpAutoPath
    } -body {
        # no error shall occur:
        # (because the default access_path shall include 1st level sub dirs so
        #  package require in a child works like in the parent)
        set v [interp eval $i {package require SafeTestPackage1}]
        # no error shall occur:
        interp eval $i {HeresPackage1}
        set v
    } -cleanup {
        safe::interpDelete $i
        if {$SyncExists} {
            safe::setSyncMode $SyncVal_TMP
        }
    } -match glob -result 1.2.3
    test safe-zipfs-7.2 {tests specific path and interpFind/AddToAccessPath with conventional AutoPathSync; zipfs} -setup {
        set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
        if {$SyncExists} {
            set SyncVal_TMP [safe::setSyncMode]
            safe::setSyncMode 1
        } else {
            set SyncVal_TMP 1
        }
    } -body {
        set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
        # should not add anything (p0)
        set token1 [safe::interpAddToAccessPath $i [info library]]
        # should add as p* (not p1 if parent has a module path)
        set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
        # should add as p* (not p2 if parent has a module path)
        set token3 [safe::interpAddToAccessPath $i [file join $ZipMountPoint auto0]]
        set confA [safe::interpConfigure $i]
        set mappA [mapList $PathMapp [dict get $confA -accessPath]]
        # an error shall occur (SafeTestPackage1 is not anymore in the secure 0-level
        # provided deep path)
        list $token1 $token2 $token3 --  [catch {interp eval $i {package require SafeTestPackage1}} msg] $msg --  $mappA -- [safe::interpDelete $i]
    } -cleanup {
        if {$SyncExists} {
            safe::setSyncMode $SyncVal_TMP
        }
    } -match glob -result {{$p(:0:)} {$p(:*:)} {$p(:*:)} -- 1 {can't find package SafeTestPackage1} -- {TCLLIB */dummy/unixlike/test/path ZIPDIR/auto0} -- {}}
    test safe-zipfs-7.4 {tests specific path and positive search with conventional AutoPathSync; zipfs} -setup {
        set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
        if {$SyncExists} {
            set SyncVal_TMP [safe::setSyncMode]
            safe::setSyncMode 1
        } else {
            set SyncVal_TMP 1
        }
    } -body {
        set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
        # should not add anything (p0)
        set token1 [safe::interpAddToAccessPath $i [info library]]
        # should add as p* (not p1 if parent has a module path)
        set token2 [safe::interpAddToAccessPath $i [file join $ZipMountPoint auto0 auto1]]
        set confA [safe::interpConfigure $i]
        set mappA [mapList $PathMapp [dict get $confA -accessPath]]
        # this time, unlike test safe-zipfs-7.2, SafeTestPackage1 should be found
        list $token1 $token2 --  [catch {interp eval $i {package require SafeTestPackage1}} msg] $msg --  $mappA -- [safe::interpDelete $i]
        # Note that the glob match elides directories (those from the module path)
        # other than the first and last in the access path.
    } -cleanup {
        if {$SyncExists} {
            safe::setSyncMode $SyncVal_TMP
        }
    } -match glob -result {{$p(:0:)} {$p(:*:)} -- 0 1.2.3 -- {TCLLIB * ZIPDIR/auto0/auto1} -- {}}

    test safe-zipfs-9.9 {interpConfigure change the access path; tclIndex commands unaffected by token rearrangement (dummy test of doreset) with conventional AutoPathSync; zipfs} -setup {
        set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
        if {$SyncExists} {
            set SyncVal_TMP [safe::setSyncMode]
            safe::setSyncMode 1
        }
    } -body {
        set i [safe::interpCreate -accessPath [list $tcl_library  [file join $ZipMountPoint auto0 auto1]  [file join $ZipMountPoint auto0 auto2]]]
        # Inspect.
        set confA [safe::interpConfigure $i]
        set mappA [mapList $PathMapp [dict get $confA -accessPath]]
        set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
        set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]

        # Load auto_load data.
        interp eval $i {catch nonExistentCommand}

        # Load and run the commands.
        # This guarantees the test will pass even if the tokens are swapped.
        set code1 [catch {interp eval $i {report1}} msg1]
        set code2 [catch {interp eval $i {report2}} msg2]

        # Rearrange access path.  Swap tokens {$p(:1:)} and {$p(:2:)}.
        safe::interpConfigure $i -accessPath [list $tcl_library  [file join $ZipMountPoint auto0 auto2]  [file join $ZipMountPoint auto0 auto1]]
        # Inspect.
        set confB [safe::interpConfigure $i]
        set mappB [mapList $PathMapp [dict get $confB -accessPath]]
        set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
        set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]

        # Run the commands.
        set code3 [catch {interp eval $i {report1}} msg3]
        set code4 [catch {interp eval $i {report2}} msg4]

        list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- $mappA -- $mappB
    } -cleanup {
        safe::interpDelete $i
        if {$SyncExists} {
            safe::setSyncMode $SyncVal_TMP
        }
    } -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} -- 0 ok1 0 ok2 -- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2*} -- {TCLLIB ZIPDIR/auto0/auto2 ZIPDIR/auto0/auto1*}}
    test safe-zipfs-9.10 {interpConfigure change the access path; tclIndex commands unaffected by token rearrangement (actual test of doreset) with conventional AutoPathSync; zipfs} -setup {
        set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
        if {$SyncExists} {
            set SyncVal_TMP [safe::setSyncMode]
            safe::setSyncMode 1
        }
    } -body {
        set i [safe::interpCreate -accessPath [list $tcl_library  [file join $ZipMountPoint auto0 auto1]  [file join $ZipMountPoint auto0 auto2]]]
        # Inspect.
        set confA [safe::interpConfigure $i]
        set mappA [mapList $PathMapp [dict get $confA -accessPath]]
        set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
        set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]

        # Load auto_load data.
        interp eval $i {catch nonExistentCommand}

        # Do not load the commands.  With the tokens swapped, the test
        # will pass only if the Safe Base has called auto_reset.

        # Rearrange access path.  Swap tokens {$p(:1:)} and {$p(:2:)}.
        safe::interpConfigure $i -accessPath [list $tcl_library  [file join $ZipMountPoint auto0 auto2]  [file join $ZipMountPoint auto0 auto1]]
        # Inspect.
        set confB [safe::interpConfigure $i]
        set mappB [mapList $PathMapp [dict get $confB -accessPath]]
        set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
        set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]

        # Load and run the commands.
        set code3 [catch {interp eval $i {report1}} msg3]
        set code4 [catch {interp eval $i {report2}} msg4]

        list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- $mappA -- $mappB
    } -cleanup {
        safe::interpDelete $i
        if {$SyncExists} {
            safe::setSyncMode $SyncVal_TMP
        }
    } -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} -- 0 ok1 0 ok2 -- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2*} -- {TCLLIB ZIPDIR/auto0/auto2 ZIPDIR/auto0/auto1*}}
    test safe-zipfs-9.11 {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement with conventional AutoPathSync; zipfs} -setup {
        set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
        if {$SyncExists} {
            set SyncVal_TMP [safe::setSyncMode]
            safe::setSyncMode 1
        }
    } -body {
        # For complete correspondence to safe-stock-9.11, include auto0 in access path.
        set i [safe::interpCreate -accessPath [list $tcl_library  [file join $ZipMountPoint auto0]  [file join $ZipMountPoint auto0 auto1]  [file join $ZipMountPoint auto0 auto2]]]
        # Inspect.
        set confA [safe::interpConfigure $i]
        set mappA [mapList $PathMapp [dict get $confA -accessPath]]
        set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0]]
        set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
        set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]

        # Load pkgIndex.tcl data.
        catch {interp eval $i {package require NOEXIST}}

        # Rearrange access path.  Swap tokens {$p(:2:)} and {$p(:3:)}.
        # This would have no effect because the records in Pkg of these directories
        # were from access as children of {$p(:1:)}.
        safe::interpConfigure $i -accessPath [list $tcl_library  [file join $ZipMountPoint auto0]  [file join $ZipMountPoint auto0 auto2]  [file join $ZipMountPoint auto0 auto1]]
        # Inspect.
        set confB [safe::interpConfigure $i]
        set mappB [mapList $PathMapp [dict get $confB -accessPath]]
        set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
        set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]

        # Try to load the packages and run a command from each one.
        set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3 opts3]
        set code4 [catch {interp eval $i {package require SafeTestPackage2}} msg4 opts4]
        set code5 [catch {interp eval $i {HeresPackage1}} msg5 opts5]
        set code6 [catch {interp eval $i {HeresPackage2}} msg6 opts6]

        list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 --  $mappA -- $mappB -- $code5 $msg5 $code6 $msg6
    } -cleanup {
        safe::interpDelete $i
        if {$SyncExists} {
            safe::setSyncMode $SyncVal_TMP
        }
    } -match glob -result {{$p(:2:)} {$p(:3:)} -- {$p(:3:)} {$p(:2:)} -- 0 1.2.3 0 2.3.4 -- {TCLLIB ZIPDIR/auto0 ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2*} -- {TCLLIB ZIPDIR/auto0 ZIPDIR/auto0/auto2 ZIPDIR/auto0/auto1*} -- 0 OK1 0 OK2}
    test safe-zipfs-9.12 {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement, 9.10 without path auto0 with conventional AutoPathSync; zipfs} -setup {
        set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
        if {$SyncExists} {
            set SyncVal_TMP [safe::setSyncMode]
            safe::setSyncMode 1
        }
    } -body {
        set i [safe::interpCreate -accessPath [list $tcl_library  [file join $ZipMountPoint auto0 auto1]  [file join $ZipMountPoint auto0 auto2]]]
        # Inspect.
        set confA [safe::interpConfigure $i]
        set mappA [mapList $PathMapp [dict get $confA -accessPath]]
        set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
        set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]

        # Load pkgIndex.tcl data.
        catch {interp eval $i {package require NOEXIST}}

        # Rearrange access path.  Swap tokens {$p(:1:)} and {$p(:2:)}.
        safe::interpConfigure $i -accessPath [list $tcl_library  [file join $ZipMountPoint auto0 auto2]  [file join $ZipMountPoint auto0 auto1]]
        # Inspect.
        set confB [safe::interpConfigure $i]
        set mappB [mapList $PathMapp [dict get $confB -accessPath]]
        set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
        set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]

        # Try to load the packages and run a command from each one.
        set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3 opts3]
        set code4 [catch {interp eval $i {package require SafeTestPackage2}} msg4 opts4]
        set code5 [catch {interp eval $i {HeresPackage1}} msg5 opts5]
        set code6 [catch {interp eval $i {HeresPackage2}} msg6 opts6]

        list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 --  $mappA -- $mappB -- $code5 $msg5 $code6 $msg6
    } -cleanup {
        safe::interpDelete $i
        if {$SyncExists} {
            safe::setSyncMode $SyncVal_TMP
        }
    } -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} -- 0 1.2.3 0 2.3.4 -- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2*} -- {TCLLIB ZIPDIR/auto0/auto2 ZIPDIR/auto0/auto1*} -- 0 OK1 0 OK2}
    test safe-zipfs-9.13 {interpConfigure change the access path; pkgIndex.tcl packages fail if directory de-listed, with conventional AutoPathSync; zipfs} -setup {
        set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
        if {$SyncExists} {
            set SyncVal_TMP [safe::setSyncMode]
            safe::setSyncMode 1
        }
    } -body {
        set i [safe::interpCreate -accessPath [list $tcl_library  [file join $ZipMountPoint auto0 auto1]  [file join $ZipMountPoint auto0 auto2]]]
        # Inspect.
        set confA [safe::interpConfigure $i]
        set mappA [mapList $PathMapp [dict get $confA -accessPath]]
        set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
        set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]

        # Load pkgIndex.tcl data.
        catch {interp eval $i {package require NOEXIST}}

        # Limit access path.  Remove tokens {$p(:1:)} and {$p(:2:)}.
        safe::interpConfigure $i -accessPath [list $tcl_library]

        # Inspect.
        set confB [safe::interpConfigure $i]
        set mappB [mapList $PathMapp [dict get $confB -accessPath]]
        set code4 [catch {::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]} path4]
        set code5 [catch {::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]} path5]

        # Try to load the packages.
        set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3]
        set code6 [catch {interp eval $i {package require SafeTestPackage2}} msg6]

        list $path1 $path2 -- $code4 $path4 -- $code5 $path5 -- $code3 $code6 --  $mappA -- $mappB
    } -cleanup {
        safe::interpDelete $i
        if {$SyncExists} {
            safe::setSyncMode $SyncVal_TMP
        }
    } -match glob -result {{$p(:1:)} {$p(:2:)} -- 1 {* not found in access path} -- 1 {* not found in access path} -- 1 1 -- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2*} -- {TCLLIB*}}
    test safe-zipfs-9.20 {check module loading, with conventional AutoPathSync; zipfs} -setup {
        set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
        if {$SyncExists} {
            set SyncVal_TMP [safe::setSyncMode]
            safe::setSyncMode 1
        }
        set oldTm [tcl::tm::path list]
        foreach path $oldTm {
            tcl::tm::path remove $path
        }
        tcl::tm::path add [file join $ZipMountPoint auto0 modules]
    } -body {
        set i [safe::interpCreate -accessPath [list $tcl_library]]

        # Inspect.
        set confA [safe::interpConfigure $i]
        set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
        set modsA [interp eval $i {tcl::tm::path list}]
        set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
        set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
        set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]

        # Try to load the packages and run a command from each one.
        set code0 [catch {interp eval $i {package require test0}} msg0]
        set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
        set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
        set out0  [interp eval $i {test0::try0}]
        set out1  [interp eval $i {mod1::test1::try1}]
        set out2  [interp eval $i {mod2::test2::try2}]

        list [lsort [list $path0 $path1 $path2]] -- $modsA --  $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $out0 $out1 $out2
    } -cleanup {
        tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
        foreach path [lreverse $oldTm] {
            tcl::tm::path add $path
        }
        safe::interpDelete $i
        if {$SyncExists} {
            safe::setSyncMode $SyncVal_TMP
        }
    } -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} -- 0 0.5 0 1.0 0 2.0 -- {TCLLIB ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} -- res0 res1 res2}
    # - The command safe::InterpSetConfig adds the parent's [tcl::tm::list] in
    #   tokenized form to the child's access path, and then adds all the
    #   descendants, discovered recursively by using glob.
    # - The order of the directories in the list returned by glob is system-dependent,
    #   and therefore this is true also for (a) the order of token assignment to
    #   descendants of the [tcl::tm::list] roots; and (b) the order of those same
    #   directories in the access path.  Both those things must be sorted before
    #   comparing with expected results.  The test is therefore not totally strict,
    #   but will notice missing or surplus directories.
    test safe-zipfs-9.21 {interpConfigure change the access path; check module loading, with conventional AutoPathSync; stale data case 1; zipfs} -setup {
        set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
        if {$SyncExists} {
            set SyncVal_TMP [safe::setSyncMode]
            safe::setSyncMode 1
        }
        set oldTm [tcl::tm::path list]
        foreach path $oldTm {
            tcl::tm::path remove $path
        }
        tcl::tm::path add [file join $ZipMountPoint auto0 modules]
    } -body {
        set i [safe::interpCreate -accessPath [list $tcl_library]]

        # Inspect.
        set confA [safe::interpConfigure $i]
        set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
        set modsA [interp eval $i {tcl::tm::path list}]
        set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
        set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
        set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]

        # Add to access path.
        # This injects more tokens, pushing modules to higher token numbers.
        safe::interpConfigure $i -accessPath [list $tcl_library  [file join $ZipMountPoint auto0 auto1]  [file join $ZipMountPoint auto0 auto2]]
        # Inspect.
        set confB [safe::interpConfigure $i]
        set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
        set modsB [interp eval $i {tcl::tm::path list}]
        set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
        set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
        set path5 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]

        # Load pkg data.
        catch {interp eval $i {package require NOEXIST}}
        catch {interp eval $i {package require mod1::NOEXIST}}
        catch {interp eval $i {package require mod2::NOEXIST}}

        # Try to load the packages and run a command from each one.
        set code0 [catch {interp eval $i {package require test0}} msg0]
        set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
        set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
        set out0  [interp eval $i {test0::try0}]
        set out1  [interp eval $i {mod1::test1::try1}]
        set out2  [interp eval $i {mod2::test2::try2}]

        list [lsort [list $path0 $path1 $path2]] -- $modsA --  [lsort [list $path3 $path4 $path5]] -- $modsB --  $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB --  $out0 $out1 $out2
    } -cleanup {
        tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
        foreach path [lreverse $oldTm] {
            tcl::tm::path add $path
        }
        safe::interpDelete $i
        if {$SyncExists} {
            safe::setSyncMode $SyncVal_TMP
        }
    } -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} -- {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} -- 0 0.5 0 1.0 0 2.0 -- {TCLLIB ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} -- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2 ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} -- res0 res1 res2}
    # See comments on lsort after test safe-zipfs-9.20.
    test safe-zipfs-9.22 {interpConfigure change the access path; check module loading, with conventional AutoPathSync; stale data case 0; zipfs} -setup {
        set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
        if {$SyncExists} {
            set SyncVal_TMP [safe::setSyncMode]
            safe::setSyncMode 1
        }
        set oldTm [tcl::tm::path list]
        foreach path $oldTm {
            tcl::tm::path remove $path
        }
        tcl::tm::path add [file join $ZipMountPoint auto0 modules]
    } -body {
        set i [safe::interpCreate -accessPath [list $tcl_library]]

        # Inspect.
        set confA [safe::interpConfigure $i]
        set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
        set modsA [interp eval $i {tcl::tm::path list}]
        set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
        set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
        set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]

        # Add to access path.
        # This injects more tokens, pushing modules to higher token numbers.
        safe::interpConfigure $i -accessPath [list $tcl_library  [file join $ZipMountPoint auto0 auto1]  [file join $ZipMountPoint auto0 auto2]]
        # Inspect.
        set confB [safe::interpConfigure $i]
        set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
        set modsB [interp eval $i {tcl::tm::path list}]
        set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
        set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
        set path5 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]

        # Try to load the packages and run a command from each one.
        set code0 [catch {interp eval $i {package require test0}} msg0]
        set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
        set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
        set out0  [interp eval $i {test0::try0}]
        set out1  [interp eval $i {mod1::test1::try1}]
        set out2  [interp eval $i {mod2::test2::try2}]

        list [lsort [list $path0 $path1 $path2]] -- $modsA --  [lsort [list $path3 $path4 $path5]] -- $modsB --  $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB --  $out0 $out1 $out2
    } -cleanup {
        tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
        foreach path [lreverse $oldTm] {
            tcl::tm::path add $path
        }
        safe::interpDelete $i
        if {$SyncExists} {
            safe::setSyncMode $SyncVal_TMP
        }
    } -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} -- {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} -- 0 0.5 0 1.0 0 2.0 -- {TCLLIB ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} -- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2 ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} -- res0 res1 res2}
    # See comments on lsort after test safe-zipfs-9.20.
    test safe-zipfs-9.23 {interpConfigure change the access path; check module loading, with conventional AutoPathSync; stale data case 3; zipfs} -setup {
        set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
        if {$SyncExists} {
            set SyncVal_TMP [safe::setSyncMode]
            safe::setSyncMode 1
        }
        set oldTm [tcl::tm::path list]
        foreach path $oldTm {
            tcl::tm::path remove $path
        }
        tcl::tm::path add [file join $ZipMountPoint auto0 modules]
    } -body {
        set i [safe::interpCreate -accessPath [list $tcl_library]]

        # Inspect.
        set confA [safe::interpConfigure $i]
        set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
        set modsA [interp eval $i {tcl::tm::path list}]
        set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
        set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
        set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]

        # Force the interpreter to acquire pkg data which will soon become stale.
        catch {interp eval $i {package require NOEXIST}}
        catch {interp eval $i {package require mod1::NOEXIST}}
        catch {interp eval $i {package require mod2::NOEXIST}}

        # Add to access path.
        # This injects more tokens, pushing modules to higher token numbers.
        safe::interpConfigure $i -accessPath [list $tcl_library  [file join $ZipMountPoint auto0 auto1]  [file join $ZipMountPoint auto0 auto2]]
        # Inspect.
        set confB [safe::interpConfigure $i]
        set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
        set modsB [interp eval $i {tcl::tm::path list}]
        set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
        set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
        set path5 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]

        # Refresh stale pkg data.
        catch {interp eval $i {package require NOEXIST}}
        catch {interp eval $i {package require mod1::NOEXIST}}
        catch {interp eval $i {package require mod2::NOEXIST}}

        # Try to load the packages and run a command from each one.
        set code0 [catch {interp eval $i {package require test0}} msg0]
        set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
        set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
        set out0  [interp eval $i {test0::try0}]
        set out1  [interp eval $i {mod1::test1::try1}]
        set out2  [interp eval $i {mod2::test2::try2}]

        list [lsort [list $path0 $path1 $path2]] -- $modsA --  [lsort [list $path3 $path4 $path5]] -- $modsB --  $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB --  $out0 $out1 $out2
    } -cleanup {
        tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
        foreach path [lreverse $oldTm] {
            tcl::tm::path add $path
        }
        safe::interpDelete $i
        if {$SyncExists} {
            safe::setSyncMode $SyncVal_TMP
        }
    } -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} -- {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} -- 0 0.5 0 1.0 0 2.0 -- {TCLLIB ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} -- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2 ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} -- res0 res1 res2}
    # See comments on lsort after test safe-zipfs-9.20.
    test safe-zipfs-9.24 {interpConfigure change the access path; check module loading, with conventional AutoPathSync; stale data case 2 (worst case); zipfs} -setup {
        set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
        if {$SyncExists} {
            set SyncVal_TMP [safe::setSyncMode]
            safe::setSyncMode 1
        }
        set oldTm [tcl::tm::path list]
        foreach path $oldTm {
            tcl::tm::path remove $path
        }
        tcl::tm::path add [file join $ZipMountPoint auto0 modules]
    } -body {
        set i [safe::interpCreate -accessPath [list $tcl_library]]

        # Inspect.
        set confA [safe::interpConfigure $i]
        set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
        set modsA [interp eval $i {tcl::tm::path list}]
        set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
        set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
        set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]

        # Force the interpreter to acquire pkg data which will soon become stale.
        catch {interp eval $i {package require NOEXIST}}
        catch {interp eval $i {package require mod1::NOEXIST}}
        catch {interp eval $i {package require mod2::NOEXIST}}

        # Add to access path.
        # This injects more tokens, pushing modules to higher token numbers.
        safe::interpConfigure $i -accessPath [list $tcl_library  [file join $ZipMountPoint auto0 auto1]  [file join $ZipMountPoint auto0 auto2]]
        # Inspect.
        set confB [safe::interpConfigure $i]
        set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
        set modsB [interp eval $i {tcl::tm::path list}]
        set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
        set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
        set path5 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]

        # Try to load the packages and run a command from each one.
        set code0 [catch {interp eval $i {package require test0}} msg0]
        set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
        set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
        set out0  [interp eval $i {test0::try0}]
        set out1  [interp eval $i {mod1::test1::try1}]
        set out2  [interp eval $i {mod2::test2::try2}]

        list [lsort [list $path0 $path1 $path2]] -- $modsA --  [lsort [list $path3 $path4 $path5]] -- $modsB --  $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB --  $out0 $out1 $out2
    } -cleanup {
        tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
        foreach path [lreverse $oldTm] {
            tcl::tm::path add $path
        }
        safe::interpDelete $i
        if {$SyncExists} {
            safe::setSyncMode $SyncVal_TMP
        }
    } -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} -- {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} -- 0 0.5 0 1.0 0 2.0 -- {TCLLIB ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} -- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2 ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} -- res0 res1 res2}
    # See comments on lsort after test safe-zipfs-9.20.

    test safe-zipfs-18.1 {cf. safe-zipfs-7.1 - tests that everything works at high level without conventional AutoPathSync; zipfs} -constraints AutoSyncDefined -setup {
        set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
        if {$SyncExists} {
            set SyncVal_TMP [safe::setSyncMode]
            safe::setSyncMode 0
        } else {
            error {This test is meaningful only if the command ::safe::setSyncMode is defined}
        }
        # Without AutoPathSync, we need a more complete auto_path,
        # because the child will use the same value.
        set lib1        [info library]
        set lib2        [file join $ZipMountPoint auto0]
        set ::auto_TMP  $::auto_path
        set ::auto_path [list $lib1 $lib2]

        set i [safe::interpCreate]
        set ::auto_path $::auto_TMP
    } -body {
        # no error shall occur:
        # (because the default access_path shall include 1st level sub dirs so
        #  package require in a child works like in the parent)
        set v [interp eval $i {package require SafeTestPackage1}]
        # no error shall occur:
        interp eval $i HeresPackage1
        set v
    } -cleanup {
        safe::interpDelete $i
        if {$SyncExists} {
            safe::setSyncMode $SyncVal_TMP
        }
    } -match glob -result 1.2.3
    test safe-zipfs-18.2 {cf. safe-zipfs-7.2 - tests specific path and interpFind/AddToAccessPath without conventional AutoPathSync; zipfs} -constraints AutoSyncDefined -setup {
        set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
        if {$SyncExists} {
            set SyncVal_TMP [safe::setSyncMode]
            safe::setSyncMode 0
        } else {
            error {This test is meaningful only if the command ::safe::setSyncMode is defined}
        }
    } -body {
        set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
        set auto1 [interp eval $i {set ::auto_path}]
        interp eval $i {set ::auto_path [list {$p(:0:)}]}
        # should not add anything (p0)
        set token1 [safe::interpAddToAccessPath $i [info library]]
        # should add as p* (not p1 if parent has a module path)
        set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
        # should add as p* (not p2 if parent has a module path)
        set token3 [safe::interpAddToAccessPath $i [file join $ZipMountPoint auto0]]
        # an error shall occur (SafeTestPackage1 is not anymore in the secure 0-level
        # provided deep path)
        list $auto1 $token1 $token2 $token3  [catch {interp eval $i {package require SafeTestPackage1}} msg] $msg  [safe::interpConfigure $i] [safe::interpDelete $i]
    } -cleanup {
        if {$SyncExists} {
            safe::setSyncMode $SyncVal_TMP
        }
    } -match glob -result "{} {\$p(:0:)} {\$p(:*:)} {\$p(:*:)} 1 {can't find package SafeTestPackage1} {-accessPath {[list $tcl_library  */dummy/unixlike/test/path  $ZipMountPoint/auto0]} -statics 0 -nested 1 -deleteHook {} -autoPath {}} {}"
    test safe-zipfs-18.4 {cf. safe-zipfs-7.4 - tests specific path and positive search and auto_path without conventional AutoPathSync; zipfs} -constraints AutoSyncDefined -setup {
        set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
        if {$SyncExists} {
            set SyncVal_TMP [safe::setSyncMode]
            safe::setSyncMode 0
        } else {
            error {This test is meaningful only if the command ::safe::setSyncMode is defined}
        }
    } -body {
        set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]

        # should not have been set by Safe Base:
        set auto1 [interp eval $i {set ::auto_path}]

        # This will differ from the value -autoPath {}
        interp eval $i {set ::auto_path [list {$p(:0:)}]}

        # should not add anything (p0)
        set token1 [safe::interpAddToAccessPath $i [info library]]

        # should add as p* (not p1 if parent has a module path)
        set token2 [safe::interpAddToAccessPath $i [file join $ZipMountPoint auto0]]

        # should add as p* (not p2 if parent has a module path)
        set token3 [safe::interpAddToAccessPath $i [file join $ZipMountPoint auto0 auto1]]

        # should not have been changed by Safe Base:
        set auto2 [interp eval $i {set ::auto_path}]

        # This will differ from the value -autoPath {}
        set auto3 [interp eval $i [list set ::auto_path [list {$p(:0:)} $token2]]]

        # This time, unlike test safe-zipfs-18.2 and the try above, SafeTestPackage1 should be found:
        list $auto1 $auto2 $token1 $token2 $token3  [catch {interp eval $i {package require SafeTestPackage1}} msg] $msg  [safe::interpConfigure $i] [safe::interpDelete $i]
    } -cleanup {
        if {$SyncExists} {
            safe::setSyncMode $SyncVal_TMP
        }
    } -match glob -result "{} {{\$p(:0:)}} {\$p(:0:)} {\$p(:*:)} {\$p(:*:)} 0 1.2.3 {-accessPath {[list $tcl_library *$ZipMountPoint/auto0 $ZipMountPoint/auto0/auto1]} -statics 0 -nested 1 -deleteHook {} -autoPath {}} {}"

    # cleanup
    set ::auto_path $SaveAutoPath
    zipfs unmount ${ZipMountPoint}
    unset SaveAutoPath TestsDir ZipMountPoint PathMapp
    rename mapList {}







|
|



|













|
|
|
|
|


|
|
|
|
|











|
|

|
|
|
|

|
|
|
|


|
|

|
|
|
|

|
|
|
|


|
|

|
|
|
|
|
|

|
|
|
|
|


|
|

|
|
|
|
|
|

|
|
|
|
|


|
|
|
|
|

|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|


|

|
|
|
|
|
|
|
|

|
|
|
|
|
|





|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|

|
|
|
|


|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|

|
|
|


|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|

|
|
|



|
|
|
|
|

|
|
|
|
|
|

|
|

|
|
|
|

|
|
|
|
|
|
|

|
|
|

|

|
|
|
|


|
|
|
|
|

|
|
|
|
|
|

|
|

|
|

|
|
|
|
|
|
|

|
|
|

|

|
|
|
|


|
|
|
|
|

|
|
|
|
|
|
|
|

|
|

|
|
|
|
|
|
|
|
|

|
|
|
|
|

|

|
|
|
|


|
|
|
|
|

|
|
|
|
|
|

|
|

|
|
|
|
|
|
|

|
|
|
|
|

|

|
|
|
|


|
|
|
|
|

|
|
|
|
|
|

|
|

|
|

|
|
|
|
|

|
|
|

|

|
|
|
|


|
|
|
|
|
|
|
|
|
|

|

|
|
|
|
|
|
|

|
|
|
|
|
|
|

|

|
|
|
|
|
|
|
|











|
|
|
|
|
|
|
|
|
|

|

|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|

|
|
|
|

|
|
|
|
|
|
|

|

|
|
|
|
|
|
|
|



|
|
|
|
|
|
|
|
|
|

|

|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|

|

|
|
|
|
|
|
|
|



|
|
|
|
|
|
|
|
|
|

|

|
|
|
|
|
|
|

|
|
|
|

|
|
|
|
|
|
|
|
|
|

|
|
|
|

|
|
|
|
|
|
|

|

|
|
|
|
|
|
|
|



|
|
|
|
|
|
|
|
|
|

|

|
|
|
|
|
|
|

|
|
|
|

|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|

|

|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
|
|
|

|
|

|
|
|
|
|
|
|

|
|
|
|


|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|

|
|
|


|
|
|
|
|
|
|

|

|
|

|
|

|
|

|
|

|
|

|
|

|
|

|
|

|
|
|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
# this file, and for a DISCLAIMER OF ALL WARRANTIES.


apply [list {} {
    global auto_path
    global tcl_library
    if {"::tcltest" ni [namespace children]} {
	package require tcltest 2.5
	namespace import -force ::tcltest::*
    }

    foreach i [interp children] {
	interp delete $i
    }

    set SaveAutoPath $::auto_path
    set ::auto_path [info library]
    set TestsDir [file normalize [file dirname [info script]]]

    set ZipMountPoint [zipfs root]auto-files
    zipfs mount [file join $TestsDir auto-files.zip] $ZipMountPoint

    set PathMapp {}
    lappend PathMapp $tcl_library TCLLIB $TestsDir TESTSDIR $ZipMountPoint ZIPDIR

    proc mapList {map listIn} {
	set listOut {}
	foreach element $listIn {
	    lappend listOut [string map $map $element]
	}
	return $listOut
    }
    proc mapAndSortList {map listIn} {
	set listOut {}
	foreach element $listIn {
	    lappend listOut [string map $map $element]
	}
	lsort $listOut
    }

    # Force actual loading of the safe package because we use un-exported (and
    # thus un-autoindexed) APIs in this test result arguments:
    catch {safe::interpConfigure}

    testConstraint AutoSyncDefined 1

    # Tests 5.* test the example files before using them to test safe interpreters.

    test safe-zipfs-5.1 {example tclIndex commands, test in parent interpreter; zipfs} -setup {
	set tmpAutoPath $::auto_path
	lappend ::auto_path [file join $ZipMountPoint auto0 auto1] [file join $ZipMountPoint auto0 auto2]
    } -body {
	# Try to load the commands.
	set code3 [catch report1 msg3]
	set code4 [catch report2 msg4]
	list $code3 $msg3 $code4 $msg4
    } -cleanup {
	catch {rename report1 {}}
	catch {rename report2 {}}
	set ::auto_path $tmpAutoPath
	auto_reset
    } -match glob -result {0 ok1 0 ok2}
    test safe-zipfs-5.2 {example tclIndex commands, negative test in parent interpreter; zipfs} -setup {
	set tmpAutoPath $::auto_path
	lappend ::auto_path [file join $ZipMountPoint auto0]
    } -body {
	# Try to load the commands.
	set code3 [catch report1 msg3]
	set code4 [catch report2 msg4]
	list $code3 $msg3 $code4 $msg4
    } -cleanup {
	catch {rename report1 {}}
	catch {rename report2 {}}
	set ::auto_path $tmpAutoPath
	auto_reset
    } -match glob -result {1 {invalid command name "report1"} 1 {invalid command name "report2"}}
    test safe-zipfs-5.3 {example pkgIndex.tcl packages, test in parent interpreter, child directories; zipfs} -setup {
	set tmpAutoPath $::auto_path
	lappend ::auto_path [file join $ZipMountPoint auto0]
    } -body {
	# Try to load the packages and run a command from each one.
	set code3 [catch {package require SafeTestPackage1} msg3]
	set code4 [catch {package require SafeTestPackage2} msg4]
	set code5 [catch HeresPackage1 msg5]
	set code6 [catch HeresPackage2 msg6]
	list $code3 $msg3 $code4 $msg4 $code5 $msg5 $code6 $msg6
    } -cleanup {
	set ::auto_path $tmpAutoPath
	catch {package forget SafeTestPackage1}
	catch {package forget SafeTestPackage2}
	catch {rename HeresPackage1 {}}
	catch {rename HeresPackage2 {}}
    } -match glob -result {0 1.2.3 0 2.3.4 0 OK1 0 OK2}
    test safe-zipfs-5.4 {example pkgIndex.tcl packages, test in parent interpreter, main directories; zipfs} -setup {
	set tmpAutoPath $::auto_path
	lappend ::auto_path [file join $ZipMountPoint auto0 auto1]  [file join $ZipMountPoint auto0 auto2]
    } -body {
	# Try to load the packages and run a command from each one.
	set code3 [catch {package require SafeTestPackage1} msg3]
	set code4 [catch {package require SafeTestPackage2} msg4]
	set code5 [catch HeresPackage1 msg5]
	set code6 [catch HeresPackage2 msg6]
	list $code3 $msg3 $code4 $msg4 $code5 $msg5 $code6 $msg6
    } -cleanup {
	set ::auto_path $tmpAutoPath
	catch {package forget SafeTestPackage1}
	catch {package forget SafeTestPackage2}
	catch {rename HeresPackage1 {}}
	catch {rename HeresPackage2 {}}
    } -match glob -result {0 1.2.3 0 2.3.4 0 OK1 0 OK2}
    test safe-zipfs-5.5 {example modules packages, test in parent interpreter, replace path; zipfs} -setup {
	set oldTm [tcl::tm::path list]
	foreach path $oldTm {
	    tcl::tm::path remove $path
	}
	tcl::tm::path add [file join $ZipMountPoint auto0 modules]
    } -body {
	# Try to load the modules and run a command from each one.
	set code0 [catch {package require test0} msg0]
	set code1 [catch {package require mod1::test1} msg1]
	set code2 [catch {package require mod2::test2} msg2]
	set out0  [test0::try0]
	set out1  [mod1::test1::try1]
	set out2  [mod2::test2::try2]
	list $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $out0 $out1 $out2
    } -cleanup {
	tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
	foreach path [lreverse $oldTm] {
	    tcl::tm::path add $path
	}
	catch {package forget test0}
	catch {package forget mod1::test1}
	catch {package forget mod2::test2}
	catch {namespace delete ::test0}
	catch {namespace delete ::mod1}
    } -match glob -result {0 0.5 0 1.0 0 2.0 -- res0 res1 res2}
    test safe-zipfs-5.6 {example modules packages, test in parent interpreter, append to path; zipfs} -setup {
	tcl::tm::path add [file join $ZipMountPoint auto0 modules]
    } -body {
	# Try to load the modules and run a command from each one.
	set code0 [catch {package require test0} msg0]
	set code1 [catch {package require mod1::test1} msg1]
	set code2 [catch {package require mod2::test2} msg2]
	set out0  [test0::try0]
	set out1  [mod1::test1::try1]
	set out2  [mod2::test2::try2]
	list $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $out0 $out1 $out2
    } -cleanup {
	tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
	catch {package forget test0}
	catch {package forget mod1::test1}
	catch {package forget mod2::test2}
	catch {namespace delete ::test0}
	catch {namespace delete ::mod1}
    } -match glob -result {0 0.5 0 1.0 0 2.0 -- res0 res1 res2}

    # high level general test
    # Use zipped example packages not http1.0 etc
    test safe-zipfs-7.1 {tests that everything works at high level with conventional AutoPathSync; zipfs} -setup {
	set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
	if {$SyncExists} {
	    set SyncVal_TMP [safe::setSyncMode]
	    safe::setSyncMode 1
	}
	set tmpAutoPath $::auto_path
	lappend ::auto_path [file join $ZipMountPoint auto0]
	set i [safe::interpCreate]
	set ::auto_path $tmpAutoPath
    } -body {
	# no error shall occur:
	# (because the default access_path shall include 1st level sub dirs so
	#  package require in a child works like in the parent)
	set v [interp eval $i {package require SafeTestPackage1}]
	# no error shall occur:
	interp eval $i {HeresPackage1}
	set v
    } -cleanup {
	safe::interpDelete $i
	if {$SyncExists} {
	    safe::setSyncMode $SyncVal_TMP
	}
    } -match glob -result 1.2.3
    test safe-zipfs-7.2 {tests specific path and interpFind/AddToAccessPath with conventional AutoPathSync; zipfs} -setup {
	set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
	if {$SyncExists} {
	    set SyncVal_TMP [safe::setSyncMode]
	    safe::setSyncMode 1
	} else {
	    set SyncVal_TMP 1
	}
    } -body {
	set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
	# should not add anything (p0)
	set token1 [safe::interpAddToAccessPath $i [info library]]
	# should add as p* (not p1 if parent has a module path)
	set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
	# should add as p* (not p2 if parent has a module path)
	set token3 [safe::interpAddToAccessPath $i [file join $ZipMountPoint auto0]]
	set confA [safe::interpConfigure $i]
	set mappA [mapList $PathMapp [dict get $confA -accessPath]]
	# an error shall occur (SafeTestPackage1 is not anymore in the secure 0-level
	# provided deep path)
	list $token1 $token2 $token3 --  [catch {interp eval $i {package require SafeTestPackage1}} msg] $msg --  $mappA -- [safe::interpDelete $i]
    } -cleanup {
	if {$SyncExists} {
	    safe::setSyncMode $SyncVal_TMP
	}
    } -match glob -result {{$p(:0:)} {$p(:*:)} {$p(:*:)} -- 1 {can't find package SafeTestPackage1} -- {TCLLIB */dummy/unixlike/test/path ZIPDIR/auto0} -- {}}
    test safe-zipfs-7.4 {tests specific path and positive search with conventional AutoPathSync; zipfs} -setup {
	set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
	if {$SyncExists} {
	    set SyncVal_TMP [safe::setSyncMode]
	    safe::setSyncMode 1
	} else {
	    set SyncVal_TMP 1
	}
    } -body {
	set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
	# should not add anything (p0)
	set token1 [safe::interpAddToAccessPath $i [info library]]
	# should add as p* (not p1 if parent has a module path)
	set token2 [safe::interpAddToAccessPath $i [file join $ZipMountPoint auto0 auto1]]
	set confA [safe::interpConfigure $i]
	set mappA [mapList $PathMapp [dict get $confA -accessPath]]
	# this time, unlike test safe-zipfs-7.2, SafeTestPackage1 should be found
	list $token1 $token2 --  [catch {interp eval $i {package require SafeTestPackage1}} msg] $msg --  $mappA -- [safe::interpDelete $i]
	# Note that the glob match elides directories (those from the module path)
	# other than the first and last in the access path.
    } -cleanup {
	if {$SyncExists} {
	    safe::setSyncMode $SyncVal_TMP
	}
    } -match glob -result {{$p(:0:)} {$p(:*:)} -- 0 1.2.3 -- {TCLLIB * ZIPDIR/auto0/auto1} -- {}}

    test safe-zipfs-9.9 {interpConfigure change the access path; tclIndex commands unaffected by token rearrangement (dummy test of doreset) with conventional AutoPathSync; zipfs} -setup {
	set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
	if {$SyncExists} {
	    set SyncVal_TMP [safe::setSyncMode]
	    safe::setSyncMode 1
	}
    } -body {
	set i [safe::interpCreate -accessPath [list $tcl_library  [file join $ZipMountPoint auto0 auto1]  [file join $ZipMountPoint auto0 auto2]]]
	# Inspect.
	set confA [safe::interpConfigure $i]
	set mappA [mapList $PathMapp [dict get $confA -accessPath]]
	set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
	set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]

	# Load auto_load data.
	interp eval $i {catch nonExistentCommand}

	# Load and run the commands.
	# This guarantees the test will pass even if the tokens are swapped.
	set code1 [catch {interp eval $i {report1}} msg1]
	set code2 [catch {interp eval $i {report2}} msg2]

	# Rearrange access path.  Swap tokens {$p(:1:)} and {$p(:2:)}.
	safe::interpConfigure $i -accessPath [list $tcl_library  [file join $ZipMountPoint auto0 auto2]  [file join $ZipMountPoint auto0 auto1]]
	# Inspect.
	set confB [safe::interpConfigure $i]
	set mappB [mapList $PathMapp [dict get $confB -accessPath]]
	set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
	set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]

	# Run the commands.
	set code3 [catch {interp eval $i {report1}} msg3]
	set code4 [catch {interp eval $i {report2}} msg4]

	list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- $mappA -- $mappB
    } -cleanup {
	safe::interpDelete $i
	if {$SyncExists} {
	    safe::setSyncMode $SyncVal_TMP
	}
    } -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} -- 0 ok1 0 ok2 -- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2*} -- {TCLLIB ZIPDIR/auto0/auto2 ZIPDIR/auto0/auto1*}}
    test safe-zipfs-9.10 {interpConfigure change the access path; tclIndex commands unaffected by token rearrangement (actual test of doreset) with conventional AutoPathSync; zipfs} -setup {
	set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
	if {$SyncExists} {
	    set SyncVal_TMP [safe::setSyncMode]
	    safe::setSyncMode 1
	}
    } -body {
	set i [safe::interpCreate -accessPath [list $tcl_library  [file join $ZipMountPoint auto0 auto1]  [file join $ZipMountPoint auto0 auto2]]]
	# Inspect.
	set confA [safe::interpConfigure $i]
	set mappA [mapList $PathMapp [dict get $confA -accessPath]]
	set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
	set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]

	# Load auto_load data.
	interp eval $i {catch nonExistentCommand}

	# Do not load the commands.  With the tokens swapped, the test
	# will pass only if the Safe Base has called auto_reset.

	# Rearrange access path.  Swap tokens {$p(:1:)} and {$p(:2:)}.
	safe::interpConfigure $i -accessPath [list $tcl_library  [file join $ZipMountPoint auto0 auto2]  [file join $ZipMountPoint auto0 auto1]]
	# Inspect.
	set confB [safe::interpConfigure $i]
	set mappB [mapList $PathMapp [dict get $confB -accessPath]]
	set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
	set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]

	# Load and run the commands.
	set code3 [catch {interp eval $i {report1}} msg3]
	set code4 [catch {interp eval $i {report2}} msg4]

	list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- $mappA -- $mappB
    } -cleanup {
	safe::interpDelete $i
	if {$SyncExists} {
	    safe::setSyncMode $SyncVal_TMP
	}
    } -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} -- 0 ok1 0 ok2 -- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2*} -- {TCLLIB ZIPDIR/auto0/auto2 ZIPDIR/auto0/auto1*}}
    test safe-zipfs-9.11 {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement with conventional AutoPathSync; zipfs} -setup {
	set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
	if {$SyncExists} {
	    set SyncVal_TMP [safe::setSyncMode]
	    safe::setSyncMode 1
	}
    } -body {
	# For complete correspondence to safe-stock-9.11, include auto0 in access path.
	set i [safe::interpCreate -accessPath [list $tcl_library  [file join $ZipMountPoint auto0]  [file join $ZipMountPoint auto0 auto1]  [file join $ZipMountPoint auto0 auto2]]]
	# Inspect.
	set confA [safe::interpConfigure $i]
	set mappA [mapList $PathMapp [dict get $confA -accessPath]]
	set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0]]
	set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
	set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]

	# Load pkgIndex.tcl data.
	catch {interp eval $i {package require NOEXIST}}

	# Rearrange access path.  Swap tokens {$p(:2:)} and {$p(:3:)}.
	# This would have no effect because the records in Pkg of these directories
	# were from access as children of {$p(:1:)}.
	safe::interpConfigure $i -accessPath [list $tcl_library  [file join $ZipMountPoint auto0]  [file join $ZipMountPoint auto0 auto2]  [file join $ZipMountPoint auto0 auto1]]
	# Inspect.
	set confB [safe::interpConfigure $i]
	set mappB [mapList $PathMapp [dict get $confB -accessPath]]
	set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
	set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]

	# Try to load the packages and run a command from each one.
	set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3 opts3]
	set code4 [catch {interp eval $i {package require SafeTestPackage2}} msg4 opts4]
	set code5 [catch {interp eval $i {HeresPackage1}} msg5 opts5]
	set code6 [catch {interp eval $i {HeresPackage2}} msg6 opts6]

	list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 --  $mappA -- $mappB -- $code5 $msg5 $code6 $msg6
    } -cleanup {
	safe::interpDelete $i
	if {$SyncExists} {
	    safe::setSyncMode $SyncVal_TMP
	}
    } -match glob -result {{$p(:2:)} {$p(:3:)} -- {$p(:3:)} {$p(:2:)} -- 0 1.2.3 0 2.3.4 -- {TCLLIB ZIPDIR/auto0 ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2*} -- {TCLLIB ZIPDIR/auto0 ZIPDIR/auto0/auto2 ZIPDIR/auto0/auto1*} -- 0 OK1 0 OK2}
    test safe-zipfs-9.12 {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement, 9.10 without path auto0 with conventional AutoPathSync; zipfs} -setup {
	set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
	if {$SyncExists} {
	    set SyncVal_TMP [safe::setSyncMode]
	    safe::setSyncMode 1
	}
    } -body {
	set i [safe::interpCreate -accessPath [list $tcl_library  [file join $ZipMountPoint auto0 auto1]  [file join $ZipMountPoint auto0 auto2]]]
	# Inspect.
	set confA [safe::interpConfigure $i]
	set mappA [mapList $PathMapp [dict get $confA -accessPath]]
	set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
	set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]

	# Load pkgIndex.tcl data.
	catch {interp eval $i {package require NOEXIST}}

	# Rearrange access path.  Swap tokens {$p(:1:)} and {$p(:2:)}.
	safe::interpConfigure $i -accessPath [list $tcl_library  [file join $ZipMountPoint auto0 auto2]  [file join $ZipMountPoint auto0 auto1]]
	# Inspect.
	set confB [safe::interpConfigure $i]
	set mappB [mapList $PathMapp [dict get $confB -accessPath]]
	set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
	set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]

	# Try to load the packages and run a command from each one.
	set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3 opts3]
	set code4 [catch {interp eval $i {package require SafeTestPackage2}} msg4 opts4]
	set code5 [catch {interp eval $i {HeresPackage1}} msg5 opts5]
	set code6 [catch {interp eval $i {HeresPackage2}} msg6 opts6]

	list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 --  $mappA -- $mappB -- $code5 $msg5 $code6 $msg6
    } -cleanup {
	safe::interpDelete $i
	if {$SyncExists} {
	    safe::setSyncMode $SyncVal_TMP
	}
    } -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} -- 0 1.2.3 0 2.3.4 -- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2*} -- {TCLLIB ZIPDIR/auto0/auto2 ZIPDIR/auto0/auto1*} -- 0 OK1 0 OK2}
    test safe-zipfs-9.13 {interpConfigure change the access path; pkgIndex.tcl packages fail if directory de-listed, with conventional AutoPathSync; zipfs} -setup {
	set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
	if {$SyncExists} {
	    set SyncVal_TMP [safe::setSyncMode]
	    safe::setSyncMode 1
	}
    } -body {
	set i [safe::interpCreate -accessPath [list $tcl_library  [file join $ZipMountPoint auto0 auto1]  [file join $ZipMountPoint auto0 auto2]]]
	# Inspect.
	set confA [safe::interpConfigure $i]
	set mappA [mapList $PathMapp [dict get $confA -accessPath]]
	set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]]
	set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]]

	# Load pkgIndex.tcl data.
	catch {interp eval $i {package require NOEXIST}}

	# Limit access path.  Remove tokens {$p(:1:)} and {$p(:2:)}.
	safe::interpConfigure $i -accessPath [list $tcl_library]

	# Inspect.
	set confB [safe::interpConfigure $i]
	set mappB [mapList $PathMapp [dict get $confB -accessPath]]
	set code4 [catch {::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto1]} path4]
	set code5 [catch {::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 auto2]} path5]

	# Try to load the packages.
	set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3]
	set code6 [catch {interp eval $i {package require SafeTestPackage2}} msg6]

	list $path1 $path2 -- $code4 $path4 -- $code5 $path5 -- $code3 $code6 --  $mappA -- $mappB
    } -cleanup {
	safe::interpDelete $i
	if {$SyncExists} {
	    safe::setSyncMode $SyncVal_TMP
	}
    } -match glob -result {{$p(:1:)} {$p(:2:)} -- 1 {* not found in access path} -- 1 {* not found in access path} -- 1 1 -- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2*} -- {TCLLIB*}}
    test safe-zipfs-9.20 {check module loading, with conventional AutoPathSync; zipfs} -setup {
	set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
	if {$SyncExists} {
	    set SyncVal_TMP [safe::setSyncMode]
	    safe::setSyncMode 1
	}
	set oldTm [tcl::tm::path list]
	foreach path $oldTm {
	    tcl::tm::path remove $path
	}
	tcl::tm::path add [file join $ZipMountPoint auto0 modules]
    } -body {
	set i [safe::interpCreate -accessPath [list $tcl_library]]

	# Inspect.
	set confA [safe::interpConfigure $i]
	set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
	set modsA [interp eval $i {tcl::tm::path list}]
	set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
	set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
	set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]

	# Try to load the packages and run a command from each one.
	set code0 [catch {interp eval $i {package require test0}} msg0]
	set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
	set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
	set out0  [interp eval $i {test0::try0}]
	set out1  [interp eval $i {mod1::test1::try1}]
	set out2  [interp eval $i {mod2::test2::try2}]

	list [lsort [list $path0 $path1 $path2]] -- $modsA --  $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $out0 $out1 $out2
    } -cleanup {
	tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
	foreach path [lreverse $oldTm] {
	    tcl::tm::path add $path
	}
	safe::interpDelete $i
	if {$SyncExists} {
	    safe::setSyncMode $SyncVal_TMP
	}
    } -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} -- 0 0.5 0 1.0 0 2.0 -- {TCLLIB ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} -- res0 res1 res2}
    # - The command safe::InterpSetConfig adds the parent's [tcl::tm::list] in
    #   tokenized form to the child's access path, and then adds all the
    #   descendants, discovered recursively by using glob.
    # - The order of the directories in the list returned by glob is system-dependent,
    #   and therefore this is true also for (a) the order of token assignment to
    #   descendants of the [tcl::tm::list] roots; and (b) the order of those same
    #   directories in the access path.  Both those things must be sorted before
    #   comparing with expected results.  The test is therefore not totally strict,
    #   but will notice missing or surplus directories.
    test safe-zipfs-9.21 {interpConfigure change the access path; check module loading, with conventional AutoPathSync; stale data case 1; zipfs} -setup {
	set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
	if {$SyncExists} {
	    set SyncVal_TMP [safe::setSyncMode]
	    safe::setSyncMode 1
	}
	set oldTm [tcl::tm::path list]
	foreach path $oldTm {
	    tcl::tm::path remove $path
	}
	tcl::tm::path add [file join $ZipMountPoint auto0 modules]
    } -body {
	set i [safe::interpCreate -accessPath [list $tcl_library]]

	# Inspect.
	set confA [safe::interpConfigure $i]
	set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
	set modsA [interp eval $i {tcl::tm::path list}]
	set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
	set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
	set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]

	# Add to access path.
	# This injects more tokens, pushing modules to higher token numbers.
	safe::interpConfigure $i -accessPath [list $tcl_library  [file join $ZipMountPoint auto0 auto1]  [file join $ZipMountPoint auto0 auto2]]
	# Inspect.
	set confB [safe::interpConfigure $i]
	set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
	set modsB [interp eval $i {tcl::tm::path list}]
	set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
	set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
	set path5 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]

	# Load pkg data.
	catch {interp eval $i {package require NOEXIST}}
	catch {interp eval $i {package require mod1::NOEXIST}}
	catch {interp eval $i {package require mod2::NOEXIST}}

	# Try to load the packages and run a command from each one.
	set code0 [catch {interp eval $i {package require test0}} msg0]
	set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
	set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
	set out0  [interp eval $i {test0::try0}]
	set out1  [interp eval $i {mod1::test1::try1}]
	set out2  [interp eval $i {mod2::test2::try2}]

	list [lsort [list $path0 $path1 $path2]] -- $modsA --  [lsort [list $path3 $path4 $path5]] -- $modsB --  $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB --  $out0 $out1 $out2
    } -cleanup {
	tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
	foreach path [lreverse $oldTm] {
	    tcl::tm::path add $path
	}
	safe::interpDelete $i
	if {$SyncExists} {
	    safe::setSyncMode $SyncVal_TMP
	}
    } -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} -- {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} -- 0 0.5 0 1.0 0 2.0 -- {TCLLIB ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} -- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2 ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} -- res0 res1 res2}
    # See comments on lsort after test safe-zipfs-9.20.
    test safe-zipfs-9.22 {interpConfigure change the access path; check module loading, with conventional AutoPathSync; stale data case 0; zipfs} -setup {
	set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
	if {$SyncExists} {
	    set SyncVal_TMP [safe::setSyncMode]
	    safe::setSyncMode 1
	}
	set oldTm [tcl::tm::path list]
	foreach path $oldTm {
	    tcl::tm::path remove $path
	}
	tcl::tm::path add [file join $ZipMountPoint auto0 modules]
    } -body {
	set i [safe::interpCreate -accessPath [list $tcl_library]]

	# Inspect.
	set confA [safe::interpConfigure $i]
	set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
	set modsA [interp eval $i {tcl::tm::path list}]
	set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
	set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
	set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]

	# Add to access path.
	# This injects more tokens, pushing modules to higher token numbers.
	safe::interpConfigure $i -accessPath [list $tcl_library  [file join $ZipMountPoint auto0 auto1]  [file join $ZipMountPoint auto0 auto2]]
	# Inspect.
	set confB [safe::interpConfigure $i]
	set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
	set modsB [interp eval $i {tcl::tm::path list}]
	set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
	set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
	set path5 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]

	# Try to load the packages and run a command from each one.
	set code0 [catch {interp eval $i {package require test0}} msg0]
	set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
	set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
	set out0  [interp eval $i {test0::try0}]
	set out1  [interp eval $i {mod1::test1::try1}]
	set out2  [interp eval $i {mod2::test2::try2}]

	list [lsort [list $path0 $path1 $path2]] -- $modsA --  [lsort [list $path3 $path4 $path5]] -- $modsB --  $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB --  $out0 $out1 $out2
    } -cleanup {
	tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
	foreach path [lreverse $oldTm] {
	    tcl::tm::path add $path
	}
	safe::interpDelete $i
	if {$SyncExists} {
	    safe::setSyncMode $SyncVal_TMP
	}
    } -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} -- {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} -- 0 0.5 0 1.0 0 2.0 -- {TCLLIB ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} -- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2 ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} -- res0 res1 res2}
    # See comments on lsort after test safe-zipfs-9.20.
    test safe-zipfs-9.23 {interpConfigure change the access path; check module loading, with conventional AutoPathSync; stale data case 3; zipfs} -setup {
	set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
	if {$SyncExists} {
	    set SyncVal_TMP [safe::setSyncMode]
	    safe::setSyncMode 1
	}
	set oldTm [tcl::tm::path list]
	foreach path $oldTm {
	    tcl::tm::path remove $path
	}
	tcl::tm::path add [file join $ZipMountPoint auto0 modules]
    } -body {
	set i [safe::interpCreate -accessPath [list $tcl_library]]

	# Inspect.
	set confA [safe::interpConfigure $i]
	set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
	set modsA [interp eval $i {tcl::tm::path list}]
	set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
	set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
	set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]

	# Force the interpreter to acquire pkg data which will soon become stale.
	catch {interp eval $i {package require NOEXIST}}
	catch {interp eval $i {package require mod1::NOEXIST}}
	catch {interp eval $i {package require mod2::NOEXIST}}

	# Add to access path.
	# This injects more tokens, pushing modules to higher token numbers.
	safe::interpConfigure $i -accessPath [list $tcl_library  [file join $ZipMountPoint auto0 auto1]  [file join $ZipMountPoint auto0 auto2]]
	# Inspect.
	set confB [safe::interpConfigure $i]
	set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
	set modsB [interp eval $i {tcl::tm::path list}]
	set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
	set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
	set path5 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]

	# Refresh stale pkg data.
	catch {interp eval $i {package require NOEXIST}}
	catch {interp eval $i {package require mod1::NOEXIST}}
	catch {interp eval $i {package require mod2::NOEXIST}}

	# Try to load the packages and run a command from each one.
	set code0 [catch {interp eval $i {package require test0}} msg0]
	set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
	set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
	set out0  [interp eval $i {test0::try0}]
	set out1  [interp eval $i {mod1::test1::try1}]
	set out2  [interp eval $i {mod2::test2::try2}]

	list [lsort [list $path0 $path1 $path2]] -- $modsA --  [lsort [list $path3 $path4 $path5]] -- $modsB --  $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB --  $out0 $out1 $out2
    } -cleanup {
	tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
	foreach path [lreverse $oldTm] {
	    tcl::tm::path add $path
	}
	safe::interpDelete $i
	if {$SyncExists} {
	    safe::setSyncMode $SyncVal_TMP
	}
    } -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} -- {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} -- 0 0.5 0 1.0 0 2.0 -- {TCLLIB ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} -- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2 ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} -- res0 res1 res2}
    # See comments on lsort after test safe-zipfs-9.20.
    test safe-zipfs-9.24 {interpConfigure change the access path; check module loading, with conventional AutoPathSync; stale data case 2 (worst case); zipfs} -setup {
	set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
	if {$SyncExists} {
	    set SyncVal_TMP [safe::setSyncMode]
	    safe::setSyncMode 1
	}
	set oldTm [tcl::tm::path list]
	foreach path $oldTm {
	    tcl::tm::path remove $path
	}
	tcl::tm::path add [file join $ZipMountPoint auto0 modules]
    } -body {
	set i [safe::interpCreate -accessPath [list $tcl_library]]

	# Inspect.
	set confA [safe::interpConfigure $i]
	set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
	set modsA [interp eval $i {tcl::tm::path list}]
	set path0 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
	set path1 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
	set path2 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]

	# Force the interpreter to acquire pkg data which will soon become stale.
	catch {interp eval $i {package require NOEXIST}}
	catch {interp eval $i {package require mod1::NOEXIST}}
	catch {interp eval $i {package require mod2::NOEXIST}}

	# Add to access path.
	# This injects more tokens, pushing modules to higher token numbers.
	safe::interpConfigure $i -accessPath [list $tcl_library  [file join $ZipMountPoint auto0 auto1]  [file join $ZipMountPoint auto0 auto2]]
	# Inspect.
	set confB [safe::interpConfigure $i]
	set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
	set modsB [interp eval $i {tcl::tm::path list}]
	set path3 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules]]
	set path4 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod1]]
	set path5 [::safe::interpFindInAccessPath $i [file join $ZipMountPoint auto0 modules mod2]]

	# Try to load the packages and run a command from each one.
	set code0 [catch {interp eval $i {package require test0}} msg0]
	set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
	set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
	set out0  [interp eval $i {test0::try0}]
	set out1  [interp eval $i {mod1::test1::try1}]
	set out2  [interp eval $i {mod2::test2::try2}]

	list [lsort [list $path0 $path1 $path2]] -- $modsA --  [lsort [list $path3 $path4 $path5]] -- $modsB --  $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB --  $out0 $out1 $out2
    } -cleanup {
	tcl::tm::path remove [file join $ZipMountPoint auto0 modules]
	foreach path [lreverse $oldTm] {
	    tcl::tm::path add $path
	}
	safe::interpDelete $i
	if {$SyncExists} {
	    safe::setSyncMode $SyncVal_TMP
	}
    } -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} -- {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} -- 0 0.5 0 1.0 0 2.0 -- {TCLLIB ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} -- {TCLLIB ZIPDIR/auto0/auto1 ZIPDIR/auto0/auto2 ZIPDIR/auto0/modules ZIPDIR/auto0/modules/mod1 ZIPDIR/auto0/modules/mod2} -- res0 res1 res2}
    # See comments on lsort after test safe-zipfs-9.20.

    test safe-zipfs-18.1 {cf. safe-zipfs-7.1 - tests that everything works at high level without conventional AutoPathSync; zipfs} -constraints AutoSyncDefined -setup {
	set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
	if {$SyncExists} {
	    set SyncVal_TMP [safe::setSyncMode]
	    safe::setSyncMode 0
	} else {
	    error {This test is meaningful only if the command ::safe::setSyncMode is defined}
	}
	# Without AutoPathSync, we need a more complete auto_path,
	# because the child will use the same value.
	set lib1        [info library]
	set lib2        [file join $ZipMountPoint auto0]
	set ::auto_TMP  $::auto_path
	set ::auto_path [list $lib1 $lib2]

	set i [safe::interpCreate]
	set ::auto_path $::auto_TMP
    } -body {
	# no error shall occur:
	# (because the default access_path shall include 1st level sub dirs so
	#  package require in a child works like in the parent)
	set v [interp eval $i {package require SafeTestPackage1}]
	# no error shall occur:
	interp eval $i HeresPackage1
	set v
    } -cleanup {
	safe::interpDelete $i
	if {$SyncExists} {
	    safe::setSyncMode $SyncVal_TMP
	}
    } -match glob -result 1.2.3
    test safe-zipfs-18.2 {cf. safe-zipfs-7.2 - tests specific path and interpFind/AddToAccessPath without conventional AutoPathSync; zipfs} -constraints AutoSyncDefined -setup {
	set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
	if {$SyncExists} {
	    set SyncVal_TMP [safe::setSyncMode]
	    safe::setSyncMode 0
	} else {
	    error {This test is meaningful only if the command ::safe::setSyncMode is defined}
	}
    } -body {
	set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
	set auto1 [interp eval $i {set ::auto_path}]
	interp eval $i {set ::auto_path [list {$p(:0:)}]}
	# should not add anything (p0)
	set token1 [safe::interpAddToAccessPath $i [info library]]
	# should add as p* (not p1 if parent has a module path)
	set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
	# should add as p* (not p2 if parent has a module path)
	set token3 [safe::interpAddToAccessPath $i [file join $ZipMountPoint auto0]]
	# an error shall occur (SafeTestPackage1 is not anymore in the secure 0-level
	# provided deep path)
	list $auto1 $token1 $token2 $token3  [catch {interp eval $i {package require SafeTestPackage1}} msg] $msg  [safe::interpConfigure $i] [safe::interpDelete $i]
    } -cleanup {
	if {$SyncExists} {
	    safe::setSyncMode $SyncVal_TMP
	}
    } -match glob -result "{} {\$p(:0:)} {\$p(:*:)} {\$p(:*:)} 1 {can't find package SafeTestPackage1} {-accessPath {[list $tcl_library  */dummy/unixlike/test/path  $ZipMountPoint/auto0]} -statics 0 -nested 1 -deleteHook {} -autoPath {}} {}"
    test safe-zipfs-18.4 {cf. safe-zipfs-7.4 - tests specific path and positive search and auto_path without conventional AutoPathSync; zipfs} -constraints AutoSyncDefined -setup {
	set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
	if {$SyncExists} {
	    set SyncVal_TMP [safe::setSyncMode]
	    safe::setSyncMode 0
	} else {
	    error {This test is meaningful only if the command ::safe::setSyncMode is defined}
	}
    } -body {
	set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]

	# should not have been set by Safe Base:
	set auto1 [interp eval $i {set ::auto_path}]

	# This will differ from the value -autoPath {}
	interp eval $i {set ::auto_path [list {$p(:0:)}]}

	# should not add anything (p0)
	set token1 [safe::interpAddToAccessPath $i [info library]]

	# should add as p* (not p1 if parent has a module path)
	set token2 [safe::interpAddToAccessPath $i [file join $ZipMountPoint auto0]]

	# should add as p* (not p2 if parent has a module path)
	set token3 [safe::interpAddToAccessPath $i [file join $ZipMountPoint auto0 auto1]]

	# should not have been changed by Safe Base:
	set auto2 [interp eval $i {set ::auto_path}]

	# This will differ from the value -autoPath {}
	set auto3 [interp eval $i [list set ::auto_path [list {$p(:0:)} $token2]]]

	# This time, unlike test safe-zipfs-18.2 and the try above, SafeTestPackage1 should be found:
	list $auto1 $auto2 $token1 $token2 $token3  [catch {interp eval $i {package require SafeTestPackage1}} msg] $msg  [safe::interpConfigure $i] [safe::interpDelete $i]
    } -cleanup {
	if {$SyncExists} {
	    safe::setSyncMode $SyncVal_TMP
	}
    } -match glob -result "{} {{\$p(:0:)}} {\$p(:0:)} {\$p(:*:)} {\$p(:*:)} 0 1.2.3 {-accessPath {[list $tcl_library *$ZipMountPoint/auto0 $ZipMountPoint/auto0/auto1]} -statics 0 -nested 1 -deleteHook {} -autoPath {}} {}"

    # cleanup
    set ::auto_path $SaveAutoPath
    zipfs unmount ${ZipMountPoint}
    unset SaveAutoPath TestsDir ZipMountPoint PathMapp
    rename mapList {}
Changes to tests/safe.test.
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
    set ap1 [lrange [lindex [safe::interpConfigure $child -autoPath] 1] 0 end]
    set ap2 [::safe::DetokPath $child [interp eval $child set ::auto_path]]
    list $ap1 -- $ap2
}
proc mapList {map listIn} {
    set listOut {}
    foreach element $listIn {
        lappend listOut [string map $map $element]
    }
    return $listOut
}
proc mapAndSortList {map listIn} {
    set listOut {}
    foreach element $listIn {
        lappend listOut [string map $map $element]
    }
    lsort $listOut
}

# Force actual loading of the safe package because we use unexported (and
# thus unautoindexed) APIs in this test result arguments:
catch {safe::interpConfigure}







|






|







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
    set ap1 [lrange [lindex [safe::interpConfigure $child -autoPath] 1] 0 end]
    set ap2 [::safe::DetokPath $child [interp eval $child set ::auto_path]]
    list $ap1 -- $ap2
}
proc mapList {map listIn} {
    set listOut {}
    foreach element $listIn {
	lappend listOut [string map $map $element]
    }
    return $listOut
}
proc mapAndSortList {map listIn} {
    set listOut {}
    foreach element $listIn {
	lappend listOut [string map $map $element]
    }
    lsort $listOut
}

# Force actual loading of the safe package because we use unexported (and
# thus unautoindexed) APIs in this test result arguments:
catch {safe::interpConfigure}
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
test safe-1.1 {safe::interpConfigure syntax} -returnCodes error -body {
    safe::interpConfigure
} -result {no value given for parameter "child" (use -help for full usage) :
    child name () name of the child}
test safe-1.2 {safe::interpCreate syntax, Sync Mode on} -returnCodes error -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    } else {
        set SyncVal_TMP 1
    }
} -body {
    safe::interpCreate -help
} -cleanup {
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {Usage information:
    Var/FlagName  Type     Value   Help
    ------------  ----     -----   ----
    (-help                         gives this help)
    ?child?       name     ()      name of the child (optional)
    -accessPath   list     ()      access path for the child
    -noStatics    boolflag (false) prevent loading of statically linked pkgs
    -statics      boolean  (true)  loading of statically linked pkgs
    -nestedLoadOk boolflag (false) allow nested loading
    -nested       boolean  (false) nested loading
    -deleteHook   script   ()      delete hook}
test safe-1.2.1 {safe::interpCreate syntax, Sync Mode off} -returnCodes error -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    safe::interpCreate -help
} -cleanup {
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {Usage information:
    Var/FlagName  Type     Value   Help
    ------------  ----     -----   ----
    (-help                         gives this help)
    ?child?       name     ()      name of the child (optional)
    -accessPath   list     ()      access path for the child







|
|

|





|















|
|

|





|







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
test safe-1.1 {safe::interpConfigure syntax} -returnCodes error -body {
    safe::interpConfigure
} -result {no value given for parameter "child" (use -help for full usage) :
    child name () name of the child}
test safe-1.2 {safe::interpCreate syntax, Sync Mode on} -returnCodes error -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    } else {
	set SyncVal_TMP 1
    }
} -body {
    safe::interpCreate -help
} -cleanup {
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {Usage information:
    Var/FlagName  Type     Value   Help
    ------------  ----     -----   ----
    (-help                         gives this help)
    ?child?       name     ()      name of the child (optional)
    -accessPath   list     ()      access path for the child
    -noStatics    boolflag (false) prevent loading of statically linked pkgs
    -statics      boolean  (true)  loading of statically linked pkgs
    -nestedLoadOk boolflag (false) allow nested loading
    -nested       boolean  (false) nested loading
    -deleteHook   script   ()      delete hook}
test safe-1.2.1 {safe::interpCreate syntax, Sync Mode off} -returnCodes error -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    safe::interpCreate -help
} -cleanup {
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {Usage information:
    Var/FlagName  Type     Value   Help
    ------------  ----     -----   ----
    (-help                         gives this help)
    ?child?       name     ()      name of the child (optional)
    -accessPath   list     ()      access path for the child
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
    catch {package forget SafeTestPackage2}
    catch {rename HeresPackage1 {}}
    catch {rename HeresPackage2 {}}
} -match glob -result {0 1.2.3 0 2.3.4 0 OK1 0 OK2}
test safe-5.4 {example pkgIndex.tcl packages, test in parent interpreter, main directories} -setup {
    set tmpAutoPath $::auto_path
    lappend ::auto_path [file join $TestsDir auto0 auto1] \
                        [file join $TestsDir auto0 auto2]
} -body {
    # Try to load the packages and run a command from each one.
    set code3 [catch {package require SafeTestPackage1} msg3]
    set code4 [catch {package require SafeTestPackage2} msg4]
    set code5 [catch HeresPackage1 msg5]
    set code6 [catch HeresPackage2 msg6]
    list $code3 $msg3 $code4 $msg4 $code5 $msg5 $code6 $msg6
} -cleanup {
    set ::auto_path $tmpAutoPath
    catch {package forget SafeTestPackage1}
    catch {package forget SafeTestPackage2}
    catch {rename HeresPackage1 {}}
    catch {rename HeresPackage2 {}}
} -match glob -result {0 1.2.3 0 2.3.4 0 OK1 0 OK2}
test safe-5.5 {example modules packages, test in parent interpreter, replace path} -setup {
    set oldTm [tcl::tm::path list]
    foreach path $oldTm {
        tcl::tm::path remove $path
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
    # Try to load the modules and run a command from each one.
    set code0 [catch {package require test0} msg0]
    set code1 [catch {package require mod1::test1} msg1]
    set code2 [catch {package require mod2::test2} msg2]
    set out0  [test0::try0]
    set out1  [mod1::test1::try1]
    set out2  [mod2::test2::try2]
    list $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $out0 $out1 $out2
} -cleanup {
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    foreach path [lreverse $oldTm] {
        tcl::tm::path add $path
    }
    catch {package forget test0}
    catch {package forget mod1::test1}
    catch {package forget mod2::test2}
    catch {namespace delete ::test0}
    catch {namespace delete ::mod1}
} -match glob -result {0 0.5 0 1.0 0 2.0 -- res0 res1 res2}







|

















|














|







274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
    catch {package forget SafeTestPackage2}
    catch {rename HeresPackage1 {}}
    catch {rename HeresPackage2 {}}
} -match glob -result {0 1.2.3 0 2.3.4 0 OK1 0 OK2}
test safe-5.4 {example pkgIndex.tcl packages, test in parent interpreter, main directories} -setup {
    set tmpAutoPath $::auto_path
    lappend ::auto_path [file join $TestsDir auto0 auto1] \
			[file join $TestsDir auto0 auto2]
} -body {
    # Try to load the packages and run a command from each one.
    set code3 [catch {package require SafeTestPackage1} msg3]
    set code4 [catch {package require SafeTestPackage2} msg4]
    set code5 [catch HeresPackage1 msg5]
    set code6 [catch HeresPackage2 msg6]
    list $code3 $msg3 $code4 $msg4 $code5 $msg5 $code6 $msg6
} -cleanup {
    set ::auto_path $tmpAutoPath
    catch {package forget SafeTestPackage1}
    catch {package forget SafeTestPackage2}
    catch {rename HeresPackage1 {}}
    catch {rename HeresPackage2 {}}
} -match glob -result {0 1.2.3 0 2.3.4 0 OK1 0 OK2}
test safe-5.5 {example modules packages, test in parent interpreter, replace path} -setup {
    set oldTm [tcl::tm::path list]
    foreach path $oldTm {
	tcl::tm::path remove $path
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
    # Try to load the modules and run a command from each one.
    set code0 [catch {package require test0} msg0]
    set code1 [catch {package require mod1::test1} msg1]
    set code2 [catch {package require mod2::test2} msg2]
    set out0  [test0::try0]
    set out1  [mod1::test1::try1]
    set out2  [mod2::test2::try2]
    list $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $out0 $out1 $out2
} -cleanup {
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    foreach path [lreverse $oldTm] {
	tcl::tm::path add $path
    }
    catch {package forget test0}
    catch {package forget mod1::test1}
    catch {package forget mod2::test2}
    catch {namespace delete ::test0}
    catch {namespace delete ::mod1}
} -match glob -result {0 0.5 0 1.0 0 2.0 -- res0 res1 res2}
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
###  7. Test the use of ::auto_path for loading commands (via tclIndex files)
###     and non-module packages (via pkgIndex.tcl files).
###     Corresponding tests with Sync Mode off are 17.*

test safe-7.1 {positive non-module package require, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    }
    set tmpAutoPath $::auto_path
    lappend ::auto_path [file join $TestsDir auto0]
    set i [safe::interpCreate]
    set ::auto_path $tmpAutoPath
} -body {
    # no error shall occur:
    # (because the default access_path shall include 1st level sub dirs so
    #  package require in a child works like in the parent)
    set v [interp eval $i {package require SafeTestPackage1}]
    # no error shall occur:
    interp eval $i {HeresPackage1}
    set v
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result 1.2.3
test safe-7.2 {negative non-module package require with specific path and interpAddToAccessPath, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    } else {
        set SyncVal_TMP 1
    }
} -body {
    set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
    # should not add anything (p0)
    set token1 [safe::interpAddToAccessPath $i [info library]]
    # should add as p* (not p1 if parent has a module path)
    set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
    # should add as p* (not p2 if parent has a module path)
    set token3 [safe::interpAddToAccessPath $i [file join $TestsDir auto0]]
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    # an error shall occur (SafeTestPackage1 is not in auto0 but a subdirectory)
    list $token1 $token2 $token3 -- \
	    [catch {interp eval $i {package require SafeTestPackage1}} msg] $msg -- \
	    $mappA -- [safe::interpDelete $i]
} -cleanup {
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:0:)} {$p(:*:)} {$p(:*:)} --\
        1 {can't find package SafeTestPackage1} --\
        {TCLLIB */dummy/unixlike/test/path TESTSDIR/auto0} -- {}}
test safe-7.3 {check that safe subinterpreters work} {
    set g [interp children]
    if {$g ne {}} {
        append g { -- residue of an earlier test}
    }
    set h [info vars ::safe::S*]
    if {$h ne {}} {
        append h { -- residue of an earlier test}
    }
    set i [safe::interpCreate]
    set j [safe::interpCreate [list $i x]]
    list $g $h [interp eval $j {join {o k} ""}] [safe::interpDelete $i] \
            [interp exists $j] [info vars ::safe::S*]
} {{} {} ok {} 0 {}}
test safe-7.3.1 {check that safe subinterpreters work with namespace names} -setup {
} -body {
    set g [interp children]
    if {$g ne {}} {
        append g { -- residue of an earlier test}
    }
    set h [info vars ::safe::S*]
    if {$h ne {}} {
        append h { -- residue of an earlier test}
    }
    set i [safe::interpCreate foo::bar]
    set j [safe::interpCreate [list $i hello::world]]
    list $g $h [interp eval $j {join {o k} ""}] \
            [foo::bar eval {hello::world eval {join {o k} ""}}] \
            [safe::interpDelete $i] \
            [interp exists $j] [info vars ::safe::S*]
} -match glob -result {{} {} ok ok {} 0 {}}
test safe-7.4 {positive non-module package require with specific path and interpAddToAccessPath, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    } else {
        set SyncVal_TMP 1
    }
} -body {
    set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
    # should not add anything (p0)
    set token1 [safe::interpAddToAccessPath $i [info library]]
    # should add as p* (not p1 if parent has a module path)
    set token2 [safe::interpAddToAccessPath $i [file join $TestsDir auto0 auto1]]
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    # this time, unlike test safe-7.2, SafeTestPackage1 should be found
    list $token1 $token2 -- \
	    [catch {interp eval $i {package require SafeTestPackage1}} msg] $msg -- \
	    $mappA -- [safe::interpDelete $i]
    # Note that the glob match elides directories (those from the module path)
    # other than the first and last in the access path.
} -cleanup {
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:0:)} {$p(:*:)} -- 0 1.2.3 --\
        {TCLLIB * TESTSDIR/auto0/auto1} -- {}}
test safe-7.5 {positive and negative module package require, including ancestor directory issue, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
    set i [safe::interpCreate]
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    interp eval $i {
        package forget mod1::test1
        catch {namespace delete ::mod1}
    }
} -body {
    # Should raise an error (module ancestor directory issue)
    set code1 [catch {interp eval $i {package require test1}} msg1]
    # Should not raise an error
    set code2 [catch {interp eval $i {package require mod1::test1}} msg2]
    return [list $code1 $msg1 $code2]
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {1 {can't find package test1} 0}

###  8. Test source control on file name.

test safe-8.1 {safe source control on file} -setup {
    set i "a"







|
|
















|





|
|

|

















|


|
|



|



|




|





|



|




|
|
|




|
|

|

















|


|



|
|





|
|










|







373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
###  7. Test the use of ::auto_path for loading commands (via tclIndex files)
###     and non-module packages (via pkgIndex.tcl files).
###     Corresponding tests with Sync Mode off are 17.*

test safe-7.1 {positive non-module package require, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    }
    set tmpAutoPath $::auto_path
    lappend ::auto_path [file join $TestsDir auto0]
    set i [safe::interpCreate]
    set ::auto_path $tmpAutoPath
} -body {
    # no error shall occur:
    # (because the default access_path shall include 1st level sub dirs so
    #  package require in a child works like in the parent)
    set v [interp eval $i {package require SafeTestPackage1}]
    # no error shall occur:
    interp eval $i {HeresPackage1}
    set v
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result 1.2.3
test safe-7.2 {negative non-module package require with specific path and interpAddToAccessPath, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    } else {
	set SyncVal_TMP 1
    }
} -body {
    set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
    # should not add anything (p0)
    set token1 [safe::interpAddToAccessPath $i [info library]]
    # should add as p* (not p1 if parent has a module path)
    set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
    # should add as p* (not p2 if parent has a module path)
    set token3 [safe::interpAddToAccessPath $i [file join $TestsDir auto0]]
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    # an error shall occur (SafeTestPackage1 is not in auto0 but a subdirectory)
    list $token1 $token2 $token3 -- \
	    [catch {interp eval $i {package require SafeTestPackage1}} msg] $msg -- \
	    $mappA -- [safe::interpDelete $i]
} -cleanup {
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:0:)} {$p(:*:)} {$p(:*:)} --\
	1 {can't find package SafeTestPackage1} --\
	{TCLLIB */dummy/unixlike/test/path TESTSDIR/auto0} -- {}}
test safe-7.3 {check that safe subinterpreters work} {
    set g [interp children]
    if {$g ne {}} {
	append g { -- residue of an earlier test}
    }
    set h [info vars ::safe::S*]
    if {$h ne {}} {
	append h { -- residue of an earlier test}
    }
    set i [safe::interpCreate]
    set j [safe::interpCreate [list $i x]]
    list $g $h [interp eval $j {join {o k} ""}] [safe::interpDelete $i] \
	    [interp exists $j] [info vars ::safe::S*]
} {{} {} ok {} 0 {}}
test safe-7.3.1 {check that safe subinterpreters work with namespace names} -setup {
} -body {
    set g [interp children]
    if {$g ne {}} {
	append g { -- residue of an earlier test}
    }
    set h [info vars ::safe::S*]
    if {$h ne {}} {
	append h { -- residue of an earlier test}
    }
    set i [safe::interpCreate foo::bar]
    set j [safe::interpCreate [list $i hello::world]]
    list $g $h [interp eval $j {join {o k} ""}] \
	    [foo::bar eval {hello::world eval {join {o k} ""}}] \
	    [safe::interpDelete $i] \
	    [interp exists $j] [info vars ::safe::S*]
} -match glob -result {{} {} ok ok {} 0 {}}
test safe-7.4 {positive non-module package require with specific path and interpAddToAccessPath, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    } else {
	set SyncVal_TMP 1
    }
} -body {
    set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
    # should not add anything (p0)
    set token1 [safe::interpAddToAccessPath $i [info library]]
    # should add as p* (not p1 if parent has a module path)
    set token2 [safe::interpAddToAccessPath $i [file join $TestsDir auto0 auto1]]
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    # this time, unlike test safe-7.2, SafeTestPackage1 should be found
    list $token1 $token2 -- \
	    [catch {interp eval $i {package require SafeTestPackage1}} msg] $msg -- \
	    $mappA -- [safe::interpDelete $i]
    # Note that the glob match elides directories (those from the module path)
    # other than the first and last in the access path.
} -cleanup {
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:0:)} {$p(:*:)} -- 0 1.2.3 --\
	{TCLLIB * TESTSDIR/auto0/auto1} -- {}}
test safe-7.5 {positive and negative module package require, including ancestor directory issue, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
    set i [safe::interpCreate]
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    interp eval $i {
	package forget mod1::test1
	catch {namespace delete ::mod1}
    }
} -body {
    # Should raise an error (module ancestor directory issue)
    set code1 [catch {interp eval $i {package require test1}} msg1]
    # Should not raise an error
    set code2 [catch {interp eval $i {package require mod1::test1}} msg2]
    return [list $code1 $msg1 $code2]
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {1 {can't find package test1} 0}

###  8. Test source control on file name.

test safe-8.1 {safe source control on file} -setup {
    set i "a"
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
test safe-9.6 {interpConfigure widget like behaviour} -body {
   # this test shall work, don't try to "fix it" unless you *really* know what
   # you are doing (ie you are me :p) -- dl
   list [set i [safe::interpCreate \
		    -noStatics \
		    -nestedLoadOk \
		    -deleteHook {foo bar}]
         safe::interpConfigure $i -accessPath /foo/bar
         safe::interpConfigure $i]\
	[safe::interpConfigure $i -aCCess]\
	[safe::interpConfigure $i -nested]\
	[safe::interpConfigure $i -statics]\
	[safe::interpConfigure $i -DEL]\
	[safe::interpConfigure $i -accessPath /blah -statics 1
	 safe::interpConfigure $i]\
	[safe::interpConfigure $i -deleteHook toto -nosta -nested 0







|
|







718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
test safe-9.6 {interpConfigure widget like behaviour} -body {
   # this test shall work, don't try to "fix it" unless you *really* know what
   # you are doing (ie you are me :p) -- dl
   list [set i [safe::interpCreate \
		    -noStatics \
		    -nestedLoadOk \
		    -deleteHook {foo bar}]
	 safe::interpConfigure $i -accessPath /foo/bar
	 safe::interpConfigure $i]\
	[safe::interpConfigure $i -aCCess]\
	[safe::interpConfigure $i -nested]\
	[safe::interpConfigure $i -statics]\
	[safe::interpConfigure $i -DEL]\
	[safe::interpConfigure $i -accessPath /blah -statics 1
	 safe::interpConfigure $i]\
	[safe::interpConfigure $i -deleteHook toto -nosta -nested 0
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
} -match glob -result {{-accessPath * -statics 0 -nested 1 -deleteHook {foo bar} -autoPath *}\
	{-accessPath *} {-nested 1} {-statics 0} {-deleteHook {foo bar}}\
	{-accessPath * -statics 1 -nested 1 -deleteHook {foo bar} -autoPath *}\
	{-accessPath * -statics 0 -nested 0 -deleteHook toto -autoPath *}}
test safe-9.8 {autoloading commands indexed in tclIndex files, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    }
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library \
                                            [file join $TestsDir auto0 auto1] \
                                            [file join $TestsDir auto0 auto2]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]

    # Load and run the commands.
    set code1 [catch {interp eval $i {report1}} msg1]
    set code2 [catch {interp eval $i {report2}} msg2]

    list $path1 $path2 -- $code1 $msg1 $code2 $msg2 -- $mappA
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- 0 ok1 0 ok2 --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*}}
test safe-9.9 {interpConfigure change the access path; tclIndex commands unaffected by token rearrangement (dummy test of doreset), Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    }
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library \
                                            [file join $TestsDir auto0 auto1] \
                                            [file join $TestsDir auto0 auto2]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]

    # Load auto_load data.
    interp eval $i {catch nonExistentCommand}

    # Load and run the commands.
    # This guarantees the test will pass even if the tokens are swapped.
    set code1 [catch {interp eval $i {report1}} msg1]
    set code2 [catch {interp eval $i {report2}} msg2]

    # Rearrange access path.  Swap tokens {$p(:1:)} and {$p(:2:)}.
    safe::interpConfigure $i -accessPath [list $tcl_library \
                                           [file join $TestsDir auto0 auto2] \
                                           [file join $TestsDir auto0 auto1]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]

    # Run the commands.
    set code3 [catch {interp eval $i {report1}} msg3]
    set code4 [catch {interp eval $i {report2}} msg4]

    list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- $mappA -- $mappB
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} -- 0 ok1 0 ok2 --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
        {TCLLIB TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1*}}
test safe-9.10 {interpConfigure change the access path; tclIndex commands unaffected by token rearrangement (actual test of doreset), Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    }
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library \
                                            [file join $TestsDir auto0 auto1] \
                                            [file join $TestsDir auto0 auto2]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]

    # Load auto_load data.
    interp eval $i {catch nonExistentCommand}

    # Do not load the commands.  With the tokens swapped, the test
    # will pass only if the Safe Base has called auto_reset.

    # Rearrange access path.  Swap tokens {$p(:1:)} and {$p(:2:)}.
    safe::interpConfigure $i -accessPath [list $tcl_library \
                                           [file join $TestsDir auto0 auto2] \
                                           [file join $TestsDir auto0 auto1]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]

    # Load and run the commands.
    set code3 [catch {interp eval $i {report1}} msg3]
    set code4 [catch {interp eval $i {report2}} msg4]

    list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- $mappA -- $mappB
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} --\
        0 ok1 0 ok2 --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
        {TCLLIB TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1*}}
test safe-9.11 {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    }
} -body {
    # For complete correspondence to safe-9.10opt, include auto0 in access path.
    set i [safe::interpCreate -accessPath [list $tcl_library \
                                            [file join $TestsDir auto0] \
                                            [file join $TestsDir auto0 auto1] \
                                            [file join $TestsDir auto0 auto2]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path0 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]

    # Load pkgIndex.tcl data.
    catch {interp eval $i {package require NOEXIST}}

    # Rearrange access path.  Swap tokens {$p(:2:)} and {$p(:3:)}.
    # This would have no effect because the records in Pkg of these directories
    # were from access as children of {$p(:1:)}.
    safe::interpConfigure $i -accessPath [list $tcl_library \
                                           [file join $TestsDir auto0] \
                                           [file join $TestsDir auto0 auto2] \
                                           [file join $TestsDir auto0 auto1]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]

    # Try to load the packages and run a command from each one.
    set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3 opts3]
    set code4 [catch {interp eval $i {package require SafeTestPackage2}} msg4 opts4]
    set code5 [catch {interp eval $i {HeresPackage1}} msg5 opts5]
    set code6 [catch {interp eval $i {HeresPackage2}} msg6 opts6]

    list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- \
         $mappA -- $mappB -- $code5 $msg5 $code6 $msg6
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:2:)} {$p(:3:)} -- {$p(:3:)} {$p(:2:)} -- 0 1.2.3 0 2.3.4 --\
        {TCLLIB TESTSDIR/auto0 TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
        {TCLLIB TESTSDIR/auto0 TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1*} --\
        0 OK1 0 OK2}
test safe-9.12 {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement, safe-9.11 without path auto0, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    }
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library \
                                            [file join $TestsDir auto0 auto1] \
                                            [file join $TestsDir auto0 auto2]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]

    # Load pkgIndex.tcl data.
    catch {interp eval $i {package require NOEXIST}}

    # Rearrange access path.  Swap tokens {$p(:1:)} and {$p(:2:)}.
    safe::interpConfigure $i -accessPath [list $tcl_library \
                                           [file join $TestsDir auto0 auto2] \
                                           [file join $TestsDir auto0 auto1]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]

    # Try to load the packages and run a command from each one.
    set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3 opts3]
    set code4 [catch {interp eval $i {package require SafeTestPackage2}} msg4 opts4]
    set code5 [catch {interp eval $i {HeresPackage1}} msg5 opts5]
    set code6 [catch {interp eval $i {HeresPackage2}} msg6 opts6]

    list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- \
            $mappA -- $mappB -- \
            $code5 $msg5 $code6 $msg6
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} --\
        0 1.2.3 0 2.3.4 --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
        {TCLLIB TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1*} --\
        0 OK1 0 OK2}
test safe-9.13 {interpConfigure change the access path; pkgIndex.tcl packages fail if directory de-listed, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    }
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library \
                                            [file join $TestsDir auto0 auto1] \
                                            [file join $TestsDir auto0 auto2]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]

    # Load pkgIndex.tcl data.







|
|



|
|














|


|



|
|



|
|
















|
|














|


|
|



|
|



|
|














|
|














|


|
|
|



|
|




|
|
|














|
|
|













|



|


|
|
|



|
|



|
|











|
|













|
|



|


|
|
|
|



|
|



|
|







762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
} -match glob -result {{-accessPath * -statics 0 -nested 1 -deleteHook {foo bar} -autoPath *}\
	{-accessPath *} {-nested 1} {-statics 0} {-deleteHook {foo bar}}\
	{-accessPath * -statics 1 -nested 1 -deleteHook {foo bar} -autoPath *}\
	{-accessPath * -statics 0 -nested 0 -deleteHook toto -autoPath *}}
test safe-9.8 {autoloading commands indexed in tclIndex files, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    }
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library \
					    [file join $TestsDir auto0 auto1] \
					    [file join $TestsDir auto0 auto2]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]

    # Load and run the commands.
    set code1 [catch {interp eval $i {report1}} msg1]
    set code2 [catch {interp eval $i {report2}} msg2]

    list $path1 $path2 -- $code1 $msg1 $code2 $msg2 -- $mappA
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- 0 ok1 0 ok2 --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*}}
test safe-9.9 {interpConfigure change the access path; tclIndex commands unaffected by token rearrangement (dummy test of doreset), Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    }
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library \
					    [file join $TestsDir auto0 auto1] \
					    [file join $TestsDir auto0 auto2]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]

    # Load auto_load data.
    interp eval $i {catch nonExistentCommand}

    # Load and run the commands.
    # This guarantees the test will pass even if the tokens are swapped.
    set code1 [catch {interp eval $i {report1}} msg1]
    set code2 [catch {interp eval $i {report2}} msg2]

    # Rearrange access path.  Swap tokens {$p(:1:)} and {$p(:2:)}.
    safe::interpConfigure $i -accessPath [list $tcl_library \
					   [file join $TestsDir auto0 auto2] \
					   [file join $TestsDir auto0 auto1]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]

    # Run the commands.
    set code3 [catch {interp eval $i {report1}} msg3]
    set code4 [catch {interp eval $i {report2}} msg4]

    list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- $mappA -- $mappB
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} -- 0 ok1 0 ok2 --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
	{TCLLIB TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1*}}
test safe-9.10 {interpConfigure change the access path; tclIndex commands unaffected by token rearrangement (actual test of doreset), Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    }
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library \
					    [file join $TestsDir auto0 auto1] \
					    [file join $TestsDir auto0 auto2]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]

    # Load auto_load data.
    interp eval $i {catch nonExistentCommand}

    # Do not load the commands.  With the tokens swapped, the test
    # will pass only if the Safe Base has called auto_reset.

    # Rearrange access path.  Swap tokens {$p(:1:)} and {$p(:2:)}.
    safe::interpConfigure $i -accessPath [list $tcl_library \
					   [file join $TestsDir auto0 auto2] \
					   [file join $TestsDir auto0 auto1]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]

    # Load and run the commands.
    set code3 [catch {interp eval $i {report1}} msg3]
    set code4 [catch {interp eval $i {report2}} msg4]

    list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- $mappA -- $mappB
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} --\
	0 ok1 0 ok2 --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
	{TCLLIB TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1*}}
test safe-9.11 {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    }
} -body {
    # For complete correspondence to safe-9.10opt, include auto0 in access path.
    set i [safe::interpCreate -accessPath [list $tcl_library \
					    [file join $TestsDir auto0] \
					    [file join $TestsDir auto0 auto1] \
					    [file join $TestsDir auto0 auto2]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path0 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]

    # Load pkgIndex.tcl data.
    catch {interp eval $i {package require NOEXIST}}

    # Rearrange access path.  Swap tokens {$p(:2:)} and {$p(:3:)}.
    # This would have no effect because the records in Pkg of these directories
    # were from access as children of {$p(:1:)}.
    safe::interpConfigure $i -accessPath [list $tcl_library \
					   [file join $TestsDir auto0] \
					   [file join $TestsDir auto0 auto2] \
					   [file join $TestsDir auto0 auto1]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]

    # Try to load the packages and run a command from each one.
    set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3 opts3]
    set code4 [catch {interp eval $i {package require SafeTestPackage2}} msg4 opts4]
    set code5 [catch {interp eval $i {HeresPackage1}} msg5 opts5]
    set code6 [catch {interp eval $i {HeresPackage2}} msg6 opts6]

    list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- \
	 $mappA -- $mappB -- $code5 $msg5 $code6 $msg6
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:2:)} {$p(:3:)} -- {$p(:3:)} {$p(:2:)} -- 0 1.2.3 0 2.3.4 --\
	{TCLLIB TESTSDIR/auto0 TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
	{TCLLIB TESTSDIR/auto0 TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1*} --\
	0 OK1 0 OK2}
test safe-9.12 {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement, safe-9.11 without path auto0, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    }
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library \
					    [file join $TestsDir auto0 auto1] \
					    [file join $TestsDir auto0 auto2]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]

    # Load pkgIndex.tcl data.
    catch {interp eval $i {package require NOEXIST}}

    # Rearrange access path.  Swap tokens {$p(:1:)} and {$p(:2:)}.
    safe::interpConfigure $i -accessPath [list $tcl_library \
					   [file join $TestsDir auto0 auto2] \
					   [file join $TestsDir auto0 auto1]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]

    # Try to load the packages and run a command from each one.
    set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3 opts3]
    set code4 [catch {interp eval $i {package require SafeTestPackage2}} msg4 opts4]
    set code5 [catch {interp eval $i {HeresPackage1}} msg5 opts5]
    set code6 [catch {interp eval $i {HeresPackage2}} msg6 opts6]

    list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- \
	    $mappA -- $mappB -- \
	    $code5 $msg5 $code6 $msg6
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} --\
	0 1.2.3 0 2.3.4 --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
	{TCLLIB TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1*} --\
	0 OK1 0 OK2}
test safe-9.13 {interpConfigure change the access path; pkgIndex.tcl packages fail if directory de-listed, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    }
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library \
					    [file join $TestsDir auto0 auto1] \
					    [file join $TestsDir auto0 auto2]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]

    # Load pkgIndex.tcl data.
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
    set code5 [catch {::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]} path5]

    # Try to load the packages.
    set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3]
    set code6 [catch {interp eval $i {package require SafeTestPackage2}} msg6]

    list $path1 $path2 -- $code4 $path4 -- $code5 $path5 -- $code3 $code6 -- \
            $mappA -- $mappB
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- 1 {* not found in access path} --\
        1 {* not found in access path} -- 1 1 --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} -- {TCLLIB*}}
test safe-9.20 {check module loading, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    }
    set oldTm [tcl::tm::path list]
    foreach path $oldTm {
        tcl::tm::path remove $path
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library]]

    # Inspect.
    set confA [safe::interpConfigure $i]







|



|


|
|



|
|



|







1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
    set code5 [catch {::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]} path5]

    # Try to load the packages.
    set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3]
    set code6 [catch {interp eval $i {package require SafeTestPackage2}} msg6]

    list $path1 $path2 -- $code4 $path4 -- $code5 $path5 -- $code3 $code6 -- \
	    $mappA -- $mappB
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- 1 {* not found in access path} --\
	1 {* not found in access path} -- 1 1 --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} -- {TCLLIB*}}
test safe-9.20 {check module loading, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    }
    set oldTm [tcl::tm::path list]
    foreach path $oldTm {
	tcl::tm::path remove $path
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library]]

    # Inspect.
    set confA [safe::interpConfigure $i]
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
    set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
    set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
    set out0  [interp eval $i {test0::try0}]
    set out1  [interp eval $i {mod1::test1::try1}]
    set out2  [interp eval $i {mod2::test2::try2}]

    list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
            $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $out0 $out1 $out2
} -cleanup {
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    foreach path [lreverse $oldTm] {
        tcl::tm::path add $path
    }
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
        0 0.5 0 1.0 0 2.0 --\
        {TCLLIB TESTSDIR/auto0/modules TESTSDIR/auto0/modules/mod1\
         TESTSDIR/auto0/modules/mod2} -- res0 res1 res2}
# - The command safe::InterpSetConfig adds the parent's [tcl::tm::list] in
#   tokenized form to the child's access path, and then adds all the
#   descendants, discovered recursively by using glob.
# - The order of the directories in the list returned by glob is system-dependent,
#   and therefore this is true also for (a) the order of token assignment to
#   descendants of the [tcl::tm::list] roots; and (b) the order of those same
#   directories in the access path.  Both those things must be sorted before
#   comparing with expected results.  The test is therefore not totally strict,
#   but will notice missing or surplus directories.
test safe-9.21 {interpConfigure change the access path; check module loading, Sync Mode on; stale data case 1} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    }
    set oldTm [tcl::tm::path list]
    foreach path $oldTm {
        tcl::tm::path remove $path
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library]]

    # Inspect.
    set confA [safe::interpConfigure $i]
    set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
    set modsA [interp eval $i {tcl::tm::path list}]
    set path0 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]

    # Add to access path.
    # This injects more tokens, pushing modules to higher token numbers.
    safe::interpConfigure $i -accessPath [list $tcl_library \
                                           [file join $TestsDir auto0 auto1] \
                                           [file join $TestsDir auto0 auto2]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
    set modsB [interp eval $i {tcl::tm::path list}]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path5 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]







|



|



|


|
|
|












|
|



|
















|
|







1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
    set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
    set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
    set out0  [interp eval $i {test0::try0}]
    set out1  [interp eval $i {mod1::test1::try1}]
    set out2  [interp eval $i {mod2::test2::try2}]

    list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
	    $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $out0 $out1 $out2
} -cleanup {
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    foreach path [lreverse $oldTm] {
	tcl::tm::path add $path
    }
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
	0 0.5 0 1.0 0 2.0 --\
	{TCLLIB TESTSDIR/auto0/modules TESTSDIR/auto0/modules/mod1\
	 TESTSDIR/auto0/modules/mod2} -- res0 res1 res2}
# - The command safe::InterpSetConfig adds the parent's [tcl::tm::list] in
#   tokenized form to the child's access path, and then adds all the
#   descendants, discovered recursively by using glob.
# - The order of the directories in the list returned by glob is system-dependent,
#   and therefore this is true also for (a) the order of token assignment to
#   descendants of the [tcl::tm::list] roots; and (b) the order of those same
#   directories in the access path.  Both those things must be sorted before
#   comparing with expected results.  The test is therefore not totally strict,
#   but will notice missing or surplus directories.
test safe-9.21 {interpConfigure change the access path; check module loading, Sync Mode on; stale data case 1} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    }
    set oldTm [tcl::tm::path list]
    foreach path $oldTm {
	tcl::tm::path remove $path
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library]]

    # Inspect.
    set confA [safe::interpConfigure $i]
    set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
    set modsA [interp eval $i {tcl::tm::path list}]
    set path0 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]

    # Add to access path.
    # This injects more tokens, pushing modules to higher token numbers.
    safe::interpConfigure $i -accessPath [list $tcl_library \
					   [file join $TestsDir auto0 auto1] \
					   [file join $TestsDir auto0 auto2]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
    set modsB [interp eval $i {tcl::tm::path list}]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path5 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
    set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
    set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
    set out0  [interp eval $i {test0::try0}]
    set out1  [interp eval $i {mod1::test1::try1}]
    set out2  [interp eval $i {mod2::test2::try2}]

    list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
            [lsort [list $path3 $path4 $path5]] -- $modsB -- \
            $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
            $out0 $out1 $out2
} -cleanup {
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    foreach path [lreverse $oldTm] {
        tcl::tm::path add $path
    }
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
        {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
        0 0.5 0 1.0 0 2.0 --\
        {TCLLIB TESTSDIR/auto0/modules TESTSDIR/auto0/modules/mod1\
         TESTSDIR/auto0/modules/mod2} --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2 TESTSDIR/auto0/modules\
         TESTSDIR/auto0/modules/mod1 TESTSDIR/auto0/modules/mod2} --\
        res0 res1 res2}
# See comments on lsort after test safe-9.20.
test safe-9.22 {interpConfigure change the access path; check module loading, Sync Mode on; stale data case 0} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    }
    set oldTm [tcl::tm::path list]
    foreach path $oldTm {
        tcl::tm::path remove $path
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library]]

    # Inspect.
    set confA [safe::interpConfigure $i]
    set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
    set modsA [interp eval $i {tcl::tm::path list}]
    set path0 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]

    # Add to access path.
    # This injects more tokens, pushing modules to higher token numbers.
    safe::interpConfigure $i -accessPath [list $tcl_library \
                                          [file join $TestsDir auto0 auto1] \
                                          [file join $TestsDir auto0 auto2]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
    set modsB [interp eval $i {tcl::tm::path list}]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path5 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]

    # Try to load the packages and run a command from each one.
    set code0 [catch {interp eval $i {package require test0}} msg0]
    set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
    set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
    set out0  [interp eval $i {test0::try0}]
    set out1  [interp eval $i {mod1::test1::try1}]
    set out2  [interp eval $i {mod2::test2::try2}]

    list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
            [lsort [list $path3 $path4 $path5]] -- $modsB -- \
            $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
            $out0 $out1 $out2
} -cleanup {
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    foreach path [lreverse $oldTm] {
        tcl::tm::path add $path
    }
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
        {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
        0 0.5 0 1.0 0 2.0 --\
        {TCLLIB TESTSDIR/auto0/modules TESTSDIR/auto0/modules/mod1\
         TESTSDIR/auto0/modules/mod2} --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2 TESTSDIR/auto0/modules\
         TESTSDIR/auto0/modules/mod1 TESTSDIR/auto0/modules/mod2} --\
        res0 res1 res2}
# See comments on lsort after test safe-9.20.
test safe-9.23 {interpConfigure change the access path; check module loading, Sync Mode on; stale data case 3} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    }
    set oldTm [tcl::tm::path list]
    foreach path $oldTm {
        tcl::tm::path remove $path
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library]]

    # Inspect.
    set confA [safe::interpConfigure $i]







|
|
|



|



|


|
|
|
|
|
|
|




|
|



|
















|
|

















|
|
|



|



|


|
|
|
|
|
|
|




|
|



|







1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
    set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
    set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
    set out0  [interp eval $i {test0::try0}]
    set out1  [interp eval $i {mod1::test1::try1}]
    set out2  [interp eval $i {mod2::test2::try2}]

    list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
	    [lsort [list $path3 $path4 $path5]] -- $modsB -- \
	    $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
	    $out0 $out1 $out2
} -cleanup {
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    foreach path [lreverse $oldTm] {
	tcl::tm::path add $path
    }
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
	{{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
	0 0.5 0 1.0 0 2.0 --\
	{TCLLIB TESTSDIR/auto0/modules TESTSDIR/auto0/modules/mod1\
	 TESTSDIR/auto0/modules/mod2} --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2 TESTSDIR/auto0/modules\
	 TESTSDIR/auto0/modules/mod1 TESTSDIR/auto0/modules/mod2} --\
	res0 res1 res2}
# See comments on lsort after test safe-9.20.
test safe-9.22 {interpConfigure change the access path; check module loading, Sync Mode on; stale data case 0} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    }
    set oldTm [tcl::tm::path list]
    foreach path $oldTm {
	tcl::tm::path remove $path
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library]]

    # Inspect.
    set confA [safe::interpConfigure $i]
    set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
    set modsA [interp eval $i {tcl::tm::path list}]
    set path0 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]

    # Add to access path.
    # This injects more tokens, pushing modules to higher token numbers.
    safe::interpConfigure $i -accessPath [list $tcl_library \
					  [file join $TestsDir auto0 auto1] \
					  [file join $TestsDir auto0 auto2]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
    set modsB [interp eval $i {tcl::tm::path list}]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path5 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]

    # Try to load the packages and run a command from each one.
    set code0 [catch {interp eval $i {package require test0}} msg0]
    set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
    set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
    set out0  [interp eval $i {test0::try0}]
    set out1  [interp eval $i {mod1::test1::try1}]
    set out2  [interp eval $i {mod2::test2::try2}]

    list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
	    [lsort [list $path3 $path4 $path5]] -- $modsB -- \
	    $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
	    $out0 $out1 $out2
} -cleanup {
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    foreach path [lreverse $oldTm] {
	tcl::tm::path add $path
    }
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
	{{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
	0 0.5 0 1.0 0 2.0 --\
	{TCLLIB TESTSDIR/auto0/modules TESTSDIR/auto0/modules/mod1\
	 TESTSDIR/auto0/modules/mod2} --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2 TESTSDIR/auto0/modules\
	 TESTSDIR/auto0/modules/mod1 TESTSDIR/auto0/modules/mod2} --\
	res0 res1 res2}
# See comments on lsort after test safe-9.20.
test safe-9.23 {interpConfigure change the access path; check module loading, Sync Mode on; stale data case 3} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    }
    set oldTm [tcl::tm::path list]
    foreach path $oldTm {
	tcl::tm::path remove $path
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library]]

    # Inspect.
    set confA [safe::interpConfigure $i]
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
    catch {interp eval $i {package require NOEXIST}}
    catch {interp eval $i {package require mod1::NOEXIST}}
    catch {interp eval $i {package require mod2::NOEXIST}}

    # Add to access path.
    # This injects more tokens, pushing modules to higher token numbers.
    safe::interpConfigure $i -accessPath [list $tcl_library \
                                           [file join $TestsDir auto0 auto1] \
                                           [file join $TestsDir auto0 auto2]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
    set modsB [interp eval $i {tcl::tm::path list}]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path5 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]







|
|







1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
    catch {interp eval $i {package require NOEXIST}}
    catch {interp eval $i {package require mod1::NOEXIST}}
    catch {interp eval $i {package require mod2::NOEXIST}}

    # Add to access path.
    # This injects more tokens, pushing modules to higher token numbers.
    safe::interpConfigure $i -accessPath [list $tcl_library \
					   [file join $TestsDir auto0 auto1] \
					   [file join $TestsDir auto0 auto2]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
    set modsB [interp eval $i {tcl::tm::path list}]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path5 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
    set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
    set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
    set out0  [interp eval $i {test0::try0}]
    set out1  [interp eval $i {mod1::test1::try1}]
    set out2  [interp eval $i {mod2::test2::try2}]

    list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
            [lsort [list $path3 $path4 $path5]] -- $modsB -- \
            $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
            $out0 $out1 $out2
} -cleanup {
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    foreach path [lreverse $oldTm] {
        tcl::tm::path add $path
    }
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
        {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
        0 0.5 0 1.0 0 2.0 --\
        {TCLLIB TESTSDIR/auto0/modules TESTSDIR/auto0/modules/mod1\
         TESTSDIR/auto0/modules/mod2} --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2 TESTSDIR/auto0/modules\
         TESTSDIR/auto0/modules/mod1 TESTSDIR/auto0/modules/mod2} --\
        res0 res1 res2}
# See comments on lsort after test safe-9.20.
test safe-9.24 {interpConfigure change the access path; check module loading, Sync Mode on; stale data case 2 (worst case)} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    }
    set oldTm [tcl::tm::path list]
    foreach path $oldTm {
        tcl::tm::path remove $path
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library]]

    # Inspect.
    set confA [safe::interpConfigure $i]







|
|
|



|



|


|
|
|
|
|
|
|




|
|



|







1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
    set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
    set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
    set out0  [interp eval $i {test0::try0}]
    set out1  [interp eval $i {mod1::test1::try1}]
    set out2  [interp eval $i {mod2::test2::try2}]

    list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
	    [lsort [list $path3 $path4 $path5]] -- $modsB -- \
	    $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
	    $out0 $out1 $out2
} -cleanup {
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    foreach path [lreverse $oldTm] {
	tcl::tm::path add $path
    }
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
	{{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
	0 0.5 0 1.0 0 2.0 --\
	{TCLLIB TESTSDIR/auto0/modules TESTSDIR/auto0/modules/mod1\
	 TESTSDIR/auto0/modules/mod2} --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2 TESTSDIR/auto0/modules\
	 TESTSDIR/auto0/modules/mod1 TESTSDIR/auto0/modules/mod2} --\
	res0 res1 res2}
# See comments on lsort after test safe-9.20.
test safe-9.24 {interpConfigure change the access path; check module loading, Sync Mode on; stale data case 2 (worst case)} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    }
    set oldTm [tcl::tm::path list]
    foreach path $oldTm {
	tcl::tm::path remove $path
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library]]

    # Inspect.
    set confA [safe::interpConfigure $i]
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
    catch {interp eval $i {package require NOEXIST}}
    catch {interp eval $i {package require mod1::NOEXIST}}
    catch {interp eval $i {package require mod2::NOEXIST}}

    # Add to access path.
    # This injects more tokens, pushing modules to higher token numbers.
    safe::interpConfigure $i -accessPath [list $tcl_library \
                                           [file join $TestsDir auto0 auto1] \
                                           [file join $TestsDir auto0 auto2]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
    set modsB [interp eval $i {tcl::tm::path list}]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path5 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]

    # Try to load the packages and run a command from each one.
    set code0 [catch {interp eval $i {package require test0}} msg0]
    set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
    set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
    set out0  [interp eval $i {test0::try0}]
    set out1  [interp eval $i {mod1::test1::try1}]
    set out2  [interp eval $i {mod2::test2::try2}]

    list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
            [lsort [list $path3 $path4 $path5]] -- $modsB -- \
            $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
            $out0 $out1 $out2
} -cleanup {
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    foreach path [lreverse $oldTm] {
        tcl::tm::path add $path
    }
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
        {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
        0 0.5 0 1.0 0 2.0 --\
        {TCLLIB TESTSDIR/auto0/modules TESTSDIR/auto0/modules/mod1\
         TESTSDIR/auto0/modules/mod2} --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2 TESTSDIR/auto0/modules\
         TESTSDIR/auto0/modules/mod1 TESTSDIR/auto0/modules/mod2} --\
        res0 res1 res2}
# See comments on lsort after test safe-9.20.

### 10. Test options -statics -nostatics -nested -nestedloadok

catch {teststaticlibrary Safepfx1 0 0}
test safe-10.1 {testing statics loading} -constraints tcl::test -setup {
    set i [safe::interpCreate]







|
|

















|
|
|



|



|


|
|
|
|
|
|
|







1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
    catch {interp eval $i {package require NOEXIST}}
    catch {interp eval $i {package require mod1::NOEXIST}}
    catch {interp eval $i {package require mod2::NOEXIST}}

    # Add to access path.
    # This injects more tokens, pushing modules to higher token numbers.
    safe::interpConfigure $i -accessPath [list $tcl_library \
					   [file join $TestsDir auto0 auto1] \
					   [file join $TestsDir auto0 auto2]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
    set modsB [interp eval $i {tcl::tm::path list}]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path5 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]

    # Try to load the packages and run a command from each one.
    set code0 [catch {interp eval $i {package require test0}} msg0]
    set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
    set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
    set out0  [interp eval $i {test0::try0}]
    set out1  [interp eval $i {mod1::test1::try1}]
    set out2  [interp eval $i {mod2::test2::try2}]

    list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
	    [lsort [list $path3 $path4 $path5]] -- $modsB -- \
	    $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
	    $out0 $out1 $out2
} -cleanup {
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    foreach path [lreverse $oldTm] {
	tcl::tm::path add $path
    }
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
	{{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
	0 0.5 0 1.0 0 2.0 --\
	{TCLLIB TESTSDIR/auto0/modules TESTSDIR/auto0/modules/mod1\
	 TESTSDIR/auto0/modules/mod2} --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2 TESTSDIR/auto0/modules\
	 TESTSDIR/auto0/modules/mod1 TESTSDIR/auto0/modules/mod2} --\
	res0 res1 res2}
# See comments on lsort after test safe-9.20.

### 10. Test options -statics -nostatics -nested -nestedloadok

catch {teststaticlibrary Safepfx1 0 0}
test safe-10.1 {testing statics loading} -constraints tcl::test -setup {
    set i [safe::interpCreate]
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
test safe-13.2 {mimic the valid glob call by ::tcl::tm::UnknownHandler [Bug 2964715]} -setup {
    set i [safe::interpCreate]
    buildEnvironment deleteme.tm
} -body {
    ::safe::interpAddToAccessPath $i $testdir2
    set result [$i eval glob -nocomplain -directory $testdir2 *.tm]
    if {$result eq [list $testfile]} {
        return "glob match"
    } else {
        return "no match: $result"
    }
} -cleanup {
    safe::interpDelete $i
    removeDirectory $testdir
} -result {glob match}
test safe-13.3 {cf 13.2 but test glob failure when -directory is outside access path [Bug 2964715]} -setup {
    set i [safe::interpCreate]







|

|







1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
test safe-13.2 {mimic the valid glob call by ::tcl::tm::UnknownHandler [Bug 2964715]} -setup {
    set i [safe::interpCreate]
    buildEnvironment deleteme.tm
} -body {
    ::safe::interpAddToAccessPath $i $testdir2
    set result [$i eval glob -nocomplain -directory $testdir2 *.tm]
    if {$result eq [list $testfile]} {
	return "glob match"
    } else {
	return "no match: $result"
    }
} -cleanup {
    safe::interpDelete $i
    removeDirectory $testdir
} -result {glob match}
test safe-13.3 {cf 13.2 but test glob failure when -directory is outside access path [Bug 2964715]} -setup {
    set i [safe::interpCreate]
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
    buildEnvironment deleteme.tm
} -body {
    ::safe::interpAddToAccessPath $i $testdir
    ::safe::interpAddToAccessPath $i $testdir2
    set result [$i eval \
	    glob -nocomplain -directory $testdir [file join deletemetoo *.tm]]
    if {$result eq [list $testfile]} {
        return "glob match"
    } else {
        return "no match: $result"
    }
} -cleanup {
    safe::interpDelete $i
    removeDirectory $testdir
} -result {glob match}
test safe-13.5 {as 13.4 but test glob failure when -directory is outside access path [Bug 2964715]} -setup {
    set i [safe::interpCreate]







|

|







1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
    buildEnvironment deleteme.tm
} -body {
    ::safe::interpAddToAccessPath $i $testdir
    ::safe::interpAddToAccessPath $i $testdir2
    set result [$i eval \
	    glob -nocomplain -directory $testdir [file join deletemetoo *.tm]]
    if {$result eq [list $testfile]} {
	return "glob match"
    } else {
	return "no match: $result"
    }
} -cleanup {
    safe::interpDelete $i
    removeDirectory $testdir
} -result {glob match}
test safe-13.5 {as 13.4 but test glob failure when -directory is outside access path [Bug 2964715]} -setup {
    set i [safe::interpCreate]
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
    set i [safe::interpCreate]
    buildEnvironment notIndex.tcl
} -body {
    ::safe::interpAddToAccessPath $i $testdir2
    set result [$i eval \
	    glob -directory $testdir -join -nocomplain * notIndex.tcl]
    if {$result eq [list $testfile]} {
        return {glob match}
    } else {
        return "no match: $result"
    }
} -cleanup {
    safe::interpDelete $i
    removeDirectory $testdir
} -result {no match: }
test safe-13.10 {as 13.8 but test silent failure when result is outside access_path [Bug 2964715]} -setup {
    set i [safe::interpCreate]







|

|







1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
    set i [safe::interpCreate]
    buildEnvironment notIndex.tcl
} -body {
    ::safe::interpAddToAccessPath $i $testdir2
    set result [$i eval \
	    glob -directory $testdir -join -nocomplain * notIndex.tcl]
    if {$result eq [list $testfile]} {
	return {glob match}
    } else {
	return "no match: $result"
    }
} -cleanup {
    safe::interpDelete $i
    removeDirectory $testdir
} -result {no match: }
test safe-13.10 {as 13.8 but test silent failure when result is outside access_path [Bug 2964715]} -setup {
    set i [safe::interpCreate]
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
### 14. Sanity checks on paths - module path, access path, auto_path.

test safe-14.1 {Check that module path is the same as in the parent interpreter [Bug 2964715]} -setup {
    set i [safe::interpCreate]
} -body {
    set tm {}
    foreach token [$i eval ::tcl::tm::path list] {
        lappend tm [dict get [set ::safe::S${i}(access_path,map)] $token]
    }
    return $tm
} -cleanup {
    safe::interpDelete $i
} -result [::tcl::tm::path list]
test safe-14.2 {Check that first element of child auto_path (and access path) is Tcl Library, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    }

    set lib1        [info library]
    set lib2        [file dirname $lib1]
    set ::auto_TMP  $::auto_path
    set ::auto_path [list $lib1 $lib2]

    set i [safe::interpCreate]
} -body {
    set autoList {}
    set token [lindex [$i eval set ::auto_path] 0]
    set auto0 [dict get [set ::safe::S${i}(access_path,map)] $token]
    set accessList [lindex [safe::interpConfigure $i -accessPath] 1]
    return [list [lindex $accessList 0] $auto0]
} -cleanup {
    set ::auto_path $::auto_TMP
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result [list [info library] [info library]]
test safe-14.2.1 {Check that first element of child auto_path (and access path) is Tcl Library, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }

    set lib1        [info library]
    set lib2        [file dirname $lib1]
    set ::auto_TMP  $::auto_path
    set ::auto_path [list $lib1 $lib2]

    set i [safe::interpCreate]
} -body {
    set autoList {}
    set token [lindex [$i eval set ::auto_path] 0]
    set auto0 [dict get [set ::safe::S${i}(access_path,map)] $token]
    set accessList [lindex [safe::interpConfigure $i -accessPath] 1]
    set autoList   [lindex [safe::interpConfigure $i -autoPath] 1]
    return [list [lindex $accessList 0] [lindex $autoList 0] $auto0]
} -cleanup {
    set ::auto_path $::auto_TMP
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result [list [info library] [info library] [info library]]
test safe-14.3 {Check that first element of child auto_path (and access path) is Tcl Library, even if not true for parent, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    }

    set lib1        [info library]
    set lib2        [file dirname $lib1]
    set ::auto_TMP  $::auto_path
    set ::auto_path [list $lib2 $lib1]
    # Unexpected order, should be reversed in the child

    set i [safe::interpCreate]
} -body {
    set autoList {}
    set token [lindex [$i eval set ::auto_path] 0]
    set auto0 [dict get [set ::safe::S${i}(access_path,map)] $token]
    set accessList [lindex [safe::interpConfigure $i -accessPath] 1]

    return [list [lindex $accessList 0] $auto0]
} -cleanup {
    set ::auto_path $::auto_TMP
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result [list [info library] [info library]]
test safe-14.3.1 {Check that first element of child auto_path (and access path) is Tcl Library, even if not true for parent, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }

    set lib1        [info library]
    set lib2        [file dirname $lib1]
    set ::auto_TMP  $::auto_path
    set ::auto_path [list $lib2 $lib1]
    # Unexpected order, should be reversed in the child







|








|
|


















|





|
|

|



















|





|
|




















|





|
|

|







1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
### 14. Sanity checks on paths - module path, access path, auto_path.

test safe-14.1 {Check that module path is the same as in the parent interpreter [Bug 2964715]} -setup {
    set i [safe::interpCreate]
} -body {
    set tm {}
    foreach token [$i eval ::tcl::tm::path list] {
	lappend tm [dict get [set ::safe::S${i}(access_path,map)] $token]
    }
    return $tm
} -cleanup {
    safe::interpDelete $i
} -result [::tcl::tm::path list]
test safe-14.2 {Check that first element of child auto_path (and access path) is Tcl Library, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    }

    set lib1        [info library]
    set lib2        [file dirname $lib1]
    set ::auto_TMP  $::auto_path
    set ::auto_path [list $lib1 $lib2]

    set i [safe::interpCreate]
} -body {
    set autoList {}
    set token [lindex [$i eval set ::auto_path] 0]
    set auto0 [dict get [set ::safe::S${i}(access_path,map)] $token]
    set accessList [lindex [safe::interpConfigure $i -accessPath] 1]
    return [list [lindex $accessList 0] $auto0]
} -cleanup {
    set ::auto_path $::auto_TMP
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result [list [info library] [info library]]
test safe-14.2.1 {Check that first element of child auto_path (and access path) is Tcl Library, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }

    set lib1        [info library]
    set lib2        [file dirname $lib1]
    set ::auto_TMP  $::auto_path
    set ::auto_path [list $lib1 $lib2]

    set i [safe::interpCreate]
} -body {
    set autoList {}
    set token [lindex [$i eval set ::auto_path] 0]
    set auto0 [dict get [set ::safe::S${i}(access_path,map)] $token]
    set accessList [lindex [safe::interpConfigure $i -accessPath] 1]
    set autoList   [lindex [safe::interpConfigure $i -autoPath] 1]
    return [list [lindex $accessList 0] [lindex $autoList 0] $auto0]
} -cleanup {
    set ::auto_path $::auto_TMP
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result [list [info library] [info library] [info library]]
test safe-14.3 {Check that first element of child auto_path (and access path) is Tcl Library, even if not true for parent, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    }

    set lib1        [info library]
    set lib2        [file dirname $lib1]
    set ::auto_TMP  $::auto_path
    set ::auto_path [list $lib2 $lib1]
    # Unexpected order, should be reversed in the child

    set i [safe::interpCreate]
} -body {
    set autoList {}
    set token [lindex [$i eval set ::auto_path] 0]
    set auto0 [dict get [set ::safe::S${i}(access_path,map)] $token]
    set accessList [lindex [safe::interpConfigure $i -accessPath] 1]

    return [list [lindex $accessList 0] $auto0]
} -cleanup {
    set ::auto_path $::auto_TMP
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result [list [info library] [info library]]
test safe-14.3.1 {Check that first element of child auto_path (and access path) is Tcl Library, even if not true for parent, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }

    set lib1        [info library]
    set lib2        [file dirname $lib1]
    set ::auto_TMP  $::auto_path
    set ::auto_path [list $lib2 $lib1]
    # Unexpected order, should be reversed in the child
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
    set autoList   [lindex [safe::interpConfigure $i -autoPath] 1]

    return [list [lindex $accessList 0] [lindex $autoList 0] $auto0]
} -cleanup {
    set ::auto_path $::auto_TMP
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result [list [info library] [info library] [info library]]

### 15. Safe file ensemble.

test safe-15.1 {safe file ensemble does not surprise code} -setup {
    set i [interp create -safe]







|







1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
    set autoList   [lindex [safe::interpConfigure $i -autoPath] 1]

    return [list [lindex $accessList 0] [lindex $autoList 0] $auto0]
} -cleanup {
    set ::auto_path $::auto_TMP
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result [list [info library] [info library] [info library]]

### 15. Safe file ensemble.

test safe-15.1 {safe file ensemble does not surprise code} -setup {
    set i [interp create -safe]
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
### 17. Test the use of ::auto_path for loading commands (via tclIndex files)
###     and non-module packages (via pkgIndex.tcl files).
###     Corresponding tests with Sync Mode on are 7.*

test safe-17.1 {cf. safe-7.1 - positive non-module package require, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    # Without AutoPathSync, we need a more complete auto_path,
    # because the child will use the same value.
    set lib1        [info library]
    set lib2        [file join $TestsDir auto0]
    set ::auto_TMP  $::auto_path
    set ::auto_path [list $lib1 $lib2]







|
|

|







1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
### 17. Test the use of ::auto_path for loading commands (via tclIndex files)
###     and non-module packages (via pkgIndex.tcl files).
###     Corresponding tests with Sync Mode on are 7.*

test safe-17.1 {cf. safe-7.1 - positive non-module package require, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    # Without AutoPathSync, we need a more complete auto_path,
    # because the child will use the same value.
    set lib1        [info library]
    set lib2        [file join $TestsDir auto0]
    set ::auto_TMP  $::auto_path
    set ::auto_path [list $lib1 $lib2]
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
    set v [interp eval $i {package require SafeTestPackage1}]
    # no error shall occur:
    interp eval $i HeresPackage1
    set v
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result 1.2.3
test safe-17.2 {cf. safe-7.2 - negative non-module package require with specific path and interpAddToAccessPath, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
    # should not have been set by Safe Base:
    set auto1 [interp eval $i {set ::auto_path}]
    # This does not change the value of option -autoPath:
    interp eval $i {set ::auto_path [list {$p(:0:)}]}
    # should not add anything (p0)
    set token1 [safe::interpAddToAccessPath $i [info library]]
    # should add as p* (not p1 if parent has a module path)
    set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
    # should add as p* (not p2 if parent has a module path)
    set token3 [safe::interpAddToAccessPath $i [file join $TestsDir auto0]]
    # an error shall occur (SafeTestPackage1 is not in auto0 but a subdirectory)
    list $auto1 $token1 $token2 $token3 \
	    [catch {interp eval $i {package require SafeTestPackage1}} msg] $msg \
	    [safe::interpConfigure $i]\
	    [safe::interpDelete $i]
} -cleanup {
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result "{} {\$p(:0:)} {\$p(:*:)} {\$p(:*:)}\
        1 {can't find package SafeTestPackage1}\
        {-accessPath {[list $tcl_library \
                            */dummy/unixlike/test/path \
                            $TestsDir/auto0]}\
        -statics 0 -nested 1 -deleteHook {} -autoPath {}} {}"
# (not a counterpart of safe-7.3)
test safe-17.3 {Check that default auto_path is the same as in the parent interpreter, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate]
} -body {
    # This file's header sets auto_path to a single directory [info library],
    # which is the one required by Safe Base to be present & first in the list.
    set ap {}
    foreach token [$i eval set ::auto_path] {
        lappend ap [dict get [set ::safe::S${i}(access_path,map)] $token]
    }
    return [list $ap [lindex [::safe::interpConfigure $i -autoPath] 1]]
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result [list $::auto_path $::auto_path]
test safe-17.4 {cf. safe-7.4 - positive non-module package require with specific path and interpAddToAccessPath, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]

    # should not have been set by Safe Base:
    set auto1 [interp eval $i {set ::auto_path}]








|





|
|

|




















|


|
|
|
|
|




|
|

|







|











|
|

|







2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
    set v [interp eval $i {package require SafeTestPackage1}]
    # no error shall occur:
    interp eval $i HeresPackage1
    set v
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result 1.2.3
test safe-17.2 {cf. safe-7.2 - negative non-module package require with specific path and interpAddToAccessPath, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
    # should not have been set by Safe Base:
    set auto1 [interp eval $i {set ::auto_path}]
    # This does not change the value of option -autoPath:
    interp eval $i {set ::auto_path [list {$p(:0:)}]}
    # should not add anything (p0)
    set token1 [safe::interpAddToAccessPath $i [info library]]
    # should add as p* (not p1 if parent has a module path)
    set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
    # should add as p* (not p2 if parent has a module path)
    set token3 [safe::interpAddToAccessPath $i [file join $TestsDir auto0]]
    # an error shall occur (SafeTestPackage1 is not in auto0 but a subdirectory)
    list $auto1 $token1 $token2 $token3 \
	    [catch {interp eval $i {package require SafeTestPackage1}} msg] $msg \
	    [safe::interpConfigure $i]\
	    [safe::interpDelete $i]
} -cleanup {
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result "{} {\$p(:0:)} {\$p(:*:)} {\$p(:*:)}\
	1 {can't find package SafeTestPackage1}\
	{-accessPath {[list $tcl_library \
			    */dummy/unixlike/test/path \
			    $TestsDir/auto0]}\
	-statics 0 -nested 1 -deleteHook {} -autoPath {}} {}"
# (not a counterpart of safe-7.3)
test safe-17.3 {Check that default auto_path is the same as in the parent interpreter, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate]
} -body {
    # This file's header sets auto_path to a single directory [info library],
    # which is the one required by Safe Base to be present & first in the list.
    set ap {}
    foreach token [$i eval set ::auto_path] {
	lappend ap [dict get [set ::safe::S${i}(access_path,map)] $token]
    }
    return [list $ap [lindex [::safe::interpConfigure $i -autoPath] 1]]
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result [list $::auto_path $::auto_path]
test safe-17.4 {cf. safe-7.4 - positive non-module package require with specific path and interpAddToAccessPath, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]

    # should not have been set by Safe Base:
    set auto1 [interp eval $i {set ::auto_path}]

2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
	    [safe::interpConfigure $i]\
	    [safe::interpDelete $i]
} -cleanup {
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result "{} {{\$p(:0:)}} {\$p(:0:)} {\$p(:*:)} {\$p(:*:)} 0 1.2.3\
        {-accessPath {[list $tcl_library *$TestsDir/auto0 $TestsDir/auto0/auto1]}\
        -statics 0 -nested 1 -deleteHook {}\
        -autoPath {}} {}"
test safe-17.5 {cf. safe-7.5 - positive and negative module package require, including ancestor directory issue, Sync Mode off} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
    set i [safe::interpCreate]
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    interp eval $i {
        package forget mod1::test1
        catch {namespace delete ::mod1}
    }
} -body {
    # Should raise an error (tests module ancestor directory rule)
    set code1 [catch {interp eval $i {package require test1}} msg1]
    # Should not raise an error
    set code2 [catch {interp eval $i {package require mod1::test1}} msg2]
    return [list $code1 $msg1 $code2]
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {1 {can't find package test1} 0}

### 18. Test tokenization of directories available to a child.

test safe-18.1 {Check that each directory of the default auto_path is a valid token, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    }
    set i [safe::interpCreate]
} -body {
    set badTokens {}
    foreach dir [$i eval {set ::auto_path}] {
        if {[regexp {^\$p\(:[0-9]+:\)$} $dir]} {
            # Match - OK - token has expected form
        } else {
            # No match - possibly an ordinary path has not been tokenized
            lappend badTokens $dir
        }
    }
    set badTokens
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {}
test safe-18.1.1 {Check that each directory of the default auto_path is a valid token, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate]
} -body {
    set badTokens {}
    foreach dir [$i eval {set ::auto_path}] {
        if {[regexp {^\$p\(:[0-9]+:\)$} $dir]} {
            # Match - OK - token has expected form
        } else {
            # No match - possibly an ordinary path has not been tokenized
            lappend badTokens $dir
        }
    }
    set badTokens
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {}
test safe-18.2 {Check that each directory of the module path is a valid token, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 1
    }
    set i [safe::interpCreate]
} -body {
    set badTokens {}
    foreach dir [$i eval {::tcl::tm::path list}] {
        if {[regexp {^\$p\(:[0-9]+:\)$} $dir]} {
            # Match - OK - token has expected form
        } else {
            # No match - possibly an ordinary path has not been tokenized
            lappend badTokens $dir
        }
    }
    set badTokens
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {}
test safe-18.2.1 {Check that each directory of the module path is a valid token, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate]
} -body {
    set badTokens {}
    foreach dir [$i eval {::tcl::tm::path list}] {
        if {[regexp {^\$p\(:[0-9]+:\)$} $dir]} {
            # Match - OK - token has expected form
        } else {
            # No match - possibly an ordinary path has not been tokenized
            lappend badTokens $dir
        }
    }
    set badTokens
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {}

### 19. Assorted options, including changes to option values.
###     Mostly these are changes to access path, auto_path, module path.
###     If Sync Mode is on, a corresponding test with Sync Mode off is 9.*

test safe-19.8 {autoloading commands indexed in tclIndex files, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library \
                                            [file join $TestsDir auto0 auto1] \
                                            [file join $TestsDir auto0 auto2]] \
                              -autoPath [list $tcl_library \
                                            [file join $TestsDir auto0 auto1] \
                                            [file join $TestsDir auto0 auto2]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappC [mapList $PathMapp [dict get $confA -autoPath]]
    set toksC [interp eval $i set ::auto_path]

    # Load and run the commands.
    set code1 [catch {interp eval $i {report1}} msg1]
    set code2 [catch {interp eval $i {report2}} msg2]

    list $path1 $path2 -- $code1 $msg1 $code2 $msg2 -- $mappA -- $mappC -- $toksC
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- 0 ok1 0 ok2 --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
        {{$p(:0:)} {$p(:1:)} {$p(:2:)}}}
test safe-19.9 {interpConfigure change the access path; tclIndex commands unaffected by token rearrangement (dummy test of doreset), Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library \
                                            [file join $TestsDir auto0 auto1] \
                                            [file join $TestsDir auto0 auto2]] \
                              -autoPath [list $tcl_library \
                                            [file join $TestsDir auto0 auto1] \
                                            [file join $TestsDir auto0 auto2]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappC [mapList $PathMapp [dict get $confA -autoPath]]
    set toksC [interp eval $i set ::auto_path]

    # Load auto_load data.
    interp eval $i {catch nonExistentCommand}

    # Load and run the commands.
    # This guarantees the test will pass even if the tokens are swapped.
    set code1 [catch {interp eval $i {report1}} msg1]
    set code2 [catch {interp eval $i {report2}} msg2]

    # Rearrange access path.  Swap tokens {$p(:1:)} and {$p(:2:)}.
    safe::interpConfigure $i -accessPath [list $tcl_library \
                                           [file join $TestsDir auto0 auto2] \
                                           [file join $TestsDir auto0 auto1]] \
                             -autoPath [list $tcl_library \
                                            [file join $TestsDir auto0 auto1] \
                                            [file join $TestsDir auto0 auto2]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappD [mapList $PathMapp [dict get $confB -autoPath]]
    set toksD [interp eval $i set ::auto_path]

    # Run the commands.
    set code3 [catch {interp eval $i {report1}} msg3]
    set code4 [catch {interp eval $i {report2}} msg4]

    list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- \
            $mappA -- $mappB -- $mappC -- $mappD -- $toksC -- $toksD
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} -- 0 ok1 0 ok2 --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
        {TCLLIB TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1*} --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
        {{$p(:0:)} {$p(:1:)} {$p(:2:)}} -- {{$p(:0:)} {$p(:2:)} {$p(:1:)}}}
test safe-19.10 {interpConfigure change the access path; tclIndex commands unaffected by token rearrangement (actual test of doreset), Sync Mode off} -constraints {AutoSyncDefined} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library \
                                            [file join $TestsDir auto0 auto1] \
                                            [file join $TestsDir auto0 auto2]] \
                              -autoPath [list $tcl_library \
                                            [file join $TestsDir auto0 auto1] \
                                            [file join $TestsDir auto0 auto2]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappC [mapList $PathMapp [dict get $confA -autoPath]]
    set toksC [interp eval $i set ::auto_path]

    # Load auto_load data.
    interp eval $i {catch nonExistentCommand}

    # Do not load the commands.  With the tokens swapped, the test
    # will pass only if the Safe Base has called auto_reset.

    # Rearrange access path.  Swap tokens {$p(:1:)} and {$p(:2:)}.
    safe::interpConfigure $i -accessPath [list $tcl_library \
                                           [file join $TestsDir auto0 auto2] \
                                           [file join $TestsDir auto0 auto1]] \
                             -autoPath [list $tcl_library \
                                            [file join $TestsDir auto0 auto1] \
                                            [file join $TestsDir auto0 auto2]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappD [mapList $PathMapp [dict get $confB -autoPath]]
    set toksD [interp eval $i set ::auto_path]

    # Load and run the commands.
    set code3 [catch {interp eval $i {report1}} msg3]
    set code4 [catch {interp eval $i {report2}} msg4]

    list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- \
            $mappA -- $mappB -- $mappC -- $mappD -- $toksC -- $toksD
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} --\
        0 ok1 0 ok2 --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
        {TCLLIB TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1*} --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2} --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2} --\
        {{$p(:0:)} {$p(:1:)} {$p(:2:)}} -- {{$p(:0:)} {$p(:2:)} {$p(:1:)}}}
test safe-19.11 {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement (1), Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library \
                                            [file join $TestsDir auto0] \
                                            [file join $TestsDir auto0 auto1] \
                                            [file join $TestsDir auto0 auto2]] \
                              -autoPath [list $tcl_library \
                                            [file join $TestsDir auto0]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path0 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappC [mapList $PathMapp [dict get $confA -autoPath]]
    set toksC [interp eval $i set ::auto_path]

    # Load pkgIndex.tcl data.
    catch {interp eval $i {package require NOEXIST}}

    # Rearrange access path.  Swap tokens {$p(:2:)} and {$p(:3:)}.
    # This would have no effect because the records in Pkg of these directories
    # were from access as children of {$p(:1:)}.
    safe::interpConfigure $i -accessPath [list $tcl_library \
                                           [file join $TestsDir auto0] \
                                           [file join $TestsDir auto0 auto2] \
                                           [file join $TestsDir auto0 auto1]] \
                              -autoPath [list $tcl_library \
                                            [file join $TestsDir auto0]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappD [mapList $PathMapp [dict get $confB -autoPath]]
    set toksD [interp eval $i set ::auto_path]

    # Try to load the packages and run a command from each one.
    set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3 opts3]
    set code4 [catch {interp eval $i {package require SafeTestPackage2}} msg4 opts4]
    set code5 [catch {interp eval $i {HeresPackage1}} msg5 opts5]
    set code6 [catch {interp eval $i {HeresPackage2}} msg6 opts6]

    list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- \
         $mappA -- $mappB -- $mappC -- $mappD -- $toksC -- $toksD -- \
         $code5 $msg5 $code6 $msg6
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:2:)} {$p(:3:)} -- {$p(:3:)} {$p(:2:)} -- 0 1.2.3 0 2.3.4 --\
        {TCLLIB TESTSDIR/auto0 TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
        {TCLLIB TESTSDIR/auto0 TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1*} --\
        {TCLLIB TESTSDIR/auto0} -- {TCLLIB TESTSDIR/auto0} --\
        {{$p(:0:)} {$p(:1:)}} -- {{$p(:0:)} {$p(:1:)}} --\
        0 OK1 0 OK2}
test safe-19.12 {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement, safe-19.11 without path auto0, Sync Mode off} -constraints {AutoSyncDefined} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    # To manage without path auto0, use an auto_path that is unusual for
    # package discovery.
    set i [safe::interpCreate -accessPath [list $tcl_library \
                                            [file join $TestsDir auto0 auto1] \
                                            [file join $TestsDir auto0 auto2]] \
                              -autoPath [list $tcl_library \
                                            [file join $TestsDir auto0 auto1] \
                                            [file join $TestsDir auto0 auto2]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappC [mapList $PathMapp [dict get $confA -autoPath]]
    set toksC [interp eval $i set ::auto_path]

    # Load pkgIndex.tcl data.
    catch {interp eval $i {package require NOEXIST}}

    # Rearrange access path.  Swap tokens {$p(:2:)} and {$p(:3:)}.
    safe::interpConfigure $i -accessPath [list $tcl_library \
                                           [file join $TestsDir auto0 auto2] \
                                           [file join $TestsDir auto0 auto1]] \
                              -autoPath [list $tcl_library \
                                            [file join $TestsDir auto0 auto2] \
                                            [file join $TestsDir auto0 auto1]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappD [mapList $PathMapp [dict get $confB -autoPath]]
    set toksD [interp eval $i set ::auto_path]

    # Try to load the packages and run a command from each one.
    set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3 opts3]
    set code4 [catch {interp eval $i {package require SafeTestPackage2}} msg4 opts4]
    set code5 [catch {interp eval $i {HeresPackage1}} msg5 opts5]
    set code6 [catch {interp eval $i {HeresPackage2}} msg6 opts6]

    list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- \
            $mappA -- $mappB -- $mappC -- $mappD -- $toksC -- $toksD -- \
            $code5 $msg5 $code6 $msg6
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} --\
        0 1.2.3 0 2.3.4 --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
        {TCLLIB TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1*} --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2} --\
        {TCLLIB TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1} --\
        {{$p(:0:)} {$p(:1:)} {$p(:2:)}} -- {{$p(:0:)} {$p(:1:)} {$p(:2:)}} --\
        0 OK1 0 OK2}
test safe-19.13 {interpConfigure change the access path; pkgIndex.tcl packages fail if directory de-listed, Sync Mode off} -constraints {AutoSyncDefined} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    # Path auto0 added (cf. safe-9.3) because it is needed for auto_path.
    set i [safe::interpCreate -accessPath [list $tcl_library \
                                            [file join $TestsDir auto0] \
                                            [file join $TestsDir auto0 auto1] \
                                            [file join $TestsDir auto0 auto2]] \
                              -autoPath [list $tcl_library \
                                            [file join $TestsDir auto0]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappC [mapList $PathMapp [dict get $confA -autoPath]]
    set toksC [interp eval $i set ::auto_path]







|
|
|



|
|

|





|
|










|








|
|





|
|
|
|
|
|





|





|
|

|





|
|
|
|
|
|





|





|
|





|
|
|
|
|
|





|





|
|

|





|
|
|
|
|
|





|










|
|

|



|
|
|
|
|
















|


|
|
|



|
|

|



|
|
|
|
|


















|
|
|
|
|













|



|


|
|
|
|
|



|
|

|



|
|
|
|
|
















|
|
|
|
|













|



|


|
|
|
|
|
|



|
|

|



|
|
|
|
|
















|
|
|
|
|















|
|



|


|
|
|
|
|



|
|

|





|
|
|
|
|













|
|
|
|
|















|
|



|


|
|
|
|
|
|
|



|
|

|




|
|
|
|
|







2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
	    [safe::interpConfigure $i]\
	    [safe::interpDelete $i]
} -cleanup {
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result "{} {{\$p(:0:)}} {\$p(:0:)} {\$p(:*:)} {\$p(:*:)} 0 1.2.3\
	{-accessPath {[list $tcl_library *$TestsDir/auto0 $TestsDir/auto0/auto1]}\
	-statics 0 -nested 1 -deleteHook {}\
	-autoPath {}} {}"
test safe-17.5 {cf. safe-7.5 - positive and negative module package require, including ancestor directory issue, Sync Mode off} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
    set i [safe::interpCreate]
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    interp eval $i {
	package forget mod1::test1
	catch {namespace delete ::mod1}
    }
} -body {
    # Should raise an error (tests module ancestor directory rule)
    set code1 [catch {interp eval $i {package require test1}} msg1]
    # Should not raise an error
    set code2 [catch {interp eval $i {package require mod1::test1}} msg2]
    return [list $code1 $msg1 $code2]
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {1 {can't find package test1} 0}

### 18. Test tokenization of directories available to a child.

test safe-18.1 {Check that each directory of the default auto_path is a valid token, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    }
    set i [safe::interpCreate]
} -body {
    set badTokens {}
    foreach dir [$i eval {set ::auto_path}] {
	if {[regexp {^\$p\(:[0-9]+:\)$} $dir]} {
	    # Match - OK - token has expected form
	} else {
	    # No match - possibly an ordinary path has not been tokenized
	    lappend badTokens $dir
	}
    }
    set badTokens
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {}
test safe-18.1.1 {Check that each directory of the default auto_path is a valid token, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate]
} -body {
    set badTokens {}
    foreach dir [$i eval {set ::auto_path}] {
	if {[regexp {^\$p\(:[0-9]+:\)$} $dir]} {
	    # Match - OK - token has expected form
	} else {
	    # No match - possibly an ordinary path has not been tokenized
	    lappend badTokens $dir
	}
    }
    set badTokens
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {}
test safe-18.2 {Check that each directory of the module path is a valid token, Sync Mode on} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 1
    }
    set i [safe::interpCreate]
} -body {
    set badTokens {}
    foreach dir [$i eval {::tcl::tm::path list}] {
	if {[regexp {^\$p\(:[0-9]+:\)$} $dir]} {
	    # Match - OK - token has expected form
	} else {
	    # No match - possibly an ordinary path has not been tokenized
	    lappend badTokens $dir
	}
    }
    set badTokens
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {}
test safe-18.2.1 {Check that each directory of the module path is a valid token, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate]
} -body {
    set badTokens {}
    foreach dir [$i eval {::tcl::tm::path list}] {
	if {[regexp {^\$p\(:[0-9]+:\)$} $dir]} {
	    # Match - OK - token has expected form
	} else {
	    # No match - possibly an ordinary path has not been tokenized
	    lappend badTokens $dir
	}
    }
    set badTokens
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {}

### 19. Assorted options, including changes to option values.
###     Mostly these are changes to access path, auto_path, module path.
###     If Sync Mode is on, a corresponding test with Sync Mode off is 9.*

test safe-19.8 {autoloading commands indexed in tclIndex files, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library \
					    [file join $TestsDir auto0 auto1] \
					    [file join $TestsDir auto0 auto2]] \
			      -autoPath [list $tcl_library \
					    [file join $TestsDir auto0 auto1] \
					    [file join $TestsDir auto0 auto2]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappC [mapList $PathMapp [dict get $confA -autoPath]]
    set toksC [interp eval $i set ::auto_path]

    # Load and run the commands.
    set code1 [catch {interp eval $i {report1}} msg1]
    set code2 [catch {interp eval $i {report2}} msg2]

    list $path1 $path2 -- $code1 $msg1 $code2 $msg2 -- $mappA -- $mappC -- $toksC
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- 0 ok1 0 ok2 --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
	{{$p(:0:)} {$p(:1:)} {$p(:2:)}}}
test safe-19.9 {interpConfigure change the access path; tclIndex commands unaffected by token rearrangement (dummy test of doreset), Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library \
					    [file join $TestsDir auto0 auto1] \
					    [file join $TestsDir auto0 auto2]] \
			      -autoPath [list $tcl_library \
					    [file join $TestsDir auto0 auto1] \
					    [file join $TestsDir auto0 auto2]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappC [mapList $PathMapp [dict get $confA -autoPath]]
    set toksC [interp eval $i set ::auto_path]

    # Load auto_load data.
    interp eval $i {catch nonExistentCommand}

    # Load and run the commands.
    # This guarantees the test will pass even if the tokens are swapped.
    set code1 [catch {interp eval $i {report1}} msg1]
    set code2 [catch {interp eval $i {report2}} msg2]

    # Rearrange access path.  Swap tokens {$p(:1:)} and {$p(:2:)}.
    safe::interpConfigure $i -accessPath [list $tcl_library \
					   [file join $TestsDir auto0 auto2] \
					   [file join $TestsDir auto0 auto1]] \
			     -autoPath [list $tcl_library \
					    [file join $TestsDir auto0 auto1] \
					    [file join $TestsDir auto0 auto2]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappD [mapList $PathMapp [dict get $confB -autoPath]]
    set toksD [interp eval $i set ::auto_path]

    # Run the commands.
    set code3 [catch {interp eval $i {report1}} msg3]
    set code4 [catch {interp eval $i {report2}} msg4]

    list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- \
	    $mappA -- $mappB -- $mappC -- $mappD -- $toksC -- $toksD
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} -- 0 ok1 0 ok2 --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
	{TCLLIB TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1*} --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
	{{$p(:0:)} {$p(:1:)} {$p(:2:)}} -- {{$p(:0:)} {$p(:2:)} {$p(:1:)}}}
test safe-19.10 {interpConfigure change the access path; tclIndex commands unaffected by token rearrangement (actual test of doreset), Sync Mode off} -constraints {AutoSyncDefined} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library \
					    [file join $TestsDir auto0 auto1] \
					    [file join $TestsDir auto0 auto2]] \
			      -autoPath [list $tcl_library \
					    [file join $TestsDir auto0 auto1] \
					    [file join $TestsDir auto0 auto2]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappC [mapList $PathMapp [dict get $confA -autoPath]]
    set toksC [interp eval $i set ::auto_path]

    # Load auto_load data.
    interp eval $i {catch nonExistentCommand}

    # Do not load the commands.  With the tokens swapped, the test
    # will pass only if the Safe Base has called auto_reset.

    # Rearrange access path.  Swap tokens {$p(:1:)} and {$p(:2:)}.
    safe::interpConfigure $i -accessPath [list $tcl_library \
					   [file join $TestsDir auto0 auto2] \
					   [file join $TestsDir auto0 auto1]] \
			     -autoPath [list $tcl_library \
					    [file join $TestsDir auto0 auto1] \
					    [file join $TestsDir auto0 auto2]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappD [mapList $PathMapp [dict get $confB -autoPath]]
    set toksD [interp eval $i set ::auto_path]

    # Load and run the commands.
    set code3 [catch {interp eval $i {report1}} msg3]
    set code4 [catch {interp eval $i {report2}} msg4]

    list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- \
	    $mappA -- $mappB -- $mappC -- $mappD -- $toksC -- $toksD
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} --\
	0 ok1 0 ok2 --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
	{TCLLIB TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1*} --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2} --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2} --\
	{{$p(:0:)} {$p(:1:)} {$p(:2:)}} -- {{$p(:0:)} {$p(:2:)} {$p(:1:)}}}
test safe-19.11 {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement (1), Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library \
					    [file join $TestsDir auto0] \
					    [file join $TestsDir auto0 auto1] \
					    [file join $TestsDir auto0 auto2]] \
			      -autoPath [list $tcl_library \
					    [file join $TestsDir auto0]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path0 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappC [mapList $PathMapp [dict get $confA -autoPath]]
    set toksC [interp eval $i set ::auto_path]

    # Load pkgIndex.tcl data.
    catch {interp eval $i {package require NOEXIST}}

    # Rearrange access path.  Swap tokens {$p(:2:)} and {$p(:3:)}.
    # This would have no effect because the records in Pkg of these directories
    # were from access as children of {$p(:1:)}.
    safe::interpConfigure $i -accessPath [list $tcl_library \
					   [file join $TestsDir auto0] \
					   [file join $TestsDir auto0 auto2] \
					   [file join $TestsDir auto0 auto1]] \
			      -autoPath [list $tcl_library \
					    [file join $TestsDir auto0]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappD [mapList $PathMapp [dict get $confB -autoPath]]
    set toksD [interp eval $i set ::auto_path]

    # Try to load the packages and run a command from each one.
    set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3 opts3]
    set code4 [catch {interp eval $i {package require SafeTestPackage2}} msg4 opts4]
    set code5 [catch {interp eval $i {HeresPackage1}} msg5 opts5]
    set code6 [catch {interp eval $i {HeresPackage2}} msg6 opts6]

    list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- \
	 $mappA -- $mappB -- $mappC -- $mappD -- $toksC -- $toksD -- \
	 $code5 $msg5 $code6 $msg6
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:2:)} {$p(:3:)} -- {$p(:3:)} {$p(:2:)} -- 0 1.2.3 0 2.3.4 --\
	{TCLLIB TESTSDIR/auto0 TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
	{TCLLIB TESTSDIR/auto0 TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1*} --\
	{TCLLIB TESTSDIR/auto0} -- {TCLLIB TESTSDIR/auto0} --\
	{{$p(:0:)} {$p(:1:)}} -- {{$p(:0:)} {$p(:1:)}} --\
	0 OK1 0 OK2}
test safe-19.12 {interpConfigure change the access path; pkgIndex.tcl packages unaffected by token rearrangement, safe-19.11 without path auto0, Sync Mode off} -constraints {AutoSyncDefined} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    # To manage without path auto0, use an auto_path that is unusual for
    # package discovery.
    set i [safe::interpCreate -accessPath [list $tcl_library \
					    [file join $TestsDir auto0 auto1] \
					    [file join $TestsDir auto0 auto2]] \
			      -autoPath [list $tcl_library \
					    [file join $TestsDir auto0 auto1] \
					    [file join $TestsDir auto0 auto2]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappC [mapList $PathMapp [dict get $confA -autoPath]]
    set toksC [interp eval $i set ::auto_path]

    # Load pkgIndex.tcl data.
    catch {interp eval $i {package require NOEXIST}}

    # Rearrange access path.  Swap tokens {$p(:2:)} and {$p(:3:)}.
    safe::interpConfigure $i -accessPath [list $tcl_library \
					   [file join $TestsDir auto0 auto2] \
					   [file join $TestsDir auto0 auto1]] \
			      -autoPath [list $tcl_library \
					    [file join $TestsDir auto0 auto2] \
					    [file join $TestsDir auto0 auto1]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappD [mapList $PathMapp [dict get $confB -autoPath]]
    set toksD [interp eval $i set ::auto_path]

    # Try to load the packages and run a command from each one.
    set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3 opts3]
    set code4 [catch {interp eval $i {package require SafeTestPackage2}} msg4 opts4]
    set code5 [catch {interp eval $i {HeresPackage1}} msg5 opts5]
    set code6 [catch {interp eval $i {HeresPackage2}} msg6 opts6]

    list $path1 $path2 -- $path3 $path4 -- $code3 $msg3 $code4 $msg4 -- \
	    $mappA -- $mappB -- $mappC -- $mappD -- $toksC -- $toksD -- \
	    $code5 $msg5 $code6 $msg6
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:2:)} {$p(:1:)} --\
	0 1.2.3 0 2.3.4 --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
	{TCLLIB TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1*} --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2} --\
	{TCLLIB TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1} --\
	{{$p(:0:)} {$p(:1:)} {$p(:2:)}} -- {{$p(:0:)} {$p(:1:)} {$p(:2:)}} --\
	0 OK1 0 OK2}
test safe-19.13 {interpConfigure change the access path; pkgIndex.tcl packages fail if directory de-listed, Sync Mode off} -constraints {AutoSyncDefined} -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    # Path auto0 added (cf. safe-9.3) because it is needed for auto_path.
    set i [safe::interpCreate -accessPath [list $tcl_library \
					    [file join $TestsDir auto0] \
					    [file join $TestsDir auto0 auto1] \
					    [file join $TestsDir auto0 auto2]] \
			      -autoPath [list $tcl_library \
					    [file join $TestsDir auto0]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappC [mapList $PathMapp [dict get $confA -autoPath]]
    set toksC [interp eval $i set ::auto_path]
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
    set toksD [interp eval $i set ::auto_path]

    # Try to load the packages.
    set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3]
    set code6 [catch {interp eval $i {package require SafeTestPackage2}} msg6]

    list $path1 $path2 -- $code4 $path4 -- $code5 $path5 -- $code3 $code6 -- \
            $mappA -- $mappB -- $mappC -- $mappD -- $toksC -- $toksD
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:2:)} {$p(:3:)} -- 1 {* not found in access path} --\
        1 {* not found in access path} -- 1 1 --\
        {TCLLIB TESTSDIR/auto0 TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
        {TCLLIB*} -- {TCLLIB TESTSDIR/auto0} -- {TCLLIB TESTSDIR/auto0} --\
        {{$p(:0:)} {$p(:1:)}} -- {{$p(:0:)}}}
# (no counterpart safe-9.14)
test safe-19.14 {when interpConfigure changes the access path, ::auto_path uses -autoPath value and new tokens, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    # Test that although -autoPath is unchanged, the child's ::auto_path changes to
    # reflect the changes in token mappings.
    set i [safe::interpCreate -accessPath [list $tcl_library \
                                            [file join $TestsDir auto0] \
                                            [file join $TestsDir auto0 auto1] \
                                            [file join $TestsDir auto0 auto2]] \
                              -autoPath [list $tcl_library \
                                            [file join $TestsDir auto0]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path0 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappC [mapList $PathMapp [dict get $confA -autoPath]]
    set toksC [interp eval $i set ::auto_path]

    # Load pkgIndex.tcl data.
    catch {interp eval $i {package require NOEXIST}}

    # Rearrange access path.  Swap tokens {$p(:1:)} and {$p(:3:)}.
    safe::interpConfigure $i -accessPath [list $tcl_library \
                                           [file join $TestsDir auto0 auto2] \
                                           [file join $TestsDir auto0 auto1] \
                                           [file join $TestsDir auto0]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path5 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0]]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappD [mapList $PathMapp [dict get $confA -autoPath]]
    set toksD [interp eval $i set ::auto_path]

    # Try to load the packages and run a command from each one.
    set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3 opts3]
    set code4 [catch {interp eval $i {package require SafeTestPackage2}} msg4 opts4]
    set code5 [catch {interp eval $i {HeresPackage1}} msg5 opts5]
    set code6 [catch {interp eval $i {HeresPackage2}} msg6 opts6]

    list $path0 $path1 $path2 -- $path5 $path3 $path4 -- $toksC -- $toksD -- \
         $code3 $msg3 $code4 $msg4 -- \
         $mappA -- $mappB -- $mappC -- $mappD -- $code5 $msg5 $code6 $msg6
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} {$p(:3:)} -- {$p(:3:)} {$p(:2:)} {$p(:1:)} -- {{$p(:0:)} {$p(:1:)}} -- {{$p(:0:)} {$p(:3:)}} -- 0 1.2.3 0 2.3.4 --\
        {TCLLIB TESTSDIR/auto0 TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
        {TCLLIB TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1 TESTSDIR/auto0*} --\
        {TCLLIB TESTSDIR/auto0} --\
        {TCLLIB TESTSDIR/auto0} --\
        0 OK1 0 OK2}
# (no counterpart safe-9.15)
test safe-19.15 {when interpConfigure changes the access path, ::auto_path uses -autoPath value and new tokens, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    # Test that although -autoPath is unchanged, the child's ::auto_path changes to
    # reflect the changes in token mappings; and that it is based on the -autoPath
    # value, not the previously restricted child ::auto_path.
    set i [safe::interpCreate -accessPath [list $tcl_library \
                                            [file join $TestsDir auto0]] \
                              -autoPath [list $tcl_library \
                                            [file join $TestsDir auto0 auto1] \
                                            [file join $TestsDir auto0 auto2]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path0 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0]]
    set mappC [mapList $PathMapp [dict get $confA -autoPath]]
    set toksC [interp eval $i set ::auto_path]

    # Load pkgIndex.tcl data.
    catch {interp eval $i {package require NOEXIST}}

    # Rearrange access path.  Add more directories.
    safe::interpConfigure $i -accessPath [list $tcl_library \
                                            [file join $TestsDir auto0] \
                                            [file join $TestsDir auto0 auto1] \
                                            [file join $TestsDir auto0 auto2]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path5 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0]]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappD [mapList $PathMapp [dict get $confA -autoPath]]
    set toksD [interp eval $i set ::auto_path]

    # Try to load the packages and run a command from each one.
    set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3 opts3]
    set code4 [catch {interp eval $i {package require SafeTestPackage2}} msg4 opts4]
    set code5 [catch {interp eval $i {HeresPackage1}} msg5 opts5]
    set code6 [catch {interp eval $i {HeresPackage2}} msg6 opts6]

    list $path0 -- $path5 $path3 $path4 -- $toksC -- $toksD -- \
         $code3 $msg3 $code4 $msg4 -- \
         $mappA -- $mappB -- $mappC -- $mappD -- $code5 $msg5 $code6 $msg6
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} -- {$p(:1:)} {$p(:2:)} {$p(:3:)} -- {{$p(:0:)}} -- {{$p(:0:)} {$p(:2:)} {$p(:3:)}} -- 0 1.2.3 0 2.3.4 --\
        {TCLLIB TESTSDIR/auto0*} --\
        {TCLLIB TESTSDIR/auto0 TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2} --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2} --\
        0 OK1 0 OK2}
# (no counterpart safe-9.16)
test safe-19.16 {default value for -accessPath and -autoPath on creation; -autoPath preserved when -accessPath changes, ::auto_path using changed tokens, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set tmpAutoPath $::auto_path
    set ::auto_path [list $tcl_library [file join $TestsDir auto0]]
    set i [safe::interpCreate]
    set ::auto_path $tmpAutoPath
} -body {
    # Test that the -autoPath acquires and keeps the parent's value unless otherwise specified.

    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappC [mapList $PathMapp [dict get $confA -autoPath]]
    set toksC [interp eval $i set ::auto_path]

    # Load pkgIndex.tcl data.
    catch {interp eval $i {package require NOEXIST}}

    # Rearrange access path.  Remove a directory.
    safe::interpConfigure $i -accessPath [list $tcl_library \
                                            [file join $TestsDir auto0] \
                                            [file join $TestsDir auto0 auto1]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path5 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0]]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set mappD [mapList $PathMapp [dict get $confA -autoPath]]
    set toksD [interp eval $i set ::auto_path]

    # Try to load the packages and run a command from each one.
    set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3]
    set code4 [catch {interp eval $i {package require SafeTestPackage2}} msg4]
    set code5 [catch {interp eval $i {HeresPackage1}} msg5 opts5]
    set code6 [catch {interp eval $i {HeresPackage2}} msg6 opts6]

    list $path5 $path3 -- [lindex $toksC 0] [llength $toksC] -- \
            $toksD -- $code3 $msg3 $code4 $msg4 -- \
            $mappB -- $mappC -- $mappD -- $code5 $msg5 $code6 $msg6
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:0:)} 2 --\
        {{$p(:0:)} {$p(:1:)}} -- 0 1.2.3 1 {can't find package SafeTestPackage2} --\
        {TCLLIB TESTSDIR/auto0 TESTSDIR/auto0/auto1*} --\
        {TCLLIB TESTSDIR/auto0} -- {TCLLIB TESTSDIR/auto0} --\
        0 OK1 1 {invalid command name "HeresPackage2"}}
test safe-19.20 {check module loading, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set oldTm [tcl::tm::path list]
    foreach path $oldTm {
        tcl::tm::path remove $path
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library]]

    # Inspect.
    set confA [safe::interpConfigure $i]







|



|


|
|
|
|




|
|

|





|
|
|
|
|














|
|
|
















|
|



|


|
|
|
|
|




|
|

|






|
|
|
|












|
|
|
















|
|



|


|
|
|
|
|




|
|

|


















|
|















|
|



|


|
|
|
|



|
|

|



|







2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
    set toksD [interp eval $i set ::auto_path]

    # Try to load the packages.
    set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3]
    set code6 [catch {interp eval $i {package require SafeTestPackage2}} msg6]

    list $path1 $path2 -- $code4 $path4 -- $code5 $path5 -- $code3 $code6 -- \
	    $mappA -- $mappB -- $mappC -- $mappD -- $toksC -- $toksD
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:2:)} {$p(:3:)} -- 1 {* not found in access path} --\
	1 {* not found in access path} -- 1 1 --\
	{TCLLIB TESTSDIR/auto0 TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
	{TCLLIB*} -- {TCLLIB TESTSDIR/auto0} -- {TCLLIB TESTSDIR/auto0} --\
	{{$p(:0:)} {$p(:1:)}} -- {{$p(:0:)}}}
# (no counterpart safe-9.14)
test safe-19.14 {when interpConfigure changes the access path, ::auto_path uses -autoPath value and new tokens, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    # Test that although -autoPath is unchanged, the child's ::auto_path changes to
    # reflect the changes in token mappings.
    set i [safe::interpCreate -accessPath [list $tcl_library \
					    [file join $TestsDir auto0] \
					    [file join $TestsDir auto0 auto1] \
					    [file join $TestsDir auto0 auto2]] \
			      -autoPath [list $tcl_library \
					    [file join $TestsDir auto0]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path0 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappC [mapList $PathMapp [dict get $confA -autoPath]]
    set toksC [interp eval $i set ::auto_path]

    # Load pkgIndex.tcl data.
    catch {interp eval $i {package require NOEXIST}}

    # Rearrange access path.  Swap tokens {$p(:1:)} and {$p(:3:)}.
    safe::interpConfigure $i -accessPath [list $tcl_library \
					   [file join $TestsDir auto0 auto2] \
					   [file join $TestsDir auto0 auto1] \
					   [file join $TestsDir auto0]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path5 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0]]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappD [mapList $PathMapp [dict get $confA -autoPath]]
    set toksD [interp eval $i set ::auto_path]

    # Try to load the packages and run a command from each one.
    set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3 opts3]
    set code4 [catch {interp eval $i {package require SafeTestPackage2}} msg4 opts4]
    set code5 [catch {interp eval $i {HeresPackage1}} msg5 opts5]
    set code6 [catch {interp eval $i {HeresPackage2}} msg6 opts6]

    list $path0 $path1 $path2 -- $path5 $path3 $path4 -- $toksC -- $toksD -- \
	 $code3 $msg3 $code4 $msg4 -- \
	 $mappA -- $mappB -- $mappC -- $mappD -- $code5 $msg5 $code6 $msg6
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} {$p(:3:)} -- {$p(:3:)} {$p(:2:)} {$p(:1:)} -- {{$p(:0:)} {$p(:1:)}} -- {{$p(:0:)} {$p(:3:)}} -- 0 1.2.3 0 2.3.4 --\
	{TCLLIB TESTSDIR/auto0 TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
	{TCLLIB TESTSDIR/auto0/auto2 TESTSDIR/auto0/auto1 TESTSDIR/auto0*} --\
	{TCLLIB TESTSDIR/auto0} --\
	{TCLLIB TESTSDIR/auto0} --\
	0 OK1 0 OK2}
# (no counterpart safe-9.15)
test safe-19.15 {when interpConfigure changes the access path, ::auto_path uses -autoPath value and new tokens, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    # Test that although -autoPath is unchanged, the child's ::auto_path changes to
    # reflect the changes in token mappings; and that it is based on the -autoPath
    # value, not the previously restricted child ::auto_path.
    set i [safe::interpCreate -accessPath [list $tcl_library \
					    [file join $TestsDir auto0]] \
			      -autoPath [list $tcl_library \
					    [file join $TestsDir auto0 auto1] \
					    [file join $TestsDir auto0 auto2]]]
    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappA [mapList $PathMapp [dict get $confA -accessPath]]
    set path0 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0]]
    set mappC [mapList $PathMapp [dict get $confA -autoPath]]
    set toksC [interp eval $i set ::auto_path]

    # Load pkgIndex.tcl data.
    catch {interp eval $i {package require NOEXIST}}

    # Rearrange access path.  Add more directories.
    safe::interpConfigure $i -accessPath [list $tcl_library \
					    [file join $TestsDir auto0] \
					    [file join $TestsDir auto0 auto1] \
					    [file join $TestsDir auto0 auto2]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path5 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0]]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto2]]
    set mappD [mapList $PathMapp [dict get $confA -autoPath]]
    set toksD [interp eval $i set ::auto_path]

    # Try to load the packages and run a command from each one.
    set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3 opts3]
    set code4 [catch {interp eval $i {package require SafeTestPackage2}} msg4 opts4]
    set code5 [catch {interp eval $i {HeresPackage1}} msg5 opts5]
    set code6 [catch {interp eval $i {HeresPackage2}} msg6 opts6]

    list $path0 -- $path5 $path3 $path4 -- $toksC -- $toksD -- \
	 $code3 $msg3 $code4 $msg4 -- \
	 $mappA -- $mappB -- $mappC -- $mappD -- $code5 $msg5 $code6 $msg6
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} -- {$p(:1:)} {$p(:2:)} {$p(:3:)} -- {{$p(:0:)}} -- {{$p(:0:)} {$p(:2:)} {$p(:3:)}} -- 0 1.2.3 0 2.3.4 --\
	{TCLLIB TESTSDIR/auto0*} --\
	{TCLLIB TESTSDIR/auto0 TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2*} --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2} --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2} --\
	0 OK1 0 OK2}
# (no counterpart safe-9.16)
test safe-19.16 {default value for -accessPath and -autoPath on creation; -autoPath preserved when -accessPath changes, ::auto_path using changed tokens, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set tmpAutoPath $::auto_path
    set ::auto_path [list $tcl_library [file join $TestsDir auto0]]
    set i [safe::interpCreate]
    set ::auto_path $tmpAutoPath
} -body {
    # Test that the -autoPath acquires and keeps the parent's value unless otherwise specified.

    # Inspect.
    set confA [safe::interpConfigure $i]
    set mappC [mapList $PathMapp [dict get $confA -autoPath]]
    set toksC [interp eval $i set ::auto_path]

    # Load pkgIndex.tcl data.
    catch {interp eval $i {package require NOEXIST}}

    # Rearrange access path.  Remove a directory.
    safe::interpConfigure $i -accessPath [list $tcl_library \
					    [file join $TestsDir auto0] \
					    [file join $TestsDir auto0 auto1]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set mappB [mapList $PathMapp [dict get $confB -accessPath]]
    set path5 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0]]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 auto1]]
    set mappD [mapList $PathMapp [dict get $confA -autoPath]]
    set toksD [interp eval $i set ::auto_path]

    # Try to load the packages and run a command from each one.
    set code3 [catch {interp eval $i {package require SafeTestPackage1}} msg3]
    set code4 [catch {interp eval $i {package require SafeTestPackage2}} msg4]
    set code5 [catch {interp eval $i {HeresPackage1}} msg5 opts5]
    set code6 [catch {interp eval $i {HeresPackage2}} msg6 opts6]

    list $path5 $path3 -- [lindex $toksC 0] [llength $toksC] -- \
	    $toksD -- $code3 $msg3 $code4 $msg4 -- \
	    $mappB -- $mappC -- $mappD -- $code5 $msg5 $code6 $msg6
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{$p(:1:)} {$p(:2:)} -- {$p(:0:)} 2 --\
	{{$p(:0:)} {$p(:1:)}} -- 0 1.2.3 1 {can't find package SafeTestPackage2} --\
	{TCLLIB TESTSDIR/auto0 TESTSDIR/auto0/auto1*} --\
	{TCLLIB TESTSDIR/auto0} -- {TCLLIB TESTSDIR/auto0} --\
	0 OK1 1 {invalid command name "HeresPackage2"}}
test safe-19.20 {check module loading, Sync Mode off} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set oldTm [tcl::tm::path list]
    foreach path $oldTm {
	tcl::tm::path remove $path
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library]]

    # Inspect.
    set confA [safe::interpConfigure $i]
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
    set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
    set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
    set out0  [interp eval $i {test0::try0}]
    set out1  [interp eval $i {mod1::test1::try1}]
    set out2  [interp eval $i {mod2::test2::try2}]

    list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
            $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $out0 $out1 $out2
} -cleanup {
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    foreach path [lreverse $oldTm] {
        tcl::tm::path add $path
    }
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
        0 0.5 0 1.0 0 2.0 --\
        {TCLLIB TESTSDIR/auto0/modules TESTSDIR/auto0/modules/mod1\
         TESTSDIR/auto0/modules/mod2} -- res0 res1 res2}
# See comments on lsort after test safe-9.20.
test safe-19.21 {interpConfigure change the access path; check module loading, Sync Mode off; stale data case 1} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set oldTm [tcl::tm::path list]
    foreach path $oldTm {
        tcl::tm::path remove $path
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library]]

    # Inspect.
    set confA [safe::interpConfigure $i]
    set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
    set modsA [interp eval $i {tcl::tm::path list}]
    set path0 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]

    # Add to access path.
    # This injects more tokens, pushing modules to higher token numbers.
    safe::interpConfigure $i -accessPath [list $tcl_library \
                                           [file join $TestsDir auto0 auto1] \
                                           [file join $TestsDir auto0 auto2]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
    set modsB [interp eval $i {tcl::tm::path list}]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path5 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]







|



|



|


|
|
|




|
|

|



|
















|
|







2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
    set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
    set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
    set out0  [interp eval $i {test0::try0}]
    set out1  [interp eval $i {mod1::test1::try1}]
    set out2  [interp eval $i {mod2::test2::try2}]

    list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
	    $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $out0 $out1 $out2
} -cleanup {
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    foreach path [lreverse $oldTm] {
	tcl::tm::path add $path
    }
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
	0 0.5 0 1.0 0 2.0 --\
	{TCLLIB TESTSDIR/auto0/modules TESTSDIR/auto0/modules/mod1\
	 TESTSDIR/auto0/modules/mod2} -- res0 res1 res2}
# See comments on lsort after test safe-9.20.
test safe-19.21 {interpConfigure change the access path; check module loading, Sync Mode off; stale data case 1} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set oldTm [tcl::tm::path list]
    foreach path $oldTm {
	tcl::tm::path remove $path
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library]]

    # Inspect.
    set confA [safe::interpConfigure $i]
    set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
    set modsA [interp eval $i {tcl::tm::path list}]
    set path0 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]

    # Add to access path.
    # This injects more tokens, pushing modules to higher token numbers.
    safe::interpConfigure $i -accessPath [list $tcl_library \
					   [file join $TestsDir auto0 auto1] \
					   [file join $TestsDir auto0 auto2]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
    set modsB [interp eval $i {tcl::tm::path list}]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path5 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
    set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
    set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
    set out0  [interp eval $i {test0::try0}]
    set out1  [interp eval $i {mod1::test1::try1}]
    set out2  [interp eval $i {mod2::test2::try2}]

    list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
            [lsort [list $path3 $path4 $path5]] -- $modsB -- \
            $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
            $out0 $out1 $out2
} -cleanup {
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    foreach path [lreverse $oldTm] {
        tcl::tm::path add $path
    }
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
        {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
        0 0.5 0 1.0 0 2.0 --\
        {TCLLIB TESTSDIR/auto0/modules TESTSDIR/auto0/modules/mod1\
         TESTSDIR/auto0/modules/mod2} --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2 TESTSDIR/auto0/modules\
         TESTSDIR/auto0/modules/mod1 TESTSDIR/auto0/modules/mod2} --\
        res0 res1 res2}
# See comments on lsort after test safe-9.20.
test safe-19.22 {interpConfigure change the access path; check module loading, Sync Mode off; stale data case 0} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set oldTm [tcl::tm::path list]
    foreach path $oldTm {
        tcl::tm::path remove $path
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library]]

    # Inspect.
    set confA [safe::interpConfigure $i]
    set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
    set modsA [interp eval $i {tcl::tm::path list}]
    set path0 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]

    # Add to access path.
    # This injects more tokens, pushing modules to higher token numbers.
    safe::interpConfigure $i -accessPath [list $tcl_library \
                                          [file join $TestsDir auto0 auto1] \
                                          [file join $TestsDir auto0 auto2]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
    set modsB [interp eval $i {tcl::tm::path list}]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path5 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]

    # Try to load the packages and run a command from each one.
    set code0 [catch {interp eval $i {package require test0}} msg0]
    set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
    set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
    set out0  [interp eval $i {test0::try0}]
    set out1  [interp eval $i {mod1::test1::try1}]
    set out2  [interp eval $i {mod2::test2::try2}]

    list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
            [lsort [list $path3 $path4 $path5]] -- $modsB -- \
            $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
            $out0 $out1 $out2
} -cleanup {
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    foreach path [lreverse $oldTm] {
        tcl::tm::path add $path
    }
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
        {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
        0 0.5 0 1.0 0 2.0 --\
        {TCLLIB TESTSDIR/auto0/modules TESTSDIR/auto0/modules/mod1\
         TESTSDIR/auto0/modules/mod2} --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2 TESTSDIR/auto0/modules\
         TESTSDIR/auto0/modules/mod1 TESTSDIR/auto0/modules/mod2} --\
        res0 res1 res2}
# See comments on lsort after test safe-9.20.
test safe-19.23 {interpConfigure change the access path; check module loading, Sync Mode off; stale data case 3} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set oldTm [tcl::tm::path list]
    foreach path $oldTm {
        tcl::tm::path remove $path
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library]]

    # Inspect.
    set confA [safe::interpConfigure $i]







|
|
|



|



|


|
|
|
|
|
|
|




|
|

|



|
















|
|

















|
|
|



|



|


|
|
|
|
|
|
|




|
|

|



|







2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
    set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
    set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
    set out0  [interp eval $i {test0::try0}]
    set out1  [interp eval $i {mod1::test1::try1}]
    set out2  [interp eval $i {mod2::test2::try2}]

    list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
	    [lsort [list $path3 $path4 $path5]] -- $modsB -- \
	    $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
	    $out0 $out1 $out2
} -cleanup {
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    foreach path [lreverse $oldTm] {
	tcl::tm::path add $path
    }
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
	{{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
	0 0.5 0 1.0 0 2.0 --\
	{TCLLIB TESTSDIR/auto0/modules TESTSDIR/auto0/modules/mod1\
	 TESTSDIR/auto0/modules/mod2} --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2 TESTSDIR/auto0/modules\
	 TESTSDIR/auto0/modules/mod1 TESTSDIR/auto0/modules/mod2} --\
	res0 res1 res2}
# See comments on lsort after test safe-9.20.
test safe-19.22 {interpConfigure change the access path; check module loading, Sync Mode off; stale data case 0} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set oldTm [tcl::tm::path list]
    foreach path $oldTm {
	tcl::tm::path remove $path
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library]]

    # Inspect.
    set confA [safe::interpConfigure $i]
    set sortA [mapAndSortList $PathMapp [dict get $confA -accessPath]]
    set modsA [interp eval $i {tcl::tm::path list}]
    set path0 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path1 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path2 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]

    # Add to access path.
    # This injects more tokens, pushing modules to higher token numbers.
    safe::interpConfigure $i -accessPath [list $tcl_library \
					  [file join $TestsDir auto0 auto1] \
					  [file join $TestsDir auto0 auto2]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
    set modsB [interp eval $i {tcl::tm::path list}]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path5 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]

    # Try to load the packages and run a command from each one.
    set code0 [catch {interp eval $i {package require test0}} msg0]
    set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
    set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
    set out0  [interp eval $i {test0::try0}]
    set out1  [interp eval $i {mod1::test1::try1}]
    set out2  [interp eval $i {mod2::test2::try2}]

    list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
	    [lsort [list $path3 $path4 $path5]] -- $modsB -- \
	    $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
	    $out0 $out1 $out2
} -cleanup {
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    foreach path [lreverse $oldTm] {
	tcl::tm::path add $path
    }
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
	{{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
	0 0.5 0 1.0 0 2.0 --\
	{TCLLIB TESTSDIR/auto0/modules TESTSDIR/auto0/modules/mod1\
	 TESTSDIR/auto0/modules/mod2} --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2 TESTSDIR/auto0/modules\
	 TESTSDIR/auto0/modules/mod1 TESTSDIR/auto0/modules/mod2} --\
	res0 res1 res2}
# See comments on lsort after test safe-9.20.
test safe-19.23 {interpConfigure change the access path; check module loading, Sync Mode off; stale data case 3} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set oldTm [tcl::tm::path list]
    foreach path $oldTm {
	tcl::tm::path remove $path
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library]]

    # Inspect.
    set confA [safe::interpConfigure $i]
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
    catch {interp eval $i {package require NOEXIST}}
    catch {interp eval $i {package require mod1::NOEXIST}}
    catch {interp eval $i {package require mod2::NOEXIST}}

    # Add to access path.
    # This injects more tokens, pushing modules to higher token numbers.
    safe::interpConfigure $i -accessPath [list $tcl_library \
                                           [file join $TestsDir auto0 auto1] \
                                           [file join $TestsDir auto0 auto2]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
    set modsB [interp eval $i {tcl::tm::path list}]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path5 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]







|
|







2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
    catch {interp eval $i {package require NOEXIST}}
    catch {interp eval $i {package require mod1::NOEXIST}}
    catch {interp eval $i {package require mod2::NOEXIST}}

    # Add to access path.
    # This injects more tokens, pushing modules to higher token numbers.
    safe::interpConfigure $i -accessPath [list $tcl_library \
					   [file join $TestsDir auto0 auto1] \
					   [file join $TestsDir auto0 auto2]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
    set modsB [interp eval $i {tcl::tm::path list}]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path5 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
    set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
    set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
    set out0  [interp eval $i {test0::try0}]
    set out1  [interp eval $i {mod1::test1::try1}]
    set out2  [interp eval $i {mod2::test2::try2}]

    list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
            [lsort [list $path3 $path4 $path5]] -- $modsB -- \
            $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
            $out0 $out1 $out2
} -cleanup {
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    foreach path [lreverse $oldTm] {
        tcl::tm::path add $path
    }
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
        {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
        0 0.5 0 1.0 0 2.0 --\
        {TCLLIB TESTSDIR/auto0/modules TESTSDIR/auto0/modules/mod1\
         TESTSDIR/auto0/modules/mod2} --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2 TESTSDIR/auto0/modules\
         TESTSDIR/auto0/modules/mod1 TESTSDIR/auto0/modules/mod2} --\
        res0 res1 res2}
# See comments on lsort after test safe-9.20.
test safe-19.24 {interpConfigure change the access path; check module loading, Sync Mode off; stale data case 2 (worst case)} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set oldTm [tcl::tm::path list]
    foreach path $oldTm {
        tcl::tm::path remove $path
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library]]

    # Inspect.
    set confA [safe::interpConfigure $i]







|
|
|



|



|


|
|
|
|
|
|
|




|
|

|



|







3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
    set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
    set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
    set out0  [interp eval $i {test0::try0}]
    set out1  [interp eval $i {mod1::test1::try1}]
    set out2  [interp eval $i {mod2::test2::try2}]

    list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
	    [lsort [list $path3 $path4 $path5]] -- $modsB -- \
	    $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
	    $out0 $out1 $out2
} -cleanup {
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    foreach path [lreverse $oldTm] {
	tcl::tm::path add $path
    }
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
	{{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
	0 0.5 0 1.0 0 2.0 --\
	{TCLLIB TESTSDIR/auto0/modules TESTSDIR/auto0/modules/mod1\
	 TESTSDIR/auto0/modules/mod2} --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2 TESTSDIR/auto0/modules\
	 TESTSDIR/auto0/modules/mod1 TESTSDIR/auto0/modules/mod2} --\
	res0 res1 res2}
# See comments on lsort after test safe-9.20.
test safe-19.24 {interpConfigure change the access path; check module loading, Sync Mode off; stale data case 2 (worst case)} -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set oldTm [tcl::tm::path list]
    foreach path $oldTm {
	tcl::tm::path remove $path
    }
    tcl::tm::path add [file join $TestsDir auto0 modules]
} -body {
    set i [safe::interpCreate -accessPath [list $tcl_library]]

    # Inspect.
    set confA [safe::interpConfigure $i]
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
    catch {interp eval $i {package require NOEXIST}}
    catch {interp eval $i {package require mod1::NOEXIST}}
    catch {interp eval $i {package require mod2::NOEXIST}}

    # Add to access path.
    # This injects more tokens, pushing modules to higher token numbers.
    safe::interpConfigure $i -accessPath [list $tcl_library \
                                           [file join $TestsDir auto0 auto1] \
                                           [file join $TestsDir auto0 auto2]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
    set modsB [interp eval $i {tcl::tm::path list}]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path5 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]

    # Try to load the packages and run a command from each one.
    set code0 [catch {interp eval $i {package require test0}} msg0]
    set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
    set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
    set out0  [interp eval $i {test0::try0}]
    set out1  [interp eval $i {mod1::test1::try1}]
    set out2  [interp eval $i {mod2::test2::try2}]

    list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
            [lsort [list $path3 $path4 $path5]] -- $modsB -- \
            $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
            $out0 $out1 $out2
} -cleanup {
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    foreach path [lreverse $oldTm] {
        tcl::tm::path add $path
    }
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
        {{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
        0 0.5 0 1.0 0 2.0 --\
        {TCLLIB TESTSDIR/auto0/modules TESTSDIR/auto0/modules/mod1\
         TESTSDIR/auto0/modules/mod2} --\
        {TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2 TESTSDIR/auto0/modules\
         TESTSDIR/auto0/modules/mod1 TESTSDIR/auto0/modules/mod2} --\
        res0 res1 res2}
# See comments on lsort after test safe-9.20.


### 20. safe::interpCreate with different cases of -accessPath, -autoPath.

set ::auto_path [list $tcl_library [file dirname $tcl_library] [file join $TestsDir auto0]]

test safe-20.1 "create -accessPath NULL -autoPath NULL -> parent's ::auto_path" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result [list $::auto_path -- $::auto_path]
test safe-20.2 "create -accessPath {} -autoPath NULL -> parent's ::auto_path" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath {}]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result [list $::auto_path -- $::auto_path]
test safe-20.3 "create -accessPath path1 -autoPath NULL -> {}" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1]]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {{} -- {}}
test safe-20.4 "create -accessPath NULL -autoPath {} -> {}" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -autoPath {}]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {{} -- {}}
test safe-20.5 "create -accessPath {} -autoPath {} -> {}" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath {} -autoPath {}]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {{} -- {}}
test safe-20.6 "create -accessPath path1 -autoPath {} -> {}" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath {}]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {{} -- {}}
test safe-20.7 "create -accessPath NULL -autoPath path2 -> path2" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -autoPath [lrange $::auto_path 0 0]]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result [list [lrange $::auto_path 0 0] -- [lrange $::auto_path 0 0]]
test safe-20.8 "create -accessPath {} -autoPath path2 -> path2" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath {} -autoPath [lrange $::auto_path 0 0]]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result [list [lrange $::auto_path 0 0] -- [lrange $::auto_path 0 0]]
test safe-20.9 "create -accessPath path1 -autoPath path2 -> path2" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result [list [lrange $::auto_path 0 0] -- [lrange $::auto_path 0 0]]
test safe-20.10 "create -accessPath NULL -autoPath pathX -> pathX" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -autoPath /not/in/access/path]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {/not/in/access/path -- {}}
test safe-20.11 "create -accessPath {} -autoPath pathX -> pathX" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath {} -autoPath /not/in/access/path]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {/not/in/access/path -- {}}
test safe-20.12 "create -accessPath path1 -autoPath pathX -> {pathX}" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath /not/in/access/path]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {/not/in/access/path -- {}}

### 21. safe::interpConfigure with different cases of -accessPath, -autoPath.

test safe-21.1 "interpConfigure -accessPath NULL -autoPath NULL -> no change" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -deleteHook {}
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result [list [lrange $::auto_path 0 0] -- [lrange $::auto_path 0 0]]
test safe-21.2 "interpConfigure -accessPath {} -autoPath NULL -> parent's ::auto_path" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -accessPath {}
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result [list $::auto_path -- $::auto_path]
test safe-21.3 "interpConfigure -accessPath path1 -autoPath NULL -> no change" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -accessPath [lrange $::auto_path 0 1]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result [list [lrange $::auto_path 0 0] -- [lrange $::auto_path 0 0]]
test safe-21.4 "interpConfigure -accessPath NULL -autoPath {} -> {}" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -autoPath {}
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {{} -- {}}
test safe-21.5 "interpConfigure -accessPath {} -autoPath {} -> {}" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -accessPath {} -autoPath {}
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {{} -- {}}
test safe-21.6 "interpConfigure -accessPath {path1} -autoPath {} -> {}" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -accessPath [lrange $::auto_path 1 1] -autoPath {}
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {{} -- {}}
test safe-21.7 "interpConfigure -accessPath NULL -autoPath path2 -> path2" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -autoPath [lrange $::auto_path 1 1]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result [list [lrange $::auto_path 1 1] -- [lrange $::auto_path 1 1]]
test safe-21.8 "interpConfigure -accessPath {} -autoPath path2 -> path2" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -accessPath {} -autoPath [lrange $::auto_path 1 1]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result [list [lrange $::auto_path 1 1] -- [lrange $::auto_path 1 1]]
test safe-21.9 "interpConfigure -accessPath path1 -autoPath path2 -> path2" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -accessPath [lrange $::auto_path 0 2] -autoPath [lrange $::auto_path 1 1]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result [list [lrange $::auto_path 1 1] -- [lrange $::auto_path 1 1]]
test safe-21.10 "interpConfigure -accessPath NULL -autoPath pathX -> pathX" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -autoPath /not/in/access/path
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {/not/in/access/path -- {}}
test safe-21.11 "interpConfigure -accessPath {} -autoPath pathX -> pathX" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -accessPath {} -autoPath /not/in/access/path
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {/not/in/access/path -- {}}
test safe-21.12 "interpConfigure -accessPath path1 -autoPath pathX -> pathX" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
        set SyncVal_TMP [safe::setSyncMode]
        safe::setSyncMode 0
    } else {
        error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -accessPath [lrange $::auto_path 0 2] -autoPath /not/in/access/path
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
        safe::setSyncMode $SyncVal_TMP
    }
} -result {/not/in/access/path -- {}}

# cleanup
set ::auto_path $SaveAutoPath
unset SaveAutoPath TestsDir PathMapp
rename getAutoPath {}







|
|

















|
|
|



|



|


|
|
|
|
|
|
|










|
|

|







|





|
|

|







|





|
|

|







|





|
|

|







|





|
|

|







|





|
|

|







|





|
|

|







|





|
|

|







|





|
|

|







|





|
|

|







|





|
|

|







|





|
|

|







|








|
|

|








|





|
|

|








|





|
|

|








|





|
|

|








|





|
|

|








|





|
|

|








|





|
|

|








|





|
|

|








|





|
|

|








|





|
|

|








|





|
|

|








|





|
|

|








|







3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
    catch {interp eval $i {package require NOEXIST}}
    catch {interp eval $i {package require mod1::NOEXIST}}
    catch {interp eval $i {package require mod2::NOEXIST}}

    # Add to access path.
    # This injects more tokens, pushing modules to higher token numbers.
    safe::interpConfigure $i -accessPath [list $tcl_library \
					   [file join $TestsDir auto0 auto1] \
					   [file join $TestsDir auto0 auto2]]
    # Inspect.
    set confB [safe::interpConfigure $i]
    set sortB [mapAndSortList $PathMapp [dict get $confB -accessPath]]
    set modsB [interp eval $i {tcl::tm::path list}]
    set path3 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules]]
    set path4 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod1]]
    set path5 [::safe::interpFindInAccessPath $i [file join $TestsDir auto0 modules mod2]]

    # Try to load the packages and run a command from each one.
    set code0 [catch {interp eval $i {package require test0}} msg0]
    set code1 [catch {interp eval $i {package require mod1::test1}} msg1]
    set code2 [catch {interp eval $i {package require mod2::test2}} msg2]
    set out0  [interp eval $i {test0::try0}]
    set out1  [interp eval $i {mod1::test1::try1}]
    set out2  [interp eval $i {mod2::test2::try2}]

    list [lsort [list $path0 $path1 $path2]] -- $modsA -- \
	    [lsort [list $path3 $path4 $path5]] -- $modsB -- \
	    $code0 $msg0 $code1 $msg1 $code2 $msg2 -- $sortA -- $sortB -- \
	    $out0 $out1 $out2
} -cleanup {
    tcl::tm::path remove [file join $TestsDir auto0 modules]
    foreach path [lreverse $oldTm] {
	tcl::tm::path add $path
    }
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -match glob -result {{{$p(:1:)} {$p(:2:)} {$p(:3:)}} -- {{$p(:1:)}} --\
	{{$p(:3:)} {$p(:4:)} {$p(:5:)}} -- {{$p(:3:)}} --\
	0 0.5 0 1.0 0 2.0 --\
	{TCLLIB TESTSDIR/auto0/modules TESTSDIR/auto0/modules/mod1\
	 TESTSDIR/auto0/modules/mod2} --\
	{TCLLIB TESTSDIR/auto0/auto1 TESTSDIR/auto0/auto2 TESTSDIR/auto0/modules\
	 TESTSDIR/auto0/modules/mod1 TESTSDIR/auto0/modules/mod2} --\
	res0 res1 res2}
# See comments on lsort after test safe-9.20.


### 20. safe::interpCreate with different cases of -accessPath, -autoPath.

set ::auto_path [list $tcl_library [file dirname $tcl_library] [file join $TestsDir auto0]]

test safe-20.1 "create -accessPath NULL -autoPath NULL -> parent's ::auto_path" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result [list $::auto_path -- $::auto_path]
test safe-20.2 "create -accessPath {} -autoPath NULL -> parent's ::auto_path" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath {}]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result [list $::auto_path -- $::auto_path]
test safe-20.3 "create -accessPath path1 -autoPath NULL -> {}" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1]]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {{} -- {}}
test safe-20.4 "create -accessPath NULL -autoPath {} -> {}" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -autoPath {}]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {{} -- {}}
test safe-20.5 "create -accessPath {} -autoPath {} -> {}" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath {} -autoPath {}]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {{} -- {}}
test safe-20.6 "create -accessPath path1 -autoPath {} -> {}" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath {}]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {{} -- {}}
test safe-20.7 "create -accessPath NULL -autoPath path2 -> path2" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -autoPath [lrange $::auto_path 0 0]]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result [list [lrange $::auto_path 0 0] -- [lrange $::auto_path 0 0]]
test safe-20.8 "create -accessPath {} -autoPath path2 -> path2" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath {} -autoPath [lrange $::auto_path 0 0]]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result [list [lrange $::auto_path 0 0] -- [lrange $::auto_path 0 0]]
test safe-20.9 "create -accessPath path1 -autoPath path2 -> path2" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result [list [lrange $::auto_path 0 0] -- [lrange $::auto_path 0 0]]
test safe-20.10 "create -accessPath NULL -autoPath pathX -> pathX" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -autoPath /not/in/access/path]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {/not/in/access/path -- {}}
test safe-20.11 "create -accessPath {} -autoPath pathX -> pathX" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath {} -autoPath /not/in/access/path]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {/not/in/access/path -- {}}
test safe-20.12 "create -accessPath path1 -autoPath pathX -> {pathX}" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
} -body {
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath /not/in/access/path]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {/not/in/access/path -- {}}

### 21. safe::interpConfigure with different cases of -accessPath, -autoPath.

test safe-21.1 "interpConfigure -accessPath NULL -autoPath NULL -> no change" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -deleteHook {}
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result [list [lrange $::auto_path 0 0] -- [lrange $::auto_path 0 0]]
test safe-21.2 "interpConfigure -accessPath {} -autoPath NULL -> parent's ::auto_path" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -accessPath {}
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result [list $::auto_path -- $::auto_path]
test safe-21.3 "interpConfigure -accessPath path1 -autoPath NULL -> no change" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -accessPath [lrange $::auto_path 0 1]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result [list [lrange $::auto_path 0 0] -- [lrange $::auto_path 0 0]]
test safe-21.4 "interpConfigure -accessPath NULL -autoPath {} -> {}" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -autoPath {}
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {{} -- {}}
test safe-21.5 "interpConfigure -accessPath {} -autoPath {} -> {}" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -accessPath {} -autoPath {}
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {{} -- {}}
test safe-21.6 "interpConfigure -accessPath {path1} -autoPath {} -> {}" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -accessPath [lrange $::auto_path 1 1] -autoPath {}
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {{} -- {}}
test safe-21.7 "interpConfigure -accessPath NULL -autoPath path2 -> path2" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -autoPath [lrange $::auto_path 1 1]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result [list [lrange $::auto_path 1 1] -- [lrange $::auto_path 1 1]]
test safe-21.8 "interpConfigure -accessPath {} -autoPath path2 -> path2" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -accessPath {} -autoPath [lrange $::auto_path 1 1]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result [list [lrange $::auto_path 1 1] -- [lrange $::auto_path 1 1]]
test safe-21.9 "interpConfigure -accessPath path1 -autoPath path2 -> path2" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -accessPath [lrange $::auto_path 0 2] -autoPath [lrange $::auto_path 1 1]
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result [list [lrange $::auto_path 1 1] -- [lrange $::auto_path 1 1]]
test safe-21.10 "interpConfigure -accessPath NULL -autoPath pathX -> pathX" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -autoPath /not/in/access/path
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {/not/in/access/path -- {}}
test safe-21.11 "interpConfigure -accessPath {} -autoPath pathX -> pathX" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -accessPath {} -autoPath /not/in/access/path
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {/not/in/access/path -- {}}
test safe-21.12 "interpConfigure -accessPath path1 -autoPath pathX -> pathX" -constraints AutoSyncDefined -setup {
    set SyncExists [expr {[info commands ::safe::setSyncMode] ne {}}]
    if {$SyncExists} {
	set SyncVal_TMP [safe::setSyncMode]
	safe::setSyncMode 0
    } else {
	error {This test is meaningful only if the command ::safe::setSyncMode is defined}
    }
    set i [safe::interpCreate -accessPath [lrange $::auto_path 0 1] -autoPath [lrange $::auto_path 0 0]]
} -body {
    safe::interpConfigure $i -accessPath [lrange $::auto_path 0 2] -autoPath /not/in/access/path
    getAutoPath $i
} -cleanup {
    safe::interpDelete $i
    if {$SyncExists} {
	safe::setSyncMode $SyncVal_TMP
    }
} -result {/not/in/access/path -- {}}

# cleanup
set ::auto_path $SaveAutoPath
unset SaveAutoPath TestsDir PathMapp
rename getAutoPath {}
Changes to tests/scan.test.
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
    list [scan "-207698809136909011942886895" \
	    %llu a] $a
} -returnCodes 1 -result {unsigned bignum scans are invalid}
test scan-5.19 {bigint scanning invalid} -setup {
    set a {};
} -body {
    list [scan "207698809136909011942886895" \
           %llu a] $a
} -result {1 207698809136909011942886895}
test scan-5.20 {ignore digit separators} -setup {
    set a {}; set b {}; set c {};
} -body {
    list [scan "10_23_45" %d_%d_%d a b c] $a $b $c
} -result {3 10 23 45}








|







548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
    list [scan "-207698809136909011942886895" \
	    %llu a] $a
} -returnCodes 1 -result {unsigned bignum scans are invalid}
test scan-5.19 {bigint scanning invalid} -setup {
    set a {};
} -body {
    list [scan "207698809136909011942886895" \
	   %llu a] $a
} -result {1 207698809136909011942886895}
test scan-5.20 {ignore digit separators} -setup {
    set a {}; set b {}; set c {};
} -body {
    list [scan "10_23_45" %d_%d_%d a b c] $a $b $c
} -result {3 10 23 45}

Changes to tests/set-old.test.
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
} {1 {unknown or ambiguous subcommand "gorp": must be anymore, default, donesearch, exists, for, get, names, nextelement, set, size, startsearch, statistics, or unset}}
test set-old-8.7 {array command, anymore option} {
    catch {unset a}
    list [catch {array anymore a x} msg] $msg
} {1 {"a" isn't an array}}
test set-old-8.8 {array command, anymore option, array doesn't exist yet but has compiler-allocated procedure slot} {
    proc foo {x} {
        if {$x==1} {
            return [array anymore a x]
        }
        set a(x) 123
    }
    list [catch {foo 1} msg] $msg
} {1 {"a" isn't an array}}
test set-old-8.9 {array command, donesearch option} {
    catch {unset a}
    list [catch {array donesearch a x} msg] $msg
} {1 {"a" isn't an array}}
test set-old-8.10 {array command, donesearch option, array doesn't exist yet but has compiler-allocated procedure slot} {
    proc foo {x} {
        if {$x==1} {
            return [array donesearch a x]
        }
        set a(x) 123
    }
    list [catch {foo 1} msg] $msg
} {1 {"a" isn't an array}}
test set-old-8.11 {array command, exists option} {
    list [catch {array exists a b} msg] $msg
} {1 {wrong # args: should be "array exists arrayName"}}
test set-old-8.12 {array command, exists option} {
    catch {unset a}
    array exists a
} {0}
test set-old-8.13 {array command, exists option} {
    catch {unset a}
    set a(0) 1
    array exists a
} {1}
test set-old-8.14 {array command, exists option, array doesn't exist yet but has compiler-allocated procedure slot} {
    proc foo {x} {
        if {$x==1} {
            return [array exists a]
        }
        set a(x) 123
    }
    list [catch {foo 1} msg] $msg
} {0 0}
test set-old-8.15 {array command, get option} {
    list [catch {array get} msg] $msg
} {1 {wrong # args: should be "array get arrayName ?pattern?"}}
test set-old-8.16 {array command, get option} {







|
|
|
|









|
|
|
|

















|
|
|
|







343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
} {1 {unknown or ambiguous subcommand "gorp": must be anymore, default, donesearch, exists, for, get, names, nextelement, set, size, startsearch, statistics, or unset}}
test set-old-8.7 {array command, anymore option} {
    catch {unset a}
    list [catch {array anymore a x} msg] $msg
} {1 {"a" isn't an array}}
test set-old-8.8 {array command, anymore option, array doesn't exist yet but has compiler-allocated procedure slot} {
    proc foo {x} {
	if {$x==1} {
	    return [array anymore a x]
	}
	set a(x) 123
    }
    list [catch {foo 1} msg] $msg
} {1 {"a" isn't an array}}
test set-old-8.9 {array command, donesearch option} {
    catch {unset a}
    list [catch {array donesearch a x} msg] $msg
} {1 {"a" isn't an array}}
test set-old-8.10 {array command, donesearch option, array doesn't exist yet but has compiler-allocated procedure slot} {
    proc foo {x} {
	if {$x==1} {
	    return [array donesearch a x]
	}
	set a(x) 123
    }
    list [catch {foo 1} msg] $msg
} {1 {"a" isn't an array}}
test set-old-8.11 {array command, exists option} {
    list [catch {array exists a b} msg] $msg
} {1 {wrong # args: should be "array exists arrayName"}}
test set-old-8.12 {array command, exists option} {
    catch {unset a}
    array exists a
} {0}
test set-old-8.13 {array command, exists option} {
    catch {unset a}
    set a(0) 1
    array exists a
} {1}
test set-old-8.14 {array command, exists option, array doesn't exist yet but has compiler-allocated procedure slot} {
    proc foo {x} {
	if {$x==1} {
	    return [array exists a]
	}
	set a(x) 123
    }
    list [catch {foo 1} msg] $msg
} {0 0}
test set-old-8.15 {array command, get option} {
    list [catch {array get} msg] $msg
} {1 {wrong # args: should be "array get arrayName ?pattern?"}}
test set-old-8.16 {array command, get option} {
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
    set a(x3) 5
    set a(b1) 24
    set a(b2) 25
    lsort [array get a x*]
} {3 4 5 x1 x2 x3}
test set-old-8.21 {array command, get option, array doesn't exist yet but has compiler-allocated procedure slot} {
    proc foo {x} {
        if {$x==1} {
            return [array get a]
        }
        set a(x) 123
    }
    list [catch {foo 1} msg] $msg
} {0 {}}
test set-old-8.22 {array command, names option} {
    catch {unset a}
    set a(22) 3
    list [catch {array names a 4 5} msg] $msg







|
|
|
|







417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
    set a(x3) 5
    set a(b1) 24
    set a(b2) 25
    lsort [array get a x*]
} {3 4 5 x1 x2 x3}
test set-old-8.21 {array command, get option, array doesn't exist yet but has compiler-allocated procedure slot} {
    proc foo {x} {
	if {$x==1} {
	    return [array get a]
	}
	set a(x) 123
    }
    list [catch {foo 1} msg] $msg
} {0 {}}
test set-old-8.22 {array command, names option} {
    catch {unset a}
    set a(22) 3
    list [catch {array names a 4 5} msg] $msg
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
    set a(bxy) 44
    set a(no) yes
    set a(xxx) value
    list [lsort [array names a *xy]] [lsort [array names a]]
} {{axy bxy} {axy bxy no xxx}}
test set-old-8.28 {array command, names option, array doesn't exist yet but has compiler-allocated procedure slot} {
    proc foo {x} {
        if {$x==1} {
            return [array names a]
        }
        set a(x) 123
    }
    list [catch {foo 1} msg] $msg
} {0 {}}
test set-old-8.29 {array command, nextelement option} {
    list [catch {array nextelement a} msg] $msg
} {1 {wrong # args: should be "array nextelement arrayName searchId"}}
test set-old-8.30 {array command, nextelement option} {
    catch {unset a}
    list [catch {array nextelement a b} msg] $msg
} {1 {"a" isn't an array}}
test set-old-8.31 {array command, nextelement option, array doesn't exist yet but has compiler-allocated procedure slot} {
    proc foo {x} {
        if {$x==1} {
            return [array nextelement a b]
        }
        set a(x) 123
    }
    list [catch {foo 1} msg] $msg
} {1 {"a" isn't an array}}
test set-old-8.32 {array command, set option} {
    list [catch {array set a} msg] $msg
} {1 {wrong # args: should be "array set arrayName list"}}
test set-old-8.33 {array command, set option} {







|
|
|
|












|
|
|
|







461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
    set a(bxy) 44
    set a(no) yes
    set a(xxx) value
    list [lsort [array names a *xy]] [lsort [array names a]]
} {{axy bxy} {axy bxy no xxx}}
test set-old-8.28 {array command, names option, array doesn't exist yet but has compiler-allocated procedure slot} {
    proc foo {x} {
	if {$x==1} {
	    return [array names a]
	}
	set a(x) 123
    }
    list [catch {foo 1} msg] $msg
} {0 {}}
test set-old-8.29 {array command, nextelement option} {
    list [catch {array nextelement a} msg] $msg
} {1 {wrong # args: should be "array nextelement arrayName searchId"}}
test set-old-8.30 {array command, nextelement option} {
    catch {unset a}
    list [catch {array nextelement a b} msg] $msg
} {1 {"a" isn't an array}}
test set-old-8.31 {array command, nextelement option, array doesn't exist yet but has compiler-allocated procedure slot} {
    proc foo {x} {
	if {$x==1} {
	    return [array nextelement a b]
	}
	set a(x) 123
    }
    list [catch {foo 1} msg] $msg
} {1 {"a" isn't an array}}
test set-old-8.32 {array command, set option} {
    list [catch {array set a} msg] $msg
} {1 {wrong # args: should be "array set arrayName list"}}
test set-old-8.33 {array command, set option} {
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
    catch {unset a}
    set a(xx) yy
    array set a {b c d e}
    lsort [array get a]
} {b c d e xx yy}
test set-old-8.37 {array command, set option, array doesn't exist yet but has compiler-allocated procedure slot} {
    proc foo {x} {
        if {$x==1} {
            return [array set a {x 0}]
        }
        set a(x)
    }
    list [catch {foo 1} msg] $msg
} {0 {}}
test set-old-8.38 {array command, set option} {
    catch {unset aVaRnAmE}
    array set aVaRnAmE {}
    list [info exists aVaRnAmE] [catch {set aVaRnAmE} msg] $msg







|
|
|
|







506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
    catch {unset a}
    set a(xx) yy
    array set a {b c d e}
    lsort [array get a]
} {b c d e xx yy}
test set-old-8.37 {array command, set option, array doesn't exist yet but has compiler-allocated procedure slot} {
    proc foo {x} {
	if {$x==1} {
	    return [array set a {x 0}]
	}
	set a(x)
    }
    list [catch {foo 1} msg] $msg
} {0 {}}
test set-old-8.38 {array command, set option} {
    catch {unset aVaRnAmE}
    array set aVaRnAmE {}
    list [info exists aVaRnAmE] [catch {set aVaRnAmE} msg] $msg
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
    catch {unset a}
    set a(22) 3;
    trace add var a(33) {read write unset} ignore
    list [catch {array size a} msg] $msg
} {0 1}
test set-old-8.45 {array command, size option, array doesn't exist yet but has compiler-allocated procedure slot} {
    proc foo {x} {
        if {$x==1} {
            return [array size a]
        }
        set a(x) 123
    }
    list [catch {foo 1} msg] $msg
} {0 0}
test set-old-8.46 {array command, startsearch option} {
    list [catch {array startsearch a b} msg] $msg
} {1 {wrong # args: should be "array startsearch arrayName"}}
test set-old-8.47 {array command, startsearch option} {
    catch {unset a}
    list [catch {array startsearch a} msg] $msg
} {1 {"a" isn't an array}}
test set-old-8.48 {array command, startsearch option, array doesn't exist yet but has compiler-allocated procedure slot} {
    catch {rename p ""}
    proc p {x} {
        if {$x==1} {
            return [array startsearch a]
        }
        set a(x) 123
    }
    list [catch {p 1} msg] $msg
} {1 {"a" isn't an array}}
test set-old-8.49 {array command, statistics option} {
    catch {unset a}
    set a(abc) 1
    set a(def) 2







|
|
|
|













|
|
|
|







580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
    catch {unset a}
    set a(22) 3;
    trace add var a(33) {read write unset} ignore
    list [catch {array size a} msg] $msg
} {0 1}
test set-old-8.45 {array command, size option, array doesn't exist yet but has compiler-allocated procedure slot} {
    proc foo {x} {
	if {$x==1} {
	    return [array size a]
	}
	set a(x) 123
    }
    list [catch {foo 1} msg] $msg
} {0 0}
test set-old-8.46 {array command, startsearch option} {
    list [catch {array startsearch a b} msg] $msg
} {1 {wrong # args: should be "array startsearch arrayName"}}
test set-old-8.47 {array command, startsearch option} {
    catch {unset a}
    list [catch {array startsearch a} msg] $msg
} {1 {"a" isn't an array}}
test set-old-8.48 {array command, startsearch option, array doesn't exist yet but has compiler-allocated procedure slot} {
    catch {rename p ""}
    proc p {x} {
	if {$x==1} {
	    return [array startsearch a]
	}
	set a(x) 123
    }
    list [catch {p 1} msg] $msg
} {1 {"a" isn't an array}}
test set-old-8.49 {array command, statistics option} {
    catch {unset a}
    set a(abc) 1
    set a(def) 2
Changes to tests/set.test.
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
test set-1.10 {TclCompileSetCmd: only two args => just getting value} {
    set i {one two}
    set i
} {one two}

test set-1.11 {TclCompileSetCmd: simple global name} {
    proc p {} {
        global i
        set i 54
        set i
    }
    p
} {54}
test set-1.12 {TclCompileSetCmd: simple local name} {
    proc p {bar} {
        set foo $bar
        set foo
    }
    p 999
} {999}
test set-1.13 {TclCompileSetCmd: simple but new (unknown) local name} {
    proc p {} {
        set bar
    }
    catch {p} msg
    set msg
} {can't read "bar": no such variable}
test set-1.14 {TclCompileSetCmd: simple local name, >255 locals} {
    proc 260locals {} {
        # create 260 locals (the last ones with index > 255)
        set a0 0; set a1 0; set a2 0; set a3 0; set a4 0
        set a5 0; set a6 0; set a7 0; set a8 0; set a9 0
        set b0 0; set b1 0; set b2 0; set b3 0; set b4 0
        set b5 0; set b6 0; set b7 0; set b8 0; set b9 0
        set c0 0; set c1 0; set c2 0; set c3 0; set c4 0
        set c5 0; set c6 0; set c7 0; set c8 0; set c9 0
        set d0 0; set d1 0; set d2 0; set d3 0; set d4 0
        set d5 0; set d6 0; set d7 0; set d8 0; set d9 0
        set e0 0; set e1 0; set e2 0; set e3 0; set e4 0
        set e5 0; set e6 0; set e7 0; set e8 0; set e9 0
        set f0 0; set f1 0; set f2 0; set f3 0; set f4 0
        set f5 0; set f6 0; set f7 0; set f8 0; set f9 0
        set g0 0; set g1 0; set g2 0; set g3 0; set g4 0
        set g5 0; set g6 0; set g7 0; set g8 0; set g9 0
        set h0 0; set h1 0; set h2 0; set h3 0; set h4 0
        set h5 0; set h6 0; set h7 0; set h8 0; set h9 0
        set i0 0; set i1 0; set i2 0; set i3 0; set i4 0
        set i5 0; set i6 0; set i7 0; set i8 0; set i9 0
        set j0 0; set j1 0; set j2 0; set j3 0; set j4 0
        set j5 0; set j6 0; set j7 0; set j8 0; set j9 0
        set k0 0; set k1 0; set k2 0; set k3 0; set k4 0
        set k5 0; set k6 0; set k7 0; set k8 0; set k9 0
        set l0 0; set l1 0; set l2 0; set l3 0; set l4 0
        set l5 0; set l6 0; set l7 0; set l8 0; set l9 0
        set m0 0; set m1 0; set m2 0; set m3 0; set m4 0
        set m5 0; set m6 0; set m7 0; set m8 0; set m9 0
        set n0 0; set n1 0; set n2 0; set n3 0; set n4 0
        set n5 0; set n6 0; set n7 0; set n8 0; set n9 0
        set o0 0; set o1 0; set o2 0; set o3 0; set o4 0
        set o5 0; set o6 0; set o7 0; set o8 0; set o9 0
        set p0 0; set p1 0; set p2 0; set p3 0; set p4 0
        set p5 0; set p6 0; set p7 0; set p8 0; set p9 0
        set q0 0; set q1 0; set q2 0; set q3 0; set q4 0
        set q5 0; set q6 0; set q7 0; set q8 0; set q9 0
        set r0 0; set r1 0; set r2 0; set r3 0; set r4 0
        set r5 0; set r6 0; set r7 0; set r8 0; set r9 0
        set s0 0; set s1 0; set s2 0; set s3 0; set s4 0
        set s5 0; set s6 0; set s7 0; set s8 0; set s9 0
        set t0 0; set t1 0; set t2 0; set t3 0; set t4 0
        set t5 0; set t6 0; set t7 0; set t8 0; set t9 0
        set u0 0; set u1 0; set u2 0; set u3 0; set u4 0
        set u5 0; set u6 0; set u7 0; set u8 0; set u9 0
        set v0 0; set v1 0; set v2 0; set v3 0; set v4 0
        set v5 0; set v6 0; set v7 0; set v8 0; set v9 0
        set w0 0; set w1 0; set w2 0; set w3 0; set w4 0
        set w5 0; set w6 0; set w7 0; set w8 0; set w9 0
        set x0 0; set x1 0; set x2 0; set x3 0; set x4 0
        set x5 0; set x6 0; set x7 0; set x8 0; set x9 0
        set y0 0; set y1 0; set y2 0; set y3 0; set y4 0
        set y5 0; set y6 0; set y7 0; set y8 0; set y9 0
        set z0 0; set z1 0; set z2 0; set z3 0; set z4 0
        set z5 0; set z6 0; set z7 0; set z8 0; set z9 1234
    }
    260locals
} {1234}
test set-1.15 {TclCompileSetCmd: variable is array} -setup {
    catch {unset a}
} -body {
    set x 27







|
|
|





|
|





|






|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
test set-1.10 {TclCompileSetCmd: only two args => just getting value} {
    set i {one two}
    set i
} {one two}

test set-1.11 {TclCompileSetCmd: simple global name} {
    proc p {} {
	global i
	set i 54
	set i
    }
    p
} {54}
test set-1.12 {TclCompileSetCmd: simple local name} {
    proc p {bar} {
	set foo $bar
	set foo
    }
    p 999
} {999}
test set-1.13 {TclCompileSetCmd: simple but new (unknown) local name} {
    proc p {} {
	set bar
    }
    catch {p} msg
    set msg
} {can't read "bar": no such variable}
test set-1.14 {TclCompileSetCmd: simple local name, >255 locals} {
    proc 260locals {} {
	# create 260 locals (the last ones with index > 255)
	set a0 0; set a1 0; set a2 0; set a3 0; set a4 0
	set a5 0; set a6 0; set a7 0; set a8 0; set a9 0
	set b0 0; set b1 0; set b2 0; set b3 0; set b4 0
	set b5 0; set b6 0; set b7 0; set b8 0; set b9 0
	set c0 0; set c1 0; set c2 0; set c3 0; set c4 0
	set c5 0; set c6 0; set c7 0; set c8 0; set c9 0
	set d0 0; set d1 0; set d2 0; set d3 0; set d4 0
	set d5 0; set d6 0; set d7 0; set d8 0; set d9 0
	set e0 0; set e1 0; set e2 0; set e3 0; set e4 0
	set e5 0; set e6 0; set e7 0; set e8 0; set e9 0
	set f0 0; set f1 0; set f2 0; set f3 0; set f4 0
	set f5 0; set f6 0; set f7 0; set f8 0; set f9 0
	set g0 0; set g1 0; set g2 0; set g3 0; set g4 0
	set g5 0; set g6 0; set g7 0; set g8 0; set g9 0
	set h0 0; set h1 0; set h2 0; set h3 0; set h4 0
	set h5 0; set h6 0; set h7 0; set h8 0; set h9 0
	set i0 0; set i1 0; set i2 0; set i3 0; set i4 0
	set i5 0; set i6 0; set i7 0; set i8 0; set i9 0
	set j0 0; set j1 0; set j2 0; set j3 0; set j4 0
	set j5 0; set j6 0; set j7 0; set j8 0; set j9 0
	set k0 0; set k1 0; set k2 0; set k3 0; set k4 0
	set k5 0; set k6 0; set k7 0; set k8 0; set k9 0
	set l0 0; set l1 0; set l2 0; set l3 0; set l4 0
	set l5 0; set l6 0; set l7 0; set l8 0; set l9 0
	set m0 0; set m1 0; set m2 0; set m3 0; set m4 0
	set m5 0; set m6 0; set m7 0; set m8 0; set m9 0
	set n0 0; set n1 0; set n2 0; set n3 0; set n4 0
	set n5 0; set n6 0; set n7 0; set n8 0; set n9 0
	set o0 0; set o1 0; set o2 0; set o3 0; set o4 0
	set o5 0; set o6 0; set o7 0; set o8 0; set o9 0
	set p0 0; set p1 0; set p2 0; set p3 0; set p4 0
	set p5 0; set p6 0; set p7 0; set p8 0; set p9 0
	set q0 0; set q1 0; set q2 0; set q3 0; set q4 0
	set q5 0; set q6 0; set q7 0; set q8 0; set q9 0
	set r0 0; set r1 0; set r2 0; set r3 0; set r4 0
	set r5 0; set r6 0; set r7 0; set r8 0; set r9 0
	set s0 0; set s1 0; set s2 0; set s3 0; set s4 0
	set s5 0; set s6 0; set s7 0; set s8 0; set s9 0
	set t0 0; set t1 0; set t2 0; set t3 0; set t4 0
	set t5 0; set t6 0; set t7 0; set t8 0; set t9 0
	set u0 0; set u1 0; set u2 0; set u3 0; set u4 0
	set u5 0; set u6 0; set u7 0; set u8 0; set u9 0
	set v0 0; set v1 0; set v2 0; set v3 0; set v4 0
	set v5 0; set v6 0; set v7 0; set v8 0; set v9 0
	set w0 0; set w1 0; set w2 0; set w3 0; set w4 0
	set w5 0; set w6 0; set w7 0; set w8 0; set w9 0
	set x0 0; set x1 0; set x2 0; set x3 0; set x4 0
	set x5 0; set x6 0; set x7 0; set x8 0; set x9 0
	set y0 0; set y1 0; set y2 0; set y3 0; set y4 0
	set y5 0; set y6 0; set y7 0; set y8 0; set y9 0
	set z0 0; set z1 0; set z2 0; set z3 0; set z4 0
	set z5 0; set z6 0; set z7 0; set z8 0; set z9 1234
    }
    260locals
} {1234}
test set-1.15 {TclCompileSetCmd: variable is array} -setup {
    catch {unset a}
} -body {
    set x 27
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
    $z i {one two}
    $z i
} {one two}

test set-3.11 {uncompiled set command: simple global name} {
    proc p {} {
	set z set
        global i
        $z i 54
        $z i
    }
    p
} {54}
test set-3.12 {uncompiled set command: simple local name} {
    proc p {bar} {
	set z set
        $z foo $bar
        $z foo
    }
    p 999
} {999}
test set-3.13 {uncompiled set command: simple but new (unknown) local name} {
    set z set
    proc p {} {
	set z set
        $z bar
    }
    catch {p} msg
    $z msg
} {can't read "bar": no such variable}
test set-3.14 {uncompiled set command: simple local name, >255 locals} {
    proc 260locals {} {
	set z set
        # create 260 locals (the last ones with index > 255)
        $z a0 0; $z a1 0; $z a2 0; $z a3 0; $z a4 0
        $z a5 0; $z a6 0; $z a7 0; $z a8 0; $z a9 0
        $z b0 0; $z b1 0; $z b2 0; $z b3 0; $z b4 0
        $z b5 0; $z b6 0; $z b7 0; $z b8 0; $z b9 0
        $z c0 0; $z c1 0; $z c2 0; $z c3 0; $z c4 0
        $z c5 0; $z c6 0; $z c7 0; $z c8 0; $z c9 0
        $z d0 0; $z d1 0; $z d2 0; $z d3 0; $z d4 0
        $z d5 0; $z d6 0; $z d7 0; $z d8 0; $z d9 0
        $z e0 0; $z e1 0; $z e2 0; $z e3 0; $z e4 0
        $z e5 0; $z e6 0; $z e7 0; $z e8 0; $z e9 0
        $z f0 0; $z f1 0; $z f2 0; $z f3 0; $z f4 0
        $z f5 0; $z f6 0; $z f7 0; $z f8 0; $z f9 0
        $z g0 0; $z g1 0; $z g2 0; $z g3 0; $z g4 0
        $z g5 0; $z g6 0; $z g7 0; $z g8 0; $z g9 0
        $z h0 0; $z h1 0; $z h2 0; $z h3 0; $z h4 0
        $z h5 0; $z h6 0; $z h7 0; $z h8 0; $z h9 0
        $z i0 0; $z i1 0; $z i2 0; $z i3 0; $z i4 0
        $z i5 0; $z i6 0; $z i7 0; $z i8 0; $z i9 0
        $z j0 0; $z j1 0; $z j2 0; $z j3 0; $z j4 0
        $z j5 0; $z j6 0; $z j7 0; $z j8 0; $z j9 0
        $z k0 0; $z k1 0; $z k2 0; $z k3 0; $z k4 0
        $z k5 0; $z k6 0; $z k7 0; $z k8 0; $z k9 0
        $z l0 0; $z l1 0; $z l2 0; $z l3 0; $z l4 0
        $z l5 0; $z l6 0; $z l7 0; $z l8 0; $z l9 0
        $z m0 0; $z m1 0; $z m2 0; $z m3 0; $z m4 0
        $z m5 0; $z m6 0; $z m7 0; $z m8 0; $z m9 0
        $z n0 0; $z n1 0; $z n2 0; $z n3 0; $z n4 0
        $z n5 0; $z n6 0; $z n7 0; $z n8 0; $z n9 0
        $z o0 0; $z o1 0; $z o2 0; $z o3 0; $z o4 0
        $z o5 0; $z o6 0; $z o7 0; $z o8 0; $z o9 0
        $z p0 0; $z p1 0; $z p2 0; $z p3 0; $z p4 0
        $z p5 0; $z p6 0; $z p7 0; $z p8 0; $z p9 0
        $z q0 0; $z q1 0; $z q2 0; $z q3 0; $z q4 0
        $z q5 0; $z q6 0; $z q7 0; $z q8 0; $z q9 0
        $z r0 0; $z r1 0; $z r2 0; $z r3 0; $z r4 0
        $z r5 0; $z r6 0; $z r7 0; $z r8 0; $z r9 0
        $z s0 0; $z s1 0; $z s2 0; $z s3 0; $z s4 0
        $z s5 0; $z s6 0; $z s7 0; $z s8 0; $z s9 0
        $z t0 0; $z t1 0; $z t2 0; $z t3 0; $z t4 0
        $z t5 0; $z t6 0; $z t7 0; $z t8 0; $z t9 0
        $z u0 0; $z u1 0; $z u2 0; $z u3 0; $z u4 0
        $z u5 0; $z u6 0; $z u7 0; $z u8 0; $z u9 0
        $z v0 0; $z v1 0; $z v2 0; $z v3 0; $z v4 0
        $z v5 0; $z v6 0; $z v7 0; $z v8 0; $z v9 0
        $z w0 0; $z w1 0; $z w2 0; $z w3 0; $z w4 0
        $z w5 0; $z w6 0; $z w7 0; $z w8 0; $z w9 0
        $z x0 0; $z x1 0; $z x2 0; $z x3 0; $z x4 0
        $z x5 0; $z x6 0; $z x7 0; $z x8 0; $z x9 0
        $z y0 0; $z y1 0; $z y2 0; $z y3 0; $z y4 0
        $z y5 0; $z y6 0; $z y7 0; $z y8 0; $z y9 0
        $z z0 0; $z z1 0; $z z2 0; $z z3 0; $z z4 0
        $z z5 0; $z z6 0; $z z7 0; $z z8 0; $z z9 1234
    }
    260locals
} {1234}
test set-3.15 {uncompiled set command: variable is array} {
    set z set
    catch {unset a}
    $z x 27







|
|
|






|
|







|







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
    $z i {one two}
    $z i
} {one two}

test set-3.11 {uncompiled set command: simple global name} {
    proc p {} {
	set z set
	global i
	$z i 54
	$z i
    }
    p
} {54}
test set-3.12 {uncompiled set command: simple local name} {
    proc p {bar} {
	set z set
	$z foo $bar
	$z foo
    }
    p 999
} {999}
test set-3.13 {uncompiled set command: simple but new (unknown) local name} {
    set z set
    proc p {} {
	set z set
	$z bar
    }
    catch {p} msg
    $z msg
} {can't read "bar": no such variable}
test set-3.14 {uncompiled set command: simple local name, >255 locals} {
    proc 260locals {} {
	set z set
	# create 260 locals (the last ones with index > 255)
	$z a0 0; $z a1 0; $z a2 0; $z a3 0; $z a4 0
	$z a5 0; $z a6 0; $z a7 0; $z a8 0; $z a9 0
	$z b0 0; $z b1 0; $z b2 0; $z b3 0; $z b4 0
	$z b5 0; $z b6 0; $z b7 0; $z b8 0; $z b9 0
	$z c0 0; $z c1 0; $z c2 0; $z c3 0; $z c4 0
	$z c5 0; $z c6 0; $z c7 0; $z c8 0; $z c9 0
	$z d0 0; $z d1 0; $z d2 0; $z d3 0; $z d4 0
	$z d5 0; $z d6 0; $z d7 0; $z d8 0; $z d9 0
	$z e0 0; $z e1 0; $z e2 0; $z e3 0; $z e4 0
	$z e5 0; $z e6 0; $z e7 0; $z e8 0; $z e9 0
	$z f0 0; $z f1 0; $z f2 0; $z f3 0; $z f4 0
	$z f5 0; $z f6 0; $z f7 0; $z f8 0; $z f9 0
	$z g0 0; $z g1 0; $z g2 0; $z g3 0; $z g4 0
	$z g5 0; $z g6 0; $z g7 0; $z g8 0; $z g9 0
	$z h0 0; $z h1 0; $z h2 0; $z h3 0; $z h4 0
	$z h5 0; $z h6 0; $z h7 0; $z h8 0; $z h9 0
	$z i0 0; $z i1 0; $z i2 0; $z i3 0; $z i4 0
	$z i5 0; $z i6 0; $z i7 0; $z i8 0; $z i9 0
	$z j0 0; $z j1 0; $z j2 0; $z j3 0; $z j4 0
	$z j5 0; $z j6 0; $z j7 0; $z j8 0; $z j9 0
	$z k0 0; $z k1 0; $z k2 0; $z k3 0; $z k4 0
	$z k5 0; $z k6 0; $z k7 0; $z k8 0; $z k9 0
	$z l0 0; $z l1 0; $z l2 0; $z l3 0; $z l4 0
	$z l5 0; $z l6 0; $z l7 0; $z l8 0; $z l9 0
	$z m0 0; $z m1 0; $z m2 0; $z m3 0; $z m4 0
	$z m5 0; $z m6 0; $z m7 0; $z m8 0; $z m9 0
	$z n0 0; $z n1 0; $z n2 0; $z n3 0; $z n4 0
	$z n5 0; $z n6 0; $z n7 0; $z n8 0; $z n9 0
	$z o0 0; $z o1 0; $z o2 0; $z o3 0; $z o4 0
	$z o5 0; $z o6 0; $z o7 0; $z o8 0; $z o9 0
	$z p0 0; $z p1 0; $z p2 0; $z p3 0; $z p4 0
	$z p5 0; $z p6 0; $z p7 0; $z p8 0; $z p9 0
	$z q0 0; $z q1 0; $z q2 0; $z q3 0; $z q4 0
	$z q5 0; $z q6 0; $z q7 0; $z q8 0; $z q9 0
	$z r0 0; $z r1 0; $z r2 0; $z r3 0; $z r4 0
	$z r5 0; $z r6 0; $z r7 0; $z r8 0; $z r9 0
	$z s0 0; $z s1 0; $z s2 0; $z s3 0; $z s4 0
	$z s5 0; $z s6 0; $z s7 0; $z s8 0; $z s9 0
	$z t0 0; $z t1 0; $z t2 0; $z t3 0; $z t4 0
	$z t5 0; $z t6 0; $z t7 0; $z t8 0; $z t9 0
	$z u0 0; $z u1 0; $z u2 0; $z u3 0; $z u4 0
	$z u5 0; $z u6 0; $z u7 0; $z u8 0; $z u9 0
	$z v0 0; $z v1 0; $z v2 0; $z v3 0; $z v4 0
	$z v5 0; $z v6 0; $z v7 0; $z v8 0; $z v9 0
	$z w0 0; $z w1 0; $z w2 0; $z w3 0; $z w4 0
	$z w5 0; $z w6 0; $z w7 0; $z w8 0; $z w9 0
	$z x0 0; $z x1 0; $z x2 0; $z x3 0; $z x4 0
	$z x5 0; $z x6 0; $z x7 0; $z x8 0; $z x9 0
	$z y0 0; $z y1 0; $z y2 0; $z y3 0; $z y4 0
	$z y5 0; $z y6 0; $z y7 0; $z y8 0; $z y9 0
	$z z0 0; $z z1 0; $z z2 0; $z z3 0; $z z4 0
	$z z5 0; $z z6 0; $z z7 0; $z z8 0; $z z9 1234
    }
    260locals
} {1234}
test set-3.15 {uncompiled set command: variable is array} {
    set z set
    catch {unset a}
    $z x 27
Changes to tests/socket.test.
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
	set port [expr {int(rand()*16383+49152)}]
    }
    return $port
}

# Check if testsocket testflags is available
testConstraint testsocket_testflags [expr {![catch {
        set h [socket -async localhost [randport]]
        testsocket testflags $h 0
        close $h
    }]}]


# Test the latency of tcp connections over the loopback interface. Some OSes
# (e.g. NetBSD) seem to use the Nagle algorithm and delayed ACKs, so it takes
# up to 200ms for a packet sent to localhost to arrive. We're measuring this
# here, so that OSes that don't have this problem can run the tests at full







|
|
|







99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
	set port [expr {int(rand()*16383+49152)}]
    }
    return $port
}

# Check if testsocket testflags is available
testConstraint testsocket_testflags [expr {![catch {
	set h [socket -async localhost [randport]]
	testsocket testflags $h 0
	close $h
    }]}]


# Test the latency of tcp connections over the loopback interface. Some OSes
# (e.g. NetBSD) seem to use the Nagle algorithm and delayed ACKs, so it takes
# up to 200ms for a packet sent to localhost to arrive. We're measuring this
# here, so that OSes that don't have this problem can run the tests at full
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
	set remoteServerIP $env(remoteServerIP)
    }
}
if {![info exists remoteServerPort]} {
    if {[info exists env(remoteServerPort)]} {
	set remoteServerPort $env(remoteServerPort)
    } else {
        if {[info exists remoteServerIP]} {
	    set remoteServerPort 2048
        }
    }
}

if 0 {
    # activate this to time the tests
    proc test {args} {
        set name [lindex $args 0]
        puts "[lindex [time {uplevel [linsert $args 0 tcltest::test]}] 0] @@@ $name"
    }
}

foreach {af localhost} {
    inet 127.0.0.1
    inet6 ::1
} {







|

|






|
|







149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
	set remoteServerIP $env(remoteServerIP)
    }
}
if {![info exists remoteServerPort]} {
    if {[info exists env(remoteServerPort)]} {
	set remoteServerPort $env(remoteServerPort)
    } else {
	if {[info exists remoteServerIP]} {
	    set remoteServerPort 2048
	}
    }
}

if 0 {
    # activate this to time the tests
    proc test {args} {
	set name [lindex $args 0]
	puts "[lindex [time {uplevel [linsert $args 0 tcltest::test]}] 0] @@@ $name"
    }
}

foreach {af localhost} {
    inet 127.0.0.1
    inet6 ::1
} {
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199

foreach {af localhost} {
    any 127.0.0.1
    inet 127.0.0.1
    inet6 ::1
} {
    if {![testConstraint supported_$af]} {
        continue
    }
    set ::tcl::unsupported::socketAF $af
#
# Check if we're supposed to do tests against the remote server
#

set doTestsWithRemoteServer 1







|







185
186
187
188
189
190
191
192
193
194
195
196
197
198
199

foreach {af localhost} {
    any 127.0.0.1
    inet 127.0.0.1
    inet6 ::1
} {
    if {![testConstraint supported_$af]} {
	continue
    }
    set ::tcl::unsupported::socketAF $af
#
# Check if we're supposed to do tests against the remote server
#

set doTestsWithRemoteServer 1
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
    }
}

# Some tests are run only if we are doing testing against a remote server.
testConstraint doTestsWithRemoteServer $doTestsWithRemoteServer
if {!$doTestsWithRemoteServer} {
    if {[string first s $::tcltest::verbose] >= 0} {
    	puts "Skipping tests with remote server. See tests/socket.test for"
	puts "information on how to run remote server."
	puts "Reason for not doing remote tests: $noRemoteTestReason"
    }
}

#
# If we do the tests, define a command to send a command to the remote server.







|







249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
    }
}

# Some tests are run only if we are doing testing against a remote server.
testConstraint doTestsWithRemoteServer $doTestsWithRemoteServer
if {!$doTestsWithRemoteServer} {
    if {[string first s $::tcltest::verbose] >= 0} {
	puts "Skipping tests with remote server. See tests/socket.test for"
	puts "information on how to run remote server."
	puts "Reason for not doing remote tests: $noRemoteTestReason"
    }
}

#
# If we do the tests, define a command to send a command to the remote server.
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
	while {1} {
	    set line [gets $commandSocket]
	    if {[eof $commandSocket]} {
		error "remote server disappaered"
	    }
	    if {$line eq "--Marker--Marker--Marker--"} {
		lassign $result code info value
                return -code $code -errorinfo $info $value
	    }
            append result $line "\n"
	}
    }
}

proc getPort sock {
    lindex [fconfigure $sock -sockname] 2
}







|

|







280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
	while {1} {
	    set line [gets $commandSocket]
	    if {[eof $commandSocket]} {
		error "remote server disappaered"
	    }
	    if {$line eq "--Marker--Marker--Marker--"} {
		lassign $result code info value
		return -code $code -errorinfo $info $value
	    }
	    append result $line "\n"
	}
    }
}

proc getPort sock {
    lindex [fconfigure $sock -sockname] 2
}
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
    set f [open $path(script) w]
    puts $f {
	set timer [after 10000 "set x timed_out"]
	set f [socket -server accept 0]
	proc accept {file addr port} {
	    global x
	    set x done
            close $file
	}
	puts ready
	puts [lindex [fconfigure $f -sockname] 2]
	vwait x
	after cancel $timer
	close $f
	puts $x







|







371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
    set f [open $path(script) w]
    puts $f {
	set timer [after 10000 "set x timed_out"]
	set f [socket -server accept 0]
	proc accept {file addr port} {
	    global x
	    set x done
	    close $file
	}
	puts ready
	puts [lindex [fconfigure $f -sockname] 2]
	vwait x
	after cancel $timer
	close $f
	puts $x
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
} -result {ready done {}}
test socket_$af-2.2 {tcp connection with client port specified} -setup {
    set port [randport]
    file delete $path(script)
    set f [open $path(script) w]
    puts $f {
	set timer [after 10000 "set x timeout"]
        set f [socket -server accept 0]
	proc accept {file addr port} {
            global x
            puts "[gets $file] $port"
            close $file
            set x done
	}
	puts ready
	puts [lindex [fconfigure $f -sockname] 2]
	vwait x
	after cancel $timer
	close $f
    }







|

|
|
|
|







399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
} -result {ready done {}}
test socket_$af-2.2 {tcp connection with client port specified} -setup {
    set port [randport]
    file delete $path(script)
    set f [open $path(script) w]
    puts $f {
	set timer [after 10000 "set x timeout"]
	set f [socket -server accept 0]
	proc accept {file addr port} {
	    global x
	    puts "[gets $file] $port"
	    close $file
	    set x done
	}
	puts ready
	puts [lindex [fconfigure $f -sockname] 2]
	vwait x
	after cancel $timer
	close $f
    }
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
    close $f
} -result {ready 1}
test socket_$af-2.3 {tcp connection with client interface specified} -setup {
    file delete $path(script)
    set f [open $path(script) w]
    puts $f {
	set timer [after 2000 "set x done"]
        set f [socket  -server accept 0]
	proc accept {file addr port} {
            global x
            puts "[gets $file] $addr"
            close $file
            set x done
	}
	puts [lindex [fconfigure $f -sockname] 2]
	puts ready
	vwait x
	after cancel $timer
	close $f
    }







|

|
|
|
|







433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
    close $f
} -result {ready 1}
test socket_$af-2.3 {tcp connection with client interface specified} -setup {
    file delete $path(script)
    set f [open $path(script) w]
    puts $f {
	set timer [after 2000 "set x done"]
	set f [socket  -server accept 0]
	proc accept {file addr port} {
	    global x
	    puts "[gets $file] $addr"
	    close $file
	    set x done
	}
	puts [lindex [fconfigure $f -sockname] 2]
	puts ready
	vwait x
	after cancel $timer
	close $f
    }
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
} -result [list ready [list hello $localhost]]
test socket_$af-2.4 {tcp connection with server interface specified} -setup {
    file delete $path(script)
    set f [open $path(script) w]
    puts $f [list set localhost $localhost]
    puts $f {
	set timer [after 2000 "set x done"]
        set f [socket -server accept -myaddr $localhost 0]
	proc accept {file addr port} {
            global x
            puts "[gets $file]"
            close $file
            set x done
	}
	puts ready
	puts [lindex [fconfigure $f -sockname] 2]
	vwait x
	after cancel $timer
	close $f
    }







|

|
|
|
|







467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
} -result [list ready [list hello $localhost]]
test socket_$af-2.4 {tcp connection with server interface specified} -setup {
    file delete $path(script)
    set f [open $path(script) w]
    puts $f [list set localhost $localhost]
    puts $f {
	set timer [after 2000 "set x done"]
	set f [socket -server accept -myaddr $localhost 0]
	proc accept {file addr port} {
	    global x
	    puts "[gets $file]"
	    close $file
	    set x done
	}
	puts ready
	puts [lindex [fconfigure $f -sockname] 2]
	vwait x
	after cancel $timer
	close $f
    }
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
    close $f
} -result {ready hello}
test socket_$af-2.5 {tcp connection with redundant server port} -setup {
    file delete $path(script)
    set f [open $path(script) w]
    puts $f {
	set timer [after 10000 "set x timeout"]
        set f [socket -server accept 0]
	proc accept {file addr port} {
            global x
            puts "[gets $file]"
            close $file
            set x done
	}
	puts ready
	puts [lindex [fconfigure $f -sockname] 2]
	vwait x
	after cancel $timer
	close $f
    }







|

|
|
|
|







500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
    close $f
} -result {ready hello}
test socket_$af-2.5 {tcp connection with redundant server port} -setup {
    file delete $path(script)
    set f [open $path(script) w]
    puts $f {
	set timer [after 10000 "set x timeout"]
	set f [socket -server accept 0]
	proc accept {file addr port} {
	    global x
	    puts "[gets $file]"
	    close $file
	    set x done
	}
	puts ready
	puts [lindex [fconfigure $f -sockname] 2]
	vwait x
	after cancel $timer
	close $f
    }
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
test socket_$af-2.7 {echo server, one line} -constraints [list socket supported_$af stdio] -setup {
    file delete $path(script)
    set f [open $path(script) w]
    puts $f {
	set timer [after 10000 "set x timeout"]
	set f [socket -server accept 0]
	proc accept {s a p} {
            fileevent $s readable [list echo $s]
	    fconfigure $s -translation lf -buffering line
        }
	proc echo {s} {
	     set l [gets $s]
             if {[eof $s]} {
                 global x
                 close $s
                 set x done
             } else {
                 puts $s $l
             }
	}
	puts ready
	puts [lindex [fconfigure $f -sockname] 2]
	vwait x
	after cancel $timer
	close $f
	puts $x







|

|


|
|
|
|
|
|
|







545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
test socket_$af-2.7 {echo server, one line} -constraints [list socket supported_$af stdio] -setup {
    file delete $path(script)
    set f [open $path(script) w]
    puts $f {
	set timer [after 10000 "set x timeout"]
	set f [socket -server accept 0]
	proc accept {s a p} {
	    fileevent $s readable [list echo $s]
	    fconfigure $s -translation lf -buffering line
	}
	proc echo {s} {
	     set l [gets $s]
	     if {[eof $s]} {
		 global x
		 close $s
		 set x done
	     } else {
		 puts $s $l
	     }
	}
	puts ready
	puts [lindex [fconfigure $f -sockname] 2]
	vwait x
	after cancel $timer
	close $f
	puts $x
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
    close $f
} -result {{hello abcdefghijklmnop} done}
removeFile script
test socket_$af-2.8 {echo server, loop 50 times, single connection} -setup {
    set path(script) [makeFile {
	set f [socket -server accept 0]
	proc accept {s a p} {
            fileevent $s readable [list echo $s]
            fconfigure $s -buffering line
        }
	proc echo {s} {
	     global i
             set l [gets $s]
             if {[eof $s]} {
                 global x
                 close $s
                 set x done
             } else {
	         incr i
                 puts $s $l
             }
	}
	set i 0
	puts ready
	puts [lindex [fconfigure $f -sockname] 2]
	set timer [after 20000 "set x done"]
	vwait x
	after cancel $timer







|
|
|


|
|
|
|
|
|
|
|
|







584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
    close $f
} -result {{hello abcdefghijklmnop} done}
removeFile script
test socket_$af-2.8 {echo server, loop 50 times, single connection} -setup {
    set path(script) [makeFile {
	set f [socket -server accept 0]
	proc accept {s a p} {
	    fileevent $s readable [list echo $s]
	    fconfigure $s -buffering line
	}
	proc echo {s} {
	     global i
	     set l [gets $s]
	     if {[eof $s]} {
		 global x
		 close $s
		 set x done
	     } else {
		 incr i
		 puts $s $l
	     }
	}
	set i 0
	puts ready
	puts [lindex [fconfigure $f -sockname] 2]
	set timer [after 20000 "set x done"]
	vwait x
	after cancel $timer
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
	set s [socket -server accept -myaddr $localhost 0]
	proc accept {s a p} {
	    fileevent $s readable [list echo $s]
	    fconfigure $s -buffering line
	}
	proc echo {s} {
	     global x
             set l [gets $s]
             if {[eof $s]} {
                 close $s
                 set x done
             } else {
                 puts $s $l
             }
	}
	puts ready
	puts [lindex [fconfigure $s -sockname] 2]
	vwait x
	after cancel $t1
	vwait x
	after cancel $t2







|
|
|
|
|
|
|







815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
	set s [socket -server accept -myaddr $localhost 0]
	proc accept {s a p} {
	    fileevent $s readable [list echo $s]
	    fconfigure $s -buffering line
	}
	proc echo {s} {
	     global x
	     set l [gets $s]
	     if {[eof $s]} {
		 close $s
		 set x done
	     } else {
		 puts $s $l
	     }
	}
	puts ready
	puts [lindex [fconfigure $s -sockname] 2]
	vwait x
	after cancel $t1
	vwait x
	after cancel $t2
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
} -constraints [list socket supported_$af stdio] -body {
    proc accept {s a p} {
	fconfigure $s -buffering line
	fileevent $s readable [list echo $s]
    }
    proc echo {s} {
	global x
        set l [gets $s]
        if {[eof $s]} {
            close $s
            set x done
        } else {
            puts $s $l
        }
    }
    set t1 [after 30000 "set x timed_out"]
    set t2 [after 31000 "set x timed_out"]
    set t3 [after 32000 "set x timed_out"]
    set s [socket -server accept -myaddr $localhost 0]
    set listen [lindex [fconfigure $s -sockname] 2]
    puts $p1 $listen







|
|
|
|
|
|
|







892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
} -constraints [list socket supported_$af stdio] -body {
    proc accept {s a p} {
	fconfigure $s -buffering line
	fileevent $s readable [list echo $s]
    }
    proc echo {s} {
	global x
	set l [gets $s]
	if {[eof $s]} {
	    close $s
	    set x done
	} else {
	    puts $s $l
	}
    }
    set t1 [after 30000 "set x timed_out"]
    set t2 [after 31000 "set x timed_out"]
    set t3 [after 32000 "set x timed_out"]
    set s [socket -server accept -myaddr $localhost 0]
    set listen [lindex [fconfigure $s -sockname] 2]
    puts $p1 $listen
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
    close [socket -server dodo -myaddr $localhost 0x3000]
    return ok
} -constraints [list socket supported_$af] -result ok

test socket_$af-5.1 {byte order problems, socket numbers, htons} -body {
    if {![catch {socket -server dodo 0x1} msg]} {
	close $msg
        return {htons problem, should be disallowed, are you running as SU?}
    }
    return {couldn't open socket: not owner}
} -constraints [list socket supported_$af unix notRoot notOSX notWindows] -result {couldn't open socket: not owner}
test socket_$af-5.2 {byte order problems, socket numbers, htons} -body {
    if {![catch {socket -server dodo 0x10000} msg]} {
	close $msg
	return {port resolution problem, should be disallowed}







|







935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
    close [socket -server dodo -myaddr $localhost 0x3000]
    return ok
} -constraints [list socket supported_$af] -result ok

test socket_$af-5.1 {byte order problems, socket numbers, htons} -body {
    if {![catch {socket -server dodo 0x1} msg]} {
	close $msg
	return {htons problem, should be disallowed, are you running as SU?}
    }
    return {couldn't open socket: not owner}
} -constraints [list socket supported_$af unix notRoot notOSX notWindows] -result {couldn't open socket: not owner}
test socket_$af-5.2 {byte order problems, socket numbers, htons} -body {
    if {![catch {socket -server dodo 0x10000} msg]} {
	close $msg
	return {port resolution problem, should be disallowed}
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
    proc accept {s a p} {expr {10 / 0}}
    sendCommand "set port [getPort $s]"
    if {[catch {
	sendCommand {
	    set peername [fconfigure $callerSocket -peername]
	    set s [socket [lindex $peername 0] $port]
	    close $s
    	 }
    } msg]} then {
	close $s
	error $msg
    }
    vwait x
    return $x
} -cleanup {







|







1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
    proc accept {s a p} {expr {10 / 0}}
    sendCommand "set port [getPort $s]"
    if {[catch {
	sendCommand {
	    set peername [fconfigure $callerSocket -peername]
	    set s [socket [lindex $peername 0] $port]
	    close $s
	}
    } msg]} then {
	close $s
	error $msg
    }
    vwait x
    return $x
} -cleanup {
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
	set f [socket -server accept -myaddr $localhost 0]
	proc accept { file addr port } {
	    close $file
	}
	exec $tcltest $delay &
	puts [lindex [fconfigure $f -sockname] 2]
	close $f
        exit
    }
    close $f
} -constraints [list socket supported_$af stdio exec] -body {
    # Launch script2 and wait 5 seconds
    ### exec [interpreter] script2 &
    set p [open "|[list [interpreter] $path(script2)]" r]
    # If we can still connect to the server, the socket got inherited.







|







1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
	set f [socket -server accept -myaddr $localhost 0]
	proc accept { file addr port } {
	    close $file
	}
	exec $tcltest $delay &
	puts [lindex [fconfigure $f -sockname] 2]
	close $f
	exit
    }
    close $f
} -constraints [list socket supported_$af stdio exec] -body {
    # Launch script2 and wait 5 seconds
    ### exec [interpreter] script2 &
    set p [open "|[list [interpreter] $path(script2)]" r]
    # If we can still connect to the server, the socket got inherited.
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
    # script1 and exits. If the child process inherited the client socket, the
    # socket will still be open.
    set f [open $path(script2) w]
    puts $f [list set tcltest [interpreter]]
    puts $f [list set delay $path(script1)]
    puts $f [list set localhost $localhost]
    puts $f {
        gets stdin port
	set f [socket $localhost $port]
        exec $tcltest $delay &
	puts $f testing
	flush $f
        exit
    }
    close $f
    # If the socket doesn't hit end-of-file in 10 seconds, the script1 process
    # must have inherited the client.
    set timeout 0
    set after [after 10000 {set x "client socket was inherited"}]
} -constraints [list socket supported_$af stdio exec] -body {
    # Create the server socket
    set server [socket -server accept -myaddr $localhost 0]
    proc accept { file host port } {
	# When the client connects, establish the read handler
	global server
	close $server
	fileevent $file readable [list getdata $file]
	fconfigure $file -buffering line -blocking 0
        set ::f $file
    }
    proc getdata { file } {
	# Read handler on the accepted socket.
	global x
	set status [catch {read $file} data]
	if {$status != 0} {
	    set x "read failed, error was $data"
	} elseif {$data ne ""} {
	} elseif {[fblocked $file]} {
	} elseif {[eof $file]} {
            set x "client socket was not inherited"
	} else {
	    set x "impossible case"
	}
    }
    # Launch the script2 process
    ### exec [interpreter] script2 &
    set p [open "|[list [interpreter] $path(script2)]" w]







|

|


|















|










|







1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
    # script1 and exits. If the child process inherited the client socket, the
    # socket will still be open.
    set f [open $path(script2) w]
    puts $f [list set tcltest [interpreter]]
    puts $f [list set delay $path(script1)]
    puts $f [list set localhost $localhost]
    puts $f {
	gets stdin port
	set f [socket $localhost $port]
	exec $tcltest $delay &
	puts $f testing
	flush $f
	exit
    }
    close $f
    # If the socket doesn't hit end-of-file in 10 seconds, the script1 process
    # must have inherited the client.
    set timeout 0
    set after [after 10000 {set x "client socket was inherited"}]
} -constraints [list socket supported_$af stdio exec] -body {
    # Create the server socket
    set server [socket -server accept -myaddr $localhost 0]
    proc accept { file host port } {
	# When the client connects, establish the read handler
	global server
	close $server
	fileevent $file readable [list getdata $file]
	fconfigure $file -buffering line -blocking 0
	set ::f $file
    }
    proc getdata { file } {
	# Read handler on the accepted socket.
	global x
	set status [catch {read $file} data]
	if {$status != 0} {
	    set x "read failed, error was $data"
	} elseif {$data ne ""} {
	} elseif {[fblocked $file]} {
	} elseif {[eof $file]} {
	    set x "client socket was not inherited"
	} else {
	    set x "impossible case"
	}
    }
    # Launch the script2 process
    ### exec [interpreter] script2 &
    set p [open "|[list [interpreter] $path(script2)]" w]
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
    puts $f [list set localhost $localhost]
    puts $f {
	set server [socket -server accept -myaddr $localhost 0]
	proc accept { file host port } {
	    global tcltest delay
	    puts $file {test data on socket}
	    exec $tcltest $delay &
            after idle exit
	}
	puts stdout [lindex [fconfigure $server -sockname] 2]
	vwait forever
    }
    close $f
} -constraints [list socket supported_$af stdio exec] -body {
    # Launch the script2 process and connect to it. See how long the socket







|







1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
    puts $f [list set localhost $localhost]
    puts $f {
	set server [socket -server accept -myaddr $localhost 0]
	proc accept { file host port } {
	    global tcltest delay
	    puts $file {test data on socket}
	    exec $tcltest $delay &
	    after idle exit
	}
	puts stdout [lindex [fconfigure $server -sockname] 2]
	vwait forever
    }
    close $f
} -constraints [list socket supported_$af stdio exec] -body {
    # Launch the script2 process and connect to it. See how long the socket
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
	global failed
	set status [catch {read $file} data]
	if {$status != 0} {
	    set x "read failed, error was $data"
	} elseif {[string compare {} $data]} {
	} elseif {[fblocked $file]} {
	} elseif {[eof $file]} {
            set x "accepted socket was not inherited"
	} else {
	    set x "impossible case"
	}
	return
    }
    vwait x
    set x
} -cleanup {
    fconfigure $f -blocking 1
    close $f
    after cancel $after
    close $p
} -result {accepted socket was not inherited}

test socket_$af-13.1 {Testing use of shared socket between two threads} -body {
    # create a thread
    set serverthread [thread::create -preserved [string map [list @localhost@ $localhost] {
        set f [socket -server accept -myaddr @localhost@ 0]
        set listen [lindex [fconfigure $f -sockname] 2]
        proc accept {s a p} {
            fileevent $s readable [list echo $s]
            fconfigure $s -buffering line
        }
        proc echo {s} {
             global i
             set l [gets $s]
             if {[eof $s]} {
                 global x
                 close $s
                 set x done
             } else {
                 incr i
                 puts $s $l
             }
        }
        set i 0
        vwait x
        close $f
    }]]
    set port [thread::send $serverthread {set listen}]
    set s [socket $localhost $port]
    fconfigure $s -buffering line
    catch {
        puts $s "hello"
        gets $s result
    }
    close $s
    thread::release $serverthread
    append result " " [llength [thread::names]]
} -result {hello 1} -constraints [list socket supported_$af thread]

proc transf_test {{testmode transfer} {maxIter 1000} {maxTime 10000}} {
  try {
    set ::count 0
    set ::testmode $testmode
    set port 0
    set srvsock {}
    # if binding on port 0 is not possible (system related, blocked on ISPs etc):
    if {[catch {close [socket -async $::localhost $port]}]} {
      # simplest server on random port (immediately closing a connect):
      set port [randport]
      set srvsock [socket -server {apply {{ch args} {close $ch}}} -myaddr $::localhost $port]
      # socket on windows has some issues yet (e. g. bug [b6d0d8cc2c]), so we simply decrease iteration count (to 1/4):
      if {$::tcl_platform(platform) eq "windows" && $maxIter > 50} {
      	set ::count [expr {$maxIter / 4 * 3 - 1}]; # bypass 3/4 iterations
      }
    }
    tcltest::DebugPuts 2 "== test \[$::localhost\]:$port $testmode =="
    set ::parent [thread::id]
    # helper thread creating async connection and initiating transfer (detach) to parent:
    set ::helper [thread::create]
    thread::send -async $::helper [list \
      lassign [list $::parent $::localhost $port $testmode] \
                     ::parent ::localhost ::port ::testmode
    ]
    thread::send -async $::helper {
      set ::helper [thread::id]
      proc iteration {args} {
        set fd [socket -async $::localhost $::port]
        if {"helper-writable" in $::testmode} {;# to test both sides during connect
          fileevent $fd writable [list apply {{fd} {
            if {[thread::id] ne $::helper} {
              thread::send -async $::parent {set ::count "ERROR: invalid thread, $::helper is expecting"}
              close $fd
              return
            }
          }} $fd]
        };#
        thread::detach $fd
        thread::send -async $::parent [list transf_parent $fd {*}$args]
      }
      iteration first
    }
    # parent proc committing transfer attempt (attach) and checking acquire was successful:
    proc transf_parent {fd args} {
      tcltest::DebugPuts 2 "** trma / $::count ** $args **"
      thread::attach $fd
      if {"parent-close" in $::testmode} {;# to test close during connect
        set ::count $::count
        close $fd
        return
      };#
      fileevent $fd writable [list apply {{fd} {
        if {[thread::id] ne $::parent} {
          thread::send -async $::parent {set ::count "ERROR: invalid thread, $::parent is expecting"}
          close $fd
          return
        }
        set ::count $::count
        close $fd
      }} $fd]
    }
    # repeat maxIter times (up to maxTime ms as timeout):
    set tout [after $maxTime {set ::count "TIMEOUT"}]
    while 1 {
      vwait ::count
      if {![string is integer $::count]} {
        # if timeout just skip (test was successful until now):
      	if {$::count eq "TIMEOUT"} {::tcltest::Skip "timing issue"}
        break
      }
      if {[incr ::count] >= $maxIter} break
      tcltest::DebugPuts 2 "** iter / $::count **"
      thread::send -async $::helper [list iteration nr $::count]
    }
    update
    set ::count







|

















|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|





|
|



















|








|




|
|
|
|
|
|
|
|
|
|
|
|








|
|
|


|
|
|
|
|
|
|







|
|
|







1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
	global failed
	set status [catch {read $file} data]
	if {$status != 0} {
	    set x "read failed, error was $data"
	} elseif {[string compare {} $data]} {
	} elseif {[fblocked $file]} {
	} elseif {[eof $file]} {
	    set x "accepted socket was not inherited"
	} else {
	    set x "impossible case"
	}
	return
    }
    vwait x
    set x
} -cleanup {
    fconfigure $f -blocking 1
    close $f
    after cancel $after
    close $p
} -result {accepted socket was not inherited}

test socket_$af-13.1 {Testing use of shared socket between two threads} -body {
    # create a thread
    set serverthread [thread::create -preserved [string map [list @localhost@ $localhost] {
	set f [socket -server accept -myaddr @localhost@ 0]
	set listen [lindex [fconfigure $f -sockname] 2]
	proc accept {s a p} {
	    fileevent $s readable [list echo $s]
	    fconfigure $s -buffering line
	}
	proc echo {s} {
	     global i
	     set l [gets $s]
	     if {[eof $s]} {
		 global x
		 close $s
		 set x done
	     } else {
		 incr i
		 puts $s $l
	     }
	}
	set i 0
	vwait x
	close $f
    }]]
    set port [thread::send $serverthread {set listen}]
    set s [socket $localhost $port]
    fconfigure $s -buffering line
    catch {
	puts $s "hello"
	gets $s result
    }
    close $s
    thread::release $serverthread
    append result " " [llength [thread::names]]
} -result {hello 1} -constraints [list socket supported_$af thread]

proc transf_test {{testmode transfer} {maxIter 1000} {maxTime 10000}} {
  try {
    set ::count 0
    set ::testmode $testmode
    set port 0
    set srvsock {}
    # if binding on port 0 is not possible (system related, blocked on ISPs etc):
    if {[catch {close [socket -async $::localhost $port]}]} {
      # simplest server on random port (immediately closing a connect):
      set port [randport]
      set srvsock [socket -server {apply {{ch args} {close $ch}}} -myaddr $::localhost $port]
      # socket on windows has some issues yet (e. g. bug [b6d0d8cc2c]), so we simply decrease iteration count (to 1/4):
      if {$::tcl_platform(platform) eq "windows" && $maxIter > 50} {
	set ::count [expr {$maxIter / 4 * 3 - 1}]; # bypass 3/4 iterations
      }
    }
    tcltest::DebugPuts 2 "== test \[$::localhost\]:$port $testmode =="
    set ::parent [thread::id]
    # helper thread creating async connection and initiating transfer (detach) to parent:
    set ::helper [thread::create]
    thread::send -async $::helper [list \
      lassign [list $::parent $::localhost $port $testmode] \
		     ::parent ::localhost ::port ::testmode
    ]
    thread::send -async $::helper {
      set ::helper [thread::id]
      proc iteration {args} {
	set fd [socket -async $::localhost $::port]
	if {"helper-writable" in $::testmode} {;# to test both sides during connect
	  fileevent $fd writable [list apply {{fd} {
	    if {[thread::id] ne $::helper} {
	      thread::send -async $::parent {set ::count "ERROR: invalid thread, $::helper is expecting"}
	      close $fd
	      return
	    }
	  }} $fd]
	};#
	thread::detach $fd
	thread::send -async $::parent [list transf_parent $fd {*}$args]
      }
      iteration first
    }
    # parent proc committing transfer attempt (attach) and checking acquire was successful:
    proc transf_parent {fd args} {
      tcltest::DebugPuts 2 "** trma / $::count ** $args **"
      thread::attach $fd
      if {"parent-close" in $::testmode} {;# to test close during connect
	set ::count $::count
	close $fd
	return
      };#
      fileevent $fd writable [list apply {{fd} {
	if {[thread::id] ne $::parent} {
	  thread::send -async $::parent {set ::count "ERROR: invalid thread, $::parent is expecting"}
	  close $fd
	  return
	}
	set ::count $::count
	close $fd
      }} $fd]
    }
    # repeat maxIter times (up to maxTime ms as timeout):
    set tout [after $maxTime {set ::count "TIMEOUT"}]
    while 1 {
      vwait ::count
      if {![string is integer $::count]} {
	# if timeout just skip (test was successful until now):
	if {$::count eq "TIMEOUT"} {::tcltest::Skip "timing issue"}
	break
      }
      if {[incr ::count] >= $maxIter} break
      tcltest::DebugPuts 2 "** iter / $::count **"
      thread::send -async $::helper [list iteration nr $::count]
    }
    update
    set ::count
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
catch {close $commandSocket}
catch {close $remoteProcChan}
}
unset ::tcl::unsupported::socketAF
test socket-14.0.0 {[socket -async] when server only listens on IPv4} \
    -constraints {socket supported_inet localhost_v4} \
    -setup {
        proc accept {s a p} {
            global x
            puts $s bye
            close $s
            set x ok
        }
        set server [socket -server accept -myaddr 127.0.0.1 0]
        set port [lindex [fconfigure $server -sockname] 2]
    } -body {
        set client [socket -async localhost $port]
        set after [after $latency {set x [fconfigure $client -error]}]
        vwait x
        set x
    } -cleanup {
        after cancel $after
        close $server
        close $client
        unset x
    } -result ok
test socket-14.0.1 {[socket -async] when server only listens on IPv6} \
    -constraints {socket supported_inet6 localhost_v6} \
    -setup {
        proc accept {s a p} {
            global x
            puts $s bye
            close $s
            set x ok
        }
        set server [socket -server accept -myaddr ::1 0]
        set port [lindex [fconfigure $server -sockname] 2]
    } -body {
        set client [socket -async localhost $port]
        set after [after $latency {set x [fconfigure $client -error]}]
        vwait x
        set x
    } -cleanup {
        after cancel $after
        close $server
        close $client
        unset x
    } -result ok
test socket-14.1 {[socket -async] fileevent while still connecting} \
    -constraints {socket} \
    -setup {
        proc accept {s a p} {
            global x
            puts $s bye
            close $s
	    lappend x ok
        }
        set server [socket -server accept -myaddr localhost 0]
        set port [lindex [fconfigure $server -sockname] 2]
        set x ""
    } -body {
        set client [socket -async localhost $port]
        fileevent $client writable {
            lappend x [fconfigure $client -error]
	    fileevent $client writable {}
        }
        set after [after $latency {lappend x timeout}]
        while {[llength $x] < 2 && "timeout" ni $x} {
            vwait x
        }
        lsort $x; # we only want to see both events, the order doesn't matter
    } -cleanup {
        after cancel $after
        close $server
        close $client
        unset x
    } -result {{} ok}
test socket-14.2 {[socket -async] fileevent connection refused} \
    -constraints {socket} \
    -body {
        set client [socket -async localhost [randport]]
        fileevent $client writable {set x ok}
        set after [after $latency {set x timeout}]
        vwait x
        after cancel $after
        lappend x [fconfigure $client -error]
    } -cleanup {
        after cancel $after
        close $client
        unset x after client
    } -result {ok {connection refused}}
test socket-14.3 {[socket -async] when server only listens on IPv6} \
    -constraints {socket supported_inet6 localhost_v6} \
    -setup {
        proc accept {s a p} {
            global x
            puts $s bye
            close $s
            set x ok
        }
        set server [socket -server accept -myaddr ::1 0]
        set port [lindex [fconfigure $server -sockname] 2]
    } -body {
        set client [socket -async localhost $port]
        set after [after $latency {set x [fconfigure $client -error]}]
        vwait x
        set x
    } -cleanup {
        after cancel $after
        close $server
        close $client
        unset x
    } -result ok
test socket-14.4 {[socket -async] and both, readdable and writable fileevents} \
    -constraints {socket} \
    -setup {
        proc accept {s a p} {
            puts $s bye
            close $s
        }
        set server [socket -server accept -myaddr localhost 0]
        set port [lindex [fconfigure $server -sockname] 2]
        set x ""
    } -body {
        set client [socket -async localhost $port]
        fileevent $client writable {
            lappend x [fconfigure $client -error]
            fileevent $client writable {}
        }
        fileevent $client readable {lappend x [gets $client]}
        set after [after $latency {lappend x timeout}]
        while {[llength $x] < 2 && "timeout" ni $x} {
            vwait x
        }
        lsort $x
    } -cleanup {
        after cancel $after
        close $client
        close $server
        unset x
    } -result {{} bye}
# FIXME: we should also have an IPv6 counterpart of this
test socket-14.5 {[socket -async] which fails before any connect() can be made} \
    -constraints {socket supported_inet notWine} \
    -body {
        # address from rfc5737
        socket -async -myaddr 192.0.2.42 127.0.0.1 [randport]
    } \
    -returnCodes 1 \
    -result {couldn't open socket: cannot assign requested address}
test socket-14.6.0 {[socket -async] with no event loop and server listening on IPv4} \
    -constraints {socket supported_inet localhost_v4} \
    -setup {
        proc accept {s a p} {
            global x
            puts $s bye
            close $s
            set x ok
        }
        set server [socket -server accept -myaddr 127.0.0.1 0]
        set port [lindex [fconfigure $server -sockname] 2]
        set x ""
    } \
    -body {
        set client [socket -async localhost $port]
        for {set i 0} {$i < 50} {incr i } {
            update
            if {$x ne ""} {
                lappend x [gets $client]
                break
            }
            after 100
        }
        set x
    } \
    -cleanup {
        close $server
        close $client
        unset x
    } \
    -result {ok bye}
test socket-14.6.1 {[socket -async] with no event loop and server listening on IPv6} \
    -constraints {socket supported_inet6 localhost_v6} \
    -setup {
        proc accept {s a p} {
            global x
            puts $s bye
            close $s
            set x ok
        }
        set server [socket -server accept -myaddr ::1 0]
        set port [lindex [fconfigure $server -sockname] 2]
        set x ""
    } \
    -body {
        set client [socket -async localhost $port]
        for {set i 0} {$i < 50} {incr i } {
            update
            if {$x ne ""} {
                lappend x [gets $client]
                break
            }
            after 100
        }
        set x
    } \
    -cleanup {
        close $server
        close $client
        unset x
    } \
    -result {ok bye}
test socket-14.7.0 {pending [socket -async] and blocking [gets], server is IPv4} \
    -constraints {socket supported_inet localhost_v4} \
    -setup {
        makeFile {
            fileevent stdin readable exit
            set server [socket -server accept -myaddr 127.0.0.1 0]
            proc accept {s h p} {puts $s ok; close $s; set ::x 1}
            puts [lindex [fconfigure $server -sockname] 2]
            flush stdout
            vwait x
        } script
        set fd [open |[list [interpreter] script] RDWR]
        set port [gets $fd]
    } -body {
        set sock [socket -async localhost $port]
        list [fconfigure $sock -error] [gets $sock] [fconfigure $sock -error]
    } -cleanup {
        close $fd
        close $sock
	removeFile script
    } -result {{} ok {}}
test socket-14.7.1 {pending [socket -async] and blocking [gets], server is IPv6} \
    -constraints {socket supported_inet6 localhost_v6} \
    -setup {
        makeFile {
            fileevent stdin readable exit
            set server [socket -server accept -myaddr ::1 0]
            proc accept {s h p} {puts $s ok; close $s; set ::x 1}
            puts [lindex [fconfigure $server -sockname] 2]
            flush stdout
            vwait x
        } script
        set fd [open |[list [interpreter] script] RDWR]
        set port [gets $fd]
    } -body {
        set sock [socket -async localhost $port]
        list [fconfigure $sock -error] [gets $sock] [fconfigure $sock -error]
    } -cleanup {
        close $fd
        close $sock
	removeFile script
    } -result {{} ok {}}
test socket-14.7.2 {pending [socket -async] and blocking [gets], no listener} \
    -constraints {socket} \
    -body {
        set sock [socket -async localhost [randport]]
        catch {gets $sock} x
        list $x [fconfigure $sock -error] [fconfigure $sock -error]
    } -cleanup {
        close $sock
    } -match glob -result {{error reading "sock*": transport endpoint is not connected} {connection refused} {}}
test socket-14.8.0 {pending [socket -async] and nonblocking [gets], server is IPv4} \
    -constraints {socket supported_inet localhost_v4} \
    -setup {
        makeFile {
            fileevent stdin readable exit
            set server [socket -server accept -myaddr 127.0.0.1 0]
            proc accept {s h p} {puts $s ok; close $s; set ::x 1}
            puts [lindex [fconfigure $server -sockname] 2]
            flush stdout
            vwait x
        } script
        set fd [open |[list [interpreter] script] RDWR]
        set port [gets $fd]
    } -body {
        set sock [socket -async localhost $port]
        fconfigure $sock -blocking 0
        for {set i 0} {$i < 50} {incr i } {
            if {[catch {gets $sock} x] || $x ne "" || ![fblocked $sock]} break
            after 200
        }
        set x
    } -cleanup {
        close $fd
        close $sock
	removeFile script
    } -result {ok}
test socket-14.8.1 {pending [socket -async] and nonblocking [gets], server is IPv6} \
    -constraints {socket supported_inet6 localhost_v6} \
    -setup {
        makeFile {
            fileevent stdin readable exit
            set server [socket -server accept -myaddr ::1 0]
            proc accept {s h p} {puts $s ok; close $s; set ::x 1}
            puts [lindex [fconfigure $server -sockname] 2]
            flush stdout
            vwait x
        } script
        set fd [open |[list [interpreter] script] RDWR]
        set port [gets $fd]
    } -body {
        set sock [socket -async localhost $port]
        fconfigure $sock -blocking 0
        for {set i 0} {$i < 50} {incr i } {
            if {[catch {gets $sock} x] || $x ne "" || ![fblocked $sock]} break
            after 200
        }
        set x
    } -cleanup {
        close $fd
        close $sock
	removeFile script
    } -result {ok}
test socket-14.8.2 {pending [socket -async] and nonblocking [gets], no listener} \
    -constraints {socket} \
    -body {
        set sock [socket -async localhost [randport]]
        fconfigure $sock -blocking 0
        for {set i 0} {$i < 50} {incr i } {
            if {[catch {gets $sock} x] || $x ne "" || ![fblocked $sock]} break
            after 200
        }
        list $x [fconfigure $sock -error] [fconfigure $sock -error]
    } -cleanup {
        close $sock
    } -match glob -result {{error reading "sock*": transport endpoint is not connected} {connection refused} {}}
test socket-14.9.0 {pending [socket -async] and blocking [puts], server is IPv4} \
    -constraints {socket supported_inet localhost_v4} \
    -setup {
        makeFile {
            fileevent stdin readable exit
            set server [socket -server accept -myaddr 127.0.0.1 0]
            proc accept {s h p} {set ::x $s}
            puts [lindex [fconfigure $server -sockname] 2]
            flush stdout
            vwait x
            puts [gets $x]
        } script
        set fd [open |[list [interpreter] script] RDWR]
        set port [gets $fd]
    } -body {
        set sock [socket -async localhost $port]
        puts $sock ok
        flush $sock
        list [fconfigure $sock -error] [gets $fd]
    } -cleanup {
        close $fd
        close $sock
	removeFile script
    } -result {{} ok}
test socket-14.9.1 {pending [socket -async] and blocking [puts], server is IPv6} \
    -constraints {socket supported_inet6 localhost_v6} \
    -setup {
        makeFile {
            fileevent stdin readable exit
            set server [socket -server accept -myaddr ::1 0]
            proc accept {s h p} {set ::x $s}
            puts [lindex [fconfigure $server -sockname] 2]
            flush stdout
            vwait x
            puts [gets $x]
        } script
        set fd [open |[list [interpreter] script] RDWR]
        set port [gets $fd]
    } -body {
        set sock [socket -async localhost $port]
        puts $sock ok
        flush $sock
        list [fconfigure $sock -error] [gets $fd]
    } -cleanup {
        close $fd
        close $sock
	removeFile script
    } -result {{} ok}
test socket-14.10.0 {pending [socket -async] and nonblocking [puts], server is IPv4} \
    -constraints {socket supported_inet localhost_v4} \
    -setup {
        makeFile {
            fileevent stdin readable exit
            set server [socket -server accept -myaddr 127.0.0.1 0]
            proc accept {s h p} {set ::x $s}
            puts [lindex [fconfigure $server -sockname] 2]
            flush stdout
            vwait x
            puts [gets $x]
        } script
        set fd [open |[list [interpreter] script] RDWR]
        set port [gets $fd]
    } -body {
        set sock [socket -async localhost $port]
        fconfigure $sock -blocking 0
        puts $sock ok
        flush $sock
        fileevent $fd readable {set x 1}
        vwait x
        list [fconfigure $sock -error] [gets $fd]
    } -cleanup {
        close $fd
        close $sock
	removeFile script
    } -result {{} ok}
test socket-14.10.1 {pending [socket -async] and nonblocking [puts], server is IPv6} \
    -constraints {socket supported_inet6 localhost_v6} \
    -setup {
        makeFile {
            fileevent stdin readable exit
            set server [socket -server accept -myaddr ::1 0]
            proc accept {s h p} {set ::x $s}
            puts [lindex [fconfigure $server -sockname] 2]
            flush stdout
            vwait x
            puts [gets $x]
        } script
        set fd [open |[list [interpreter] script] RDWR]
        set port [gets $fd]
    } -body {
        set sock [socket -async localhost $port]
        fconfigure $sock -blocking 0
        puts $sock ok
        flush $sock
        fileevent $fd readable {set x 1}
        vwait x
        list [fconfigure $sock -error] [gets $fd]
    } -cleanup {
        close $fd
        close $sock
	removeFile script
    } -result {{} ok}
test socket-14.11.0 {pending [socket -async] and nonblocking [puts], no listener, no flush} \
    -constraints {socket notWinCI} \
    -body {
        set sock [socket -async localhost [randport]]
        fconfigure $sock -blocking 0
        puts $sock ok
        fileevent $sock writable {set x 1}
        vwait x
        close $sock
    } -cleanup {
        catch {close $sock}
        unset x
    } -result {transport endpoint is not connected} -returnCodes 1
test socket-14.11.1 {pending [socket -async] and nonblocking [puts], no listener, flush} \
    -constraints {socket testsocket_testflags} \
    -body {
        set sock [socket -async localhost [randport]]
        # Set the socket in async test mode.
        # The async connect will not be continued on the following fconfigure
        # and puts/flush. Thus, the connect will fail after them.
        testsocket testflags $sock 1
        fconfigure $sock -blocking 0
        puts $sock ok
        flush $sock
        testsocket testflags $sock 0
        fileevent $sock writable {set x 1}
        vwait x
        close $sock
    } -cleanup {
        catch {close $sock}
        catch {unset x}
    } -result {transport endpoint is not connected} -returnCodes 1
test socket-14.12 {[socket -async] background progress triggered by [fconfigure -error]} \
    -constraints {socket} \
    -body {
        set s [socket -async localhost [randport]]
        for {set i 0} {$i < 50} {incr i} {
            set x [fconfigure $s -error]
            if {$x != ""} break
            after 200
        }
        set x
    } -cleanup {
        close $s
        unset x s
    } -result {connection refused}

test socket-14.13 {testing writable event when quick failure} \
    -constraints {socket win supported_inet notWine} \
    -body {
    # Test for bug 336441ed59 where a quick background fail was ignored








|
|
|
|
|
|
|
|

|
|
|
|

|
|
|
|




|
|
|
|
|
|
|
|

|
|
|
|

|
|
|
|




|
|
|
|

|
|
|
|

|
|
|

|
|
|
|
|
|

|
|
|
|




|
|
|
|
|
|

|
|
|




|
|
|
|
|
|
|
|

|
|
|
|

|
|
|
|




|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|

|
|
|
|





|
|






|
|
|
|
|
|
|
|
|


|
|
|
|
|
|
|
|
|
|


|
|
|





|
|
|
|
|
|
|
|
|


|
|
|
|
|
|
|
|
|
|


|
|
|





|
|
|
|
|
|
|
|
|
|

|
|

|
|





|
|
|
|
|
|
|
|
|
|

|
|

|
|





|
|
|

|




|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|

|
|





|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|

|
|





|
|
|
|
|
|
|

|




|
|
|
|
|
|
|
|
|
|
|

|
|
|
|

|
|





|
|
|
|
|
|
|
|
|
|
|

|
|
|
|

|
|





|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|

|
|





|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|

|
|





|
|
|
|
|
|

|
|




|
|
|
|
|
|
|
|
|
|
|
|

|
|




|
|
|
|
|
|
|

|
|







1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
catch {close $commandSocket}
catch {close $remoteProcChan}
}
unset ::tcl::unsupported::socketAF
test socket-14.0.0 {[socket -async] when server only listens on IPv4} \
    -constraints {socket supported_inet localhost_v4} \
    -setup {
	proc accept {s a p} {
	    global x
	    puts $s bye
	    close $s
	    set x ok
	}
	set server [socket -server accept -myaddr 127.0.0.1 0]
	set port [lindex [fconfigure $server -sockname] 2]
    } -body {
	set client [socket -async localhost $port]
	set after [after $latency {set x [fconfigure $client -error]}]
	vwait x
	set x
    } -cleanup {
	after cancel $after
	close $server
	close $client
	unset x
    } -result ok
test socket-14.0.1 {[socket -async] when server only listens on IPv6} \
    -constraints {socket supported_inet6 localhost_v6} \
    -setup {
	proc accept {s a p} {
	    global x
	    puts $s bye
	    close $s
	    set x ok
	}
	set server [socket -server accept -myaddr ::1 0]
	set port [lindex [fconfigure $server -sockname] 2]
    } -body {
	set client [socket -async localhost $port]
	set after [after $latency {set x [fconfigure $client -error]}]
	vwait x
	set x
    } -cleanup {
	after cancel $after
	close $server
	close $client
	unset x
    } -result ok
test socket-14.1 {[socket -async] fileevent while still connecting} \
    -constraints {socket} \
    -setup {
	proc accept {s a p} {
	    global x
	    puts $s bye
	    close $s
	    lappend x ok
	}
	set server [socket -server accept -myaddr localhost 0]
	set port [lindex [fconfigure $server -sockname] 2]
	set x ""
    } -body {
	set client [socket -async localhost $port]
	fileevent $client writable {
	    lappend x [fconfigure $client -error]
	    fileevent $client writable {}
	}
	set after [after $latency {lappend x timeout}]
	while {[llength $x] < 2 && "timeout" ni $x} {
	    vwait x
	}
	lsort $x; # we only want to see both events, the order doesn't matter
    } -cleanup {
	after cancel $after
	close $server
	close $client
	unset x
    } -result {{} ok}
test socket-14.2 {[socket -async] fileevent connection refused} \
    -constraints {socket} \
    -body {
	set client [socket -async localhost [randport]]
	fileevent $client writable {set x ok}
	set after [after $latency {set x timeout}]
	vwait x
	after cancel $after
	lappend x [fconfigure $client -error]
    } -cleanup {
	after cancel $after
	close $client
	unset x after client
    } -result {ok {connection refused}}
test socket-14.3 {[socket -async] when server only listens on IPv6} \
    -constraints {socket supported_inet6 localhost_v6} \
    -setup {
	proc accept {s a p} {
	    global x
	    puts $s bye
	    close $s
	    set x ok
	}
	set server [socket -server accept -myaddr ::1 0]
	set port [lindex [fconfigure $server -sockname] 2]
    } -body {
	set client [socket -async localhost $port]
	set after [after $latency {set x [fconfigure $client -error]}]
	vwait x
	set x
    } -cleanup {
	after cancel $after
	close $server
	close $client
	unset x
    } -result ok
test socket-14.4 {[socket -async] and both, readdable and writable fileevents} \
    -constraints {socket} \
    -setup {
	proc accept {s a p} {
	    puts $s bye
	    close $s
	}
	set server [socket -server accept -myaddr localhost 0]
	set port [lindex [fconfigure $server -sockname] 2]
	set x ""
    } -body {
	set client [socket -async localhost $port]
	fileevent $client writable {
	    lappend x [fconfigure $client -error]
	    fileevent $client writable {}
	}
	fileevent $client readable {lappend x [gets $client]}
	set after [after $latency {lappend x timeout}]
	while {[llength $x] < 2 && "timeout" ni $x} {
	    vwait x
	}
	lsort $x
    } -cleanup {
	after cancel $after
	close $client
	close $server
	unset x
    } -result {{} bye}
# FIXME: we should also have an IPv6 counterpart of this
test socket-14.5 {[socket -async] which fails before any connect() can be made} \
    -constraints {socket supported_inet notWine} \
    -body {
	# address from rfc5737
	socket -async -myaddr 192.0.2.42 127.0.0.1 [randport]
    } \
    -returnCodes 1 \
    -result {couldn't open socket: cannot assign requested address}
test socket-14.6.0 {[socket -async] with no event loop and server listening on IPv4} \
    -constraints {socket supported_inet localhost_v4} \
    -setup {
	proc accept {s a p} {
	    global x
	    puts $s bye
	    close $s
	    set x ok
	}
	set server [socket -server accept -myaddr 127.0.0.1 0]
	set port [lindex [fconfigure $server -sockname] 2]
	set x ""
    } \
    -body {
	set client [socket -async localhost $port]
	for {set i 0} {$i < 50} {incr i } {
	    update
	    if {$x ne ""} {
		lappend x [gets $client]
		break
	    }
	    after 100
	}
	set x
    } \
    -cleanup {
	close $server
	close $client
	unset x
    } \
    -result {ok bye}
test socket-14.6.1 {[socket -async] with no event loop and server listening on IPv6} \
    -constraints {socket supported_inet6 localhost_v6} \
    -setup {
	proc accept {s a p} {
	    global x
	    puts $s bye
	    close $s
	    set x ok
	}
	set server [socket -server accept -myaddr ::1 0]
	set port [lindex [fconfigure $server -sockname] 2]
	set x ""
    } \
    -body {
	set client [socket -async localhost $port]
	for {set i 0} {$i < 50} {incr i } {
	    update
	    if {$x ne ""} {
		lappend x [gets $client]
		break
	    }
	    after 100
	}
	set x
    } \
    -cleanup {
	close $server
	close $client
	unset x
    } \
    -result {ok bye}
test socket-14.7.0 {pending [socket -async] and blocking [gets], server is IPv4} \
    -constraints {socket supported_inet localhost_v4} \
    -setup {
	makeFile {
	    fileevent stdin readable exit
	    set server [socket -server accept -myaddr 127.0.0.1 0]
	    proc accept {s h p} {puts $s ok; close $s; set ::x 1}
	    puts [lindex [fconfigure $server -sockname] 2]
	    flush stdout
	    vwait x
	} script
	set fd [open |[list [interpreter] script] RDWR]
	set port [gets $fd]
    } -body {
	set sock [socket -async localhost $port]
	list [fconfigure $sock -error] [gets $sock] [fconfigure $sock -error]
    } -cleanup {
	close $fd
	close $sock
	removeFile script
    } -result {{} ok {}}
test socket-14.7.1 {pending [socket -async] and blocking [gets], server is IPv6} \
    -constraints {socket supported_inet6 localhost_v6} \
    -setup {
	makeFile {
	    fileevent stdin readable exit
	    set server [socket -server accept -myaddr ::1 0]
	    proc accept {s h p} {puts $s ok; close $s; set ::x 1}
	    puts [lindex [fconfigure $server -sockname] 2]
	    flush stdout
	    vwait x
	} script
	set fd [open |[list [interpreter] script] RDWR]
	set port [gets $fd]
    } -body {
	set sock [socket -async localhost $port]
	list [fconfigure $sock -error] [gets $sock] [fconfigure $sock -error]
    } -cleanup {
	close $fd
	close $sock
	removeFile script
    } -result {{} ok {}}
test socket-14.7.2 {pending [socket -async] and blocking [gets], no listener} \
    -constraints {socket} \
    -body {
	set sock [socket -async localhost [randport]]
	catch {gets $sock} x
	list $x [fconfigure $sock -error] [fconfigure $sock -error]
    } -cleanup {
	close $sock
    } -match glob -result {{error reading "sock*": transport endpoint is not connected} {connection refused} {}}
test socket-14.8.0 {pending [socket -async] and nonblocking [gets], server is IPv4} \
    -constraints {socket supported_inet localhost_v4} \
    -setup {
	makeFile {
	    fileevent stdin readable exit
	    set server [socket -server accept -myaddr 127.0.0.1 0]
	    proc accept {s h p} {puts $s ok; close $s; set ::x 1}
	    puts [lindex [fconfigure $server -sockname] 2]
	    flush stdout
	    vwait x
	} script
	set fd [open |[list [interpreter] script] RDWR]
	set port [gets $fd]
    } -body {
	set sock [socket -async localhost $port]
	fconfigure $sock -blocking 0
	for {set i 0} {$i < 50} {incr i } {
	    if {[catch {gets $sock} x] || $x ne "" || ![fblocked $sock]} break
	    after 200
	}
	set x
    } -cleanup {
	close $fd
	close $sock
	removeFile script
    } -result {ok}
test socket-14.8.1 {pending [socket -async] and nonblocking [gets], server is IPv6} \
    -constraints {socket supported_inet6 localhost_v6} \
    -setup {
	makeFile {
	    fileevent stdin readable exit
	    set server [socket -server accept -myaddr ::1 0]
	    proc accept {s h p} {puts $s ok; close $s; set ::x 1}
	    puts [lindex [fconfigure $server -sockname] 2]
	    flush stdout
	    vwait x
	} script
	set fd [open |[list [interpreter] script] RDWR]
	set port [gets $fd]
    } -body {
	set sock [socket -async localhost $port]
	fconfigure $sock -blocking 0
	for {set i 0} {$i < 50} {incr i } {
	    if {[catch {gets $sock} x] || $x ne "" || ![fblocked $sock]} break
	    after 200
	}
	set x
    } -cleanup {
	close $fd
	close $sock
	removeFile script
    } -result {ok}
test socket-14.8.2 {pending [socket -async] and nonblocking [gets], no listener} \
    -constraints {socket} \
    -body {
	set sock [socket -async localhost [randport]]
	fconfigure $sock -blocking 0
	for {set i 0} {$i < 50} {incr i } {
	    if {[catch {gets $sock} x] || $x ne "" || ![fblocked $sock]} break
	    after 200
	}
	list $x [fconfigure $sock -error] [fconfigure $sock -error]
    } -cleanup {
	close $sock
    } -match glob -result {{error reading "sock*": transport endpoint is not connected} {connection refused} {}}
test socket-14.9.0 {pending [socket -async] and blocking [puts], server is IPv4} \
    -constraints {socket supported_inet localhost_v4} \
    -setup {
	makeFile {
	    fileevent stdin readable exit
	    set server [socket -server accept -myaddr 127.0.0.1 0]
	    proc accept {s h p} {set ::x $s}
	    puts [lindex [fconfigure $server -sockname] 2]
	    flush stdout
	    vwait x
	    puts [gets $x]
	} script
	set fd [open |[list [interpreter] script] RDWR]
	set port [gets $fd]
    } -body {
	set sock [socket -async localhost $port]
	puts $sock ok
	flush $sock
	list [fconfigure $sock -error] [gets $fd]
    } -cleanup {
	close $fd
	close $sock
	removeFile script
    } -result {{} ok}
test socket-14.9.1 {pending [socket -async] and blocking [puts], server is IPv6} \
    -constraints {socket supported_inet6 localhost_v6} \
    -setup {
	makeFile {
	    fileevent stdin readable exit
	    set server [socket -server accept -myaddr ::1 0]
	    proc accept {s h p} {set ::x $s}
	    puts [lindex [fconfigure $server -sockname] 2]
	    flush stdout
	    vwait x
	    puts [gets $x]
	} script
	set fd [open |[list [interpreter] script] RDWR]
	set port [gets $fd]
    } -body {
	set sock [socket -async localhost $port]
	puts $sock ok
	flush $sock
	list [fconfigure $sock -error] [gets $fd]
    } -cleanup {
	close $fd
	close $sock
	removeFile script
    } -result {{} ok}
test socket-14.10.0 {pending [socket -async] and nonblocking [puts], server is IPv4} \
    -constraints {socket supported_inet localhost_v4} \
    -setup {
	makeFile {
	    fileevent stdin readable exit
	    set server [socket -server accept -myaddr 127.0.0.1 0]
	    proc accept {s h p} {set ::x $s}
	    puts [lindex [fconfigure $server -sockname] 2]
	    flush stdout
	    vwait x
	    puts [gets $x]
	} script
	set fd [open |[list [interpreter] script] RDWR]
	set port [gets $fd]
    } -body {
	set sock [socket -async localhost $port]
	fconfigure $sock -blocking 0
	puts $sock ok
	flush $sock
	fileevent $fd readable {set x 1}
	vwait x
	list [fconfigure $sock -error] [gets $fd]
    } -cleanup {
	close $fd
	close $sock
	removeFile script
    } -result {{} ok}
test socket-14.10.1 {pending [socket -async] and nonblocking [puts], server is IPv6} \
    -constraints {socket supported_inet6 localhost_v6} \
    -setup {
	makeFile {
	    fileevent stdin readable exit
	    set server [socket -server accept -myaddr ::1 0]
	    proc accept {s h p} {set ::x $s}
	    puts [lindex [fconfigure $server -sockname] 2]
	    flush stdout
	    vwait x
	    puts [gets $x]
	} script
	set fd [open |[list [interpreter] script] RDWR]
	set port [gets $fd]
    } -body {
	set sock [socket -async localhost $port]
	fconfigure $sock -blocking 0
	puts $sock ok
	flush $sock
	fileevent $fd readable {set x 1}
	vwait x
	list [fconfigure $sock -error] [gets $fd]
    } -cleanup {
	close $fd
	close $sock
	removeFile script
    } -result {{} ok}
test socket-14.11.0 {pending [socket -async] and nonblocking [puts], no listener, no flush} \
    -constraints {socket notWinCI} \
    -body {
	set sock [socket -async localhost [randport]]
	fconfigure $sock -blocking 0
	puts $sock ok
	fileevent $sock writable {set x 1}
	vwait x
	close $sock
    } -cleanup {
	catch {close $sock}
	unset x
    } -result {transport endpoint is not connected} -returnCodes 1
test socket-14.11.1 {pending [socket -async] and nonblocking [puts], no listener, flush} \
    -constraints {socket testsocket_testflags} \
    -body {
	set sock [socket -async localhost [randport]]
	# Set the socket in async test mode.
	# The async connect will not be continued on the following fconfigure
	# and puts/flush. Thus, the connect will fail after them.
	testsocket testflags $sock 1
	fconfigure $sock -blocking 0
	puts $sock ok
	flush $sock
	testsocket testflags $sock 0
	fileevent $sock writable {set x 1}
	vwait x
	close $sock
    } -cleanup {
	catch {close $sock}
	catch {unset x}
    } -result {transport endpoint is not connected} -returnCodes 1
test socket-14.12 {[socket -async] background progress triggered by [fconfigure -error]} \
    -constraints {socket} \
    -body {
	set s [socket -async localhost [randport]]
	for {set i 0} {$i < 50} {incr i} {
	    set x [fconfigure $s -error]
	    if {$x != ""} break
	    after 200
	}
	set x
    } -cleanup {
	close $s
	unset x s
    } -result {connection refused}

test socket-14.13 {testing writable event when quick failure} \
    -constraints {socket win supported_inet notWine} \
    -body {
    # Test for bug 336441ed59 where a quick background fail was ignored

2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
} -cleanup {
    catch {close $s}
    after cancel $a1
} -result readable

test socket-14.15 {blocking read on async socket should not trigger event handlers} \
    -constraints socket -body {
        set s [socket -async localhost [randport]]
        set x ok
        fileevent $s writable {set x fail}
        catch {read $s}
	close $s
        set x
    } -result ok

# v4 and v6 is required to prevent that the async connect does not terminate
# before the fconfigure command. There is always an additional ip to try.
test socket-14.16 {empty -peername while [socket -async] connecting} \
    -constraints {socket localhost_v4 localhost_v6} \
    -body {
        set client [socket -async localhost [randport]]
        fconfigure $client -peername
    } -cleanup {
        catch {close $client}
    } -result {}

# v4 and v6 is required to prevent that the async connect does not terminate
# before the fconfigure command. There is always an additional ip to try.
test socket-14.17 {empty -sockname while [socket -async] connecting} \
    -constraints {socket localhost_v4 localhost_v6} \
    -body {
        set client [socket -async localhost [randport]]
        fconfigure $client -sockname
    } -cleanup {
        catch {close $client}
    } -result {}

# test for bug c6ed4acfd8: running async socket connect with other connect
# established will block tcl as it goes in an infinite loop in vwait
test socket-14.18 {bug c6ed4acfd8: running async socket connect made other connect block} \
    -constraints {socket} \
    -body {
        proc accept {channel address port} {}
        set port [randport]
        set ssock [socket -server accept $port]
        set csock1 [socket -async localhost [randport]]
        set csock2 [socket localhost $port]
        after 1000 {set done ok}
        vwait done
} -cleanup {
        catch {close $ssock}
        catch {close $csock1}
        catch {close $csock2}
    } -result {}

test socket-14.19 {tip 456 -- introduce the -reuseport option} \
    -constraints {socket notWine} \
    -body {
        proc accept {channel address port} {}
        set port [randport]
        set ssock1 [socket -server accept -reuseport yes $port]
        set ssock2 [socket -server accept -reuseport yes $port]
        return ok
} -cleanup {
    catch {close $ssock1}
    catch {close $ssock2}
    } -result ok

set num 0

set x {localhost {socket} 127.0.0.1 {supported_inet} ::1 {supported_inet6}}
set resultok {-result "sock*" -match glob}
set resulterr {
    -result {couldn't open socket: connection refused}
    -returnCodes 1
}
foreach {servip sc} $x {
    foreach {cliip cc} $x {
        set constraints socket
        lappend constraints $sc $cc
        set result $resulterr
        switch -- [lsort -unique [list $servip $cliip]] {
            localhost - 127.0.0.1 - ::1 {
                set result $resultok
            }
            {127.0.0.1 localhost} {
                if {[testConstraint localhost_v4]} {
                    set result $resultok
                }
            }
            {::1 localhost} {
                if {[testConstraint localhost_v6]} {
                    set result $resultok
                }
            }
        }
        test socket-15.1.$num "Connect to $servip from $cliip" \
            -constraints $constraints -setup {
                set server [socket -server accept -myaddr $servip 0]
                proc accept {s h p} { close $s }
                set port [lindex [fconfigure $server -sockname] 2]
            } -body {
                set s [socket $cliip $port]
            } -cleanup {
                close $server
                catch {close $s}
            } {*}$result
        incr num
    }
}

test socket-bug-31fc36fe47 "Crash listening in multiple threads" \
    -constraints thread -body {
        close [socket -server xxx 0]
        set tid [thread::create]
        thread::send $tid {close [socket -server accept 0]}
        thread::release $tid
    } -result 0

::tcltest::cleanupTests
flush stdout
return

# Local Variables:
# mode: tcl
# fill-column: 78
# End:







|
|
|
|

|







|
|

|







|
|

|







|
|
|
|
|
|
|

|
|
|





|
|
|
|
|















|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|





|
|
|
|










2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
} -cleanup {
    catch {close $s}
    after cancel $a1
} -result readable

test socket-14.15 {blocking read on async socket should not trigger event handlers} \
    -constraints socket -body {
	set s [socket -async localhost [randport]]
	set x ok
	fileevent $s writable {set x fail}
	catch {read $s}
	close $s
	set x
    } -result ok

# v4 and v6 is required to prevent that the async connect does not terminate
# before the fconfigure command. There is always an additional ip to try.
test socket-14.16 {empty -peername while [socket -async] connecting} \
    -constraints {socket localhost_v4 localhost_v6} \
    -body {
	set client [socket -async localhost [randport]]
	fconfigure $client -peername
    } -cleanup {
	catch {close $client}
    } -result {}

# v4 and v6 is required to prevent that the async connect does not terminate
# before the fconfigure command. There is always an additional ip to try.
test socket-14.17 {empty -sockname while [socket -async] connecting} \
    -constraints {socket localhost_v4 localhost_v6} \
    -body {
	set client [socket -async localhost [randport]]
	fconfigure $client -sockname
    } -cleanup {
	catch {close $client}
    } -result {}

# test for bug c6ed4acfd8: running async socket connect with other connect
# established will block tcl as it goes in an infinite loop in vwait
test socket-14.18 {bug c6ed4acfd8: running async socket connect made other connect block} \
    -constraints {socket} \
    -body {
	proc accept {channel address port} {}
	set port [randport]
	set ssock [socket -server accept $port]
	set csock1 [socket -async localhost [randport]]
	set csock2 [socket localhost $port]
	after 1000 {set done ok}
	vwait done
} -cleanup {
	catch {close $ssock}
	catch {close $csock1}
	catch {close $csock2}
    } -result {}

test socket-14.19 {tip 456 -- introduce the -reuseport option} \
    -constraints {socket notWine} \
    -body {
	proc accept {channel address port} {}
	set port [randport]
	set ssock1 [socket -server accept -reuseport yes $port]
	set ssock2 [socket -server accept -reuseport yes $port]
	return ok
} -cleanup {
    catch {close $ssock1}
    catch {close $ssock2}
    } -result ok

set num 0

set x {localhost {socket} 127.0.0.1 {supported_inet} ::1 {supported_inet6}}
set resultok {-result "sock*" -match glob}
set resulterr {
    -result {couldn't open socket: connection refused}
    -returnCodes 1
}
foreach {servip sc} $x {
    foreach {cliip cc} $x {
	set constraints socket
	lappend constraints $sc $cc
	set result $resulterr
	switch -- [lsort -unique [list $servip $cliip]] {
	    localhost - 127.0.0.1 - ::1 {
		set result $resultok
	    }
	    {127.0.0.1 localhost} {
		if {[testConstraint localhost_v4]} {
		    set result $resultok
		}
	    }
	    {::1 localhost} {
		if {[testConstraint localhost_v6]} {
		    set result $resultok
		}
	    }
	}
	test socket-15.1.$num "Connect to $servip from $cliip" \
	    -constraints $constraints -setup {
		set server [socket -server accept -myaddr $servip 0]
		proc accept {s h p} { close $s }
		set port [lindex [fconfigure $server -sockname] 2]
	    } -body {
		set s [socket $cliip $port]
	    } -cleanup {
		close $server
		catch {close $s}
	    } {*}$result
	incr num
    }
}

test socket-bug-31fc36fe47 "Crash listening in multiple threads" \
    -constraints thread -body {
	close [socket -server xxx 0]
	set tid [thread::create]
	thread::send $tid {close [socket -server accept 0]}
	thread::release $tid
    } -result 0

::tcltest::cleanupTests
flush stdout
return

# Local Variables:
# mode: tcl
# fill-column: 78
# End:
Changes to tests/source.test.
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
    source $sourcefile
} -cleanup {
    removeFile source.file
} -result {a b c d e f}

proc ListGlobMatch {expected actual} {
    if {[llength $expected] != [llength $actual]} {
        return 0
    }
    foreach e $expected a $actual {
        if {![string match $e $a]} {
            return 0
        }
    }
    return 1
}
customMatch listGlob [namespace which ListGlobMatch]

test source-2.3 {source error conditions} -setup {
    set sourcefile [makeFile {







|


|
|
|







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
    source $sourcefile
} -cleanup {
    removeFile source.file
} -result {a b c d e f}

proc ListGlobMatch {expected actual} {
    if {[llength $expected] != [llength $actual]} {
	return 0
    }
    foreach e $expected a $actual {
	if {![string match $e $a]} {
	    return 0
	}
    }
    return 1
}
customMatch listGlob [namespace which ListGlobMatch]

test source-2.3 {source error conditions} -setup {
    set sourcefile [makeFile {
Changes to tests/split.test.
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
    split {}
} {}
test split-1.7 {basic split commands} {
    split {   }
} {{} {} {} {}}
test split-1.8 {basic split commands} {
    proc foo {} {
        set x {}
        foreach f [split {]\n} {}] {
            append x $f
        }
        return $x
    }
    foo
} {]\n}
test split-1.9 {basic split commands} {
    proc foo {} {
        set x ab\x00c
        set y [split $x {}]
        return $y
    }
    foo
} "a b \x00 c"
test split-1.10 {basic split commands} {
    split "a0ab1b2bbb3\x00c4" ab\x00c
} {{} 0 {} 1 2 {} {} 3 {} 4}
test split-1.11 {basic split commands} {







|
|
|
|
|





|
|
|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
    split {}
} {}
test split-1.7 {basic split commands} {
    split {   }
} {{} {} {} {}}
test split-1.8 {basic split commands} {
    proc foo {} {
	set x {}
	foreach f [split {]\n} {}] {
	    append x $f
	}
	return $x
    }
    foo
} {]\n}
test split-1.9 {basic split commands} {
    proc foo {} {
	set x ab\x00c
	set y [split $x {}]
	return $y
    }
    foo
} "a b \x00 c"
test split-1.10 {basic split commands} {
    split "a0ab1b2bbb3\x00c4" ab\x00c
} {{} 0 {} 1 2 {} {} 3 {} 4}
test split-1.11 {basic split commands} {
Changes to tests/string.test.
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
testConstraint testevalex [expr {[info commands testevalex] ne {}}]
testConstraint testbytestring   [llength [info commands testbytestring]]

# Used for constraining memory leak tests
testConstraint memory [llength [info commands memory]]
if {[testConstraint memory]} {
    proc getbytes {} {
        set lines [split [memory info] \n]
        return [lindex $lines 3 3]
    }
    proc leaktest {script {iterations 3}} {
        set end [getbytes]
        for {set i 0} {$i < $iterations} {incr i} {
            uplevel 1 $script
            set tmp $end
            set end [getbytes]
        }
        return [expr {$end - $tmp}]
    }
}

proc representationpoke s {
    set r [::tcl::unsupported::representation $s]
    list [lindex $r 3] [string match {*, string representation "*"} $r]
}







|
|


|
|
|
|
|
|
|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
testConstraint testevalex [expr {[info commands testevalex] ne {}}]
testConstraint testbytestring   [llength [info commands testbytestring]]

# Used for constraining memory leak tests
testConstraint memory [llength [info commands memory]]
if {[testConstraint memory]} {
    proc getbytes {} {
	set lines [split [memory info] \n]
	return [lindex $lines 3 3]
    }
    proc leaktest {script {iterations 3}} {
	set end [getbytes]
	for {set i 0} {$i < $iterations} {incr i} {
	    uplevel 1 $script
	    set tmp $end
	    set end [getbytes]
	}
	return [expr {$end - $tmp}]
    }
}

proc representationpoke s {
    set r [::tcl::unsupported::representation $s]
    list [lindex $r 3] [string match {*, string representation "*"} $r]
}
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
test string-1.2.$noComp {error conditions} {
    list [catch {run {string}} msg] $msg
} {1 {wrong # args: should be "string subcommand ?arg ...?"}}
test stringComp-1.3.$noComp {error condition - undefined method during compile} {
    # We don't want this to complain about 'never' because it may never
    # be called, or string may get redefined.  This must compile OK.
    proc foo {str i} {
        if {"yes" == "no"} { string never called but complains here }
        string index $str $i
    }
    foo abc 0
} a

test string-2.1.$noComp {string compare, not enough args} {
    list [catch {run {string compare a}} msg] $msg
} {1 {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"}}







|
|







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
test string-1.2.$noComp {error conditions} {
    list [catch {run {string}} msg] $msg
} {1 {wrong # args: should be "string subcommand ?arg ...?"}}
test stringComp-1.3.$noComp {error condition - undefined method during compile} {
    # We don't want this to complain about 'never' because it may never
    # be called, or string may get redefined.  This must compile OK.
    proc foo {str i} {
	if {"yes" == "no"} { string never called but complains here }
	string index $str $i
    }
    foo abc 0
} a

test string-2.1.$noComp {string compare, not enough args} {
    list [catch {run {string compare a}} msg] $msg
} {1 {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"}}
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
} {0 1 1 1 0 0}
test string-11.55.$noComp {string match, invalid binary optimization} {
    [format string] match \u0141 [binary format c 65]
} 0

test stringComp-12.1.0.$noComp {Bug 3588366: end-offsets before start} {
    apply {s {
        string range $s 0 end-5
    }} 12345
} {}
test string-12.1.$noComp {string range} {
    list [catch {run {string range}} msg] $msg
} {1 {wrong # args: should be "string range string first last"}}
test string-12.2.$noComp {string range} {
    list [catch {run {string range a 1}} msg] $msg







|







1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
} {0 1 1 1 0 0}
test string-11.55.$noComp {string match, invalid binary optimization} {
    [format string] match \u0141 [binary format c 65]
} 0

test stringComp-12.1.0.$noComp {Bug 3588366: end-offsets before start} {
    apply {s {
	string range $s 0 end-5
    }} 12345
} {}
test string-12.1.$noComp {string range} {
    list [catch {run {string range}} msg] $msg
} {1 {wrong # args: should be "string range string first last"}}
test string-12.2.$noComp {string range} {
    list [catch {run {string range a 1}} msg] $msg
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
test string-14.24.$noComp {string replace \xC0 \x80} testbytestring {
    run {string length [string replace ?[testbytestring \x80] 0 end-1 [testbytestring \xC0]]}
} 2


test stringComp-14.21.$noComp {Bug 82e7f67325} {
    apply {x {
        set a [join $x {}]
        lappend b [string length [string replace ___! 0 2 $a]]
        lappend b [string length [string replace ___! 0 2 $a[unset a]]]
    }} {a b}
} {3 3}
test stringComp-14.22.$noComp {Bug 82e7f67325} memory {
    # As in stringComp-14.1, but make sure we don't retain too many refs
    leaktest {
        apply {x {
            set a [join $x {}]
            lappend b [string length [string replace ___! 0 2 $a]]
            lappend b [string length [string replace ___! 0 2 $a[unset a]]]
        }} {a b}
    }
} {0}
test stringComp-14.23.$noComp {Bug 0dca3bfa8f} {
    apply {arg {
        set argCopy $arg
        set arg [string replace $arg 1 2 aa]
        # Crashes in comparison before fix
        expr {$arg ne $argCopy}
    }} abcde
} 1
test stringComp-14.24.$noComp {Bug 1af8de570511} {
    apply {{x y} {
        # Generate an unshared string value
        set val ""
        for { set i 0 } { $i < $x } { incr i } {
            set val [format "0%s" $val]
        }
        string replace $val[unset val] 1 1 $y
    }} 4 x
} 0x00
test stringComp-14.25.$noComp {} {
    string length [string replace [string repeat a\xFE 2] 3 end {}]
} 3
test stringComp-14.26.$noComp {} {
    run {string replace abcd 0x10000000000000000-0xffffffffffffffff 2 e}







|
|
|





|
|
|
|
|




|
|
|
|




|
|
|
|
|
|







1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
test string-14.24.$noComp {string replace \xC0 \x80} testbytestring {
    run {string length [string replace ?[testbytestring \x80] 0 end-1 [testbytestring \xC0]]}
} 2


test stringComp-14.21.$noComp {Bug 82e7f67325} {
    apply {x {
	set a [join $x {}]
	lappend b [string length [string replace ___! 0 2 $a]]
	lappend b [string length [string replace ___! 0 2 $a[unset a]]]
    }} {a b}
} {3 3}
test stringComp-14.22.$noComp {Bug 82e7f67325} memory {
    # As in stringComp-14.1, but make sure we don't retain too many refs
    leaktest {
	apply {x {
	    set a [join $x {}]
	    lappend b [string length [string replace ___! 0 2 $a]]
	    lappend b [string length [string replace ___! 0 2 $a[unset a]]]
	}} {a b}
    }
} {0}
test stringComp-14.23.$noComp {Bug 0dca3bfa8f} {
    apply {arg {
	set argCopy $arg
	set arg [string replace $arg 1 2 aa]
	# Crashes in comparison before fix
	expr {$arg ne $argCopy}
    }} abcde
} 1
test stringComp-14.24.$noComp {Bug 1af8de570511} {
    apply {{x y} {
	# Generate an unshared string value
	set val ""
	for { set i 0 } { $i < $x } { incr i } {
	    set val [format "0%s" $val]
	}
	string replace $val[unset val] 1 1 $y
    }} 4 x
} 0x00
test stringComp-14.25.$noComp {} {
    string length [string replace [string repeat a\xFE 2] 3 end {}]
} 3
test stringComp-14.26.$noComp {} {
    run {string replace abcd 0x10000000000000000-0xffffffffffffffff 2 e}
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
    set x 5
    catch {testindexobj $x foo bar soom}
    run {string is boolean $x}
} 0
test string-23.1.$noComp {string is command with empty string} {
    set s ""
    list \
        [run {string is alnum $s}] \
        [run {string is alpha $s}] \
        [run {string is ascii $s}] \
        [run {string is control $s}] \
        [run {string is boolean $s}] \
        [run {string is digit $s}] \
        [run {string is double $s}] \
        [run {string is false $s}] \
        [run {string is graph $s}] \
        [run {string is integer $s}] \
        [run {string is lower $s}] \
        [run {string is print $s}] \
        [run {string is punct $s}] \
        [run {string is space $s}] \
        [run {string is true $s}] \
        [run {string is upper $s}] \
        [run {string is wordchar $s}] \
        [run {string is xdigit $s}] \

} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1}
test string-23.2.$noComp {string is command with empty string} {
    set s ""
    list \
        [run {string is alnum -strict $s}] \
        [run {string is alpha -strict $s}] \
        [run {string is ascii -strict $s}] \
        [run {string is control -strict $s}] \
        [run {string is boolean -strict $s}] \
        [run {string is digit -strict $s}] \
        [run {string is double -strict $s}] \
        [run {string is false -strict $s}] \
        [run {string is graph -strict $s}] \
        [run {string is integer -strict $s}] \
        [run {string is lower -strict $s}] \
        [run {string is print -strict $s}] \
        [run {string is punct -strict $s}] \
        [run {string is space -strict $s}] \
        [run {string is true -strict $s}] \
        [run {string is upper -strict $s}] \
        [run {string is wordchar -strict $s}] \
        [run {string is xdigit -strict $s}] \

} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}

test string-24.1.$noComp {string reverse command} -body {
    run {string reverse}
} -returnCodes error -result "wrong # args: should be \"string reverse string\""
test string-24.2.$noComp {string reverse command} -body {







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|





|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
    set x 5
    catch {testindexobj $x foo bar soom}
    run {string is boolean $x}
} 0
test string-23.1.$noComp {string is command with empty string} {
    set s ""
    list \
	[run {string is alnum $s}] \
	[run {string is alpha $s}] \
	[run {string is ascii $s}] \
	[run {string is control $s}] \
	[run {string is boolean $s}] \
	[run {string is digit $s}] \
	[run {string is double $s}] \
	[run {string is false $s}] \
	[run {string is graph $s}] \
	[run {string is integer $s}] \
	[run {string is lower $s}] \
	[run {string is print $s}] \
	[run {string is punct $s}] \
	[run {string is space $s}] \
	[run {string is true $s}] \
	[run {string is upper $s}] \
	[run {string is wordchar $s}] \
	[run {string is xdigit $s}] \

} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1}
test string-23.2.$noComp {string is command with empty string} {
    set s ""
    list \
	[run {string is alnum -strict $s}] \
	[run {string is alpha -strict $s}] \
	[run {string is ascii -strict $s}] \
	[run {string is control -strict $s}] \
	[run {string is boolean -strict $s}] \
	[run {string is digit -strict $s}] \
	[run {string is double -strict $s}] \
	[run {string is false -strict $s}] \
	[run {string is graph -strict $s}] \
	[run {string is integer -strict $s}] \
	[run {string is lower -strict $s}] \
	[run {string is print -strict $s}] \
	[run {string is punct -strict $s}] \
	[run {string is space -strict $s}] \
	[run {string is true -strict $s}] \
	[run {string is upper -strict $s}] \
	[run {string is wordchar -strict $s}] \
	[run {string is xdigit -strict $s}] \

} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}

test string-24.1.$noComp {string reverse command} -body {
    run {string reverse}
} -returnCodes error -result "wrong # args: should be \"string reverse string\""
test string-24.2.$noComp {string reverse command} -body {
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
    tcl::prefix match -error {} {apa bepa bear depa} be
} -returnCodes 0 -result {}
test string-26.10.$noComp {tcl::prefix} -body {
    tcl::prefix match -error {-level 1} {apa bepa bear depa} be
} -returnCodes 2 -result {ambiguous option "be": must be apa, bepa, bear, or depa}
test string-26.10.1.$noComp {tcl::prefix} -setup {
    proc _testprefix {args} {
        array set opts {-a x -b y -c y}
        foreach {opt val} $args {
            set opt [tcl::prefix match -error {-level 1} {-a -b -c} $opt]
            set opts($opt) $val
        }
        array get opts
    }
} -body {
    set a [catch {_testprefix -x u} result options]
    dict get $options -errorinfo
} -cleanup {
    rename _testprefix {}
} -result {bad option "-x": must be -a, -b, or -c
    while executing
"_testprefix -x u"}

# Helper for memory stress tests
# Repeat each body in a local space checking that memory does not increase
proc MemStress {args} {
    set res {}
    foreach body $args {
        set end 0
        for {set i 0} {$i < 5} {incr i} {
            proc MemStress_Body {} $body
            uplevel 1 MemStress_Body
            rename MemStress_Body {}
            set tmp $end
            set end [lindex [lindex [split [memory info] "\n"] 3] 3]
        }
        lappend res [expr {$end - $tmp}]
    }
    return $res
}

test string-26.11.$noComp {tcl::prefix: testing for leaks} -body {
    # This test is made to stress object reference management
    MemStress {
        set table {hejj miff gurk}
        set item [lindex $table 1]
        # If not careful, this can cause a circular reference
        # that will cause a leak.
        tcl::prefix match $table $item
    } {
        # A similar case with nested lists
        set table2 {hejj {miff maff} gurk}
        set item [lindex [lindex $table2 1] 0]
        tcl::prefix match $table2 $item
    } {
        # A similar case with dict
        set table3 {hejj {miff maff} gurk2}
        set item [lindex [dict keys [lindex $table3 1]] 0]
        tcl::prefix match $table3 $item
    }
} -constraints memory -result {0 0 0}

test string-26.12.$noComp {tcl::prefix: testing for leaks} -body {
    # This is a memory leak test in a form that might actually happen
    # in real code.  The shared literal "miff" causes a connection
    # between the item and the table.
    MemStress {
        proc stress1 {item} {
            set table [list hejj miff gurk]
            tcl::prefix match $table $item
        }
        proc stress2 {} {
            stress1 miff
        }
        stress2
        rename stress1 {}
        rename stress2 {}
    }
} -constraints memory -result 0

test string-26.13.$noComp {tcl::prefix: testing for leaks} -body {
    # This test is made to stress object reference management
    MemStress {
        set table [list hejj miff]
        set item $table
        set error $table
        # Use the same objects in all places
        catch {
            tcl::prefix match -error $error $table $item
        }
    }
} -constraints memory -result {0}

test string-27.1.$noComp {tcl::prefix all, not enough args} -body {
    tcl::prefix all a
} -returnCodes 1 -result {wrong # args: should be "tcl::prefix all table string"}
test string-27.2.$noComp {tcl::prefix all, bad args} -body {







|
|
|
|
|
|















|
|
|
|
|
|
|
|
|







|
|
|
|
|

|
|
|
|

|
|
|
|








|
|
|
|
|
|
|
|
|
|






|
|
|
|
|
|
|







2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
    tcl::prefix match -error {} {apa bepa bear depa} be
} -returnCodes 0 -result {}
test string-26.10.$noComp {tcl::prefix} -body {
    tcl::prefix match -error {-level 1} {apa bepa bear depa} be
} -returnCodes 2 -result {ambiguous option "be": must be apa, bepa, bear, or depa}
test string-26.10.1.$noComp {tcl::prefix} -setup {
    proc _testprefix {args} {
	array set opts {-a x -b y -c y}
	foreach {opt val} $args {
	    set opt [tcl::prefix match -error {-level 1} {-a -b -c} $opt]
	    set opts($opt) $val
	}
	array get opts
    }
} -body {
    set a [catch {_testprefix -x u} result options]
    dict get $options -errorinfo
} -cleanup {
    rename _testprefix {}
} -result {bad option "-x": must be -a, -b, or -c
    while executing
"_testprefix -x u"}

# Helper for memory stress tests
# Repeat each body in a local space checking that memory does not increase
proc MemStress {args} {
    set res {}
    foreach body $args {
	set end 0
	for {set i 0} {$i < 5} {incr i} {
	    proc MemStress_Body {} $body
	    uplevel 1 MemStress_Body
	    rename MemStress_Body {}
	    set tmp $end
	    set end [lindex [lindex [split [memory info] "\n"] 3] 3]
	}
	lappend res [expr {$end - $tmp}]
    }
    return $res
}

test string-26.11.$noComp {tcl::prefix: testing for leaks} -body {
    # This test is made to stress object reference management
    MemStress {
	set table {hejj miff gurk}
	set item [lindex $table 1]
	# If not careful, this can cause a circular reference
	# that will cause a leak.
	tcl::prefix match $table $item
    } {
	# A similar case with nested lists
	set table2 {hejj {miff maff} gurk}
	set item [lindex [lindex $table2 1] 0]
	tcl::prefix match $table2 $item
    } {
	# A similar case with dict
	set table3 {hejj {miff maff} gurk2}
	set item [lindex [dict keys [lindex $table3 1]] 0]
	tcl::prefix match $table3 $item
    }
} -constraints memory -result {0 0 0}

test string-26.12.$noComp {tcl::prefix: testing for leaks} -body {
    # This is a memory leak test in a form that might actually happen
    # in real code.  The shared literal "miff" causes a connection
    # between the item and the table.
    MemStress {
	proc stress1 {item} {
	    set table [list hejj miff gurk]
	    tcl::prefix match $table $item
	}
	proc stress2 {} {
	    stress1 miff
	}
	stress2
	rename stress1 {}
	rename stress2 {}
    }
} -constraints memory -result 0

test string-26.13.$noComp {tcl::prefix: testing for leaks} -body {
    # This test is made to stress object reference management
    MemStress {
	set table [list hejj miff]
	set item $table
	set error $table
	# Use the same objects in all places
	catch {
	    tcl::prefix match -error $error $table $item
	}
    }
} -constraints memory -result {0}

test string-27.1.$noComp {tcl::prefix all, not enough args} -body {
    tcl::prefix all a
} -returnCodes 1 -result {wrong # args: should be "tcl::prefix all table string"}
test string-27.2.$noComp {tcl::prefix all, bad args} -body {
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
    run {tcl::string::insert [makeByteArray 0123] 4 [makeByteArray _]}
} 0123_
test string-31.15.$noComp {string insert, pure byte array, neither shared} {
    run {tcl::string::insert [makeByteArray 0123] 2 [makeByteArray _]}
} 01_23
test string-31.16.$noComp {string insert, pure byte array, first shared} {
    run {tcl::string::insert [makeShared [makeByteArray 0123]] 2\
            [makeByteArray _]}
} 01_23
test string-31.17.$noComp {string insert, pure byte array, second shared} {
    run {tcl::string::insert [makeByteArray 0123] 2\
            [makeShared [makeByteArray _]]}
} 01_23
test string-31.18.$noComp {string insert, pure byte array, both shared} {
    run {tcl::string::insert [makeShared [makeByteArray 0123]] 2\
            [makeShared [makeByteArray _]]}
} 01_23
test string-31.19.$noComp {string insert, start of string, pure Unicode} {
    run {tcl::string::insert [makeUnicode 0123] 0 [makeUnicode _]}
} _0123
test string-31.20.$noComp {string insert, middle of string, pure Unicode} {
    run {tcl::string::insert [makeUnicode 0123] 2 [makeUnicode _]}
} 01_23
test string-31.21.$noComp {string insert, end of string, pure Unicode} {
    run {tcl::string::insert [makeUnicode 0123] 4 [makeUnicode _]}
} 0123_
test string-31.22.$noComp {string insert, str start, pure Uni, first shared} {
    run {tcl::string::insert [makeShared [makeUnicode 0123]] 0 [makeUnicode _]}
} _0123
test string-31.23.$noComp {string insert, string mid, pure Uni, 2nd shared} {
    run {tcl::string::insert [makeUnicode 0123] 2 [makeShared [makeUnicode _]]}
} 01_23
test string-31.24.$noComp {string insert, string end, pure Uni, both shared} {
    run {tcl::string::insert [makeShared [makeUnicode 0123]] 4\
            [makeShared [makeUnicode _]]}
} 0123_
test string-31.25.$noComp {string insert, neither byte array nor Unicode} {
    run {tcl::string::insert [makeList a b c] 1 zzzzzz}
} {azzzzzz b c}
test string-31.26.$noComp {[11229bad5f] string insert, compiler} -setup {
    set i 2
} -body {







|



|



|


















|







2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
    run {tcl::string::insert [makeByteArray 0123] 4 [makeByteArray _]}
} 0123_
test string-31.15.$noComp {string insert, pure byte array, neither shared} {
    run {tcl::string::insert [makeByteArray 0123] 2 [makeByteArray _]}
} 01_23
test string-31.16.$noComp {string insert, pure byte array, first shared} {
    run {tcl::string::insert [makeShared [makeByteArray 0123]] 2\
	    [makeByteArray _]}
} 01_23
test string-31.17.$noComp {string insert, pure byte array, second shared} {
    run {tcl::string::insert [makeByteArray 0123] 2\
	    [makeShared [makeByteArray _]]}
} 01_23
test string-31.18.$noComp {string insert, pure byte array, both shared} {
    run {tcl::string::insert [makeShared [makeByteArray 0123]] 2\
	    [makeShared [makeByteArray _]]}
} 01_23
test string-31.19.$noComp {string insert, start of string, pure Unicode} {
    run {tcl::string::insert [makeUnicode 0123] 0 [makeUnicode _]}
} _0123
test string-31.20.$noComp {string insert, middle of string, pure Unicode} {
    run {tcl::string::insert [makeUnicode 0123] 2 [makeUnicode _]}
} 01_23
test string-31.21.$noComp {string insert, end of string, pure Unicode} {
    run {tcl::string::insert [makeUnicode 0123] 4 [makeUnicode _]}
} 0123_
test string-31.22.$noComp {string insert, str start, pure Uni, first shared} {
    run {tcl::string::insert [makeShared [makeUnicode 0123]] 0 [makeUnicode _]}
} _0123
test string-31.23.$noComp {string insert, string mid, pure Uni, 2nd shared} {
    run {tcl::string::insert [makeUnicode 0123] 2 [makeShared [makeUnicode _]]}
} 01_23
test string-31.24.$noComp {string insert, string end, pure Uni, both shared} {
    run {tcl::string::insert [makeShared [makeUnicode 0123]] 4\
	    [makeShared [makeUnicode _]]}
} 0123_
test string-31.25.$noComp {string insert, neither byte array nor Unicode} {
    run {tcl::string::insert [makeList a b c] 1 zzzzzz}
} {azzzzzz b c}
test string-31.26.$noComp {[11229bad5f] string insert, compiler} -setup {
    set i 2
} -body {
Changes to tests/switch.test.
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
	c {}
    }
} -returnCodes error -result {invalid command name "-foo"}

test switch-8.1 {empty body} {
    set msg {}
    switch {2} {
    	1 {set msg 1}
        2 {}
        default {set msg 2}
    }
} {}
proc test_switch_body {} {
    return "INVOKED"
}
test switch-8.2 {weird body text, variable} {
    set cmd {test_switch_body}
    switch Foo {
    	Foo $cmd
    }
} {INVOKED}
test switch-8.3 {weird body text, variable} {
    set cmd {test_switch_body}
    switch Foo {
    	Foo {$cmd}
    }
} {INVOKED}

test switch-9.1 {empty pattern/body list} -returnCodes error -body {
    switch x
} -result {wrong # args: should be "switch ?-option ...? string ?pattern body ...? ?default body?"}
test switch-9.2 {unpaired pattern} -returnCodes error -body {







|
|
|








|





|







242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
	c {}
    }
} -returnCodes error -result {invalid command name "-foo"}

test switch-8.1 {empty body} {
    set msg {}
    switch {2} {
	1 {set msg 1}
	2 {}
	default {set msg 2}
    }
} {}
proc test_switch_body {} {
    return "INVOKED"
}
test switch-8.2 {weird body text, variable} {
    set cmd {test_switch_body}
    switch Foo {
	Foo $cmd
    }
} {INVOKED}
test switch-8.3 {weird body text, variable} {
    set cmd {test_switch_body}
    switch Foo {
	Foo {$cmd}
    }
} {INVOKED}

test switch-9.1 {empty pattern/body list} -returnCodes error -body {
    switch x
} -result {wrong # args: should be "switch ?-option ...? string ?pattern body ...? ?default body?"}
test switch-9.2 {unpaired pattern} -returnCodes error -body {
Changes to tests/tcltest.test.
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
    ::tcltest::PrintError "a really short string"
    ::tcltest::PrintError "a really really really really really really long \
	    string containing \"quotes\" and other bad bad stuff"
    ::tcltest::PrintError "a really really long string containing a \
	    \"Path/that/is/really/long/and/contains/no/spaces\""
    ::tcltest::PrintError "a really really long string containing a \
	    \"Really/Long/Path/that/contains/no/spaces/and/is/longer/than/eighty/characters/to/see/what/happens\""
    ::tcltest::PrintError "Problem renaming file: error renaming \"Z:/ws/tcl8.2/win32-ix86/tests/core\" to \"Z:/ws/tcl8.2/win32-ix86/tests/movecore-core\""
    exit
} printerror.tcl]

test tcltest-6.1 {tcltest -outfile, -errfile defaults} {
    -constraints unixOrWin
    -body {
	child msg $printerror







|







349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
    ::tcltest::PrintError "a really short string"
    ::tcltest::PrintError "a really really really really really really long \
	    string containing \"quotes\" and other bad bad stuff"
    ::tcltest::PrintError "a really really long string containing a \
	    \"Path/that/is/really/long/and/contains/no/spaces\""
    ::tcltest::PrintError "a really really long string containing a \
	    \"Really/Long/Path/that/contains/no/spaces/and/is/longer/than/eighty/characters/to/see/what/happens\""
    ::tcltest::PrintError "Problem renaming file: error renaming \"Z:/ws/tcl9.0/win32-ix86/tests/core\" to \"Z:/ws/tcl9.0/win32-ix86/tests/movecore-core\""
    exit
} printerror.tcl]

test tcltest-6.1 {tcltest -outfile, -errfile defaults} {
    -constraints unixOrWin
    -body {
	child msg $printerror
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
	set f2 [pwd]
	set f3 [workingDirectory $current]
	set f4 [pwd]
	set f5 [workingDirectory]
	list $f1 $f2 $f3 $f4 $f5
    }
    -result "[list $normaldirectory \
                   $normaldirectory \
                   $current \
                   $current \
                   $current]"
    -cleanup {
	set ::tcltest::workingDirectory $old
	cd $current
    }
}

# clean up from directory testing







|
|
|
|







702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
	set f2 [pwd]
	set f3 [workingDirectory $current]
	set f4 [pwd]
	set f5 [workingDirectory]
	list $f1 $f2 $f3 $f4 $f5
    }
    -result "[list $normaldirectory \
		   $normaldirectory \
		   $current \
		   $current \
		   $current]"
    -cleanup {
	set ::tcltest::workingDirectory $old
	cd $current
    }
}

# clean up from directory testing
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
	-body {list a b c d e} \
	-result {[ab] b c d e} \
	-match glob

test tcltest-21.8 {force a test command failure} \
    -setup {set fail $::tcltest::currentFailure} \
    -body {
        test tcltest-21.8.0 {
            return 2
        } {1}
    } \
    -returnCodes 1 \
    -cleanup {set ::tcltest::currentFailure $fail} \
    -result {bad option "1": must be -body, -cleanup, -constraints, -errorCode, -errorOutput, -match, -output, -result, -returnCodes, or -setup}

test tcltest-21.9 {test command with setup} \
	-setup {set foo 1} \







|
|
|







1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
	-body {list a b c d e} \
	-result {[ab] b c d e} \
	-match glob

test tcltest-21.8 {force a test command failure} \
    -setup {set fail $::tcltest::currentFailure} \
    -body {
	test tcltest-21.8.0 {
	    return 2
	} {1}
    } \
    -returnCodes 1 \
    -cleanup {set ::tcltest::currentFailure $fail} \
    -result {bad option "1": must be -body, -cleanup, -constraints, -errorCode, -errorOutput, -match, -output, -result, -returnCodes, or -setup}

test tcltest-21.9 {test command with setup} \
	-setup {set foo 1} \
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
}

# customMatch
proc matchNegative { expected actual } {
   set match 0
   foreach a $actual e $expected {
      if { $a != $e } {
         set match 1
        break
      }
   }
   return $match
}

test tcltest-24.0 {
	customMatch: syntax







|
|







1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
}

# customMatch
proc matchNegative { expected actual } {
   set match 0
   foreach a $actual e $expected {
      if { $a != $e } {
	 set match 1
	break
      }
   }
   return $match
}

test tcltest-24.0 {
	customMatch: syntax
Changes to tests/tcltests.tcl.
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
    # Expected result is as generated by Tcl_WrongNumArgs
    # Only works if optional arguments come after fixed arguments
    # E.g.
    #  testnumargs "zipfs mount" "" "?mountpoint? ?zipfile? ?password?"
    #  testnumargs "lappend" "varName" "?value ...?"
    proc testnumargs {cmd {fixed {}} {optional {}} args} {
	variable count
        set minargs [llength $fixed]
        set maxargs [expr {$minargs + [llength $optional]}]
        if {[regexp {\.\.\.\??$} [lindex $optional end]]} {
            unset maxargs; # No upper limit on num of args
        }
        set message "wrong # args: should be \"$cmd"
        if {[llength $fixed]} {
            append message " $fixed"
        }
        if {[llength $optional]} {
            append message " $optional"
        }
        if {[llength $fixed] == 0 && [llength $optional] == 0} {
            append message " \""
        } else {
            append message "\""
        }
        set label [join $cmd -]
        if {$minargs > 0} {
            set arguments [lrepeat [expr {$minargs-1}] x]
            test $label-minargs-[incr count($label-minargs)] \
		"$label no arguments" \
                -body "$cmd" \
                -result $message -returnCodes error \
                {*}$args
            if {$minargs > 1} {
                test $label-minargs-[incr count($label-minargs)] \
		    "$label missing arguments" \
                    -body "$cmd $arguments" \
                    -result $message -returnCodes error \
                    {*}$args
            }
        }
        if {[info exists maxargs]} {
            set arguments [lrepeat [expr {$maxargs+1}] x]
            test $label-maxargs-[incr count($label-maxargs)] \
		"$label extra arguments" \
                -body "$cmd $arguments" \
                -result $message -returnCodes error \
                {*}$args
        }
    }

    init

    package provide tcltests 0.1
}








|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|

|
|
|
|
|
|
|
|

|
|
|
|







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
    # Expected result is as generated by Tcl_WrongNumArgs
    # Only works if optional arguments come after fixed arguments
    # E.g.
    #  testnumargs "zipfs mount" "" "?mountpoint? ?zipfile? ?password?"
    #  testnumargs "lappend" "varName" "?value ...?"
    proc testnumargs {cmd {fixed {}} {optional {}} args} {
	variable count
	set minargs [llength $fixed]
	set maxargs [expr {$minargs + [llength $optional]}]
	if {[regexp {\.\.\.\??$} [lindex $optional end]]} {
	    unset maxargs; # No upper limit on num of args
	}
	set message "wrong # args: should be \"$cmd"
	if {[llength $fixed]} {
	    append message " $fixed"
	}
	if {[llength $optional]} {
	    append message " $optional"
	}
	if {[llength $fixed] == 0 && [llength $optional] == 0} {
	    append message " \""
	} else {
	    append message "\""
	}
	set label [join $cmd -]
	if {$minargs > 0} {
	    set arguments [lrepeat [expr {$minargs-1}] x]
	    test $label-minargs-[incr count($label-minargs)] \
		"$label no arguments" \
		-body "$cmd" \
		-result $message -returnCodes error \
		{*}$args
	    if {$minargs > 1} {
		test $label-minargs-[incr count($label-minargs)] \
		    "$label missing arguments" \
		    -body "$cmd $arguments" \
		    -result $message -returnCodes error \
		    {*}$args
	    }
	}
	if {[info exists maxargs]} {
	    set arguments [lrepeat [expr {$maxargs+1}] x]
	    test $label-maxargs-[incr count($label-maxargs)] \
		"$label extra arguments" \
		-body "$cmd $arguments" \
		-result $message -returnCodes error \
		{*}$args
	}
    }

    init

    package provide tcltests 0.1
}

Changes to tests/thread.test.
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
    thread::release
}

proc getThreadErrorFromInfo { info } {
    set list [split $info \n]
    set idx [lsearch -glob $list "*eval*unwound*"]
    if {$idx >= 0} then {
        return [lindex $list $idx]
    }
    set idx [lsearch -glob $list "*eval*canceled*"]
    if {$idx >= 0} then {
        return [lindex $list $idx]
    }
    return ""; # some other error we do not care about.
}

proc findThreadError { info } {
    foreach error [lreverse $info] {
        set error [getThreadErrorFromInfo $error]
        if {[string length $error] > 0} then {
            return $error
        }
    }
    return ""; # some other error we do not care about.
}

proc ThreadError {id info} {
    global threadSawError
    if {[string length [getThreadErrorFromInfo $info]] > 0} then {
        global threadId threadError
        set threadId $id
        lappend threadError($id) $info
    }
    set threadSawError($id) true; # signal main thread to exit [vwait].
}

proc threadSuperKill id {
    variable threadSuperKillScript
    try {







|



|






|
|
|
|







|
|
|







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
    thread::release
}

proc getThreadErrorFromInfo { info } {
    set list [split $info \n]
    set idx [lsearch -glob $list "*eval*unwound*"]
    if {$idx >= 0} then {
	return [lindex $list $idx]
    }
    set idx [lsearch -glob $list "*eval*canceled*"]
    if {$idx >= 0} then {
	return [lindex $list $idx]
    }
    return ""; # some other error we do not care about.
}

proc findThreadError { info } {
    foreach error [lreverse $info] {
	set error [getThreadErrorFromInfo $error]
	if {[string length $error] > 0} then {
	    return $error
	}
    }
    return ""; # some other error we do not care about.
}

proc ThreadError {id info} {
    global threadSawError
    if {[string length [getThreadErrorFromInfo $info]] > 0} then {
	global threadId threadError
	set threadId $id
	lappend threadError($id) $info
    }
    set threadSawError($id) true; # signal main thread to exit [vwait].
}

proc threadSuperKill id {
    variable threadSuperKillScript
    try {
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
    set numthreads [llength [thread::names]]
    thread::release -wait $serverthread
    set numthreads
} 2
test thread-1.5 {Tcl_ThreadObjCmd: thread create one shot} {thread} {
    thread::create {set x 5}
    foreach try {0 1 2 4 5 6} {
        # Try various ways to yield
        update
        after 10
        set l [llength [thread::names]]
        if {$l == 1} {
            break
        }
    }
    set l
} 1
test thread-1.6 {Tcl_ThreadObjCmd: thread exit} {thread} {
    thread::create {{*}{}}
    update
    after 10







|
|
|
|
|
|
|







108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
    set numthreads [llength [thread::names]]
    thread::release -wait $serverthread
    set numthreads
} 2
test thread-1.5 {Tcl_ThreadObjCmd: thread create one shot} {thread} {
    thread::create {set x 5}
    foreach try {0 1 2 4 5 6} {
	# Try various ways to yield
	update
	after 10
	set l [llength [thread::names]]
	if {$l == 1} {
	    break
	}
    }
    set l
} 1
test thread-1.6 {Tcl_ThreadObjCmd: thread exit} {thread} {
    thread::create {{*}{}}
    update
    after 10
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval canceled}}
test thread-7.5 {cancel: pure inside-command loop} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \







|
|
|
|







277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval canceled}}
test thread-7.5 {cancel: pure inside-command loop} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval canceled}}
test thread-7.6 {cancel: pure bytecode loop -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \







|
|
|
|







309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval canceled}}
test thread-7.6 {cancel: pure bytecode loop -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel -unwind $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.7 {cancel: pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \







|
|
|
|







340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel -unwind $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.7 {cancel: pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel -unwind $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.8 {cancel: pure bytecode loop custom result} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \







|
|
|
|







372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel -unwind $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.8 {cancel: pure bytecode loop custom result} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel $serverthread "the eval was canceled"]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {the eval was canceled}}
test thread-7.9 {cancel: pure inside-command loop custom result} -constraints {
    thread
    drainEventQueue
} -setup {







|
|
|
|







403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel $serverthread "the eval was canceled"]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {the eval was canceled}}
test thread-7.9 {cancel: pure inside-command loop custom result} -constraints {
    thread
    drainEventQueue
} -setup {
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel $serverthread "the eval was canceled"]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {the eval was canceled}}
test thread-7.10 {cancel: pure bytecode loop custom result -unwind} -constraints {
    thread
    drainEventQueue
} -setup {







|
|
|
|







438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel $serverthread "the eval was canceled"]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {the eval was canceled}}
test thread-7.10 {cancel: pure bytecode loop custom result -unwind} -constraints {
    thread
    drainEventQueue
} -setup {
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel -unwind $serverthread "the eval was unwound"]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {the eval was unwound}}
test thread-7.11 {cancel: pure inside-command loop custom result -unwind} -constraints {
    thread
    drainEventQueue
} -setup {







|
|
|
|







472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel -unwind $serverthread "the eval was unwound"]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {the eval was unwound}}
test thread-7.11 {cancel: pure inside-command loop custom result -unwind} -constraints {
    thread
    drainEventQueue
} -setup {
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel -unwind $serverthread "the eval was unwound"]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {the eval was unwound}}
test thread-7.12 {cancel: after} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \







|
|
|
|







507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel -unwind $serverthread "the eval was unwound"]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {the eval was unwound}}
test thread-7.12 {cancel: after} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval canceled}}
test thread-7.13 {cancel: after -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \







|
|
|
|







533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval canceled}}
test thread-7.13 {cancel: after -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel -unwind $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.14 {cancel: vwait} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \







|
|
|
|







559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel -unwind $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.14 {cancel: vwait} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval canceled}}
test thread-7.15 {cancel: vwait -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \







|
|
|
|







585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval canceled}}
test thread-7.15 {cancel: vwait -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel -unwind $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.16 {cancel: expr} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \







|
|
|
|







611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel -unwind $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.16 {cancel: expr} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval canceled}}
test thread-7.17 {cancel: expr -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \







|
|
|
|







642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval canceled}}
test thread-7.17 {cancel: expr -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel -unwind $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.18 {cancel: expr bignum} {thread drainEventQueue knownBug} {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
    set serverthread [thread::create -joinable \
	    [string map [list %ID% [thread::id]] {
        set i [interp create]
	$i eval "package require -exact Thread [package present Thread]"
        $i eval {
            if {![info exists foo]} then {
                # signal the primary thread that we are ready
                # to be canceled now (we are running).
                thread::send %ID% [list set ::threadIdStarted [thread::id]]
                set foo 1
            }
            #
            # BUGBUG: This will not cancel because libtommath
            #         does not check Tcl_Canceled.
            #
            expr {2**99999}
        }
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted; after 1000
    set res [thread::cancel $serverthread]
    vwait ::threadSawError($serverthread); # WARNING: Never returns (see above).
    thread::join $serverthread; drainEventQueue; # WARNING: Never returns (see above).
    list $res [expr {[info exists ::threadIdStarted] ? \
                  $::threadIdStarted == $serverthread : 0}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} {{} 1 0 {}}
test thread-7.19 {cancel: expr bignum -unwind} {thread drainEventQueue knownBug} {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
    set serverthread [thread::create -joinable \
	    [string map [list %ID% [thread::id]] {
        set i [interp create]
	$i eval "package require -exact Thread [package present Thread]"
        $i eval {
            if {![info exists foo]} then {
                # signal the primary thread that we are ready
                # to be canceled now (we are running).
                thread::send %ID% [list set ::threadIdStarted [thread::id]]
                set foo 1
            }
            #
            # BUGBUG: This will not cancel because libtommath
            #         does not check Tcl_Canceled.
            #
            expr {2**99999}
        }
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted; after 1000
    set res [thread::cancel -unwind $serverthread]
    vwait ::threadSawError($serverthread); # WARNING: Never returns (see above).
    thread::join $serverthread; drainEventQueue; # WARNING: Never returns (see above).
    list $res [expr {[info exists ::threadIdStarted] ? \
                  $::threadIdStarted == $serverthread : 0}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} {{} 1 0 {}}
test thread-7.20 {cancel: subst} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \
	    [string map [list %ID% [thread::id]] {
	set i [interp create]







|
|
|
|







|

|
|
|
|
|
|
|
|
|
|
|
|
|







|
|
|
|
|





|

|
|
|
|
|
|
|
|
|
|
|
|
|







|
|
|
|
|







672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel -unwind $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.18 {cancel: expr bignum} {thread drainEventQueue knownBug} {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
    set serverthread [thread::create -joinable \
	    [string map [list %ID% [thread::id]] {
	set i [interp create]
	$i eval "package require -exact Thread [package present Thread]"
	$i eval {
	    if {![info exists foo]} then {
		# signal the primary thread that we are ready
		# to be canceled now (we are running).
		thread::send %ID% [list set ::threadIdStarted [thread::id]]
		set foo 1
	    }
	    #
	    # BUGBUG: This will not cancel because libtommath
	    #         does not check Tcl_Canceled.
	    #
	    expr {2**99999}
	}
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted; after 1000
    set res [thread::cancel $serverthread]
    vwait ::threadSawError($serverthread); # WARNING: Never returns (see above).
    thread::join $serverthread; drainEventQueue; # WARNING: Never returns (see above).
    list $res [expr {[info exists ::threadIdStarted] ? \
		  $::threadIdStarted == $serverthread : 0}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} {{} 1 0 {}}
test thread-7.19 {cancel: expr bignum -unwind} {thread drainEventQueue knownBug} {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
    set serverthread [thread::create -joinable \
	    [string map [list %ID% [thread::id]] {
	set i [interp create]
	$i eval "package require -exact Thread [package present Thread]"
	$i eval {
	    if {![info exists foo]} then {
		# signal the primary thread that we are ready
		# to be canceled now (we are running).
		thread::send %ID% [list set ::threadIdStarted [thread::id]]
		set foo 1
	    }
	    #
	    # BUGBUG: This will not cancel because libtommath
	    #         does not check Tcl_Canceled.
	    #
	    expr {2**99999}
	}
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted; after 1000
    set res [thread::cancel -unwind $serverthread]
    vwait ::threadSawError($serverthread); # WARNING: Never returns (see above).
    thread::join $serverthread; drainEventQueue; # WARNING: Never returns (see above).
    list $res [expr {[info exists ::threadIdStarted] ? \
		  $::threadIdStarted == $serverthread : 0}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} {{} 1 0 {}}
test thread-7.20 {cancel: subst} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \
	    [string map [list %ID% [thread::id]] {
	set i [interp create]
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval canceled}}
test thread-7.21 {cancel: subst -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \







|
|
|
|







766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval canceled}}
test thread-7.21 {cancel: subst -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel -unwind $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.22 {cancel: child interp} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \







|
|
|
|







796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel -unwind $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.22 {cancel: child interp} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval canceled}}
test thread-7.23 {cancel: child interp -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \







|
|
|
|







826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval canceled}}
test thread-7.23 {cancel: child interp -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel -unwind $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.24 {cancel: nested catch inside pure bytecode loop} {thread drainEventQueue} {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
    set serverthread [thread::create -joinable \
	    [string map [list %ID% [thread::id]] {







|
|
|
|







856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel -unwind $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.24 {cancel: nested catch inside pure bytecode loop} {thread drainEventQueue} {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
    set serverthread [thread::create -joinable \
	    [string map [list %ID% [thread::id]] {
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::send -async $serverthread {interp cancel -- -unwind}]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval canceled}}
test thread-7.28 {cancel: send async cancel nested catch inside pure bytecode loop} {thread drainEventQueue} {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
    set serverthread [thread::create -joinable \
	    [string map [list %ID% [thread::id]] {







|
|
|
|







998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::send -async $serverthread {interp cancel -- -unwind}]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval canceled}}
test thread-7.28 {cancel: send async cancel nested catch inside pure bytecode loop} {thread drainEventQueue} {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
    set serverthread [thread::create -joinable \
	    [string map [list %ID% [thread::id]] {
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel -unwind $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.33 {cancel: nested catch inside pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \







|
|
|
|







1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel -unwind $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.33 {cancel: nested catch inside pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel -unwind $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.34 {cancel: send async cancel nested catch inside pure bytecode loop -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \







|
|
|
|







1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::cancel -unwind $serverthread]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.34 {cancel: send async cancel nested catch inside pure bytecode loop -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::send -async $serverthread {interp cancel -unwind}]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.35 {cancel: send async cancel nested catch inside pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \







|
|
|
|







1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::send -async $serverthread {interp cancel -unwind}]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.35 {cancel: send async cancel nested catch inside pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::send -async $serverthread {interp cancel -unwind}]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.36 {cancel: send async thread cancel nested catch inside pure bytecode loop -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \







|
|
|
|







1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::send -async $serverthread {interp cancel -unwind}]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.36 {cancel: send async thread cancel nested catch inside pure bytecode loop -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::send -async $serverthread {thread::cancel -unwind [thread::id]}]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.37 {cancel: send async thread cancel nested catch inside pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \







|
|
|
|







1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::send -async $serverthread {thread::cancel -unwind [thread::id]}]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}
test thread-7.37 {cancel: send async thread cancel nested catch inside pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -body {
    set serverthread [thread::create -joinable \
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::send -async $serverthread {thread::cancel -unwind [thread::id]}]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
              [expr {[info exists ::threadId] ? \
                  $::threadId == $serverthread : 0}] \
              [expr {[info exists ::threadError($serverthread)] ? \
                  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}

test thread-8.1 {threaded fork stress} -constraints {thread} -setup {
    unset -nocomplain ::threadCount ::execCount ::threads ::thread
    set ::threadCount 10







|
|
|
|







1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
    }]]
    # wait for other thread to signal "ready to cancel"
    vwait ::threadIdStarted
    set res [thread::send -async $serverthread {thread::cancel -unwind [thread::id]}]
    vwait ::threadSawError($serverthread)
    thread::join $serverthread; drainEventQueue
    list $res [expr {$::threadIdStarted == $serverthread}] \
	      [expr {[info exists ::threadId] ? \
		  $::threadId == $serverthread : 0}] \
	      [expr {[info exists ::threadError($serverthread)] ? \
		  [findThreadError $::threadError($serverthread)] : ""}]
} -cleanup {
    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
} -result {{} 1 1 {eval unwound}}

test thread-8.1 {threaded fork stress} -constraints {thread} -setup {
    unset -nocomplain ::threadCount ::execCount ::threads ::thread
    set ::threadCount 10
Changes to tests/trace.test.
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
    list [catch {set x(2)} msg] $msg $info
} {0 zzz {x 2 read 0 zzz}}
test trace-1.6 {trace array element reads} {
    unset -nocomplain x
    set info {}
    trace add variable x read traceArray2
    proc p {} {
        global x
        set x(2) willi
        return $x(2)
    }
    list [catch {p} msg] $msg $info
} {0 willi {x 2 read}}
test trace-1.7 {trace array element reads, create element undefined if nonexistant} {
    unset -nocomplain x
    set info {}
    trace add variable x read q
    proc q {name1 name2 op} {
        global info
        set info [list $name1 $name2 $op]
        global $name1
        set ${name1}($name2) wolf
    }
    proc p {} {
        global x
        set x(X) willi
        return $x(Y)
    }
    list [catch {p} msg] $msg $info
} {0 wolf {x Y read}}
test trace-1.8 {trace reads on whole arrays} {
    unset -nocomplain x
    set info {}
    trace add variable x read traceArray







|
|
|








|
|
|
|


|
|
|







116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
    list [catch {set x(2)} msg] $msg $info
} {0 zzz {x 2 read 0 zzz}}
test trace-1.6 {trace array element reads} {
    unset -nocomplain x
    set info {}
    trace add variable x read traceArray2
    proc p {} {
	global x
	set x(2) willi
	return $x(2)
    }
    list [catch {p} msg] $msg $info
} {0 willi {x 2 read}}
test trace-1.7 {trace array element reads, create element undefined if nonexistant} {
    unset -nocomplain x
    set info {}
    trace add variable x read q
    proc q {name1 name2 op} {
	global info
	set info [list $name1 $name2 $op]
	global $name1
	set ${name1}($name2) wolf
    }
    proc p {} {
	global x
	set x(X) willi
	return $x(Y)
    }
    list [catch {p} msg] $msg $info
} {0 wolf {x Y read}}
test trace-1.8 {trace reads on whole arrays} {
    unset -nocomplain x
    set info {}
    trace add variable x read traceArray
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
} {{foo {set b 3} 0 3 leavestep}}

test trace-21.9 {trace execution: TCL_EVAL_GLOBAL} testevalobjv {
    trace add execution foo enter soom
    proc ::soom args {lappend ::info SUCCESS [info level]}
    set ::info {}
    namespace eval test_ns_1 {
        proc soom args {lappend ::info FAIL [info level]}
        # [testevalobjv 1 ...] ought to produce the same
       # results as [uplevel #0 ...].
        testevalobjv 1 foo x
       uplevel #0 foo x
    }
    namespace delete test_ns_1
    trace remove execution foo enter soom
    set ::info
} {SUCCESS 1 SUCCESS 1}

test trace-21.10 {trace execution: TCL_EVAL_GLOBAL} testevalobjv {
    trace add execution foo leave soom
    proc ::soom args {lappend ::info SUCCESS [info level]}
    set ::info {}
    namespace eval test_ns_1 {
        proc soom args {lappend ::info FAIL [info level]}
        # [testevalobjv 1 ...] ought to produce the same
       # results as [uplevel #0 ...].
        testevalobjv 1 foo x
       uplevel #0 foo x
    }
    namespace delete test_ns_1
    trace remove execution foo leave soom
    set ::info
} {SUCCESS 1 SUCCESS 1}








|
|

|












|
|

|







1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
} {{foo {set b 3} 0 3 leavestep}}

test trace-21.9 {trace execution: TCL_EVAL_GLOBAL} testevalobjv {
    trace add execution foo enter soom
    proc ::soom args {lappend ::info SUCCESS [info level]}
    set ::info {}
    namespace eval test_ns_1 {
	proc soom args {lappend ::info FAIL [info level]}
	# [testevalobjv 1 ...] ought to produce the same
       # results as [uplevel #0 ...].
	testevalobjv 1 foo x
       uplevel #0 foo x
    }
    namespace delete test_ns_1
    trace remove execution foo enter soom
    set ::info
} {SUCCESS 1 SUCCESS 1}

test trace-21.10 {trace execution: TCL_EVAL_GLOBAL} testevalobjv {
    trace add execution foo leave soom
    proc ::soom args {lappend ::info SUCCESS [info level]}
    set ::info {}
    namespace eval test_ns_1 {
	proc soom args {lappend ::info FAIL [info level]}
	# [testevalobjv 1 ...] ought to produce the same
       # results as [uplevel #0 ...].
	testevalobjv 1 foo x
       uplevel #0 foo x
    }
    namespace delete test_ns_1
    trace remove execution foo leave soom
    set ::info
} {SUCCESS 1 SUCCESS 1}

2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
    list [catch {trace info command thisdoesntexist} res] $res
} {1 {unknown command "thisdoesntexist"}}


test trace-28.1 {enterstep and leavestep traces with update idletasks (615043)} {
    catch {rename foo {}}
    proc foo {} {
        set a 1
        update idletasks
        set b 1
    }

    set info {}
    trace add execution foo {enter enterstep leavestep leave} \
        [list traceExecute foo]
    update
    after idle {set a "idle"}
    foo

    trace remove execution foo {enter enterstep leavestep leave} \
        [list traceExecute foo]
    rename foo {}
    unset -nocomplain a
    join $info "\n"
} {foo foo enter
foo {set a 1} enterstep
foo {set a 1} 0 1 leavestep
foo {update idletasks} enterstep







|
|
|




|





|







2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
    list [catch {trace info command thisdoesntexist} res] $res
} {1 {unknown command "thisdoesntexist"}}


test trace-28.1 {enterstep and leavestep traces with update idletasks (615043)} {
    catch {rename foo {}}
    proc foo {} {
	set a 1
	update idletasks
	set b 1
    }

    set info {}
    trace add execution foo {enter enterstep leavestep leave} \
	[list traceExecute foo]
    update
    after idle {set a "idle"}
    foo

    trace remove execution foo {enter enterstep leavestep leave} \
	[list traceExecute foo]
    rename foo {}
    unset -nocomplain a
    join $info "\n"
} {foo foo enter
foo {set a 1} enterstep
foo {set a 1} 0 1 leavestep
foo {update idletasks} enterstep
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
    llength [trace info variable x]
} 0

test trace-34.1 {Bug 1201035} {
    set ::x [list]
    proc foo {} {lappend ::x foo}
    proc bar args {
        lappend ::x $args
        trace remove execution foo leavestep bar
        trace remove execution foo enterstep bar
        trace add execution foo leavestep bar
        trace add execution foo enterstep bar
        lappend ::x done
    }
    trace add execution foo leavestep bar
    trace add execution foo enterstep bar
    foo
    set ::x
} {{{lappend ::x foo} enterstep} done foo}








|
|
|
|
|
|







2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
    llength [trace info variable x]
} 0

test trace-34.1 {Bug 1201035} {
    set ::x [list]
    proc foo {} {lappend ::x foo}
    proc bar args {
	lappend ::x $args
	trace remove execution foo leavestep bar
	trace remove execution foo enterstep bar
	trace add execution foo leavestep bar
	trace add execution foo enterstep bar
	lappend ::x done
    }
    trace add execution foo leavestep bar
    trace add execution foo enterstep bar
    foo
    set ::x
} {{{lappend ::x foo} enterstep} done foo}

2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
} {}

# We test here for the half-documented and currently valid interplay between
# delete traces and namespace deletion.
test trace-34.4 {Bug 1047286} {
    variable x notrace
    proc callback {old - -} {
        variable x "$old exists: [namespace which -command $old]"
    }
    namespace eval ::foo {proc bar {} {}}
    trace add command ::foo::bar delete [namespace code callback]
    namespace delete ::foo
    set x
} {::foo::bar exists: ::foo::bar}

test trace-34.5 {Bug 1047286} {
    variable x notrace
    proc callback {old - -} {
        variable x "$old exists: [namespace which -command $old]"
    }
    namespace eval ::foo {proc bar {} {}}
    trace add command ::foo::bar delete [namespace code callback]
    namespace eval ::foo namespace delete ::foo
    set x
} {::foo::bar exists: }

test trace-34.6 {Bug 1458266} -setup {
    proc dummy {} {}
    proc stepTraceHandler {cmdString args} {
        variable log
        append log "[expr {[info level] - 1}]: [lindex [split $cmdString] 0]\n"
        dummy
        isTracedInside_2
    }
    proc cmdTraceHandler {cmdString args} {
        # silent
    }
    proc isTracedInside_1 {} {
        isTracedInside_2
    }
    proc isTracedInside_2 {} {
        set x 2
    }
} -body {
    variable log {}
    trace add execution isTracedInside_1 enterstep stepTraceHandler
    trace add execution isTracedInside_2 enterstep stepTraceHandler
    isTracedInside_1
    variable first $log







|










|










|
|
|
|


|


|


|







2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
} {}

# We test here for the half-documented and currently valid interplay between
# delete traces and namespace deletion.
test trace-34.4 {Bug 1047286} {
    variable x notrace
    proc callback {old - -} {
	variable x "$old exists: [namespace which -command $old]"
    }
    namespace eval ::foo {proc bar {} {}}
    trace add command ::foo::bar delete [namespace code callback]
    namespace delete ::foo
    set x
} {::foo::bar exists: ::foo::bar}

test trace-34.5 {Bug 1047286} {
    variable x notrace
    proc callback {old - -} {
	variable x "$old exists: [namespace which -command $old]"
    }
    namespace eval ::foo {proc bar {} {}}
    trace add command ::foo::bar delete [namespace code callback]
    namespace eval ::foo namespace delete ::foo
    set x
} {::foo::bar exists: }

test trace-34.6 {Bug 1458266} -setup {
    proc dummy {} {}
    proc stepTraceHandler {cmdString args} {
	variable log
	append log "[expr {[info level] - 1}]: [lindex [split $cmdString] 0]\n"
	dummy
	isTracedInside_2
    }
    proc cmdTraceHandler {cmdString args} {
	# silent
    }
    proc isTracedInside_1 {} {
	isTracedInside_2
    }
    proc isTracedInside_2 {} {
	set x 2
    }
} -body {
    variable log {}
    trace add execution isTracedInside_1 enterstep stepTraceHandler
    trace add execution isTracedInside_2 enterstep stepTraceHandler
    isTracedInside_1
    variable first $log
Changes to tests/twapiTlsPlus.tcl.
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# Replacement for ::socket, use with http::register.

proc twapiTlsPlus::socket {args} {
    variable socketCmd

    set targ [lsearch -exact $args -type]
    if {$targ != -1} {
        set token [lindex $args $targ+1]
        set args [lreplace $args $targ $targ+1 -socketcmd [list {*}$socketCmd -type $token]]
    }
    ::twapi::tls_socket {*}$args
}

# Variable twapi::tls::_socket_cmd does it.

proc twapiTlsPlus::TraceSocketCmd {args} {







|
|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# Replacement for ::socket, use with http::register.

proc twapiTlsPlus::socket {args} {
    variable socketCmd

    set targ [lsearch -exact $args -type]
    if {$targ != -1} {
	set token [lindex $args $targ+1]
	set args [lreplace $args $targ $targ+1 -socketcmd [list {*}$socketCmd -type $token]]
    }
    ::twapi::tls_socket {*}$args
}

# Variable twapi::tls::_socket_cmd does it.

proc twapiTlsPlus::TraceSocketCmd {args} {
Changes to tests/unixNotfy.test.
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
    -constraints {noTk unix thread} \
    -body {
	update
	set f [open [makeFile "" foo] w]
	fileevent $f writable {set x 1}
	vwait x
	close $f
   	thread::create "thread::send [thread::id] {set x ok}"
	vwait x
	set x
    } \
    -result {ok} \
    -cleanup {
	catch { close $f }
	catch { removeFile foo }
    }
test unixNotfy-2.2 {Tcl_DeleteFileHandler} \
    -constraints {noTk unix thread} \
    -body {
	update
	set f1 [open [makeFile "" foo] w]
	set f2 [open [makeFile "" foo2] w]
	fileevent $f1 writable {set x 1}
	fileevent $f2 writable {set y 1}
	vwait x
	close $f1
	vwait y
	close $f2
   	thread::create "thread::send [thread::id] {set x ok}"
	vwait x
	set x
    } \
    -result {ok} \
    -cleanup {
	catch { close $f1 }
	catch { close $f2 }







|




















|







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
    -constraints {noTk unix thread} \
    -body {
	update
	set f [open [makeFile "" foo] w]
	fileevent $f writable {set x 1}
	vwait x
	close $f
	thread::create "thread::send [thread::id] {set x ok}"
	vwait x
	set x
    } \
    -result {ok} \
    -cleanup {
	catch { close $f }
	catch { removeFile foo }
    }
test unixNotfy-2.2 {Tcl_DeleteFileHandler} \
    -constraints {noTk unix thread} \
    -body {
	update
	set f1 [open [makeFile "" foo] w]
	set f2 [open [makeFile "" foo2] w]
	fileevent $f1 writable {set x 1}
	fileevent $f2 writable {set y 1}
	vwait x
	close $f1
	vwait y
	close $f2
	thread::create "thread::send [thread::id] {set x ok}"
	vwait x
	set x
    } \
    -result {ok} \
    -cleanup {
	catch { close $f1 }
	catch { close $f2 }
Changes to tests/unload.test.
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
    set pkgua_unloaded {}
}
test unload-3.1 {basic loading of non-unloadable package in a safe interpreter} \
	[list $dll $loaded] {
    catch {rename pkgb_sub {}}
    load [file join $testDir tcl9pkgb$ext] Pkgb child
    list [child eval pkgb_sub 44 13] [catch {child eval pkgb_unsafe} msg] $msg \
         [catch {pkgb_sub 12 10} msg2] $msg2
} {31 1 {invalid command name "pkgb_unsafe"} 1 {invalid command name "pkgb_sub"}}
test unload-3.2 {basic loading of unloadable package in a safe interpreter} \
	[list $dll $loaded] {
    list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
	    [load [file join $testDir tcl9pkgua$ext] Pkgua child] \
	    [child eval pkgua_eq abc def] \
	    [lsort [child eval info commands pkgua_*]] \







|







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
    set pkgua_unloaded {}
}
test unload-3.1 {basic loading of non-unloadable package in a safe interpreter} \
	[list $dll $loaded] {
    catch {rename pkgb_sub {}}
    load [file join $testDir tcl9pkgb$ext] Pkgb child
    list [child eval pkgb_sub 44 13] [catch {child eval pkgb_unsafe} msg] $msg \
	 [catch {pkgb_sub 12 10} msg2] $msg2
} {31 1 {invalid command name "pkgb_unsafe"} 1 {invalid command name "pkgb_sub"}}
test unload-3.2 {basic loading of unloadable package in a safe interpreter} \
	[list $dll $loaded] {
    list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
	    [load [file join $testDir tcl9pkgua$ext] Pkgua child] \
	    [child eval pkgua_eq abc def] \
	    [lsort [child eval info commands pkgua_*]] \
Changes to tests/upvar.test.
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
} {1234}
catch {unset a}

test upvar-10.1 {CompileWord OBOE} -setup {
    proc linenumber {} {dict get [info frame -1] line}
} -body {
    apply {n {
        upvar 1 {*}{
        } [return [incr n -[linenumber]]] x
    }} [linenumber]
} -cleanup {
    rename linenumber {}
} -result 1

#
# Tests for 'namespace upvar'. As the implementation is essentially the same as







|
|







517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
} {1234}
catch {unset a}

test upvar-10.1 {CompileWord OBOE} -setup {
    proc linenumber {} {dict get [info frame -1] line}
} -body {
    apply {n {
	upvar 1 {*}{
	} [return [incr n -[linenumber]]] x
    }} [linenumber]
} -cleanup {
    rename linenumber {}
} -result 1

#
# Tests for 'namespace upvar'. As the implementation is essentially the same as
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
    namespace delete test_ns_1
} -result {}

test upvar-NS-3.1 {CompileWord OBOE} -setup {
    proc linenumber {} {dict get [info frame -1] line}
} -body {
    apply {n {
        namespace upvar {*}{
        } [return [incr n -[linenumber]]] x y
    }} [linenumber]
} -cleanup {
    rename linenumber {}
} -result 1
test upvar-NS-3.2 {CompileWord OBOE} -setup {
    proc linenumber {} {dict get [info frame -1] line}
} -body {
    apply {n {
        namespace upvar :: {*}{
        } [return [incr n -[linenumber]]] x
    }} [linenumber]
} -cleanup {
    rename linenumber {}
} -result 1
test upvar-NS-3.3 {CompileWord OBOE} -setup {
    proc linenumber {} {dict get [info frame -1] line}
} -body {
    apply {n {
        variable x {*}{
        } [return [incr n -[linenumber]]]
    }} [linenumber]
} -cleanup {
    rename linenumber {}
} -result 1

# cleanup
::tcltest::cleanupTests
return

# Local Variables:
# mode: tcl
# End:







|
|








|
|








|
|












651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
    namespace delete test_ns_1
} -result {}

test upvar-NS-3.1 {CompileWord OBOE} -setup {
    proc linenumber {} {dict get [info frame -1] line}
} -body {
    apply {n {
	namespace upvar {*}{
	} [return [incr n -[linenumber]]] x y
    }} [linenumber]
} -cleanup {
    rename linenumber {}
} -result 1
test upvar-NS-3.2 {CompileWord OBOE} -setup {
    proc linenumber {} {dict get [info frame -1] line}
} -body {
    apply {n {
	namespace upvar :: {*}{
	} [return [incr n -[linenumber]]] x
    }} [linenumber]
} -cleanup {
    rename linenumber {}
} -result 1
test upvar-NS-3.3 {CompileWord OBOE} -setup {
    proc linenumber {} {dict get [info frame -1] line}
} -body {
    apply {n {
	variable x {*}{
	} [return [incr n -[linenumber]]]
    }} [linenumber]
} -cleanup {
    rename linenumber {}
} -result 1

# cleanup
::tcltest::cleanupTests
return

# Local Variables:
# mode: tcl
# End:
Changes to tests/utf.test.
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
unset count
rename UniCharCaseCmpTest {}

proc GetUniCharTest {s index result} {
    variable count
    # Use quotes, not {} so test output shows exact string on error
    test getunichar-1.$count "Tcl_GetUniChar $s $index" \
        -constraints testgetunichar \
        -body "testgetunichar $s $index" \
        -result $result
    incr count
}
variable count 1
set errorIndicator -1
GetUniCharTest abcd -2   $errorIndicator
GetUniCharTest abcd -1   $errorIndicator
GetUniCharTest abcd  0   97 ;# a -> ASCII 97







|
|
|







1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
unset count
rename UniCharCaseCmpTest {}

proc GetUniCharTest {s index result} {
    variable count
    # Use quotes, not {} so test output shows exact string on error
    test getunichar-1.$count "Tcl_GetUniChar $s $index" \
	-constraints testgetunichar \
	-body "testgetunichar $s $index" \
	-result $result
    incr count
}
variable count 1
set errorIndicator -1
GetUniCharTest abcd -2   $errorIndicator
GetUniCharTest abcd -1   $errorIndicator
GetUniCharTest abcd  0   97 ;# a -> ASCII 97
Changes to tests/utfext.test.
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226














































227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252



253
254


255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
    #   tests. -1 to skip
    # 4 external fragmentation index - where to split field 2 for fragmentation
    #   tests. -1 to skip
    #
    # THE HEX DEFINITIONS SHOULD SEPARATE EACH CHARACTER BY WHITESPACE
    # (assumed by the charlimit tests)
    lappend utfExtMap {*}{
        ascii {
            {basic {41 42 43} {41 42 43} -1 -1}
        }
        utf-8 {
            {bmp    {41 c3a9 42}     {41 c3a9 42}      2  2}
            {nonbmp-frag-1 {41 f09f9880 42} {41 f09f9880 42}  2  2}
            {nonbmp-frag-2 {41 f09f9880 42} {41 f09f9880 42}  3  3}
            {nonbmp-frag-3 {41 f09f9880 42} {41 f09f9880 42}  4  4}
            {null   {41 c080 42} {41 00 42}    2 -1}
        }
        cesu-8 {
            {bmp    {41 c3a9 42}     {41 c3a9 42}      2  2}
            {nonbmp-frag-surr-low {41 f09f9880 42} {41 eda0bd edb880 42} 2 2}
            {nonbmp-split-surr {41 f09f9880 42} {41 eda0bd edb880 42} 3 -1}
            {nonbmp-frag-surr-high {41 f09f9880 42} {41 eda0bd edb880 42} 4 6}
            {null   {41 c080 42} {41 00 42}    2 -1}
        }
        utf-16le {
            {bmp    {41 c3a9 42}     {4100 e900 4200}     2  3}
            {nonbmp {41 f09f9880 42} {4100 3dd8 00de 4200} 4  3}
            {split-surrogate {41 f09f9080 42} {4100 3dd8 00dc 4200} 3  4}
            {null   {41 c080 42} {4100 0000 4200}  2 3}
        }
        utf-16be {
            {bmp    {41 c3a9 42}     {0041 00e9 0042}     2  3}
            {nonbmp {41 f09f9880 42} {0041 d83d de00 0042} 4  3}
            {split-surrogate {41 f09f9080 42} {0041 d83d dc00 0042} 3  4}
            {null   {41 c080 42} {0041 0000 0042}  2 3}
        }
        utf-32le {
            {bmp    {41 c3a9 42}     {41000000 e9000000 42000000}     2  3}
            {nonbmp {41 f09f9880 42} {41000000 00f60100 42000000} 4  6}
            {null   {41 c080 42} {41000000 00000000 42000000}  2 3}
        }
        utf-32be {
            {bmp    {41 c3a9 42}     {00000041 000000e9 00000042}     2  3}
            {nonbmp {41 f09f9880 42} {00000041 0001f600 00000042} 4  3}
            {null   {41 c080 42} {00000041 00000000 00000042}  2 3}
        }
        iso8859-1 {
            {basic {41 c3a9 42} {41 e9 42} 2 -1}
            {null  {41 c080 42} {41 00 42} 2 -1}
        }
        iso8859-3 {
            {basic {41 c4a0 42} {41 d5 42} 2 -1}
            {null  {41 c080 42} {41 00 42} 2 -1}
        }
        shiftjis {
            {basic {41 e4b98e 42} {41 8cc1 42} 3 2}
        }
        jis0208 {
            {basic {e4b98e e590be} {3843 3863} 1 1}
        }
        iso2022-jp {
            {frag-in-leadescape {58 e4b98e 5a} {58 1b2442 3843 1b2842 5a} 2 2}
            {frag-in-char {58 e4b98e 5a} {58 1b2442 3843 1b2842 5a} 2 5}
            {frag-in-trailescape {58 e4b98e 5a} {58 1b2442 3843 1b2842 5a} 2 8}
        }
    }

    # Return a binary string containing nul terminator for encoding
    proc hexnuls {enc} {
        return [binary encode hex [encoding convertto $enc \x00]]
    }

    # The C wrapper fills entire destination buffer with FF.
    # Anything beyond expected output should have FF's
    proc fill {bin buflen} {
        return [string range "$bin[string repeat \xFF $buflen]" 0 $buflen-1]
    }

    proc testutf {direction enc comment hexin hexout args} {
        set id $comment-[join $hexin ""]
        if {$direction eq "toutf"} {
            set cmd Tcl_ExternalToUtf
        } else {
            set cmd Tcl_UtfToExternal
        }
        set in [binary decode hex $hexin]
        set out [binary decode hex $hexout]
        set dstlen 40 ;# Should be enough for all encoding tests

        set status ok
        set flags [list start end]
        set constraints [list testencoding]
        set profiles [encoding profiles]
        while {[llength $args] > 1} {
            set opt [lpop args 0]
            switch $opt {
                -flags       { set flags [lpop args 0] }
                -constraints { lappend constraints {*}[lpop args 0] }
                -profiles    { set profiles [lpop args 0] }
                -status      { set status [lpop args 0]}
                default {
                    error "Unknown option \"$opt\""
                }
            }
        }
        if {[llength $args]} {
            error "No value supplied for option [lindex $args 0]."
        }

        set result [list $status {} [fill $out $dstlen]]

        test $cmd-$enc-$id-[join $flags -] "$cmd - $enc - $hexin - $flags" -body \
            [list testencoding $cmd $enc $in $flags {} $dstlen] \
            -result $result -constraints $constraints
        foreach profile $profiles {
            set flags2 [linsert $flags end $profile]
            test $cmd-$enc-$id-[join $flags2 -] "$cmd - $enc - $hexin - $flags2" -body \
                [list testencoding $cmd $enc $in $flags2 {} $dstlen] \
                -result $result -constraints $constraints
        }
    }

    proc testfragment {direction enc comment hexin hexout fragindex args} {

        if {$fragindex < 0} {
            # Single byte encodings so no question of fragmentation
            return
        }
        set id $comment-[join $hexin ""]-fragment

        if {$direction eq "toutf"} {
            set cmd Tcl_ExternalToUtf
        } else {
            set cmd Tcl_UtfToExternal
        }

        set status1 multibyte; # Return status to expect after first call
        while {[llength $args] > 1} {
            set opt [lpop args 0]
            switch $opt {
                -status1  { set status1 [lpop args 0]}
                default {
                    error "Unknown option \"$opt\""
                }
            }
        }

        set in [binary decode hex $hexin]
        set infrag [string range $in 0 $fragindex-1]
        set out [binary decode hex $hexout]
        set dstlen 40 ;# Should be enough for all encoding tests

        test $cmd-$enc-$id "$cmd - $enc - $hexin - frag" -constraints testencoding -body {
            set frag1Result [testencoding $cmd $enc [string range $in 0 $fragindex-1] {start} 0 $dstlen frag1Read frag1Written]
            lassign $frag1Result frag1Status frag1State frag1Decoded
            set frag2Result [testencoding $cmd $enc [string range $in $frag1Read end] {end} $frag1State $dstlen frag2Read frag2Written]
            lassign $frag2Result frag2Status frag2State frag2Decoded
            set decoded [string cat [string range $frag1Decoded 0 $frag1Written-1] [string range $frag2Decoded 0 $frag2Written-1]]
            list $frag1Status [expr {$frag1Read <= $fragindex}] \
                $frag2Status [expr {$frag1Read+$frag2Read}] \
                [expr {$frag1Written+$frag2Written}] $decoded
        } -result [list $status1 1 ok [string length $in] [string length $out] $out]
    }

    proc testcharlimit {direction enc comment hexin hexout} {
        set id $comment-[join $hexin ""]-charlimit

        if {$direction eq "toutf"} {
            set cmd Tcl_ExternalToUtf
        } else {
            set cmd Tcl_UtfToExternal
        }

        set maxchars [llength $hexout]
        set in [binary decode hex $hexin]
        set out [binary decode hex $hexout]
        set dstlen 40 ;# Should be enough for all encoding tests

        for {set nchars 0} {$nchars <= $maxchars} {incr nchars} {
            set expected_bytes [binary decode hex [lrange $hexout 0 $nchars-1]]
            set expected_nwritten [string length $expected_bytes]
            test $cmd-$enc-$id-$nchars "$cmd - $enc - $hexin - nchars $nchars" -constraints testencoding -body {
                set charlimit $nchars
                lassign [testencoding $cmd $enc $in \
                             {start end charlimit} 0 $dstlen nread nwritten charlimit] \
                    status state buf
                list $status $nwritten [string range $buf 0 $nwritten-1]
            } -result [list [expr {$nchars == $maxchars ? "ok" : "nospace"}] $expected_nwritten $expected_bytes]
        }
    }
















































    #
    # Basic tests
    foreach {enc testcases} $utfExtMap {
        foreach testcase $testcases {
            lassign $testcase {*}{comment utfhex hex internalfragindex externalfragindex}

            # Basic test - TCL_ENCODING_START|TCL_ENCODING_END
            # Note by default output should be terminated with \0
            set encnuls [hexnuls $enc]
            testutf toutf $enc $comment $hex ${utfhex}00
            testutf fromutf $enc $comment $utfhex $hex$encnuls

            # Test TCL_ENCODING_NO_TERMINATE
            testutf toutf $enc $comment $hex $utfhex -flags {start end noterminate}
            # noterminate is specific to ExternalToUtf,
            # should have no effect in other direction
            testutf fromutf $enc $comment $utfhex $hex$encnuls -flags {start end noterminate}

            # Fragments
            testfragment toutf $enc $comment $hex $utfhex $externalfragindex
            testfragment fromutf $enc $comment $utfhex $hex $internalfragindex

            # Char limits - note no fromutf as Tcl_UtfToExternal does not support it
            testcharlimit toutf $enc $comment $hex $utfhex
        }



    }



    # Special cases - cesu2 high and low surrogates in separate fragments
    # This will (correctly) return "ok", not "multibyte" after first frag
    testfragment toutf cesu-8 nonbmp-split-surr \
        {41 eda0bd edb880 42} {41 f09f9880 42} 4 -status1 ok

    # Bug regression tests
    test Tcl_UtfToExternal-bug-183a1adcc0 {buffer overflow} -body {
        testencoding Tcl_UtfToExternal utf-16 A {start end} {} 1
    } -result [list nospace {} \xFF] -constraints testencoding

    test Tcl_ExternalToUtf-bug-5be203d6ca {
        truncated prefix in table encoding
    } -body {
        set src \x82\x4F\x82\x50\x82
        set result [list [testencoding Tcl_ExternalToUtf shiftjis $src {start tcl8} 0 16 srcRead dstWritten charsWritten] $srcRead $dstWritten $charsWritten]
        lappend result {*}[list [testencoding Tcl_ExternalToUtf shiftjis [string range $src $srcRead end] {end tcl8} 0 10 srcRead dstWritten charsWritten] $srcRead $dstWritten $charsWritten]
    } -result [list [list multibyte 0 \xEF\xBC\x90\xEF\xBC\x91\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF] 4 6 2 [list ok 0 \xC2\x82\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF] 1 2 1] -constraints testencoding
}

namespace delete utftest

::tcltest::cleanupTests
return







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|




|





|



|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|

|
|
|
|
|
|
|
|
|




|
|
|
|
|

|
|
|
|
|

|
|
|
|
|
|
|
|
|
|

|
|
|
|

|
|
|
|
|
|
|
|
|
|



|

|
|
|
|
|

|
|
|
|

|
|
|
|
|
|
|
|
|
|
|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|
|

|
|
|
|
|

|
|
|
|
|

|
|
|

|
|
|
>
>
>
|
|
>
>



|



|



|

|
|
|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
    #   tests. -1 to skip
    # 4 external fragmentation index - where to split field 2 for fragmentation
    #   tests. -1 to skip
    #
    # THE HEX DEFINITIONS SHOULD SEPARATE EACH CHARACTER BY WHITESPACE
    # (assumed by the charlimit tests)
    lappend utfExtMap {*}{
	ascii {
	    {basic {41 42 43} {41 42 43} -1 -1}
	}
	utf-8 {
	    {bmp    {41 c3a9 42}     {41 c3a9 42}      2  2}
	    {nonbmp-frag-1 {41 f09f9880 42} {41 f09f9880 42}  2  2}
	    {nonbmp-frag-2 {41 f09f9880 42} {41 f09f9880 42}  3  3}
	    {nonbmp-frag-3 {41 f09f9880 42} {41 f09f9880 42}  4  4}
	    {null   {41 c080 42} {41 00 42}    2 -1}
	}
	cesu-8 {
	    {bmp    {41 c3a9 42}     {41 c3a9 42}      2  2}
	    {nonbmp-frag-surr-low {41 f09f9880 42} {41 eda0bd edb880 42} 2 2}
	    {nonbmp-split-surr {41 f09f9880 42} {41 eda0bd edb880 42} 3 -1}
	    {nonbmp-frag-surr-high {41 f09f9880 42} {41 eda0bd edb880 42} 4 6}
	    {null   {41 c080 42} {41 00 42}    2 -1}
	}
	utf-16le {
	    {bmp    {41 c3a9 42}     {4100 e900 4200}     2  3}
	    {nonbmp {41 f09f9880 42} {4100 3dd8 00de 4200} 4  3}
	    {split-surrogate {41 f09f9080 42} {4100 3dd8 00dc 4200} 3  4}
	    {null   {41 c080 42} {4100 0000 4200}  2 3}
	}
	utf-16be {
	    {bmp    {41 c3a9 42}     {0041 00e9 0042}     2  3}
	    {nonbmp {41 f09f9880 42} {0041 d83d de00 0042} 4  3}
	    {split-surrogate {41 f09f9080 42} {0041 d83d dc00 0042} 3  4}
	    {null   {41 c080 42} {0041 0000 0042}  2 3}
	}
	utf-32le {
	    {bmp    {41 c3a9 42}     {41000000 e9000000 42000000}     2  3}
	    {nonbmp {41 f09f9880 42} {41000000 00f60100 42000000} 4  6}
	    {null   {41 c080 42} {41000000 00000000 42000000}  2 3}
	}
	utf-32be {
	    {bmp    {41 c3a9 42}     {00000041 000000e9 00000042}     2  3}
	    {nonbmp {41 f09f9880 42} {00000041 0001f600 00000042} 4  3}
	    {null   {41 c080 42} {00000041 00000000 00000042}  2 3}
	}
	iso8859-1 {
	    {basic {41 c3a9 42} {41 e9 42} 2 -1}
	    {null  {41 c080 42} {41 00 42} 2 -1}
	}
	iso8859-3 {
	    {basic {41 c4a0 42} {41 d5 42} 2 -1}
	    {null  {41 c080 42} {41 00 42} 2 -1}
	}
	shiftjis {
	    {basic {41 e4b98e 42} {41 8cc1 42} 3 2}
	}
	jis0208 {
	    {basic {e4b98e e590be} {3843 3863} 1 1}
	}
	iso2022-jp {
	    {frag-in-leadescape {58 e4b98e 5a} {58 1b2442 3843 1b2842 5a} 2 2}
	    {frag-in-char {58 e4b98e 5a} {58 1b2442 3843 1b2842 5a} 2 5}
	    {frag-in-trailescape {58 e4b98e 5a} {58 1b2442 3843 1b2842 5a} 2 8}
	}
    }

    # Return a binary string containing nul terminator for encoding
    proc hexnuls {enc} {
	return [binary encode hex [encoding convertto $enc \x00]]
    }

    # The C wrapper fills entire destination buffer with FF.
    # Anything beyond expected output should have FF's
    proc fill {bin buflen} {
	return [string range "$bin[string repeat \xFF $buflen]" 0 $buflen-1]
    }

    proc testutf {direction enc comment hexin hexout args} {
	set id $comment-[join $hexin ""]
	if {$direction eq "toutf"} {
	    set cmd Tcl_ExternalToUtf
	} else {
	    set cmd Tcl_UtfToExternal
	}
	set in [binary decode hex $hexin]
	set out [binary decode hex $hexout]
	set dstlen 40 ;# Should be enough for all encoding tests

	set status ok
	set flags [list start end]
	set constraints [list testencoding]
	set profiles [encoding profiles]
	while {[llength $args] > 1} {
	    set opt [lpop args 0]
	    switch $opt {
		-flags       { set flags [lpop args 0] }
		-constraints { lappend constraints {*}[lpop args 0] }
		-profiles    { set profiles [lpop args 0] }
		-status      { set status [lpop args 0]}
		default {
		    error "Unknown option \"$opt\""
		}
	    }
	}
	if {[llength $args]} {
	    error "No value supplied for option [lindex $args 0]."
	}

	set result [list $status {} [fill $out $dstlen]]

	test $cmd-$enc-$id-[join $flags -] "$cmd - $enc - $hexin - $flags" -body \
	    [list testencoding $cmd $enc $in $flags {} $dstlen] \
	    -result $result -constraints $constraints
	foreach profile $profiles {
	    set flags2 [linsert $flags end $profile]
	    test $cmd-$enc-$id-[join $flags2 -] "$cmd - $enc - $hexin - $flags2" -body \
		[list testencoding $cmd $enc $in $flags2 {} $dstlen] \
		-result $result -constraints $constraints
	}
    }

    proc testfragment {direction enc comment hexin hexout fragindex args} {

	if {$fragindex < 0} {
	    # Single byte encodings so no question of fragmentation
	    return
	}
	set id $comment-[join $hexin ""]-fragment

	if {$direction eq "toutf"} {
	    set cmd Tcl_ExternalToUtf
	} else {
	    set cmd Tcl_UtfToExternal
	}

	set status1 multibyte; # Return status to expect after first call
	while {[llength $args] > 1} {
	    set opt [lpop args 0]
	    switch $opt {
		-status1  { set status1 [lpop args 0]}
		default {
		    error "Unknown option \"$opt\""
		}
	    }
	}

	set in [binary decode hex $hexin]
	set infrag [string range $in 0 $fragindex-1]
	set out [binary decode hex $hexout]
	set dstlen 40 ;# Should be enough for all encoding tests

	test $cmd-$enc-$id "$cmd - $enc - $hexin - frag" -constraints testencoding -body {
	    set frag1Result [testencoding $cmd $enc [string range $in 0 $fragindex-1] {start} 0 $dstlen frag1Read frag1Written]
	    lassign $frag1Result frag1Status frag1State frag1Decoded
	    set frag2Result [testencoding $cmd $enc [string range $in $frag1Read end] {end} $frag1State $dstlen frag2Read frag2Written]
	    lassign $frag2Result frag2Status frag2State frag2Decoded
	    set decoded [string cat [string range $frag1Decoded 0 $frag1Written-1] [string range $frag2Decoded 0 $frag2Written-1]]
	    list $frag1Status [expr {$frag1Read <= $fragindex}] \
		$frag2Status [expr {$frag1Read+$frag2Read}] \
		[expr {$frag1Written+$frag2Written}] $decoded
	} -result [list $status1 1 ok [string length $in] [string length $out] $out]
    }

    proc testcharlimit {direction enc comment hexin hexout} {
	set id $comment-[join $hexin ""]-charlimit

	if {$direction eq "toutf"} {
	    set cmd Tcl_ExternalToUtf
	} else {
	    set cmd Tcl_UtfToExternal
	}

	set maxchars [llength $hexout]
	set in [binary decode hex $hexin]
	set out [binary decode hex $hexout]
	set dstlen 40 ;# Should be enough for all encoding tests

	for {set nchars 0} {$nchars <= $maxchars} {incr nchars} {
	    set expected_bytes [binary decode hex [lrange $hexout 0 $nchars-1]]
	    set expected_nwritten [string length $expected_bytes]
	    test $cmd-$enc-$id-$nchars "$cmd - $enc - $hexin - nchars $nchars" -constraints testencoding -body {
		set charlimit $nchars
		lassign [testencoding $cmd $enc $in \
			     {start end charlimit} 0 $dstlen nread nwritten charlimit] \
		    status state buf
		list $status $nwritten [string range $buf 0 $nwritten-1]
	    } -result [list [expr {$nchars == $maxchars ? "ok" : "nospace"}] $expected_nwritten $expected_bytes]
	}
    }

    proc testspacelimit {direction enc comment hexin hexout} {
	set id $comment-[join $hexin ""]-spacelimit

        # Triple the input to avoid pathological short input case where
        # whereby nothing is written to output. The test below
        # requires $nchars > 0
        set hexin $hexin$hexin$hexin
        set hexout $hexout$hexout$hexout

	set flags [list start end]
	set constraints [list testencoding]

	set maxchars [llength $hexout]
	set in [binary decode hex $hexin]
	set out [binary decode hex $hexout]
	set dstlen [expr {[string length $out] - 1}]; # Smaller buffer than needed

	if {$direction eq "toutf"} {
	    set cmd Tcl_ExternalToUtf
            set str [encoding convertfrom $enc $in]
	} else {
	    set cmd Tcl_UtfToExternal
            set str [encoding convertfrom $enc $out]
	}

        # Note the tests are loose because the some encoding operations will
        # stop even there is actually still room in the destination. For example,
        # below only one char is written though there is room in the output.
        # % testencoding Tcl_ExternalToUtf ascii abc {start end} {} 5 nread nwritten nchars
        # nospace {} aÿÿÿ#
        # % puts $nread,$nwritten,$nchars
        # 1,1,1
        #

	test $cmd-$enc-$id-[join $flags -] "$cmd - $enc - $hexin - $flags" \
            -constraints $constraints \
            -body {
            lassign [testencoding $cmd $enc $in $flags {} $dstlen nread nwritten nchars] status state buf
            list \
                $status \
                [expr {$nread < [string length $in]}] \
                [expr {$nwritten <= $dstlen}] \
                [expr {$nchars > 0 && $nchars < [string length $str]}] \
                [expr {[string range $out 0 $nwritten-1] eq [string range $buf 0 $nwritten-1]}]
            } -result {nospace 1 1 1 1}
    }

    #
    # Basic tests
    foreach {enc testcases} $utfExtMap {
	foreach testcase $testcases {
	    lassign $testcase {*}{comment utfhex hex internalfragindex externalfragindex}

	    # Basic test - TCL_ENCODING_START|TCL_ENCODING_END
	    # Note by default output should be terminated with \0
	    set encnuls [hexnuls $enc]
	    testutf toutf $enc $comment $hex ${utfhex}00
	    testutf fromutf $enc $comment $utfhex $hex$encnuls

	    # Test TCL_ENCODING_NO_TERMINATE
	    testutf toutf $enc $comment $hex $utfhex -flags {start end noterminate}
	    # noterminate is specific to ExternalToUtf,
	    # should have no effect in other direction
	    testutf fromutf $enc $comment $utfhex $hex$encnuls -flags {start end noterminate}

	    # Fragments
	    testfragment toutf $enc $comment $hex $utfhex $externalfragindex
	    testfragment fromutf $enc $comment $utfhex $hex $internalfragindex

	    # Char limits - note no fromutf as Tcl_UtfToExternal does not support it
	    testcharlimit toutf $enc $comment $hex $utfhex

            # Space limits
            testspacelimit toutf $enc $comment $hex $utfhex
            testspacelimit fromutf $enc $comment $utfhex $hex
	}
    }


    # Special cases - cesu2 high and low surrogates in separate fragments
    # This will (correctly) return "ok", not "multibyte" after first frag
    testfragment toutf cesu-8 nonbmp-split-surr \
	{41 eda0bd edb880 42} {41 f09f9880 42} 4 -status1 ok

    # Bug regression tests
    test Tcl_UtfToExternal-bug-183a1adcc0 {buffer overflow} -body {
	testencoding Tcl_UtfToExternal utf-16 A {start end} {} 1
    } -result [list nospace {} \xFF] -constraints testencoding

    test Tcl_ExternalToUtf-bug-5be203d6ca {
	truncated prefix in table encoding
    } -body {
	set src \x82\x4F\x82\x50\x82
	set result [list [testencoding Tcl_ExternalToUtf shiftjis $src {start tcl8} 0 16 srcRead dstWritten charsWritten] $srcRead $dstWritten $charsWritten]
	lappend result {*}[list [testencoding Tcl_ExternalToUtf shiftjis [string range $src $srcRead end] {end tcl8} 0 10 srcRead dstWritten charsWritten] $srcRead $dstWritten $charsWritten]
    } -result [list [list multibyte 0 \xEF\xBC\x90\xEF\xBC\x91\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF] 4 6 2 [list ok 0 \xC2\x82\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF] 1 2 1] -constraints testencoding
}

namespace delete utftest

::tcltest::cleanupTests
return
Changes to tests/util.test.
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
    lassign [testdoubledigits $double [string length $digits1] e] \
	outdigits decpt outsign
    if {[string index $digits2 0] >= 5} {
	incr digits1
    }
    if {$outsign != $signum || $outdigits != $digits1 || $decpt != $decexp} {
	return -code error "result is ${outsign}0.${outdigits}E$decpt\
                            should be ${signum}0.${digits1}E$decexp"
    }
}

test util-1.1 {TclFindElement procedure - binary element in middle of list} {
    lindex {0 foo\x00help 1} 1
} "foo\x00help"
test util-1.2 {TclFindElement procedure - binary element at end of list} {







|







116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
    lassign [testdoubledigits $double [string length $digits1] e] \
	outdigits decpt outsign
    if {[string index $digits2 0] >= 5} {
	incr digits1
    }
    if {$outsign != $signum || $outdigits != $digits1 || $decpt != $decexp} {
	return -code error "result is ${outsign}0.${outdigits}E$decpt\
			    should be ${signum}0.${digits1}E$decexp"
    }
}

test util-1.1 {TclFindElement procedure - binary element in middle of list} {
    lindex {0 foo\x00help 1} 1
} "foo\x00help"
test util-1.2 {TclFindElement procedure - binary element at end of list} {
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
} {0 0 -}

# Verdonk test vectors

test util-13.1 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1754e31cd072da E+1008 +4_000000000000000000& E+303
    }
    -result {}
}
test util-13.2 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1afcef51f0fb5f E+265 -1_000000000000000000& E+80
    }
    -result {}
}
test util-13.3 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1754e31cd072da E+1006 +1_000000000000000000& E+303
    }
    -result {}
}
test util-13.4 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1754e31cd072da E+1007 -2_000000000000000000& E+303
    }
    -result {}
}
test util-13.5 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1e07b27dd78b14 E-848 +1_00000000000000000& E-255
    }
    -result {}
}
test util-13.6 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1e29e9c56687fe E-709 -7_00000000000000000& E-214
    }
    -result {}
}
test util-13.7 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1be03d0bf225c7 E-137 +1_00000000000000000& E-41
    }
    -result {}
}
test util-13.8 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1a2fe76a3f9475 E-499 -1_00000000000000000& E-150
    }
    -result {}
}
test util-13.9 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 19a2028368022e E+1019 +8_999999999999999999& E+306
    }
    -result {}
}
test util-13.10 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1317e5ef3ab327 E+509 -1_999999999999999999& E+153
    }
    -result {}
}
test util-13.11 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1317e5ef3ab327 E+510 +3_99999999999999999& E+153
    }
    -result {}
}
test util-13.12 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1317e5ef3ab327 E+511 -7_99999999999999999& E+153
    }
    -result {}
}
test util-13.13 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1eb8e84fa0b278 E-1008 +6_999999999999999999& E-304
    }
    -result {}
}
test util-13.14 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -13339131c46f8b E-1004 -6_999999999999999999& E-303
    }
    -result {}
}
test util-13.15 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1c0f92a6276c9d E-162 +2_999999999999999999& E-49
    }
    -result {}
}
test util-13.16 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -15ce1f143d7ad2 E-443 -5_99999999999999999& E-134
    }
    -result {}
}
test util-13.17 {just over exact - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1c0794d9d40e96 E-301 +43_000000000000000000& E-92
    }
    -result {}
}
test util-13.18 {just over exact - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1c0794d9d40e96 E-300 -86_000000000000000000& E-92
    }
    -result {}
}
test util-13.19 {just over exact - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1cd5bee57763e6 E-241 +51_000000000000000000& E-74
    }
    -result {}
}
test util-13.20 {just under exact - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1d1c26db7d0dae E+651 +16_999999999999999999& E+195
    }
    -result {}
}
test util-13.21 {just under exact - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -13f7ced916872b E-5 -38_999999999999999999& E-3
    }
    -result {}
}
test util-13.22 {just over exact - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 17d93193f78fc6 E+588 +151_0000000000000000000& E+175
    }
    -result {}
}
test util-13.23 {just over exact - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1a82a1631eeb30 E-625 -119_000000000000000000& E-190
    }
    -result {}
}
test util-13.24 {just under exact - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -16c309024bab4b E+290 -282_999999999999999999& E+85
    }
    -result {}
}
test util-13.25 {just over exact - 8 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1dbbac6f83a821 E-800 +27869147_0000000000000000000& E-248
    }
    -result {}
}
test util-13.26 {just under exact - 9 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1c569e968e0944 E+430 -491080653_9999999999999999999& E+121
    }
    -result {}
}
test util-13.27 {just under exact - 9 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1c569e968e0944 E+429 +245540326_9999999999999999999& E+121
    }
    -result {}
}
test util-13.28 {just over exact - 10 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1fc575867314ee E-330 -9078555839_0000000000000000000& E-109
    }
    -result {}
}
test util-13.29 {just under exact - 10 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1c569e968e0944 E+428 -1227701634_9999999999999999999& E+120
    }
    -result {}
}
test util-13.30 {just over exact - 11 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1fc575867314ee E-329 +18157111678_0000000000000000000& E-109
    }
    -result {}
}
test util-13.31 {just over exact - 14 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -18bf7e7fa6f02a E-196 -15400733123779_0000000000000000000& E-72
    }
    -result {}
}
test util-13.32 {just over exact - 17 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -13de005bd620df E+217 -26153245263757307_0000000000000000000& E+49
    }
    -result {}
}
test util-13.33 {just over exact - 18 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1f92bacb3cb40c E+718 +272104041512242479_0000000000000000000& E+199
    }
    -result {}
}
test util-13.34 {just over exact - 18 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1f92bacb3cb40c E+719 -544208083024484958_0000000000000000000& E+199
    }
    -result {}
}
test util-13.35 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 142dbf25096cf5 E+148 +4_500000000000000000& E+44
    }
    -result {}
}
test util-13.36 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1afcef51f0fb5f E+263 -2_500000000000000000& E+79
    }
    -result {}
}
test util-13.37 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 102498ea6df0c4 E+145 +4_500000000000000000& E+43
    }
    -result {}
}
test util-13.38 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1754e31cd072da E+1004 -2_500000000000000000& E+302
    }
    -result {}
}
test util-13.39 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 12deac01e2b4f7 E-557 +2_50000000000000000& E-168
    }
    -result {}
}
test util-13.40 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1b1df536c13eee E-307 -6_50000000000000000& E-93
    }
    -result {}
}
test util-13.41 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 10711fed5b19a4 E-154 +4_50000000000000000& E-47
    }
    -result {}
}
test util-13.42 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -148d67e8b1e00d E-151 -4_50000000000000000& E-46
    }
    -result {}
}
test util-13.43 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1c8c574c0c6be7 E+187 +3_49999999999999999& E+56
    }
    -result {}
}
test util-13.44 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1756183c147514 E+206 -1_49999999999999999& E+62
    }
    -result {}
}
test util-13.45 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 12ab469676c410 E+203 +1_49999999999999999& E+61
    }
    -result {}
}
test util-13.46 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1539684e774b48 E+246 -1_49999999999999999& E+74
    }
    -result {}
}
test util-13.47 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 12e5f5dfa4fe9d E-286 +9_499999999999999999& E-87
    }
    -result {}
}
test util-13.48 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1bdc2417bf7787 E-838 -9_499999999999999999& E-253
    }
    -result {}
}
test util-13.49 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1eb8e84fa0b278 E-1009 +3_499999999999999999& E-304
    }
    -result {}
}
test util-13.50 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1e3cbc9907fdc8 E-290 -9_499999999999999999& E-88
    }
    -result {}
}
test util-13.51 {just over half ulp - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 10ad836f269a17 E-324 +30_500000000000000000& E-99
    }
    -result {}
}
test util-13.52 {just over half ulp - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1b39ae1909c31b E-687 -26_500000000000000000& E-208
    }
    -result {}
}
test util-13.53 {just over half ulp - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1b2ab18615fcc6 E-576 +686_500000000000000000& E-176
    }
    -result {}
}
test util-13.54 {just over half ulp - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -13e1f90a573064 E-624 -178_500000000000000000& E-190
    }
    -result {}
}
test util-13.55 {just under half ulp - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 16c309024bab4b E+289 +141_499999999999999999& E+85
    }
    -result {}
}
test util-13.56 {just under half ulp - 4 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -159bd3ad46e346 E+193 -1695_499999999999999999& E+55
    }
    -result {}
}
test util-13.57 {just under half ulp - 4 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1df4170f0fdecc E+124 +3981_499999999999999999& E+34
    }
    -result {}
}
test util-13.58 {just over half ulp - 6 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 17e1e0f1c7a4ac E+415 +126300_5000000000000000000& E+120
    }
    -result {}
}
test util-13.59 {just over half ulp - 6 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1dda592e398dd7 E+418 -126300_5000000000000000000& E+121
    }
    -result {}
}
test util-13.60 {just under half ulp - 7 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1e597c0b94b7ae E+453 -4411845_499999999999999999& E+130
    }
    -result {}
}
test util-13.61 {just under half ulp - 9 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1c569e968e0944 E+427 +613850817_4999999999999999999& E+120
    }
    -result {}
}
test util-13.62 {just under half ulp - 9 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1c569e968e0944 E+428 -122770163_49999999999999999999& E+121
    }
    -result {}
}
test util-13.63 {just over half ulp - 18 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 17ae0c186d8709 E+719 +408156062268363718_5000000000000000000& E+199
    }
    -result {}
}
test util-13.64 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 152d02c7e14af7 E+76 +1_0000000000000000& E+23
    }
    -result {}
}
test util-13.65 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -19d971e4fe8402 E+89 -1_0000000000000000& E+27
    }
    -result {}
}
test util-13.66 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 19d971e4fe8402 E+90 +2_0000000000000000& E+27
    }
    -result {}
}
test util-13.67 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -19d971e4fe8402 E+91 -4_0000000000000000& E+27
    }
    -result {}
}
test util-13.68 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 15798ee2308c3a E-27 +1_0000000000000000& E-8
    }
    -result {}
}
test util-13.69 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -15798ee2308c3a E-26 -2_0000000000000000& E-8
    }
    -result {}
}
test util-13.70 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 15798ee2308c3a E-25 +4_0000000000000000& E-8
    }
    -result {}
}
test util-13.71 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1ef2d0f5da7dd9 E-84 -1_0000000000000000& E-25
    }
    -result {}
}
test util-13.72 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1a784379d99db4 E+78 +4_9999999999999999& E+23
    }
    -result {}
}
test util-13.73 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1a784379d99db4 E+80 -1_9999999999999999& E+24
    }
    -result {}
}
test util-13.74 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 13da329b633647 E+81 +2_9999999999999999& E+24
    }
    -result {}
}
test util-13.75 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1cf389cd46047d E+85 -6_9999999999999999& E+25
    }
    -result {}
}
test util-13.76 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 19999999999999 E-3 +1_99999999999999999& E-1
    }
    -result {}
}
test util-13.77 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -13333333333333 E-2 -2_99999999999999999& E-1
    }
    -result {}
}
test util-13.78 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 16849b86a12b9b E-48 +4_99999999999999999& E-15
    }
    -result {}
}
test util-13.79 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -16849b86a12b9b E-46 -1_99999999999999999& E-14
    }
    -result {}
}
test util-13.80 {just over exact - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 17ccfc73126788 E-71 +63_00000000000000000& E-23
    }
    -result {}
}
test util-13.81 {just over exact - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1dc03b8fd7016a E-68 -63_00000000000000000& E-22
    }
    -result {}
}
test util-13.82 {just under exact - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 13f7ced916872b E-5 +38_999999999999999999& E-3
    }
    -result {}
}
test util-13.83 {just over exact - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1b297cad9f70b6 E+97 +269_000000000000000000& E+27
    }
    -result {}
}
test util-13.84 {just over exact - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1b297cad9f70b6 E+98 -538_00000000000000000& E+27
    }
    -result {}
}
test util-13.85 {just over exact - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1cdc06b20ef183 E-82 +373_00000000000000000& E-27
    }
    -result {}
}
test util-13.86 {just over exact - 4 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1b297cad9f70b6 E+96 +1345_00000000000000000& E+26
    }
    -result {}
}
# this one is not 4 digits, it is 3, and it is covered above.
test util-13.87 {just over exact - 4 digits} {*}{
    -constraints {testdoubledigits knownBadTest}
    -body {
        verdonk_test -1b297cad9f70b6 E+97 -2690_00000000000000000& E+26
    }
    -result {}
}
test util-13.88 {just over exact - 5 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -150a246ecd44f3 E-63 -14257_00000000000000000& E-23
    }
    -result {}
}
test util-13.89 {just under exact - 6 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -119b96f36ec68b E-19 -209900_999999999999999999& E-11
    }
    -result {}
}
test util-13.90 {just over exact - 11 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1c06d366394441 E-35 +50980203373_000000000000000000& E-21
    }
    -result {}
}
test util-13.91 {just under exact - 12 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1f58ac4db68c90 E+122 -104166211810_99999999999999999& E+26
    }
    -result {}
}
test util-13.92 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 19d971e4fe8402 E+87 +2_5000000000000000& E+26
    }
    -result {}
}
test util-13.93 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1dc74be914d16b E+81 -4_500000000000000& E+24
    }
    -result {}
}
test util-13.94 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 14adf4b7320335 E+84 +2_500000000000000& E+25
    }
    -result {}
}
test util-13.95 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1ae22487c1042b E+85 -6_5000000000000000& E+25
    }
    -result {}
}
test util-13.96 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 187fe49aab41e0 E-54 +8_5000000000000000& E-17
    }
    -result {}
}
test util-13.97 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1f5c05e4b23fd7 E-61 -8_5000000000000000& E-19
    }
    -result {}
}
test util-13.98 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1faa7ab552a552 E-42 +4_5000000000000000& E-13
    }
    -result {}
}
test util-13.99 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1b7cdfd9d7bdbb E-36 -2_5000000000000000& E-11
    }
    -result {}
}
test util-13.100 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 13da329b633647 E+80 +1_4999999999999999& E+24
    }
    -result {}
}
test util-13.101 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1cf389cd46047d E+84 -3_49999999999999999& E+25
    }
    -result {}
}
test util-13.102 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1f04ef12cb04cf E+85 +7_4999999999999999& E+25
    }
    -result {}
}
test util-13.103 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1f04ef12cb04cf E+86 -1_4999999999999999& E+26
    }
    -result {}
}
test util-13.104 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 13333333333333 E-3 +1_49999999999999999& E-1
    }
    -result {}
}
test util-13.105 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -107e1fe91b0b70 E-36 -1_49999999999999999& E-11
    }
    -result {}
}
test util-13.106 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 149da7e361ce4c E-33 +1_49999999999999999& E-10
    }
    -result {}
}
test util-13.107 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -19c511dc3a41df E-30 -1_49999999999999999& E-9
    }
    -result {}
}
test util-13.108 {just over half ulp - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1aa83d74267822 E+93 -16_5000000000000000& E+27
    }
    -result {}
}
test util-13.109 {just over half ulp - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 18f1d5969453de E+89 +96_5000000000000000& E+25
    }
    -result {}
}
test util-13.110 {just over half ulp - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 11d9bd564dcda6 E-70 +94_50000000000000000& E-23
    }
    -result {}
}
test util-13.111 {just over half ulp - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1a58973ecbede6 E-48 -58_50000000000000000& E-16
    }
    -result {}
}
test util-13.112 {just over half ulp - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1b297cad9f70b6 E+95 +672_50000000000000000& E+26
    }
    -result {}
}
test util-13.113 {just over half ulp - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -1b297cad9f70b6 E+96 -134_500000000000000000& E+27
    }
    -result {}
}
test util-13.114 {just over half ulp - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1cdc06b20ef183 E-83 +186_50000000000000000& E-27
    }
    -result {}
}
test util-13.115 {just over half ulp - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -136071dcae4565 E-47 -860_50000000000000000& E-17
    }
    -result {}
}
test util-13.116 {just over half ulp - 6 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1cb968d297dde8 E+99 +113788_50000000000000000& E+25
    }
    -result {}
}
test util-13.117 {just over half ulp - 6 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test -11f3e1839eeab1 E+103 -113788_50000000000000000& E+26
    }
    -result {}
}
test util-13.118 {just under half ulp - 9 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1e9cec176c96f8 E+117 +317903333_49999999999999999& E+27
    }
    -result {}
}
test util-13.119 {just over half ulp - 11 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1c06d366394441 E-36 +25490101686_500000000000000000& E-21
    }
    -result {}
}
test util-13.120 {just under half ulp - 11 digits} {*}{
    -constraints testdoubledigits
    -body {
        verdonk_test 1f58ac4db68c90 E+121 +52083105905_49999999999999999& E+26
    }
    -result {}
}

test util-14.1 {funky NaN} {*}{
    -constraints {ieeeFloatingPoint controversialNaN}
    -body {







|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|







|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|






|







1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
} {0 0 -}

# Verdonk test vectors

test util-13.1 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1754e31cd072da E+1008 +4_000000000000000000& E+303
    }
    -result {}
}
test util-13.2 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1afcef51f0fb5f E+265 -1_000000000000000000& E+80
    }
    -result {}
}
test util-13.3 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1754e31cd072da E+1006 +1_000000000000000000& E+303
    }
    -result {}
}
test util-13.4 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1754e31cd072da E+1007 -2_000000000000000000& E+303
    }
    -result {}
}
test util-13.5 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1e07b27dd78b14 E-848 +1_00000000000000000& E-255
    }
    -result {}
}
test util-13.6 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1e29e9c56687fe E-709 -7_00000000000000000& E-214
    }
    -result {}
}
test util-13.7 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1be03d0bf225c7 E-137 +1_00000000000000000& E-41
    }
    -result {}
}
test util-13.8 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1a2fe76a3f9475 E-499 -1_00000000000000000& E-150
    }
    -result {}
}
test util-13.9 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 19a2028368022e E+1019 +8_999999999999999999& E+306
    }
    -result {}
}
test util-13.10 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1317e5ef3ab327 E+509 -1_999999999999999999& E+153
    }
    -result {}
}
test util-13.11 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1317e5ef3ab327 E+510 +3_99999999999999999& E+153
    }
    -result {}
}
test util-13.12 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1317e5ef3ab327 E+511 -7_99999999999999999& E+153
    }
    -result {}
}
test util-13.13 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1eb8e84fa0b278 E-1008 +6_999999999999999999& E-304
    }
    -result {}
}
test util-13.14 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -13339131c46f8b E-1004 -6_999999999999999999& E-303
    }
    -result {}
}
test util-13.15 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1c0f92a6276c9d E-162 +2_999999999999999999& E-49
    }
    -result {}
}
test util-13.16 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -15ce1f143d7ad2 E-443 -5_99999999999999999& E-134
    }
    -result {}
}
test util-13.17 {just over exact - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1c0794d9d40e96 E-301 +43_000000000000000000& E-92
    }
    -result {}
}
test util-13.18 {just over exact - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1c0794d9d40e96 E-300 -86_000000000000000000& E-92
    }
    -result {}
}
test util-13.19 {just over exact - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1cd5bee57763e6 E-241 +51_000000000000000000& E-74
    }
    -result {}
}
test util-13.20 {just under exact - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1d1c26db7d0dae E+651 +16_999999999999999999& E+195
    }
    -result {}
}
test util-13.21 {just under exact - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -13f7ced916872b E-5 -38_999999999999999999& E-3
    }
    -result {}
}
test util-13.22 {just over exact - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 17d93193f78fc6 E+588 +151_0000000000000000000& E+175
    }
    -result {}
}
test util-13.23 {just over exact - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1a82a1631eeb30 E-625 -119_000000000000000000& E-190
    }
    -result {}
}
test util-13.24 {just under exact - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -16c309024bab4b E+290 -282_999999999999999999& E+85
    }
    -result {}
}
test util-13.25 {just over exact - 8 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1dbbac6f83a821 E-800 +27869147_0000000000000000000& E-248
    }
    -result {}
}
test util-13.26 {just under exact - 9 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1c569e968e0944 E+430 -491080653_9999999999999999999& E+121
    }
    -result {}
}
test util-13.27 {just under exact - 9 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1c569e968e0944 E+429 +245540326_9999999999999999999& E+121
    }
    -result {}
}
test util-13.28 {just over exact - 10 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1fc575867314ee E-330 -9078555839_0000000000000000000& E-109
    }
    -result {}
}
test util-13.29 {just under exact - 10 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1c569e968e0944 E+428 -1227701634_9999999999999999999& E+120
    }
    -result {}
}
test util-13.30 {just over exact - 11 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1fc575867314ee E-329 +18157111678_0000000000000000000& E-109
    }
    -result {}
}
test util-13.31 {just over exact - 14 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -18bf7e7fa6f02a E-196 -15400733123779_0000000000000000000& E-72
    }
    -result {}
}
test util-13.32 {just over exact - 17 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -13de005bd620df E+217 -26153245263757307_0000000000000000000& E+49
    }
    -result {}
}
test util-13.33 {just over exact - 18 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1f92bacb3cb40c E+718 +272104041512242479_0000000000000000000& E+199
    }
    -result {}
}
test util-13.34 {just over exact - 18 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1f92bacb3cb40c E+719 -544208083024484958_0000000000000000000& E+199
    }
    -result {}
}
test util-13.35 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 142dbf25096cf5 E+148 +4_500000000000000000& E+44
    }
    -result {}
}
test util-13.36 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1afcef51f0fb5f E+263 -2_500000000000000000& E+79
    }
    -result {}
}
test util-13.37 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 102498ea6df0c4 E+145 +4_500000000000000000& E+43
    }
    -result {}
}
test util-13.38 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1754e31cd072da E+1004 -2_500000000000000000& E+302
    }
    -result {}
}
test util-13.39 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 12deac01e2b4f7 E-557 +2_50000000000000000& E-168
    }
    -result {}
}
test util-13.40 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1b1df536c13eee E-307 -6_50000000000000000& E-93
    }
    -result {}
}
test util-13.41 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 10711fed5b19a4 E-154 +4_50000000000000000& E-47
    }
    -result {}
}
test util-13.42 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -148d67e8b1e00d E-151 -4_50000000000000000& E-46
    }
    -result {}
}
test util-13.43 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1c8c574c0c6be7 E+187 +3_49999999999999999& E+56
    }
    -result {}
}
test util-13.44 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1756183c147514 E+206 -1_49999999999999999& E+62
    }
    -result {}
}
test util-13.45 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 12ab469676c410 E+203 +1_49999999999999999& E+61
    }
    -result {}
}
test util-13.46 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1539684e774b48 E+246 -1_49999999999999999& E+74
    }
    -result {}
}
test util-13.47 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 12e5f5dfa4fe9d E-286 +9_499999999999999999& E-87
    }
    -result {}
}
test util-13.48 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1bdc2417bf7787 E-838 -9_499999999999999999& E-253
    }
    -result {}
}
test util-13.49 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1eb8e84fa0b278 E-1009 +3_499999999999999999& E-304
    }
    -result {}
}
test util-13.50 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1e3cbc9907fdc8 E-290 -9_499999999999999999& E-88
    }
    -result {}
}
test util-13.51 {just over half ulp - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 10ad836f269a17 E-324 +30_500000000000000000& E-99
    }
    -result {}
}
test util-13.52 {just over half ulp - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1b39ae1909c31b E-687 -26_500000000000000000& E-208
    }
    -result {}
}
test util-13.53 {just over half ulp - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1b2ab18615fcc6 E-576 +686_500000000000000000& E-176
    }
    -result {}
}
test util-13.54 {just over half ulp - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -13e1f90a573064 E-624 -178_500000000000000000& E-190
    }
    -result {}
}
test util-13.55 {just under half ulp - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 16c309024bab4b E+289 +141_499999999999999999& E+85
    }
    -result {}
}
test util-13.56 {just under half ulp - 4 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -159bd3ad46e346 E+193 -1695_499999999999999999& E+55
    }
    -result {}
}
test util-13.57 {just under half ulp - 4 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1df4170f0fdecc E+124 +3981_499999999999999999& E+34
    }
    -result {}
}
test util-13.58 {just over half ulp - 6 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 17e1e0f1c7a4ac E+415 +126300_5000000000000000000& E+120
    }
    -result {}
}
test util-13.59 {just over half ulp - 6 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1dda592e398dd7 E+418 -126300_5000000000000000000& E+121
    }
    -result {}
}
test util-13.60 {just under half ulp - 7 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1e597c0b94b7ae E+453 -4411845_499999999999999999& E+130
    }
    -result {}
}
test util-13.61 {just under half ulp - 9 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1c569e968e0944 E+427 +613850817_4999999999999999999& E+120
    }
    -result {}
}
test util-13.62 {just under half ulp - 9 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1c569e968e0944 E+428 -122770163_49999999999999999999& E+121
    }
    -result {}
}
test util-13.63 {just over half ulp - 18 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 17ae0c186d8709 E+719 +408156062268363718_5000000000000000000& E+199
    }
    -result {}
}
test util-13.64 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 152d02c7e14af7 E+76 +1_0000000000000000& E+23
    }
    -result {}
}
test util-13.65 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -19d971e4fe8402 E+89 -1_0000000000000000& E+27
    }
    -result {}
}
test util-13.66 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 19d971e4fe8402 E+90 +2_0000000000000000& E+27
    }
    -result {}
}
test util-13.67 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -19d971e4fe8402 E+91 -4_0000000000000000& E+27
    }
    -result {}
}
test util-13.68 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 15798ee2308c3a E-27 +1_0000000000000000& E-8
    }
    -result {}
}
test util-13.69 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -15798ee2308c3a E-26 -2_0000000000000000& E-8
    }
    -result {}
}
test util-13.70 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 15798ee2308c3a E-25 +4_0000000000000000& E-8
    }
    -result {}
}
test util-13.71 {just over exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1ef2d0f5da7dd9 E-84 -1_0000000000000000& E-25
    }
    -result {}
}
test util-13.72 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1a784379d99db4 E+78 +4_9999999999999999& E+23
    }
    -result {}
}
test util-13.73 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1a784379d99db4 E+80 -1_9999999999999999& E+24
    }
    -result {}
}
test util-13.74 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 13da329b633647 E+81 +2_9999999999999999& E+24
    }
    -result {}
}
test util-13.75 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1cf389cd46047d E+85 -6_9999999999999999& E+25
    }
    -result {}
}
test util-13.76 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 19999999999999 E-3 +1_99999999999999999& E-1
    }
    -result {}
}
test util-13.77 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -13333333333333 E-2 -2_99999999999999999& E-1
    }
    -result {}
}
test util-13.78 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 16849b86a12b9b E-48 +4_99999999999999999& E-15
    }
    -result {}
}
test util-13.79 {just under exact - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -16849b86a12b9b E-46 -1_99999999999999999& E-14
    }
    -result {}
}
test util-13.80 {just over exact - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 17ccfc73126788 E-71 +63_00000000000000000& E-23
    }
    -result {}
}
test util-13.81 {just over exact - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1dc03b8fd7016a E-68 -63_00000000000000000& E-22
    }
    -result {}
}
test util-13.82 {just under exact - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 13f7ced916872b E-5 +38_999999999999999999& E-3
    }
    -result {}
}
test util-13.83 {just over exact - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1b297cad9f70b6 E+97 +269_000000000000000000& E+27
    }
    -result {}
}
test util-13.84 {just over exact - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1b297cad9f70b6 E+98 -538_00000000000000000& E+27
    }
    -result {}
}
test util-13.85 {just over exact - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1cdc06b20ef183 E-82 +373_00000000000000000& E-27
    }
    -result {}
}
test util-13.86 {just over exact - 4 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1b297cad9f70b6 E+96 +1345_00000000000000000& E+26
    }
    -result {}
}
# this one is not 4 digits, it is 3, and it is covered above.
test util-13.87 {just over exact - 4 digits} {*}{
    -constraints {testdoubledigits knownBadTest}
    -body {
	verdonk_test -1b297cad9f70b6 E+97 -2690_00000000000000000& E+26
    }
    -result {}
}
test util-13.88 {just over exact - 5 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -150a246ecd44f3 E-63 -14257_00000000000000000& E-23
    }
    -result {}
}
test util-13.89 {just under exact - 6 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -119b96f36ec68b E-19 -209900_999999999999999999& E-11
    }
    -result {}
}
test util-13.90 {just over exact - 11 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1c06d366394441 E-35 +50980203373_000000000000000000& E-21
    }
    -result {}
}
test util-13.91 {just under exact - 12 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1f58ac4db68c90 E+122 -104166211810_99999999999999999& E+26
    }
    -result {}
}
test util-13.92 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 19d971e4fe8402 E+87 +2_5000000000000000& E+26
    }
    -result {}
}
test util-13.93 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1dc74be914d16b E+81 -4_500000000000000& E+24
    }
    -result {}
}
test util-13.94 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 14adf4b7320335 E+84 +2_500000000000000& E+25
    }
    -result {}
}
test util-13.95 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1ae22487c1042b E+85 -6_5000000000000000& E+25
    }
    -result {}
}
test util-13.96 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 187fe49aab41e0 E-54 +8_5000000000000000& E-17
    }
    -result {}
}
test util-13.97 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1f5c05e4b23fd7 E-61 -8_5000000000000000& E-19
    }
    -result {}
}
test util-13.98 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1faa7ab552a552 E-42 +4_5000000000000000& E-13
    }
    -result {}
}
test util-13.99 {just over half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1b7cdfd9d7bdbb E-36 -2_5000000000000000& E-11
    }
    -result {}
}
test util-13.100 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 13da329b633647 E+80 +1_4999999999999999& E+24
    }
    -result {}
}
test util-13.101 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1cf389cd46047d E+84 -3_49999999999999999& E+25
    }
    -result {}
}
test util-13.102 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1f04ef12cb04cf E+85 +7_4999999999999999& E+25
    }
    -result {}
}
test util-13.103 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1f04ef12cb04cf E+86 -1_4999999999999999& E+26
    }
    -result {}
}
test util-13.104 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 13333333333333 E-3 +1_49999999999999999& E-1
    }
    -result {}
}
test util-13.105 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -107e1fe91b0b70 E-36 -1_49999999999999999& E-11
    }
    -result {}
}
test util-13.106 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 149da7e361ce4c E-33 +1_49999999999999999& E-10
    }
    -result {}
}
test util-13.107 {just under half ulp - 1 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -19c511dc3a41df E-30 -1_49999999999999999& E-9
    }
    -result {}
}
test util-13.108 {just over half ulp - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1aa83d74267822 E+93 -16_5000000000000000& E+27
    }
    -result {}
}
test util-13.109 {just over half ulp - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 18f1d5969453de E+89 +96_5000000000000000& E+25
    }
    -result {}
}
test util-13.110 {just over half ulp - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 11d9bd564dcda6 E-70 +94_50000000000000000& E-23
    }
    -result {}
}
test util-13.111 {just over half ulp - 2 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1a58973ecbede6 E-48 -58_50000000000000000& E-16
    }
    -result {}
}
test util-13.112 {just over half ulp - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1b297cad9f70b6 E+95 +672_50000000000000000& E+26
    }
    -result {}
}
test util-13.113 {just over half ulp - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -1b297cad9f70b6 E+96 -134_500000000000000000& E+27
    }
    -result {}
}
test util-13.114 {just over half ulp - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1cdc06b20ef183 E-83 +186_50000000000000000& E-27
    }
    -result {}
}
test util-13.115 {just over half ulp - 3 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -136071dcae4565 E-47 -860_50000000000000000& E-17
    }
    -result {}
}
test util-13.116 {just over half ulp - 6 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1cb968d297dde8 E+99 +113788_50000000000000000& E+25
    }
    -result {}
}
test util-13.117 {just over half ulp - 6 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test -11f3e1839eeab1 E+103 -113788_50000000000000000& E+26
    }
    -result {}
}
test util-13.118 {just under half ulp - 9 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1e9cec176c96f8 E+117 +317903333_49999999999999999& E+27
    }
    -result {}
}
test util-13.119 {just over half ulp - 11 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1c06d366394441 E-36 +25490101686_500000000000000000& E-21
    }
    -result {}
}
test util-13.120 {just under half ulp - 11 digits} {*}{
    -constraints testdoubledigits
    -body {
	verdonk_test 1f58ac4db68c90 E+121 +52083105905_49999999999999999& E+26
    }
    -result {}
}

test util-14.1 {funky NaN} {*}{
    -constraints {ieeeFloatingPoint controversialNaN}
    -body {
Changes to tests/var.test.
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

testConstraint testupvar [llength [info commands testupvar]]
testConstraint testgetvarfullname [llength [info commands testgetvarfullname]]
testConstraint testsetnoerr [llength [info commands testsetnoerr]]
testConstraint memory [llength [info commands memory]]
if {[testConstraint memory]} {
    proc getbytes {} {
        return [lindex [split [memory info] \n] 3 3]
    }
    proc leaktest {script {iterations 3}} {
        set end [getbytes]
        for {set i 0} {$i < $iterations} {incr i} {
            uplevel 1 $script
            set tmp $end
            set end [getbytes]
        }
        return [expr {$end - $tmp}]
    }
}


catch {rename p ""}
catch {namespace delete test_ns_var}
catch {unset xx}







|


|
|
|
|
|
|
|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

testConstraint testupvar [llength [info commands testupvar]]
testConstraint testgetvarfullname [llength [info commands testgetvarfullname]]
testConstraint testsetnoerr [llength [info commands testsetnoerr]]
testConstraint memory [llength [info commands memory]]
if {[testConstraint memory]} {
    proc getbytes {} {
	return [lindex [split [memory info] \n] 3 3]
    }
    proc leaktest {script {iterations 3}} {
	set end [getbytes]
	for {set i 0} {$i < $iterations} {incr i} {
	    uplevel 1 $script
	    set tmp $end
	    set end [getbytes]
	}
	return [expr {$end - $tmp}]
    }
}


catch {rename p ""}
catch {namespace delete test_ns_var}
catch {unset xx}
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
} -result {11 11 38 38}
set ::x "global value"
namespace eval test_ns_var {
    variable x "namespace value"
}
test var-1.2 {TclLookupVar, TCL_GLOBAL_ONLY implies global namespace var} {
    namespace eval test_ns_var {
        proc p {} {
            global x  ;# specifies TCL_GLOBAL_ONLY to get global x
            return $x
        }
    }
    test_ns_var::p
} {global value}
test var-1.3 {TclLookupVar, TCL_NAMESPACE_ONLY implies namespace var} {
    namespace eval test_ns_var {
        proc q {} {
            variable x  ;# specifies TCL_NAMESPACE_ONLY to get namespace x
            return $x
        }
    }
    test_ns_var::q
} {namespace value}
test var-1.4 {TclLookupVar, no active call frame implies global namespace var} {
    set x
} {global value}
test var-1.5 {TclLookupVar, active call frame pushed for namespace eval implies namespace var} {
    namespace eval test_ns_var {set x}
} {namespace value}
test var-1.6 {TclLookupVar, name starts with :: implies some namespace var} {
    namespace eval test_ns_var {set ::x}
} {global value}
test var-1.7 {TclLookupVar, error finding namespace var} -body {
    set a:::b
} -returnCodes error -result {can't read "a:::b": no such variable}
test var-1.8 {TclLookupVar, error finding namespace var} -body {
    set ::foobarfoo
} -returnCodes error -result {can't read "::foobarfoo": no such variable}
test var-1.9 {TclLookupVar, create new namespace var} {
    namespace eval test_ns_var {
        set v hello
    }
} {hello}
test var-1.10 {TclLookupVar, create new namespace var} -setup {
    catch {unset y}
} -body {
    namespace eval test_ns_var {
        set ::y 789
    }
    set y
} -result {789}
test var-1.11 {TclLookupVar, error creating new namespace var} -body {
    namespace eval test_ns_var {
        set ::test_ns_var::foo::bar 314159
    }
} -returnCodes error -result {can't set "::test_ns_var::foo::bar": parent namespace doesn't exist}
test var-1.12 {TclLookupVar, error creating new namespace var} -body {
    namespace eval test_ns_var {
        set ::test_ns_var::foo:: 1997
    }
} -returnCodes error -result {can't set "::test_ns_var::foo::": parent namespace doesn't exist}
test var-1.13 {TclLookupVar, new namespace var is created in a particular namespace} {
    catch {unset aNeWnAmEiNnS}
    namespace eval test_ns_var {
        namespace eval test_ns_var2::test_ns_var3 {
            set aNeWnAmEiNnS 77777
        }
        # namespace which builds a name by traversing nsPtr chain to ::
        namespace which -variable test_ns_var2::test_ns_var3::aNeWnAmEiNnS
    }
} {::test_ns_var::test_ns_var2::test_ns_var3::aNeWnAmEiNnS}
test var-1.14 {TclLookupVar, namespace code ignores ":"s in middle and end of var names} {
    namespace eval test_ns_var {
        set : 123
        set v: 456
        set x:y: 789
        list [set :] [set v:] [set x:y:] \
             ${:} ${v:} ${x:y:} \
             [expr {":" in [info vars]}] \
             [expr {"v:" in [info vars]}] \
             [expr {"x:y:" in [info vars]}]
    }
} {123 456 789 123 456 789 1 1 1}
test var-1.15 {TclLookupVar, resurrect variable via upvar to deleted namespace: compiled code path} {
    namespace eval test_ns_var {
	variable foo 2
    }
    proc p {} {
	variable ::test_ns_var::foo
	lappend result [catch {set foo} msg] $msg
        namespace delete ::test_ns_var
	lappend result [catch {set foo 3} msg] $msg
	lappend result [catch {set foo(3) 3} msg] $msg
    }
    p
} {0 2 1 {can't set "foo": upvar refers to variable in deleted namespace} 1 {can't set "foo(3)": upvar refers to variable in deleted namespace}}
test var-1.16 {TclLookupVar, resurrect variable via upvar to deleted namespace: uncompiled code path} {
    namespace eval test_ns_var {
	variable result
        namespace eval subns {
	    variable foo 2
	}
	upvar 0 subns::foo foo
	lappend result [catch {set foo} msg] $msg
        namespace delete subns
	lappend result [catch {set foo 3} msg] $msg
	lappend result [catch {set foo(3) 3} msg] $msg
        namespace delete [namespace current]
	set result
    }
} {0 2 1 {can't set "foo": upvar refers to variable in deleted namespace} 1 {can't set "foo(3)": upvar refers to variable in deleted namespace}}
test var-1.17 {TclLookupVar, resurrect array element via upvar to deleted array: compiled code path} {
    namespace eval test_ns_var {
	variable result
	proc p {} {
	    array set x {1 2 3 4}
	    upvar 0 x(1) foo
	    lappend result [catch {set foo} msg] $msg
	    unset x
	    lappend result [catch {set foo 3} msg] $msg
	}
	set result [p]
        namespace delete [namespace current]
	set result
    }
} {0 2 1 {can't set "foo": upvar refers to element in deleted array}}
test var-1.18 {TclLookupVar, resurrect array element via upvar to deleted array: uncompiled code path} -setup {
    unset -nocomplain test_ns_var::x
} -body {
    namespace eval test_ns_var {
	variable result {}
	variable x
	array set x {1 2 3 4}
	upvar 0 x(1) foo
	lappend result [catch {set foo} msg] $msg
	unset x
	lappend result [catch {set foo 3} msg] $msg
        namespace delete [namespace current]
	set result
    }
} -result {0 2 1 {can't set "foo": upvar refers to element in deleted array}}
test var-1.19 {TclLookupVar, right error message when parsing variable name} -body {
    [format set] thisvar(doesntexist)
} -returnCodes error -result {can't read "thisvar(doesntexist)": no such variable}
test var-1.20 {TclLookupVar, regression on utf-8 variable names} -setup {







|
|
|
|





|
|
|
|




















|






|





|




|





|
|
|
|
|




|
|
|
|
|
|
|
|









|








|




|


|














|














|







61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
} -result {11 11 38 38}
set ::x "global value"
namespace eval test_ns_var {
    variable x "namespace value"
}
test var-1.2 {TclLookupVar, TCL_GLOBAL_ONLY implies global namespace var} {
    namespace eval test_ns_var {
	proc p {} {
	    global x  ;# specifies TCL_GLOBAL_ONLY to get global x
	    return $x
	}
    }
    test_ns_var::p
} {global value}
test var-1.3 {TclLookupVar, TCL_NAMESPACE_ONLY implies namespace var} {
    namespace eval test_ns_var {
	proc q {} {
	    variable x  ;# specifies TCL_NAMESPACE_ONLY to get namespace x
	    return $x
	}
    }
    test_ns_var::q
} {namespace value}
test var-1.4 {TclLookupVar, no active call frame implies global namespace var} {
    set x
} {global value}
test var-1.5 {TclLookupVar, active call frame pushed for namespace eval implies namespace var} {
    namespace eval test_ns_var {set x}
} {namespace value}
test var-1.6 {TclLookupVar, name starts with :: implies some namespace var} {
    namespace eval test_ns_var {set ::x}
} {global value}
test var-1.7 {TclLookupVar, error finding namespace var} -body {
    set a:::b
} -returnCodes error -result {can't read "a:::b": no such variable}
test var-1.8 {TclLookupVar, error finding namespace var} -body {
    set ::foobarfoo
} -returnCodes error -result {can't read "::foobarfoo": no such variable}
test var-1.9 {TclLookupVar, create new namespace var} {
    namespace eval test_ns_var {
	set v hello
    }
} {hello}
test var-1.10 {TclLookupVar, create new namespace var} -setup {
    catch {unset y}
} -body {
    namespace eval test_ns_var {
	set ::y 789
    }
    set y
} -result {789}
test var-1.11 {TclLookupVar, error creating new namespace var} -body {
    namespace eval test_ns_var {
	set ::test_ns_var::foo::bar 314159
    }
} -returnCodes error -result {can't set "::test_ns_var::foo::bar": parent namespace doesn't exist}
test var-1.12 {TclLookupVar, error creating new namespace var} -body {
    namespace eval test_ns_var {
	set ::test_ns_var::foo:: 1997
    }
} -returnCodes error -result {can't set "::test_ns_var::foo::": parent namespace doesn't exist}
test var-1.13 {TclLookupVar, new namespace var is created in a particular namespace} {
    catch {unset aNeWnAmEiNnS}
    namespace eval test_ns_var {
	namespace eval test_ns_var2::test_ns_var3 {
	    set aNeWnAmEiNnS 77777
	}
	# namespace which builds a name by traversing nsPtr chain to ::
	namespace which -variable test_ns_var2::test_ns_var3::aNeWnAmEiNnS
    }
} {::test_ns_var::test_ns_var2::test_ns_var3::aNeWnAmEiNnS}
test var-1.14 {TclLookupVar, namespace code ignores ":"s in middle and end of var names} {
    namespace eval test_ns_var {
	set : 123
	set v: 456
	set x:y: 789
	list [set :] [set v:] [set x:y:] \
	     ${:} ${v:} ${x:y:} \
	     [expr {":" in [info vars]}] \
	     [expr {"v:" in [info vars]}] \
	     [expr {"x:y:" in [info vars]}]
    }
} {123 456 789 123 456 789 1 1 1}
test var-1.15 {TclLookupVar, resurrect variable via upvar to deleted namespace: compiled code path} {
    namespace eval test_ns_var {
	variable foo 2
    }
    proc p {} {
	variable ::test_ns_var::foo
	lappend result [catch {set foo} msg] $msg
	namespace delete ::test_ns_var
	lappend result [catch {set foo 3} msg] $msg
	lappend result [catch {set foo(3) 3} msg] $msg
    }
    p
} {0 2 1 {can't set "foo": upvar refers to variable in deleted namespace} 1 {can't set "foo(3)": upvar refers to variable in deleted namespace}}
test var-1.16 {TclLookupVar, resurrect variable via upvar to deleted namespace: uncompiled code path} {
    namespace eval test_ns_var {
	variable result
	namespace eval subns {
	    variable foo 2
	}
	upvar 0 subns::foo foo
	lappend result [catch {set foo} msg] $msg
	namespace delete subns
	lappend result [catch {set foo 3} msg] $msg
	lappend result [catch {set foo(3) 3} msg] $msg
	namespace delete [namespace current]
	set result
    }
} {0 2 1 {can't set "foo": upvar refers to variable in deleted namespace} 1 {can't set "foo(3)": upvar refers to variable in deleted namespace}}
test var-1.17 {TclLookupVar, resurrect array element via upvar to deleted array: compiled code path} {
    namespace eval test_ns_var {
	variable result
	proc p {} {
	    array set x {1 2 3 4}
	    upvar 0 x(1) foo
	    lappend result [catch {set foo} msg] $msg
	    unset x
	    lappend result [catch {set foo 3} msg] $msg
	}
	set result [p]
	namespace delete [namespace current]
	set result
    }
} {0 2 1 {can't set "foo": upvar refers to element in deleted array}}
test var-1.18 {TclLookupVar, resurrect array element via upvar to deleted array: uncompiled code path} -setup {
    unset -nocomplain test_ns_var::x
} -body {
    namespace eval test_ns_var {
	variable result {}
	variable x
	array set x {1 2 3 4}
	upvar 0 x(1) foo
	lappend result [catch {set foo} msg] $msg
	unset x
	lappend result [catch {set foo 3} msg] $msg
	namespace delete [namespace current]
	set result
    }
} -result {0 2 1 {can't set "foo": upvar refers to element in deleted array}}
test var-1.19 {TclLookupVar, right error message when parsing variable name} -body {
    [format set] thisvar(doesntexist)
} -returnCodes error -result {can't read "thisvar(doesntexist)": no such variable}
test var-1.20 {TclLookupVar, regression on utf-8 variable names} -setup {
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
} {1 2}

test var-3.1 {MakeUpvar, TCL_NAMESPACE_ONLY not specified for other var} -setup {
    catch {unset x}
} -body {
    set x 1997
    proc p {} {
        global x  ;# calls MakeUpvar with TCL_NAMESPACE_ONLY for other var x
        return $x
    }
    p
} -result {1997}
test var-3.2 {MakeUpvar, other var has TCL_NAMESPACE_ONLY specified} {
    namespace eval test_ns_var {
        catch {unset v}
        variable v 1998
        proc p {} {
            variable v  ;# TCL_NAMESPACE_ONLY specified for other var x
            return $v
        }
        p
    }
} {1998}
test var-3.3 {MakeUpvar, my var has TCL_GLOBAL_ONLY specified} -setup {
    catch {unset a}
} -constraints testupvar -body {
    set a 123321
    proc p {} {







|
|





|
|
|
|
|
|
|







231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
} {1 2}

test var-3.1 {MakeUpvar, TCL_NAMESPACE_ONLY not specified for other var} -setup {
    catch {unset x}
} -body {
    set x 1997
    proc p {} {
	global x  ;# calls MakeUpvar with TCL_NAMESPACE_ONLY for other var x
	return $x
    }
    p
} -result {1997}
test var-3.2 {MakeUpvar, other var has TCL_NAMESPACE_ONLY specified} {
    namespace eval test_ns_var {
	catch {unset v}
	variable v 1998
	proc p {} {
	    variable v  ;# TCL_NAMESPACE_ONLY specified for other var x
	    return $v
	}
	p
    }
} {1998}
test var-3.3 {MakeUpvar, my var has TCL_GLOBAL_ONLY specified} -setup {
    catch {unset a}
} -constraints testupvar -body {
    set a 123321
    proc p {} {
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
    list [set xxxxx] [set aaaaa]
} -result {77777 77777}
test var-3.6 {MakeUpvar, active call frame pushed for namespace eval} -setup {
    catch {unset a}
} -body {
    set a 121212
    namespace eval test_ns_var {
        upvar ::a vvv
        set vvv
    }
} -result {121212}
test var-3.7 {MakeUpvar, my var has ::s} -setup {
    catch {unset a}
} -body {
    set a 789789
    upvar #0 a test_ns_var::lnk
    namespace eval test_ns_var {
        set lnk
    }
} -result {789789}
test var-3.8 {MakeUpvar, my var already exists in global ns} -setup {
    upvar #0 aaaaa xxxxx
    catch {unset aaaaa}
    catch {unset xxxxx}
} -body {







|
|








|







285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
    list [set xxxxx] [set aaaaa]
} -result {77777 77777}
test var-3.6 {MakeUpvar, active call frame pushed for namespace eval} -setup {
    catch {unset a}
} -body {
    set a 121212
    namespace eval test_ns_var {
	upvar ::a vvv
	set vvv
    }
} -result {121212}
test var-3.7 {MakeUpvar, my var has ::s} -setup {
    catch {unset a}
} -body {
    set a 789789
    upvar #0 a test_ns_var::lnk
    namespace eval test_ns_var {
	set lnk
    }
} -result {789789}
test var-3.8 {MakeUpvar, my var already exists in global ns} -setup {
    upvar #0 aaaaa xxxxx
    catch {unset aaaaa}
    catch {unset xxxxx}
} -body {
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
    catch {unset a}
} -body {
    set a bar
    namespace which -variable a
} -result {::a}
test var-5.2 {Tcl_GetVariableFullName, namespace variable} {
    namespace eval test_ns_var {
        variable martha
        namespace which -variable martha
    }
} {::test_ns_var::martha}
test var-5.3 {Tcl_GetVariableFullName, namespace variable} -setup {
    namespace eval test_ns_var {variable martha}
} -body {
    namespace which -variable test_ns_var::martha
} -result {::test_ns_var::martha}

test var-6.1 {Tcl_GlobalObjCmd, variable is qualified by a namespace name} {
    namespace eval test_ns_var {
        variable boeing 777
    }
    apply {{} {
        global ::test_ns_var::boeing
        set boeing
    }}
} {777}
test var-6.2 {Tcl_GlobalObjCmd, variable is qualified by a namespace name} {
    namespace eval test_ns_var {
        namespace eval test_ns_nested {
            variable java java
        }
        proc p {} {
            global ::test_ns_var::test_ns_nested::java
            set java
        }
    }
    test_ns_var::p
} {java}
test var-6.3 {Tcl_GlobalObjCmd, variable named {} qualified by a namespace name} {
    namespace eval ::test_ns_var::test_ns_nested {}
    set ::test_ns_var::test_ns_nested:: 24
    apply {{} {
        global ::test_ns_var::test_ns_nested::
        set {}
    }}
} {24}
test var-6.4 {Tcl_GlobalObjCmd, variable name matching :*} {
    # Test for Tcl Bug 480176
    set :v broken
    proc p {} {
	global :v







|
|










|


|
|




|
|
|
|
|
|
|







|
|







357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
    catch {unset a}
} -body {
    set a bar
    namespace which -variable a
} -result {::a}
test var-5.2 {Tcl_GetVariableFullName, namespace variable} {
    namespace eval test_ns_var {
	variable martha
	namespace which -variable martha
    }
} {::test_ns_var::martha}
test var-5.3 {Tcl_GetVariableFullName, namespace variable} -setup {
    namespace eval test_ns_var {variable martha}
} -body {
    namespace which -variable test_ns_var::martha
} -result {::test_ns_var::martha}

test var-6.1 {Tcl_GlobalObjCmd, variable is qualified by a namespace name} {
    namespace eval test_ns_var {
	variable boeing 777
    }
    apply {{} {
	global ::test_ns_var::boeing
	set boeing
    }}
} {777}
test var-6.2 {Tcl_GlobalObjCmd, variable is qualified by a namespace name} {
    namespace eval test_ns_var {
	namespace eval test_ns_nested {
	    variable java java
	}
	proc p {} {
	    global ::test_ns_var::test_ns_nested::java
	    set java
	}
    }
    test_ns_var::p
} {java}
test var-6.3 {Tcl_GlobalObjCmd, variable named {} qualified by a namespace name} {
    namespace eval ::test_ns_var::test_ns_nested {}
    set ::test_ns_var::test_ns_nested:: 24
    apply {{} {
	global ::test_ns_var::test_ns_nested::
	set {}
    }}
} {24}
test var-6.4 {Tcl_GlobalObjCmd, variable name matching :*} {
    # Test for Tcl Bug 480176
    set :v broken
    proc p {} {
	global :v
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
    p
} {}

test var-7.1 {Tcl_VariableObjCmd, create and initialize one new ns variable} -setup {
    catch {namespace delete test_ns_var}
} -body {
    namespace eval test_ns_var {
        variable one 1
    }
    list [info vars test_ns_var::*] [set test_ns_var::one]
} -result {::test_ns_var::one 1}
test var-7.2 {Tcl_VariableObjCmd, if new and no value, leave undefined} {
    set two 2222222
    namespace eval test_ns_var {
        variable two
    }
    list [info exists test_ns_var::two] [catch {set test_ns_var::two} msg] $msg
} {0 1 {can't read "test_ns_var::two": no such variable}}
test var-7.3 {Tcl_VariableObjCmd, "define" var already created above} -setup {
    catch {namespace delete test_ns_var}
    namespace eval test_ns_var {variable one 1}
} -body {
    namespace eval test_ns_var {
        variable two 2
    }
    list [lsort [info vars test_ns_var::*]] \
         [namespace eval test_ns_var {set two}]
} -result [list [lsort {::test_ns_var::two ::test_ns_var::one}] 2]
test var-7.4 {Tcl_VariableObjCmd, list of vars} -setup {
    catch {namespace delete test_ns_var}
    namespace eval test_ns_var {variable one 1; variable two 2}
} -body {
    namespace eval test_ns_var {
        variable three 3 four 4
    }
    list [lsort [info vars test_ns_var::*]] \
         [namespace eval test_ns_var {expr {$three+$four}}]
} -result [list [lsort {::test_ns_var::four ::test_ns_var::three ::test_ns_var::two ::test_ns_var::one}] 7]
test var-7.5 {Tcl_VariableObjCmd, value for last var is optional} -setup {
    catch {unset a}
    catch {unset five}
    catch {unset six}
} -body {
    set a ""
    set five 555
    set six  666
    namespace eval test_ns_var {
        variable five 5 six
        lappend ::a $five
    }
    lappend a $test_ns_var::five \
        [set test_ns_var::six 6] [set test_ns_var::six] $six
} -cleanup {
    catch {unset five}
    catch {unset six}
} -result {5 5 6 6 666}
test var-7.6 {Tcl_VariableObjCmd, variable name can be qualified} -setup {
    catch {unset newvar}
} -body {
    namespace eval test_ns_var {
        variable ::newvar cheers!
    }
    return $newvar
} -cleanup {
    catch {unset newvar}
} -result {cheers!}
test var-7.7 {Tcl_VariableObjCmd, bad var name} -returnCodes error -body {
    namespace eval test_ns_var {
        variable sev:::en 7
    }
} -result {can't define "sev:::en": parent namespace doesn't exist}
test var-7.8 {Tcl_VariableObjCmd, if var already exists and no value is given, leave value unchanged} {
    set a ""
    namespace eval test_ns_var {
        variable eight 8
        lappend ::a $eight
        variable eight
        lappend ::a $eight
    }
    set a
} {8 8}
test var-7.9 {Tcl_VariableObjCmd, mark as namespace var so var persists until namespace is destroyed or var is unset} -setup {
    catch {namespace delete test_ns_var2}
} -body {
    set a ""
    namespace eval test_ns_var2 {
        variable x 123
        variable y
        variable z
    }
    lappend a [lsort [info vars test_ns_var2::*]]
    lappend a [info exists test_ns_var2::x] [info exists test_ns_var2::y] \
        [info exists test_ns_var2::z]
    lappend a [list [catch {set test_ns_var2::y} msg] $msg]
    lappend a [lsort [info vars test_ns_var2::*]]
    lappend a [info exists test_ns_var2::y] [info exists test_ns_var2::z]
    lappend a [set test_ns_var2::y hello]
    lappend a [info exists test_ns_var2::y] [info exists test_ns_var2::z]
    lappend a [list [catch {unset test_ns_var2::y} msg] $msg]
    lappend a [lsort [info vars test_ns_var2::*]]







|






|








|


|






|


|










|
|


|








|







|





|
|
|
|








|
|
|



|







420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
    p
} {}

test var-7.1 {Tcl_VariableObjCmd, create and initialize one new ns variable} -setup {
    catch {namespace delete test_ns_var}
} -body {
    namespace eval test_ns_var {
	variable one 1
    }
    list [info vars test_ns_var::*] [set test_ns_var::one]
} -result {::test_ns_var::one 1}
test var-7.2 {Tcl_VariableObjCmd, if new and no value, leave undefined} {
    set two 2222222
    namespace eval test_ns_var {
	variable two
    }
    list [info exists test_ns_var::two] [catch {set test_ns_var::two} msg] $msg
} {0 1 {can't read "test_ns_var::two": no such variable}}
test var-7.3 {Tcl_VariableObjCmd, "define" var already created above} -setup {
    catch {namespace delete test_ns_var}
    namespace eval test_ns_var {variable one 1}
} -body {
    namespace eval test_ns_var {
	variable two 2
    }
    list [lsort [info vars test_ns_var::*]] \
	 [namespace eval test_ns_var {set two}]
} -result [list [lsort {::test_ns_var::two ::test_ns_var::one}] 2]
test var-7.4 {Tcl_VariableObjCmd, list of vars} -setup {
    catch {namespace delete test_ns_var}
    namespace eval test_ns_var {variable one 1; variable two 2}
} -body {
    namespace eval test_ns_var {
	variable three 3 four 4
    }
    list [lsort [info vars test_ns_var::*]] \
	 [namespace eval test_ns_var {expr {$three+$four}}]
} -result [list [lsort {::test_ns_var::four ::test_ns_var::three ::test_ns_var::two ::test_ns_var::one}] 7]
test var-7.5 {Tcl_VariableObjCmd, value for last var is optional} -setup {
    catch {unset a}
    catch {unset five}
    catch {unset six}
} -body {
    set a ""
    set five 555
    set six  666
    namespace eval test_ns_var {
	variable five 5 six
	lappend ::a $five
    }
    lappend a $test_ns_var::five \
	[set test_ns_var::six 6] [set test_ns_var::six] $six
} -cleanup {
    catch {unset five}
    catch {unset six}
} -result {5 5 6 6 666}
test var-7.6 {Tcl_VariableObjCmd, variable name can be qualified} -setup {
    catch {unset newvar}
} -body {
    namespace eval test_ns_var {
	variable ::newvar cheers!
    }
    return $newvar
} -cleanup {
    catch {unset newvar}
} -result {cheers!}
test var-7.7 {Tcl_VariableObjCmd, bad var name} -returnCodes error -body {
    namespace eval test_ns_var {
	variable sev:::en 7
    }
} -result {can't define "sev:::en": parent namespace doesn't exist}
test var-7.8 {Tcl_VariableObjCmd, if var already exists and no value is given, leave value unchanged} {
    set a ""
    namespace eval test_ns_var {
	variable eight 8
	lappend ::a $eight
	variable eight
	lappend ::a $eight
    }
    set a
} {8 8}
test var-7.9 {Tcl_VariableObjCmd, mark as namespace var so var persists until namespace is destroyed or var is unset} -setup {
    catch {namespace delete test_ns_var2}
} -body {
    set a ""
    namespace eval test_ns_var2 {
	variable x 123
	variable y
	variable z
    }
    lappend a [lsort [info vars test_ns_var2::*]]
    lappend a [info exists test_ns_var2::x] [info exists test_ns_var2::y] \
	[info exists test_ns_var2::z]
    lappend a [list [catch {set test_ns_var2::y} msg] $msg]
    lappend a [lsort [info vars test_ns_var2::*]]
    lappend a [info exists test_ns_var2::y] [info exists test_ns_var2::z]
    lappend a [set test_ns_var2::y hello]
    lappend a [info exists test_ns_var2::y] [info exists test_ns_var2::z]
    lappend a [list [catch {unset test_ns_var2::y} msg] $msg]
    lappend a [lsort [info vars test_ns_var2::*]]
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
	[lsort {::test_ns_var2::x ::test_ns_var2::z}] 0 0\
	{1 {can't unset "test_ns_var2::z": no such variable}}\
	{}]
test var-7.10 {Tcl_VariableObjCmd, variable cmd inside proc creates local link var} -setup {
    namespace eval test_ns_var { variable eight 8 }
} -body {
    namespace eval test_ns_var {
        proc p {} {
            variable eight
            list [set eight] [info vars]
        }
        p
    }
} -result {8 eight}
test var-7.11 {Tcl_VariableObjCmd, variable cmd inside proc creates local link var} -setup {
    namespace eval test_ns_var { variable eight 8 }
} -body {
    proc p {} {   ;# note this proc is at global :: scope
        variable test_ns_var::eight
        list [set eight] [info vars]
    }
    p
} -result {8 eight}
test var-7.12 {Tcl_VariableObjCmd, variable cmd inside proc creates local link var} {
    namespace eval test_ns_var {
        variable {} {My name is empty}
    }
    proc p {} {   ;# note this proc is at global :: scope
        variable test_ns_var::
        list [set {}] [info vars]
    }
    p
} {{My name is empty} {{}}}
test var-7.13 {Tcl_VariableObjCmd, variable named ":"} {
    namespace eval test_ns_var {
        variable : {My name is ":"}
	proc p {} {
	    variable :
	    list [set :] [info vars]
	}
	p
    }
} {{My name is ":"} :}







|
|
|
|
|






|
|





|


|
|





|







528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
	[lsort {::test_ns_var2::x ::test_ns_var2::z}] 0 0\
	{1 {can't unset "test_ns_var2::z": no such variable}}\
	{}]
test var-7.10 {Tcl_VariableObjCmd, variable cmd inside proc creates local link var} -setup {
    namespace eval test_ns_var { variable eight 8 }
} -body {
    namespace eval test_ns_var {
	proc p {} {
	    variable eight
	    list [set eight] [info vars]
	}
	p
    }
} -result {8 eight}
test var-7.11 {Tcl_VariableObjCmd, variable cmd inside proc creates local link var} -setup {
    namespace eval test_ns_var { variable eight 8 }
} -body {
    proc p {} {   ;# note this proc is at global :: scope
	variable test_ns_var::eight
	list [set eight] [info vars]
    }
    p
} -result {8 eight}
test var-7.12 {Tcl_VariableObjCmd, variable cmd inside proc creates local link var} {
    namespace eval test_ns_var {
	variable {} {My name is empty}
    }
    proc p {} {   ;# note this proc is at global :: scope
	variable test_ns_var::
	list [set {}] [info vars]
    }
    p
} {{My name is empty} {{}}}
test var-7.13 {Tcl_VariableObjCmd, variable named ":"} {
    namespace eval test_ns_var {
	variable : {My name is ":"}
	proc p {} {
	    variable :
	    list [set :] [info vars]
	}
	p
    }
} {{My name is ":"} :}
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
} {}

test var-8.1 {TclDeleteVars, "unset" traces are called with fully-qualified var names} -setup {
    catch {namespace delete test_ns_var}
    catch {unset a}
} -body {
    namespace eval test_ns_var {
        variable v 123
        variable info ""
        proc traceUnset {name1 name2 op} {
            variable info
            set info [concat $info [list $name1 $name2 $op]]
        }
        trace add var v unset [namespace code traceUnset]
    }
    list [unset test_ns_var::v] $test_ns_var::info
} -result {{} {test_ns_var::v {} unset}}
test var-8.2 {TclDeleteNamespaceVars, "unset" traces on ns delete are called with fully-qualified var names} -setup {
    catch {namespace delete test_ns_var}
    catch {unset a}
} -body {
    set info ""
    namespace eval test_ns_var {
        variable v 123 1
        trace add var v unset ::traceUnset
    }
    proc traceUnset {name1 name2 op} {
	set ::info [concat $::info [list $name1 $name2 $op]]
    }
    list [namespace delete test_ns_var] $::info
} -result {{} {::test_ns_var::v {} unset}}








|
|
|
|
|
|
|









|
|







588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
} {}

test var-8.1 {TclDeleteVars, "unset" traces are called with fully-qualified var names} -setup {
    catch {namespace delete test_ns_var}
    catch {unset a}
} -body {
    namespace eval test_ns_var {
	variable v 123
	variable info ""
	proc traceUnset {name1 name2 op} {
	    variable info
	    set info [concat $info [list $name1 $name2 $op]]
	}
	trace add var v unset [namespace code traceUnset]
    }
    list [unset test_ns_var::v] $test_ns_var::info
} -result {{} {test_ns_var::v {} unset}}
test var-8.2 {TclDeleteNamespaceVars, "unset" traces on ns delete are called with fully-qualified var names} -setup {
    catch {namespace delete test_ns_var}
    catch {unset a}
} -body {
    set info ""
    namespace eval test_ns_var {
	variable v 123 1
	trace add var v unset ::traceUnset
    }
    proc traceUnset {name1 name2 op} {
	set ::info [concat $::info [list $name1 $name2 $op]]
    }
    list [namespace delete test_ns_var] $::info
} -result {{} {::test_ns_var::v {} unset}}

808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
	array nextelement a $s
    }}
} -returnCodes error -result {couldn't find search "s-1-a"}
test var-13.3 {unset array with search, SIGSEGV, bug 46a2410650} -body {
    apply {{} {
	array set a {aa 11 bb 22 cc 33 dd 44 ee 55 ff 66}
	set s [array startsearch a]
        unset a(ff)
	array nextelement a $s
    }}
} -returnCodes error -result {couldn't find search "s-1-a"}

test var-14.1 {array names syntax} -body {
    array names foo bar baz snafu
} -returnCodes 1 -match glob -result *







|







808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
	array nextelement a $s
    }}
} -returnCodes error -result {couldn't find search "s-1-a"}
test var-13.3 {unset array with search, SIGSEGV, bug 46a2410650} -body {
    apply {{} {
	array set a {aa 11 bb 22 cc 33 dd 44 ee 55 ff 66}
	set s [array startsearch a]
	unset a(ff)
	array nextelement a $s
    }}
} -returnCodes error -result {couldn't find search "s-1-a"}

test var-14.1 {array names syntax} -body {
    array names foo bar baz snafu
} -returnCodes 1 -match glob -result *
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
} -result baz

test var-21.0 {PushVarNameWord OBOE in compiled unset} -setup {
    proc linenumber {} {dict get [info frame -1] line}
} -body {
    apply {n {
	set foo bar
        unset foo {*}{
        } [return [incr n -[linenumber]]]
    }} [linenumber]
} -cleanup {
    rename linenumber {}
} -result 1

test var-22.0 {leak in array element unset: Bug a3309d01db} -setup {
    proc doit k {
	variable A
	set A($k) {}
	foreach n [array names A] {
	    if {$n <= $k-1} {
		unset A($n)
	    }
	}
    }
} -constraints memory -body {
    set end [getbytes]
    for {set i 0} {$i < 5} {incr i} {
	doit $i
        set tmp $end
        set end [getbytes]
    }
    set leakedBytes [expr {$end - $tmp}]
} -cleanup {
    array unset A
    rename doit {}
} -result 0
test var-22.1 {leak in localVarName internalrep: Bug 80304238ac} -setup {







|
|



















|
|







1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
} -result baz

test var-21.0 {PushVarNameWord OBOE in compiled unset} -setup {
    proc linenumber {} {dict get [info frame -1] line}
} -body {
    apply {n {
	set foo bar
	unset foo {*}{
	} [return [incr n -[linenumber]]]
    }} [linenumber]
} -cleanup {
    rename linenumber {}
} -result 1

test var-22.0 {leak in array element unset: Bug a3309d01db} -setup {
    proc doit k {
	variable A
	set A($k) {}
	foreach n [array names A] {
	    if {$n <= $k-1} {
		unset A($n)
	    }
	}
    }
} -constraints memory -body {
    set end [getbytes]
    for {set i 0} {$i < 5} {incr i} {
	doit $i
	set tmp $end
	set end [getbytes]
    }
    set leakedBytes [expr {$end - $tmp}]
} -cleanup {
    array unset A
    rename doit {}
} -result 0
test var-22.1 {leak in localVarName internalrep: Bug 80304238ac} -setup {
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
	}
	interp delete child
    }
} -constraints memory -body {
    set end [getbytes]
    for {set i 0} {$i < 5} {incr i} {
	doit
        set tmp $end
        set end [getbytes]
    }
    set leakedBytes [expr {$end - $tmp}]
} -cleanup {
    array unset A
    rename doit {}
} -result 0
test var-22.2 {leak in parsedVarName} -constraints memory -body {







|
|







1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
	}
	interp delete child
    }
} -constraints memory -body {
    set end [getbytes]
    for {set i 0} {$i < 5} {incr i} {
	doit
	set tmp $end
	set end [getbytes]
    }
    set leakedBytes [expr {$end - $tmp}]
} -cleanup {
    array unset A
    rename doit {}
} -result 0
test var-22.2 {leak in parsedVarName} -constraints memory -body {
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
} -returnCodes error -body {
    array for {k v} a {}
} -result {"a" isn't an array}
test var-23.6 {array command, for loop, array doesn't exist yet but has compiler-allocated procedure slot} -setup {
    catch {rename p ""}
} -returnCodes error -body {
    apply {{x} {
        if {$x==1} {
            return [array for {k v} a {}]
        }
        set a(x) 123
    }} 1
} -result {"a" isn't an array}
test var-23.7 {array enumeration} -setup {
    unset -nocomplain a
    set reslist [list]
} -body {
    array set a {a 1 b 2 c 3}







|
|
|
|







1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
} -returnCodes error -body {
    array for {k v} a {}
} -result {"a" isn't an array}
test var-23.6 {array command, for loop, array doesn't exist yet but has compiler-allocated procedure slot} -setup {
    catch {rename p ""}
} -returnCodes error -body {
    apply {{x} {
	if {$x==1} {
	    return [array for {k v} a {}]
	}
	set a(x) 123
    }} 1
} -result {"a" isn't an array}
test var-23.7 {array enumeration} -setup {
    unset -nocomplain a
    set reslist [list]
} -body {
    array set a {a 1 b 2 c 3}
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
    unset -nocomplain a
    set reslist [list]
} -body {
    set retval {}
    try {
      array set a {a 1 b 2 c 3 d 4}
      array for {k v} a {
  	lappend reslist $k $v
          if { $k eq "a" } {
            unset a(c)
          }
      }
      lsort -stride 2 -index 0 $reslist
    } on error {err res} {
      set retval [dict get $res -errorinfo]
    }
    set retval
} -cleanup {
    unset -nocomplain a
    unset -nocomplain reslist
    unset -nocomplain retval
} -result {array changed during iteration*}
test var-23.11 {array enumeration, insert key} -match glob -setup {
    unset -nocomplain a
    set reslist [list]
} -body {
    set retval {}
    try {
      array set a {a 1 b 2 c 3 d 4}
      array for {k v} a {
  	lappend reslist $k $v
          if { $k eq "a" } {
            set a(e) 5
          }
      }
      lsort -stride 2 -index 0 $reslist
    } on error {err res} {
      set retval [dict get $res -errorinfo]
    }
} -cleanup {
    unset -nocomplain a
    unset -nocomplain reslist
} -result {array changed during iteration*}
test var-23.12 {array enumeration, change value} -setup {
    unset -nocomplain a
    set reslist [list]
} -body {
    array set a {a 1 b 2 c 3}
    array for {k v} a {
	lappend reslist $k $v
        if { $k eq "a" } {
          set a(c) 9
        }
    }
    lsort -stride 2 -index 0 $reslist
} -cleanup {
    unset -nocomplain a
    unset -nocomplain reslist
} -result {a 1 b 2 c 9}
test var-23.13 {array enumeration, number of traces} -setup {







|
|
|
|



















|
|
|
|
















|
|
|







1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
    unset -nocomplain a
    set reslist [list]
} -body {
    set retval {}
    try {
      array set a {a 1 b 2 c 3 d 4}
      array for {k v} a {
	lappend reslist $k $v
	  if { $k eq "a" } {
	    unset a(c)
	  }
      }
      lsort -stride 2 -index 0 $reslist
    } on error {err res} {
      set retval [dict get $res -errorinfo]
    }
    set retval
} -cleanup {
    unset -nocomplain a
    unset -nocomplain reslist
    unset -nocomplain retval
} -result {array changed during iteration*}
test var-23.11 {array enumeration, insert key} -match glob -setup {
    unset -nocomplain a
    set reslist [list]
} -body {
    set retval {}
    try {
      array set a {a 1 b 2 c 3 d 4}
      array for {k v} a {
	lappend reslist $k $v
	  if { $k eq "a" } {
	    set a(e) 5
	  }
      }
      lsort -stride 2 -index 0 $reslist
    } on error {err res} {
      set retval [dict get $res -errorinfo]
    }
} -cleanup {
    unset -nocomplain a
    unset -nocomplain reslist
} -result {array changed during iteration*}
test var-23.12 {array enumeration, change value} -setup {
    unset -nocomplain a
    set reslist [list]
} -body {
    array set a {a 1 b 2 c 3}
    array for {k v} a {
	lappend reslist $k $v
	if { $k eq "a" } {
	  set a(c) 9
	}
    }
    lsort -stride 2 -index 0 $reslist
} -cleanup {
    unset -nocomplain a
    unset -nocomplain reslist
} -result {a 1 b 2 c 9}
test var-23.13 {array enumeration, number of traces} -setup {
Changes to tests/while-old.test.
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
    }
    set value
} 6
test while-old-1.4 {basic while loops, multiline test expr} {
    set value 1
    while {($tcl_platform(platform) != "foobar1") && \
	    ($tcl_platform(platform) != "foobar2")} {
        incr value
        break
    }
    set value
} {2}
test while-old-1.5 {basic while loops, test expr in quotes} {
    set value 1
    while "0 < 3" {set value 2; break}
    set value







|
|







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
    }
    set value
} 6
test while-old-1.4 {basic while loops, multiline test expr} {
    set value 1
    while {($tcl_platform(platform) != "foobar1") && \
	    ($tcl_platform(platform) != "foobar2")} {
	incr value
	break
    }
    set value
} {2}
test while-old-1.5 {basic while loops, test expr in quotes} {
    set value 1
    while "0 < 3" {set value 2; break}
    set value
Changes to tests/while.test.
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
test while-1.3 {TclCompileWhileCmd: error in test expression} -body {
    while {"a"+"b"} {error "loop aborted"}
} -returnCodes error -result {cannot use non-numeric string "a" as left operand of "+"}
test while-1.4 {TclCompileWhileCmd: multiline test expr} -body {
    set value 1
    while {($tcl_platform(platform) != "foobar1") && \
	    ($tcl_platform(platform) != "foobar2")} {
        incr value
        break
    }
    return $value
} -cleanup {
    unset value
} -result {2}
test while-1.5 {TclCompileWhileCmd: non-numeric boolean test expr} -body {
    set value 1







|
|







33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
test while-1.3 {TclCompileWhileCmd: error in test expression} -body {
    while {"a"+"b"} {error "loop aborted"}
} -returnCodes error -result {cannot use non-numeric string "a" as left operand of "+"}
test while-1.4 {TclCompileWhileCmd: multiline test expr} -body {
    set value 1
    while {($tcl_platform(platform) != "foobar1") && \
	    ($tcl_platform(platform) != "foobar2")} {
	incr value
	break
    }
    return $value
} -cleanup {
    unset value
} -result {2}
test while-1.5 {TclCompileWhileCmd: non-numeric boolean test expr} -body {
    set value 1
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
"set"*}
test while-1.9 {TclCompileWhileCmd: simple command body} -body {
    set a {}
    set i 1
    while {$i<6} {
	if {$i==4} break
	set a [concat $a $i]
        incr i
    }
    return $a
} -cleanup {
    unset a i
} -result {1 2 3}
test while-1.10 {TclCompileWhileCmd: command body in quotes} -body {
    set a {}







|







75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
"set"*}
test while-1.9 {TclCompileWhileCmd: simple command body} -body {
    set a {}
    set i 1
    while {$i<6} {
	if {$i==4} break
	set a [concat $a $i]
	incr i
    }
    return $a
} -cleanup {
    unset a i
} -result {1 2 3}
test while-1.10 {TclCompileWhileCmd: command body in quotes} -body {
    set a {}
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	set a [concat $a $i]
        incr i
    }
    return $a
} -cleanup {
    unset a i
} -result {1 2 3}
test while-1.13 {TclCompileWhileCmd: while command result} -body {
    set i 0







|







136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	set a [concat $a $i]
	incr i
    }
    return $a
} -cleanup {
    unset a i
} -result {1 2 3}
test while-1.13 {TclCompileWhileCmd: while command result} -body {
    set i 0
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207

# Check "while" and "continue".

test while-2.1 {continue tests} -body {
    set a {}
    set i 1
    while {$i <= 4} {
        incr i
	if {$i == 3} continue
	set a [concat $a $i]
    }
    return $a
} -cleanup {
    unset a i
} -result {2 4 5}
test while-2.2 {continue tests} -body {
    set a {}
    set i 1
    while {$i <= 4} {
        incr i
	if {$i != 2} continue
	set a [concat $a $i]
    }
    return $a
} -cleanup {
    unset a i
} -result {2}
test while-2.3 {continue tests, nested loops} -body {
    set msg {}
    set i 1
    while {$i <= 4} {
        incr i
        set a 1
	while {$a <= 2} {
            incr a
            if {$i>=3 && $a>=3} continue
            set msg [concat $msg "$i.$a"]
        }
    }
    return $msg
} -cleanup {
    unset a i msg
} -result {2.2 2.3 3.2 4.2 5.2}
test while-2.4 {continue tests, long command body} -body {
    set a {}







|











|











|
|

|
|
|
|







163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207

# Check "while" and "continue".

test while-2.1 {continue tests} -body {
    set a {}
    set i 1
    while {$i <= 4} {
	incr i
	if {$i == 3} continue
	set a [concat $a $i]
    }
    return $a
} -cleanup {
    unset a i
} -result {2 4 5}
test while-2.2 {continue tests} -body {
    set a {}
    set i 1
    while {$i <= 4} {
	incr i
	if {$i != 2} continue
	set a [concat $a $i]
    }
    return $a
} -cleanup {
    unset a i
} -result {2}
test while-2.3 {continue tests, nested loops} -body {
    set msg {}
    set i 1
    while {$i <= 4} {
	incr i
	set a 1
	while {$a <= 2} {
	    incr a
	    if {$i>=3 && $a>=3} continue
	    set msg [concat $msg "$i.$a"]
	}
    }
    return $msg
} -cleanup {
    unset a i msg
} -result {2.2 2.3 3.2 4.2 5.2}
test while-2.4 {continue tests, long command body} -body {
    set a {}
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	set a [concat $a $i]
        incr i
    }
    return $a
} -cleanup {
    unset a i
} -result {1 3}

# Check "while" and "break".

test while-3.1 {break tests} -body {
    set a {}
    set i 1
    while {$i <= 4} {
	if {$i == 3} break
	set a [concat $a $i]
        incr i
    }
    return $a
} -cleanup {
    unset a i
} -result {1 2}
test while-3.2 {break tests, nested loops} -body {
    set msg {}
    set i 1
    while {$i <= 4} {
        set a 1
	while {$a <= 2} {
            if {$i>=2 && $a>=2} break
            set msg [concat $msg "$i.$a"]
            incr a
        }
        incr i
    }
    return $msg
} -cleanup {
    unset a i msg
} -result {1.1 1.2 2.1 3.1 4.1}
test while-3.3 {break tests, long command body} -body {
    set a {}







|














|









|

|
|
|
|
|







232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	set a [concat $a $i]
	incr i
    }
    return $a
} -cleanup {
    unset a i
} -result {1 3}

# Check "while" and "break".

test while-3.1 {break tests} -body {
    set a {}
    set i 1
    while {$i <= 4} {
	if {$i == 3} break
	set a [concat $a $i]
	incr i
    }
    return $a
} -cleanup {
    unset a i
} -result {1 2}
test while-3.2 {break tests, nested loops} -body {
    set msg {}
    set i 1
    while {$i <= 4} {
	set a 1
	while {$a <= 2} {
	    if {$i>=2 && $a>=2} break
	    set msg [concat $msg "$i.$a"]
	    incr a
	}
	incr i
    }
    return $msg
} -cleanup {
    unset a i msg
} -result {1.1 1.2 2.1 3.1 4.1}
test while-3.3 {break tests, long command body} -body {
    set a {}
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	set a [concat $a $i]
        incr i
    }
    return $a
} -cleanup {
    unset a i
} -result {1 3}

# Check "while" with computed command names.

test while-4.1 {while and computed command names} -body {
    set i 0
    set z while
    $z {$i < 10} {
        incr i
    }
    return $i
} -cleanup {
    unset i z
} -result 10
test while-4.2 {while (not compiled): missing test expression} -body {
    set z while







|












|







303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	set a [concat $a $i]
	incr i
    }
    return $a
} -cleanup {
    unset a i
} -result {1 3}

# Check "while" with computed command names.

test while-4.1 {while and computed command names} -body {
    set i 0
    set z while
    $z {$i < 10} {
	incr i
    }
    return $i
} -cleanup {
    unset i z
} -result 10
test while-4.2 {while (not compiled): missing test expression} -body {
    set z while
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
    $z {"a"+"b"} {error "loop aborted"}
} -returnCodes error -result {cannot use non-numeric string "a" as left operand of "+"}
test while-4.5 {while (not compiled): multiline test expr} -body {
    set value 1
    set z while
    $z {($tcl_platform(platform) != "foobar1") && \
	    ($tcl_platform(platform) != "foobar2")} {
        incr value
        break
    }
    return $value
} -cleanup {
    unset value z
} -result {2}
test while-4.6 {while (not compiled): non-numeric boolean test expr} -body {
    set value 1







|
|







345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
    $z {"a"+"b"} {error "loop aborted"}
} -returnCodes error -result {cannot use non-numeric string "a" as left operand of "+"}
test while-4.5 {while (not compiled): multiline test expr} -body {
    set value 1
    set z while
    $z {($tcl_platform(platform) != "foobar1") && \
	    ($tcl_platform(platform) != "foobar2")} {
	incr value
	break
    }
    return $value
} -cleanup {
    unset value z
} -result {2}
test while-4.6 {while (not compiled): non-numeric boolean test expr} -body {
    set value 1
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
test while-4.10 {while (not compiled): simple command body} -body {
    set a {}
    set i 1
    set z while
    $z {$i<6} {
	if {$i==4} break
	set a [concat $a $i]
        incr i
    }
    return $a
} -cleanup {
    unset a i z
} -result {1 2 3}
test while-4.11 {while (not compiled): command body in quotes} -body {
    set a {}







|







399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
test while-4.10 {while (not compiled): simple command body} -body {
    set a {}
    set i 1
    set z while
    $z {$i<6} {
	if {$i==4} break
	set a [concat $a $i]
	incr i
    }
    return $a
} -cleanup {
    unset a i z
} -result {1 2 3}
test while-4.11 {while (not compiled): command body in quotes} -body {
    set a {}
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	set a [concat $a $i]
        incr i
    }
    return $a
} -cleanup {
    unset a i z
} -result {1 2 3}
test while-4.14 {while (not compiled): while command result} -body {
    set i 0







|







463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	set a [concat $a $i]
	incr i
    }
    return $a
} -cleanup {
    unset a i z
} -result {1 2 3}
test while-4.14 {while (not compiled): while command result} -body {
    set i 0
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537

# Check "break" with computed command names.

test while-5.1 {break and computed command names} -body {
    set i 0
    set z break
    while 1 {
        if {$i > 10} $z
        incr i
    }
    return $i
} -cleanup {
    unset i z
} -result 11
test while-5.2 {break tests with computed command names} -body {
    set a {}
    set i 1
    set z break
    while {$i <= 4} {
	if {$i == 3} $z
	set a [concat $a $i]
        incr i
    }
    return $a
} -cleanup {
    unset a i z
} -result {1 2}
test while-5.3 {break tests, nested loops with computed command names} -body {
    set msg {}
    set i 1
    set z break
    while {$i <= 4} {
        set a 1
	while {$a <= 2} {
            if {$i>=2 && $a>=2} $z
            set msg [concat $msg "$i.$a"]
            incr a
        }
        incr i
    }
    return $msg
} -cleanup {
    unset a i z msg
} -result {1.1 1.2 2.1 3.1 4.1}
test while-5.4 {break tests, long command body with computed command names} -body {
    set a {}







|
|












|










|

|
|
|
|
|







492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537

# Check "break" with computed command names.

test while-5.1 {break and computed command names} -body {
    set i 0
    set z break
    while 1 {
	if {$i > 10} $z
	incr i
    }
    return $i
} -cleanup {
    unset i z
} -result 11
test while-5.2 {break tests with computed command names} -body {
    set a {}
    set i 1
    set z break
    while {$i <= 4} {
	if {$i == 3} $z
	set a [concat $a $i]
	incr i
    }
    return $a
} -cleanup {
    unset a i z
} -result {1 2}
test while-5.3 {break tests, nested loops with computed command names} -body {
    set msg {}
    set i 1
    set z break
    while {$i <= 4} {
	set a 1
	while {$a <= 2} {
	    if {$i>=2 && $a>=2} $z
	    set msg [concat $msg "$i.$a"]
	    incr a
	}
	incr i
    }
    return $msg
} -cleanup {
    unset a i z msg
} -result {1.1 1.2 2.1 3.1 4.1}
test while-5.4 {break tests, long command body with computed command names} -body {
    set a {}
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	set a [concat $a $i]
        incr i
    }
    return $a
} -cleanup {
    unset a i z
} -result {1 3}

# Check "continue" with computed command names.

test while-6.1 {continue and computed command names} -body {
    set i 0
    set z continue
    while 1 {
        incr i
        if {$i < 10} $z
        break
    }
    return $i
} -cleanup {
    unset i z
} -result 10
test while-6.2 {continue tests} -body {
    set a {}
    set i 1
    set z continue
    while {$i <= 4} {
        incr i
	if {$i == 3} $z
	set a [concat $a $i]
    }
    return $a
} -cleanup {
    unset a i z
} -result {2 4 5}
test while-6.3 {continue tests with computed command names} -body {
    set a {}
    set i 1
    set z continue
    while {$i <= 4} {
        incr i
	if {$i != 2} $z
	set a [concat $a $i]
    }
    return $a
} -cleanup {
    unset a i z
} -result {2}
test while-6.4 {continue tests, nested loops with computed command names} -body {
    set msg {}
    set i 1
    set z continue
    while {$i <= 4} {
        incr i
        set a 1
	while {$a <= 2} {
            incr a
            if {$i>=3 && $a>=3} $z
            set msg [concat $msg "$i.$a"]
        }
    }
    return $msg
} -cleanup {
    unset a i z msg
} -result {2.2 2.3 3.2 4.2 5.2}
test while-6.5 {continue tests, long command body with computed command names} -body {
    set a {}







|












|
|
|










|












|












|
|

|
|
|
|







564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	set a [concat $a $i]
	incr i
    }
    return $a
} -cleanup {
    unset a i z
} -result {1 3}

# Check "continue" with computed command names.

test while-6.1 {continue and computed command names} -body {
    set i 0
    set z continue
    while 1 {
	incr i
	if {$i < 10} $z
	break
    }
    return $i
} -cleanup {
    unset i z
} -result 10
test while-6.2 {continue tests} -body {
    set a {}
    set i 1
    set z continue
    while {$i <= 4} {
	incr i
	if {$i == 3} $z
	set a [concat $a $i]
    }
    return $a
} -cleanup {
    unset a i z
} -result {2 4 5}
test while-6.3 {continue tests with computed command names} -body {
    set a {}
    set i 1
    set z continue
    while {$i <= 4} {
	incr i
	if {$i != 2} $z
	set a [concat $a $i]
    }
    return $a
} -cleanup {
    unset a i z
} -result {2}
test while-6.4 {continue tests, nested loops with computed command names} -body {
    set msg {}
    set i 1
    set z continue
    while {$i <= 4} {
	incr i
	set a 1
	while {$a <= 2} {
	    incr a
	    if {$i>=3 && $a>=3} $z
	    set msg [concat $msg "$i.$a"]
	}
    }
    return $msg
} -cleanup {
    unset a i z msg
} -result {2.2 2.3 3.2 4.2 5.2}
test while-6.5 {continue tests, long command body with computed command names} -body {
    set a {}
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	set a [concat $a $i]
        incr i
    }
    return $a
} -cleanup {
    unset a i z
} -result {1 3}

# Test for incorrect "double evaluation" semantics







|







662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	set a [concat $a $i]
	incr i
    }
    return $a
} -cleanup {
    unset a i z
} -result {1 3}

# Test for incorrect "double evaluation" semantics
Changes to tests/winConsole.test.
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# Prompt user for a yes/no response
proc yesno {question {default "Y"}} {
    set answer ""
    # Make sure we are seen but catch because ui and console
    # packages may not be available
    catch {twapi::set_foreground_window [twapi::get_console_window]}
    while {![string is boolean -strict $answer]} {
        puts -nonewline stdout "$question Type Y/N followed by Enter \[$default\] : "
        flush stdout
        set answer [string trim [gets stdin]]
        if {$answer eq ""} {
            set answer $default
        }
    }
    return [expr {!! $answer}]
}

proc prompt {prompt} {
    # Make sure we are seen but catch because twapi ui and console
    # packages may not be available







|
|
|
|
|
|







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# Prompt user for a yes/no response
proc yesno {question {default "Y"}} {
    set answer ""
    # Make sure we are seen but catch because ui and console
    # packages may not be available
    catch {twapi::set_foreground_window [twapi::get_console_window]}
    while {![string is boolean -strict $answer]} {
	puts -nonewline stdout "$question Type Y/N followed by Enter \[$default\] : "
	flush stdout
	set answer [string trim [gets stdin]]
	if {$answer eq ""} {
	    set answer $default
	}
    }
    return [expr {!! $answer}]
}

proc prompt {prompt} {
    # Make sure we are seen but catch because twapi ui and console
    # packages may not be available
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
} -body {
    set oldmode [fconfigure stdin]

    prompt "Type \"abc\" and hit Enter: "
    fileevent stdin readable {
	if {[gets stdin line] >= 0} {
	    lappend result2 $line
            if {[llength $result2] > 1} {
                set result $result2
            } else {
                prompt "Type \"def\" and hit Enter: "
            }
	} elseif {[eof stdin]} {
	    set result "gets failed"
	}
    }

    fconfigure stdin -blocking 0 -buffering line








|
|
|
|
|







58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
} -body {
    set oldmode [fconfigure stdin]

    prompt "Type \"abc\" and hit Enter: "
    fileevent stdin readable {
	if {[gets stdin line] >= 0} {
	    lappend result2 $line
	    if {[llength $result2] > 1} {
		set result $result2
	    } else {
		prompt "Type \"def\" and hit Enter: "
	    }
	} elseif {[eof stdin]} {
	    set result "gets failed"
	}
    }

    fconfigure stdin -blocking 0 -buffering line

89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
    unset -nocomplain result
    unset -nocomplain result2
} -body {
    prompt "Type \"abc\" and hit Enter: "
    fileevent stdin readable {
	if {[gets stdin line] >= 0} {
	    lappend result2 $line
            if {[llength $result2] > 1} {
                set result $result2
            } else {
                prompt "Type \"def\" and hit Enter: "
            }
	} elseif {[eof stdin]} {
	    set result "gets failed"
	}
    }

    vwait result








|
|
|
|
|







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
    unset -nocomplain result
    unset -nocomplain result2
} -body {
    prompt "Type \"abc\" and hit Enter: "
    fileevent stdin readable {
	if {[gets stdin line] >= 0} {
	    lappend result2 $line
	    if {[llength $result2] > 1} {
		set result $result2
	    } else {
		prompt "Type \"def\" and hit Enter: "
	    }
	} elseif {[eof stdin]} {
	    set result "gets failed"
	}
    }

    vwait result

132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
    puts ""; # Because CRLF also would not have been echoed
} -body {
    set input ""
    fconfigure stdin -blocking 0 -buffering line -inputmode raw
    prompt "Type \"abc\". Do NOT hit Enter. You will NOT see characters echoed."

    fileevent stdin readable {
        set c [read stdin 1]
        if {$c eq ""} {
            if {[eof stdin]} {
                set result "read eof"
            }
        } else {
            append input $c
            if {[string length $input] == 3} {
                set result $input
            }
        }
    }

    set result {}
    vwait result
    fileevent stdin readable {}
    set result
} -result abc







|
|
|
|
|
|
|
|
|
|
|







132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
    puts ""; # Because CRLF also would not have been echoed
} -body {
    set input ""
    fconfigure stdin -blocking 0 -buffering line -inputmode raw
    prompt "Type \"abc\". Do NOT hit Enter. You will NOT see characters echoed."

    fileevent stdin readable {
	set c [read stdin 1]
	if {$c eq ""} {
	    if {[eof stdin]} {
		set result "read eof"
	    }
	} else {
	    append input $c
	    if {[string length $input] == 3} {
		set result $input
	    }
	}
    }

    set result {}
    vwait result
    fileevent stdin readable {}
    set result
} -result abc
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206

test console-input-3.2 {Console gets nonblocking - long lines bug-bda99f2393} -constraints {
    win interactive
} -body {
    prompt "Try typing a line of at least 256 characters. Hit ENTER exactly once unless you don't see another prompt.\n"
    fconfigure stdin -blocking 0
    while {[gets stdin line] < 0} {
        after 1000
    }
    fconfigure stdin -blocking 1
    set len [string length $line]
    list [yesno "Did you hit ENTER only once?"] [expr {$len > 256}] [yesno "Line length was $len characters. Is this correct?"]
} -result {1 1 1}

test console-input-3.3 {Console gets nonblocking small channel buffer size - long lines bug-bda99f2393} -constraints {
    win interactive
} -body {
    prompt "Try typing a line of at least 256 characters. Hit ENTER exactly once unless you don't see another prompt.\n"
    set bufSize [fconfigure stdin -buffersize]
    fconfigure stdin -blocking 0 -buffersize 10
    while {[gets stdin line] < 0} {
        after 1000
    }
    fconfigure stdin -blocking 1 -buffersize $bufSize
    set len [string length $line]
    list [yesno "Did you hit ENTER only once?"] [expr {$len > 256}] [yesno "Line length was $len characters. Is this correct?"]
} -result {1 1 1}

# Output tests







|













|







178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206

test console-input-3.2 {Console gets nonblocking - long lines bug-bda99f2393} -constraints {
    win interactive
} -body {
    prompt "Try typing a line of at least 256 characters. Hit ENTER exactly once unless you don't see another prompt.\n"
    fconfigure stdin -blocking 0
    while {[gets stdin line] < 0} {
	after 1000
    }
    fconfigure stdin -blocking 1
    set len [string length $line]
    list [yesno "Did you hit ENTER only once?"] [expr {$len > 256}] [yesno "Line length was $len characters. Is this correct?"]
} -result {1 1 1}

test console-input-3.3 {Console gets nonblocking small channel buffer size - long lines bug-bda99f2393} -constraints {
    win interactive
} -body {
    prompt "Try typing a line of at least 256 characters. Hit ENTER exactly once unless you don't see another prompt.\n"
    set bufSize [fconfigure stdin -buffersize]
    fconfigure stdin -blocking 0 -buffersize 10
    while {[gets stdin line] < 0} {
	after 1000
    }
    fconfigure stdin -blocking 1 -buffersize $bufSize
    set len [string length $line]
    list [yesno "Did you hit ENTER only once?"] [expr {$len > 256}] [yesno "Line length was $len characters. Is this correct?"]
} -result {1 1 1}

# Output tests
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
    dict unset oldmode -winsize
} -cleanup {
    fconfigure stdout {*}$oldmode
} -body {
    fconfigure stdout -blocking 0 -buffering line
    set count 0
    fileevent stdout writable {
        if {[incr count] < 4} {
            puts "$count"
        } else {
            fileevent stdout writable {}
            set done 1
        }
    }
    vwait done
    yesno "Did you see 1, 2, 3 printed on consecutive lines?"
} -result 1

test console-output-2.0 {Console blocking puts stderr} -constraints {win interactive} -body {
    puts stderr "456"







|
|
|
|
|
|







217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
    dict unset oldmode -winsize
} -cleanup {
    fconfigure stdout {*}$oldmode
} -body {
    fconfigure stdout -blocking 0 -buffering line
    set count 0
    fileevent stdout writable {
	if {[incr count] < 4} {
	    puts "$count"
	} else {
	    fileevent stdout writable {}
	    set done 1
	}
    }
    vwait done
    yesno "Did you see 1, 2, 3 printed on consecutive lines?"
} -result 1

test console-output-2.0 {Console blocking puts stderr} -constraints {win interactive} -body {
    puts stderr "456"
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
    -buffering line
    -buffersize 4096
    -encoding utf-16
    -inputmode normal
    -translation auto
} {
    test console-fconfigure-get-1.[incr testnum] "Console get stdin option $opt" \
        -constraints {win interactive} -body {
        fconfigure stdin $opt
    } -result $result
}
test console-fconfigure-get-1.[incr testnum] {
    Console get stdin option -eofchar
} -constraints {win interactive} -body {
    fconfigure stdin -eofchar
} -result ""

test console-fconfigure-get-1.[incr testnum] {
    fconfigure -winsize
} -constraints {win interactive} -body {
    fconfigure stdin -winsize
} -result {bad option "-winsize": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -profile, -translation, or -inputmode} -returnCodes error

## fconfigure get stdout/stderr
foreach chan {stdout stderr} major {2 3} {
    test console-fconfigure-get-$major.0 "Console get $chan configuration" -constraints {
        win interactive
    } -body {
        lsort [dict keys [fconfigure $chan]]
    } -result {-blocking -buffering -buffersize -encoding -eofchar -profile -translation -winsize}
    set testnum 0
    foreach {opt result} {
        -blocking 1
        -buffersize 4096
        -encoding utf-16
        -translation crlf
    } {
        test console-fconfigure-get-$major.[incr testnum] "Console get $chan option $opt" \
            -constraints {win interactive} -body {
                fconfigure $chan $opt
            } -result $result
    }

    test console-fconfigure-get-$major.[incr testnum] "Console get $chan option -winsize" \
        -constraints {win interactive} -body {
        fconfigure $chan -winsize
    } -result {\d+ \d+} -match regexp

    test console-fconfigure-get-$major.[incr testnum] "Console get $chan option -buffering" \
        -constraints {win interactive} -body {
        fconfigure $chan -buffering
    } -result [expr {$chan eq "stdout" ? "line" : "none"}]

    test console-fconfigure-get-$major.[incr testnum] {
        fconfigure -inputmode
    } -constraints {win interactive} -body {
        fconfigure $chan -inputmode
    } -result {bad option "-inputmode": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -profile, -translation, or -winsize} -returnCodes error

}

## fconfigure set stdin

test console-fconfigure-set-1.0 {







|
|

















|

|



|
|
|
|

|
|
|
|



|
|



|
|



|

|







254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
    -buffering line
    -buffersize 4096
    -encoding utf-16
    -inputmode normal
    -translation auto
} {
    test console-fconfigure-get-1.[incr testnum] "Console get stdin option $opt" \
	-constraints {win interactive} -body {
	fconfigure stdin $opt
    } -result $result
}
test console-fconfigure-get-1.[incr testnum] {
    Console get stdin option -eofchar
} -constraints {win interactive} -body {
    fconfigure stdin -eofchar
} -result ""

test console-fconfigure-get-1.[incr testnum] {
    fconfigure -winsize
} -constraints {win interactive} -body {
    fconfigure stdin -winsize
} -result {bad option "-winsize": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -profile, -translation, or -inputmode} -returnCodes error

## fconfigure get stdout/stderr
foreach chan {stdout stderr} major {2 3} {
    test console-fconfigure-get-$major.0 "Console get $chan configuration" -constraints {
	win interactive
    } -body {
	lsort [dict keys [fconfigure $chan]]
    } -result {-blocking -buffering -buffersize -encoding -eofchar -profile -translation -winsize}
    set testnum 0
    foreach {opt result} {
	-blocking 1
	-buffersize 4096
	-encoding utf-16
	-translation crlf
    } {
	test console-fconfigure-get-$major.[incr testnum] "Console get $chan option $opt" \
	    -constraints {win interactive} -body {
		fconfigure $chan $opt
	    } -result $result
    }

    test console-fconfigure-get-$major.[incr testnum] "Console get $chan option -winsize" \
	-constraints {win interactive} -body {
	fconfigure $chan -winsize
    } -result {\d+ \d+} -match regexp

    test console-fconfigure-get-$major.[incr testnum] "Console get $chan option -buffering" \
	-constraints {win interactive} -body {
	fconfigure $chan -buffering
    } -result [expr {$chan eq "stdout" ? "line" : "none"}]

    test console-fconfigure-get-$major.[incr testnum] {
	fconfigure -inputmode
    } -constraints {win interactive} -body {
	fconfigure $chan -inputmode
    } -result {bad option "-inputmode": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -profile, -translation, or -winsize} -returnCodes error

}

## fconfigure set stdin

test console-fconfigure-set-1.0 {
Changes to tests/winDde.test.
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
    file delete -force $::scriptName

    set f [open $::scriptName w+]
    fconfigure $f -encoding utf-8
    puts $f [list set ddeServerName $ddeServerName]
    puts $f [list load $::ddelib Dde]
    puts $f {
        # DDE child server -
        #
	if {"::tcltest" ni [namespace children]} {
	    package require tcltest 2.5
	    namespace import -force ::tcltest::*
	}

        # If an error occurs during the tests, this process may end up not
        # being closed down. To deal with this we create a 30s timeout.
        proc ::DoTimeout {} {
            global done ddeServerName
            set done 1
            puts "winDde.test child process $ddeServerName timed out."
            flush stdout
        }
        set timeout [after 30000 ::DoTimeout]

        # Define a restricted handler.
        proc Handler1 {cmd} {
            if {$cmd eq "stop"} {set ::done 1}
            if {$cmd == ""} {
                set cmd "null data"
            }
            puts $cmd ; flush stdout
            return
        }
        proc Handler2 {cmd} {
            if {$cmd eq "stop"} {set ::done 1}
            puts [uplevel \#0 $cmd] ; flush stdout
            return
        }
        proc Handler3 {prefix cmd} {
            if {$cmd eq "stop"} {set ::done 1}
            puts [list $prefix $cmd] ; flush stdout
            return
        }
    }
    # set the dde server name to the supplied argument.
    puts $f [list dde servername {*}$args -- $ddeServerName]
    puts $f {
        # run the server and handle final cleanup.
        after 200;# give dde a chance to get going.
	puts ready
        flush stdout
	vwait done
	# allow enough time for the calling process to
	# claim all results, to avoid spurious "server did
	# not respond"
	after 200 {set reallyDone 1}
	vwait reallyDone
	exit







|
|





|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|




|
|

|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
    file delete -force $::scriptName

    set f [open $::scriptName w+]
    fconfigure $f -encoding utf-8
    puts $f [list set ddeServerName $ddeServerName]
    puts $f [list load $::ddelib Dde]
    puts $f {
	# DDE child server -
	#
	if {"::tcltest" ni [namespace children]} {
	    package require tcltest 2.5
	    namespace import -force ::tcltest::*
	}

	# If an error occurs during the tests, this process may end up not
	# being closed down. To deal with this we create a 30s timeout.
	proc ::DoTimeout {} {
	    global done ddeServerName
	    set done 1
	    puts "winDde.test child process $ddeServerName timed out."
	    flush stdout
	}
	set timeout [after 30000 ::DoTimeout]

	# Define a restricted handler.
	proc Handler1 {cmd} {
	    if {$cmd eq "stop"} {set ::done 1}
	    if {$cmd == ""} {
		set cmd "null data"
	    }
	    puts $cmd ; flush stdout
	    return
	}
	proc Handler2 {cmd} {
	    if {$cmd eq "stop"} {set ::done 1}
	    puts [uplevel \#0 $cmd] ; flush stdout
	    return
	}
	proc Handler3 {prefix cmd} {
	    if {$cmd eq "stop"} {set ::done 1}
	    puts [list $prefix $cmd] ; flush stdout
	    return
	}
    }
    # set the dde server name to the supplied argument.
    puts $f [list dde servername {*}$args -- $ddeServerName]
    puts $f {
	# run the server and handle final cleanup.
	after 200;# give dde a chance to get going.
	puts ready
	flush stdout
	vwait done
	# allow enough time for the calling process to
	# claim all results, to avoid spurious "server did
	# not respond"
	after 200 {set reallyDone 1}
	vwait reallyDone
	exit
Changes to tests/winFCmd.test.
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
}

proc cleanupRecurse {args} {
    # Assumes no loops via links!
    # Need to change permissions BEFORE deletion
    catch {testchmod 0o777 {*}$args}
    foreach victim $args {
        if {[file isdirectory $victim]} {
            cleanupRecurse {*}[glob -nocomplain -directory $victim td* tf* Test*]
        }
        file delete -force $victim
    }
}
proc cleanup {args} {
    foreach p [list [pwd] {*}$args] {
        cleanupRecurse {*}[glob -nocomplain -directory $p tf* td*]
    }
}

# find a CD-ROM so we can test read-only filesystems.

proc findfile {dir} {
    foreach p [glob -nocomplain -type f -directory $dir *] {
	return $p
    }
    foreach p [glob -nocomplain -type d -directory $dir *] {
	set f [findfile $p]
	if {$f ne ""} {
	    return $f
	}
    }
    return ""
}

if {[testConstraint testvolumetype]} {
    foreach p {d e f g h i j k l m n o p q r s t u v w x y z} {
        if {![catch {testvolumetype ${p}:} result] && $result in {CDFS UDF}} {
            set cdrom ${p}:
	    set cdfile [findfile $cdrom]
	    testConstraint cdrom 1
	    break
        }
    }
}

# NB: filename is chosen to be short but unlikely to clash with other apps
if {[file exists c:/] && [file exists d:/]} {
    catch {file delete d:/TclTmpF.1}
    catch {file delete d:/TclTmpD.1}







|
|
|
|




|




















|
|



|







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
}

proc cleanupRecurse {args} {
    # Assumes no loops via links!
    # Need to change permissions BEFORE deletion
    catch {testchmod 0o777 {*}$args}
    foreach victim $args {
	if {[file isdirectory $victim]} {
	    cleanupRecurse {*}[glob -nocomplain -directory $victim td* tf* Test*]
	}
	file delete -force $victim
    }
}
proc cleanup {args} {
    foreach p [list [pwd] {*}$args] {
	cleanupRecurse {*}[glob -nocomplain -directory $p tf* td*]
    }
}

# find a CD-ROM so we can test read-only filesystems.

proc findfile {dir} {
    foreach p [glob -nocomplain -type f -directory $dir *] {
	return $p
    }
    foreach p [glob -nocomplain -type d -directory $dir *] {
	set f [findfile $p]
	if {$f ne ""} {
	    return $f
	}
    }
    return ""
}

if {[testConstraint testvolumetype]} {
    foreach p {d e f g h i j k l m n o p q r s t u v w x y z} {
	if {![catch {testvolumetype ${p}:} result] && $result in {CDFS UDF}} {
	    set cdrom ${p}:
	    set cdfile [findfile $cdrom]
	    testConstraint cdrom 1
	    break
	}
    }
}

# NB: filename is chosen to be short but unlikely to clash with other apps
if {[file exists c:/] && [file exists d:/]} {
    catch {file delete d:/TclTmpF.1}
    catch {file delete d:/TclTmpD.1}
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
    expr {$statExe(ino) != 0}
}]

proc MakeFiles {dirname} {
    set inodes {}
    set ndx -1
    while {1} {
        # upped to 50K for 64bit Server 2008
        if {$ndx > 50000} {
            tcltest::Skip "limit-reached:no-collistion"
        }
        set filename [file join $dirname Test[incr ndx]]
        set f [open $filename w]
        close $f
        file stat $filename stat
        if {[set n [lsearch -exact -integer $inodes $stat(ino)]] >= 0} {
            return [list [file join $dirname Test$n] $filename]
        }
        lappend inodes $stat(ino)
        unset stat
    }
}

test winFCmd-1.38 {TclpRenameFile: check rename of conflicting inodes} -setup {
    cleanup
} -constraints {win winNonZeroInodes knownMsvcBug notInCIenv extensive} -body {
    file mkdir td1







|
|
|
|
|
|
|
|
|
|
|
|
|







361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
    expr {$statExe(ino) != 0}
}]

proc MakeFiles {dirname} {
    set inodes {}
    set ndx -1
    while {1} {
	# upped to 50K for 64bit Server 2008
	if {$ndx > 50000} {
	    tcltest::Skip "limit-reached:no-collistion"
	}
	set filename [file join $dirname Test[incr ndx]]
	set f [open $filename w]
	close $f
	file stat $filename stat
	if {[set n [lsearch -exact -integer $inodes $stat(ino)]] >= 0} {
	    return [list [file join $dirname Test$n] $filename]
	}
	lappend inodes $stat(ino)
	unset stat
    }
}

test winFCmd-1.38 {TclpRenameFile: check rename of conflicting inodes} -setup {
    cleanup
} -constraints {win winNonZeroInodes knownMsvcBug notInCIenv extensive} -body {
    file mkdir td1
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
    }
    # Old versions of Tcl gave a misleading error that the
    # directory in question didn't exist.
    if {[llength $d] && [catch {cd [lindex $d 0]} err]} {
	regsub ".*: " $err "" err
	set err
    } else {
        set err "permission denied"
    }
} -cleanup {
    cd $pwd
} -result "permission denied"

cd $pwd
unset d dd pwd







|







1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
    }
    # Old versions of Tcl gave a misleading error that the
    # directory in question didn't exist.
    if {[llength $d] && [catch {cd [lindex $d 0]} err]} {
	regsub ".*: " $err "" err
	set err
    } else {
	set err "permission denied"
    }
} -cleanup {
    cd $pwd
} -result "permission denied"

cd $pwd
unset d dd pwd
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
    file normalize //?/c:/windows/../windows/win.ini
} -result //?/c:/windows/win.ini
test winFCmd-19.3 {Windows extended path names} -constraints win -setup {
    set tmpfile [file join $::env(TEMP) tcl[string repeat x 20].tmp]
    set tmpfile [file normalize $tmpfile]
} -body {
    list [catch {
        set f [open $tmpfile [list WRONLY CREAT]]
        close $f
    } res] $res
} -cleanup {
    catch {file delete $tmpfile}
} -result [list 0 {}]
test winFCmd-19.4 {Windows extended path names} -constraints win -setup {
    set tmpfile [file join $::env(TEMP) tcl[string repeat x 20].tmp]
    set tmpfile //?/[file normalize $tmpfile]
} -body {
    list [catch {
        set f [open $tmpfile [list WRONLY CREAT]]
        close $f
    } res] $res
} -cleanup {
    catch {file delete $tmpfile}
} -result [list 0 {}]
test winFCmd-19.5 {Windows extended path names} -constraints win -setup {
    set tmpfile [file join $::env(TEMP) tcl[string repeat x 248].tmp]
    set tmpfile [file normalize $tmpfile]
} -body {
    list [catch {
        set f [open $tmpfile [list WRONLY CREAT]]
        close $f
    } res] $res
} -cleanup {
    catch {file delete $tmpfile}
} -result [list 0 {}]
test winFCmd-19.6 {Windows extended path names} -constraints win -setup {
    set tmpfile [file join $::env(TEMP) tcl[string repeat x 248].tmp]
    set tmpfile //?/[file normalize $tmpfile]
} -body {
    list [catch {
        set f [open $tmpfile [list WRONLY CREAT]]
        close $f
    } res] $res
} -cleanup {
    catch {file delete $tmpfile}
} -result [list 0 {}]
test winFCmd-19.7 {Windows extended path names} -constraints win -setup {
    set tmpfile [file join $::env(TEMP) "tcl[pid].tmp "]
    set tmpfile [file normalize $tmpfile]
} -body {
    list [catch {
        set f [open $tmpfile [list WRONLY CREAT]]
        close $f
    } res] $res [glob -directory $::env(TEMP) -tails tcl[pid].*]
} -cleanup {
    catch {file delete $tmpfile}
} -result [list 0 {} [list tcl[pid].tmp]]
test winFCmd-19.8 {Windows extended path names} -constraints win -setup {
    set tmpfile [file join $::env(TEMP) "tcl[pid].tmp "]
    set tmpfile //?/[file normalize $tmpfile]
} -body {
    list [catch {
        set f [open $tmpfile [list WRONLY CREAT]]
        close $f
    } res] $res [glob -directory $::env(TEMP) -tails tcl[pid].*]
} -cleanup {
    catch {file delete $tmpfile}
} -result [list 0 {} [list "tcl[pid].tmp "]]

test winFCmd-19.9 {Windows devices path names} -constraints win -body {
    file normalize //./com1







|
|









|
|









|
|









|
|









|
|









|
|







1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
    file normalize //?/c:/windows/../windows/win.ini
} -result //?/c:/windows/win.ini
test winFCmd-19.3 {Windows extended path names} -constraints win -setup {
    set tmpfile [file join $::env(TEMP) tcl[string repeat x 20].tmp]
    set tmpfile [file normalize $tmpfile]
} -body {
    list [catch {
	set f [open $tmpfile [list WRONLY CREAT]]
	close $f
    } res] $res
} -cleanup {
    catch {file delete $tmpfile}
} -result [list 0 {}]
test winFCmd-19.4 {Windows extended path names} -constraints win -setup {
    set tmpfile [file join $::env(TEMP) tcl[string repeat x 20].tmp]
    set tmpfile //?/[file normalize $tmpfile]
} -body {
    list [catch {
	set f [open $tmpfile [list WRONLY CREAT]]
	close $f
    } res] $res
} -cleanup {
    catch {file delete $tmpfile}
} -result [list 0 {}]
test winFCmd-19.5 {Windows extended path names} -constraints win -setup {
    set tmpfile [file join $::env(TEMP) tcl[string repeat x 248].tmp]
    set tmpfile [file normalize $tmpfile]
} -body {
    list [catch {
	set f [open $tmpfile [list WRONLY CREAT]]
	close $f
    } res] $res
} -cleanup {
    catch {file delete $tmpfile}
} -result [list 0 {}]
test winFCmd-19.6 {Windows extended path names} -constraints win -setup {
    set tmpfile [file join $::env(TEMP) tcl[string repeat x 248].tmp]
    set tmpfile //?/[file normalize $tmpfile]
} -body {
    list [catch {
	set f [open $tmpfile [list WRONLY CREAT]]
	close $f
    } res] $res
} -cleanup {
    catch {file delete $tmpfile}
} -result [list 0 {}]
test winFCmd-19.7 {Windows extended path names} -constraints win -setup {
    set tmpfile [file join $::env(TEMP) "tcl[pid].tmp "]
    set tmpfile [file normalize $tmpfile]
} -body {
    list [catch {
	set f [open $tmpfile [list WRONLY CREAT]]
	close $f
    } res] $res [glob -directory $::env(TEMP) -tails tcl[pid].*]
} -cleanup {
    catch {file delete $tmpfile}
} -result [list 0 {} [list tcl[pid].tmp]]
test winFCmd-19.8 {Windows extended path names} -constraints win -setup {
    set tmpfile [file join $::env(TEMP) "tcl[pid].tmp "]
    set tmpfile //?/[file normalize $tmpfile]
} -body {
    list [catch {
	set f [open $tmpfile [list WRONLY CREAT]]
	close $f
    } res] $res [glob -directory $::env(TEMP) -tails tcl[pid].*]
} -cleanup {
    catch {file delete $tmpfile}
} -result [list 0 {} [list "tcl[pid].tmp "]]

test winFCmd-19.9 {Windows devices path names} -constraints win -body {
    file normalize //./com1
Changes to tests/winFile.test.
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
    set tryname $fname
    if {[file isdirectory $fname]} {
	set tryname [file dirname $fname]
    }
    set owner ""
    set tail [file tail $tryname]
    if {[info exists env(OSTYPE)] && $env(OSTYPE) eq "msys"} {
        set dirtext [exec ls -l $fname]
        foreach line [split $dirtext "\n"] {
            set owner [lindex $line 2]
        }
    } else {
        set dirtext [exec cmd /c dir /q [file nativename $fname]]
        foreach line [split $dirtext "\n"] {
            if {[string match -nocase "*$tail" $line]} {
                set attrs [string range $line 0 end-[string length $tail]]
                regexp { [^ \\]+\\.*$} $attrs owner
                set owner [string trim $owner]
            }
        }
    }
    if {$owner eq ""} {
	error "getuser: Owner not found in output of dir/q"
    }
    return $owner
}








|
|
|
|

|
|
|
|
|
|
|
|







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
    set tryname $fname
    if {[file isdirectory $fname]} {
	set tryname [file dirname $fname]
    }
    set owner ""
    set tail [file tail $tryname]
    if {[info exists env(OSTYPE)] && $env(OSTYPE) eq "msys"} {
	set dirtext [exec ls -l $fname]
	foreach line [split $dirtext "\n"] {
	    set owner [lindex $line 2]
	}
    } else {
	set dirtext [exec cmd /c dir /q [file nativename $fname]]
	foreach line [split $dirtext "\n"] {
	    if {[string match -nocase "*$tail" $line]} {
		set attrs [string range $line 0 end-[string length $tail]]
		regexp { [^ \\]+\\.*$} $attrs owner
		set owner [string trim $owner]
	    }
	}
    }
    if {$owner eq ""} {
	error "getuser: Owner not found in output of dir/q"
    }
    return $owner
}

Changes to tests/winTime.test.
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
    set failed {}
    set ok 1
    foreach start_sec [testwinclock] break
    while { 1 } {
	foreach { sys_sec sys_usec tcl_sec tcl_usec } [testwinclock] break
	set diff [expr { $tcl_sec - $sys_sec
			 + 1.0e-6 * ( $tcl_usec - $sys_usec ) }]
        if { abs($diff) > 0.1 } {
	    set failed "Tcl clock differs from system clock by $diff sec"
	    break
	} else {
	    testwinsleep 1
	}
	if { $sys_sec - $start_sec >= 30 } break
    }







|







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
    set failed {}
    set ok 1
    foreach start_sec [testwinclock] break
    while { 1 } {
	foreach { sys_sec sys_usec tcl_sec tcl_usec } [testwinclock] break
	set diff [expr { $tcl_sec - $sys_sec
			 + 1.0e-6 * ( $tcl_usec - $sys_usec ) }]
	if { abs($diff) > 0.1 } {
	    set failed "Tcl clock differs from system clock by $diff sec"
	    break
	} else {
	    testwinsleep 1
	}
	if { $sys_sec - $start_sec >= 30 } break
    }
Changes to tests/zipfs.test.
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
namespace eval test_ns_zipfs {
    namespace import ::tcltest::test
    namespace path ::tcltests
    variable zipTestDir [file normalize [file join [file dirname [info script]] zipfiles]]
    variable defMountPt [file join [zipfs root] testmount]

    proc readbin {path} {
        set fd [open $path rb]
        set data [read $fd]
        close $fd
        return $data
    }

    # Wrapper to ease transition if Tcl changes order of argument to zipfs mount
    # or the zipfs prefix
    proc mount [list zippath [list mountpoint $defMountPt]] {
        return [zipfs mount $zippath $mountpoint]
    }

    # Make full path to zip file
    proc zippath {zippath} {
        variable zipTestDir
        if {[file pathtype $zippath] eq "absolute"} {
            return $zippath
        } else {
            return [file join $zipTestDir $zippath]
        }
    }

    # list of paths -> list of paths under mount point mt
    proc zipfspathsmt {mt args} {
        return [lsort [lmap path $args {file join $mt $path}]]
    }

    # list of paths -> list of paths under [zipfs root]
    proc zipfspaths {args} {
        return [zipfspathsmt [zipfs root] {*}$args]
    }

    proc cleanup {} {
        dict for {mount -} [zipfs mount] {
            if {[string match //zipfs:/test* $mount]} {
                zipfs unmount $mount
            }
        }
        zipfs unmount [zipfs root]
    }

    proc mounttarget {mountpoint} {
        return [dict getdef [zipfs mount] $mountpoint ""]
    }

    #
    # zipfs root - only arg count check since do not want to assume
    # what it resolves to
    testnumargs "zipfs root" "" ""

    #
    # zipfs mount

    proc testbadmount {id zippath messagePattern args} {
        variable defMountPt
        set zippath [zippath $zippath]
        test zipfs-mount-$id $id -body {
            list [catch {mount $zippath} message] \
                [string match $messagePattern $message] \
                [mounttarget $defMountPt]
        } -cleanup {
            # In case mount succeeded when it should not
            cleanup
        } -result {1 1 {}} {*}$args

        if {![file exists $zippath]} {
            return
        }
        set data [readbin $zippath]
        test zipfs-mountdata-$id $id -body {
            list [catch {zipfs mountdata $data $defMountPt} message] \
                [string match $messagePattern $message] \
                [mounttarget $defMountPt]
        } -cleanup {
            # In case mount succeeded when it should not
            cleanup
        } -result {1 1 {}} {*}$args
    }

    # Generates tests for file, file on root, memory buffer cases for an archive
    proc testmount {id zippath checkPath mountpoint args} {
        set zippath [zippath $zippath]
        test zipfs-mount-$id "zipfs mount $id" -body {
            set canon [mount $zippath $mountpoint]
            list [file exists [file join $canon $checkPath]] \
                [zipfs mount $canon] [zipfs mount $mountpoint]
        } -cleanup {
            zipfs unmount $mountpoint
        } -result [list 1 $zippath $zippath] {*}$args

        # Mount memory buffer
        test zipfs-mountdata-$id "zipfs mountdata $id" -body {
            set canon [zipfs mountdata [readbin $zippath] $mountpoint]
            list [file exists [file join $canon $checkPath]] \
                [zipfs mount $canon] [zipfs mount $mountpoint]
        } -cleanup {
            cleanup
        } -result [list 1 {Memory Buffer} {Memory Buffer}] {*}$args

    }

    testnumargs "zipfs mount" "" "?zipfile? ?mountpoint? ?password?"
    testnumargs "zipfs mountdata" "data mountpoint" ""

    # Not supported zip files
    testbadmount non-existent-file    nosuchfile.zip "couldn't open*nosuchfile.zip*no such file or directory"
    testbadmount not-zipfile          [file normalize [info script]]      "archive directory end signature not found"
    testbadmount zip64-unsupported    zip64.zip      "wrong header signature"

    # Inconsistent metadata
    testbadmount bad-directory-offset incons-cdoffset.zip          "archive directory truncated"
    testbadmount bad-directory-magic  incons-central-magic-bad.zip "wrong header signature"
    testbadmount bad-local-magic      incons-local-magic-bad.zip   "Failed to find local header"
    testbadmount bad-file-count-high  incons-file-count-high.zip   "truncated directory"
    testbadmount bad-file-count-low   incons-file-count-low.zip    "short file count"

    test zipfs-mount-on-drive "Mount point include drive" -body {
        zipfs mount [zippath test.zip] C:/foo
    } -result {Invalid mount path "C:/foo"} -returnCodes error -constraints win
    test zipfs-mountdata-on-drive "Mount point include drive" -body {
        zipfs mountdata [readbin [zippath test.zip]] C:/foo
    } -result {Invalid mount path "C:/foo"} -returnCodes error -constraints win
    test zipfs-mount-on-unc "Mount point is unc" -body {
        zipfs mount [zippath test.zip] //unc/share/foo
    } -result {Invalid mount path "//unc/share/foo"} -returnCodes error
    test zipfs-mountdata-on-unc "Mount point include unc" -body {
        zipfs mountdata [readbin [zippath test.zip]] //unc/share/foo
    } -result {Invalid mount path "//unc/share/foo"} -returnCodes error

    # Good mounts
    testmount basic             test.zip           testdir/test2 $defMountPt
    testmount basic-on-default  test.zip           testdir/test2 ""
    testmount basic-on-root     test.zip           testdir/test2 [zipfs root]
    testmount basic-on-slash    test.zip           testdir/test2 /
    testmount basic-on-bslash   test.zip           testdir/test2 \\ -constraints win
    testmount basic-on-relative test.zip           testdir/test2 testmount
    testmount basic-on-absolute test.zip           testdir/test2 /testmount
    testmount basic-on-absolute-bslash test.zip    testdir/test2 \\testmount -constraints win
    testmount zip-at-end        junk-at-start.zip  testdir/test2 $defMountPt
    testmount zip-at-start      junk-at-end.zip    testdir/test2 $defMountPt
    testmount zip-in-zip [file join [zipfs root] test2 test.zip] testdir/test2 $defMountPt -setup {
        mount [zippath test-zip-in-zip.zip] [file join [zipfs root] test2]
    } -cleanup {
        zipfs unmount $mountpoint
        zipfs unmount [file join [zipfs root] test2]
    }
    testmount relative-mount-point test.zip testdir/test2 ""

    test zipfs-mount-busy-1 "Attempt to mount on existing mount point" -setup {
        mount [zippath test.zip]
    } -cleanup {
        cleanup
    } -body {
        zipfs mount [zippath testfile-cp437.zip] $defMountPt
    } -result "[zippath test.zip] is already mounted on $defMountPt" -returnCodes error

    test zipfs-mount-no-args-1 "mount - get mount list" -setup {
        mount [zippath test.zip]
    } -cleanup {
        cleanup
    } -body {
        set mounts [zipfs mount]
        lsearch -inline -stride 2 $mounts $defMountPt
    } -result [list $defMountPt [zippath test.zip]]

    test zipfs-mount-one-arg-1 "mount - get mount target - absolute path" -setup {
        mount [zippath test.zip]
    } -cleanup {
        cleanup
    } -body {
        zipfs mount $defMountPt
    } -result [zippath test.zip]

    test zipfs-mount-one-arg-2 "mount - get mount target - relative path" -setup {
        file copy [zippath test.zip] test.zip
        mount ./test.zip
    } -cleanup {
        cleanup
        file delete ./test.zip
    } -body {
        zipfs mount $defMountPt
    } -result [file normalize ./test.zip]

    test zipfs-mount-password-1 "mount - verify plaintext readable without password" -body {
        zipfs mount [zippath test-password.zip] $defMountPt
        readbin [file join $defMountPt plain.txt]
    } -cleanup {
        cleanup
    } -result plaintext

    test zipfs-mount-password-2 "mount - verify uncompressed cipher unreadable without password" -body {
        zipfs mount [zippath test-password.zip] $defMountPt
        set chans [lsort [chan names]]; # Want to ensure open does not leave dangling channel
        set result [list ]
        lappend result [catch {open [file join $defMountPt cipher.bin]} message]
        lappend result $message
        lappend result [string equal $chans [lsort [chan names]]]
    } -cleanup {
        cleanup
    } -result {1 {decryption failed - no password provided} 1}

    test zipfs-mount-password-3 "mount - verify compressed cipher unreadable without password" -body {
        zipfs mount [zippath test-password.zip] $defMountPt
        set chans [lsort [chan names]]; # Want to ensure open does not leave dangling channel
        set result [list ]
        lappend result [catch {open [file join $defMountPt cipher-deflate.bin]} message]
        lappend result $message
        lappend result [string equal $chans [lsort [chan names]]]
    } -cleanup {
        cleanup
    } -result {1 {decryption failed - no password provided} 1}

    test zipfs-mount-nested-1 "mount - nested mount on non-existing path" -setup {
        mount [zippath test.zip]
    } -cleanup {
        cleanup
    } -body {
        set newmount [file join $defMountPt newdir]
        mount [zippath test-overlay.zip] $newmount
        list \
            [lsort [glob -tails -dir $defMountPt *]] \
            [lsort [glob -tails -dir $newmount *]] \
            [readbin [file join $newmount test2]]
    } -result {{newdir test testdir} {test2 test3} test2-overlay}

    test zipfs-mount-nested-2 "mount - nested mount on existing path" -setup {
        mount [zippath test.zip]
    } -cleanup {
        cleanup
    } -body {
        set newmount [file join $defMountPt testdir]
        mount [zippath test-overlay.zip] $newmount
        # Note - file from existing mount is preserved (testdir/test2)
        # Not clear this is desired but defined as such by the
        # current implementation
        list \
            [lsort [glob -tails -dir $defMountPt *]] \
            [lsort [glob -tails -dir $newmount *]] \
            [readbin [file join $newmount test2]]
    } -result [list {test testdir} {test2 test3} test\n]

    #
    # unmount - only special cases. Normal case already tested as part of other tests

    testnumargs "zipfs unmount" "mountpoint" ""

    test zipfs-unmount-1 "Unmount bogus mount" -body {
        zipfs unmount [file join [zipfs root] nosuchmount]
    } -result ""

    test zipfs-unmount-2 "Unmount mount with open files" -setup {
        mount [zippath test.zip]
        set fd [open [file join $defMountPt test]]
    } -cleanup {
        close $fd
        cleanup
    } -body {
        zipfs unmount $defMountPt
    } -result {filesystem is busy} -returnCodes error

    test zipfs-unmount-3 "Unmount mount with current directory" -setup {
        set cwd [pwd]
        mount [zippath test.zip]
    } -cleanup {
        cd $cwd
        cleanup
    } -body {
        # Current directory does not change on unmount.
        # This is the same behavior as when USB pen drive is unmounted
        set cwd2 [file join $defMountPt testdir]
        cd $cwd2
        list [pwd] [zipfs unmount $defMountPt] [string equal [pwd] $cwd2]
    } -result [list [file join $defMountPt testdir] {} 1]

    test zipfs-unmount-nested-1 "unmount parent of nested mount on new directory should not affect nested mount" -setup {
        mount [zippath test.zip]
        set newmount [file join [zipfs root] test newdir]
        mount [zippath test-overlay.zip] $newmount
    } -cleanup {
        cleanup
    } -body {
        zipfs unmount $defMountPt
        list \
            [zipfs mount $defMountPt] \
            [lsort [glob -tails -dir $newmount *]] \
            [readbin [file join $newmount test2]]
    } -result {{} {test2 test3} test2-overlay}

    test zipfs-unmount-nested-2 "unmount parent of nested mount on existing directory should not affect nested mount" -setup {
        mount [zippath test.zip]
        set newmount [file join [zipfs root] test testdir]
        mount [zippath test-overlay.zip] $newmount
    } -constraints bug-4ae42446ab -cleanup {
        cleanup
    } -body {
        # KNOWN BUG. The test2 file is also present in parent mount.
        # After the unmount, the test2 in the nested mount is not
        # made available.
        zipfs unmount $defMountPt
        list \
            [zipfs mount $defMountPt] \
            [lsort [glob -tails -dir $newmount *]] \
            [readbin [file join $newmount test2]]
    } -result {{} {test2 test3} test2-overlay}

    #
    # paths inside a zip
    # TODO - paths encoded in utf-8 vs fallback encoding
    test zipfs-content-paths-1 "Test absolute and full paths" -setup {
        mount [zippath test-paths.zip]
    } -cleanup {
        cleanup
    } -body {
        # Primarily verifies that drive letters are stripped and paths maintained
        lsort [zipfs find $defMountPt]
    } -result {//zipfs:/testmount/filename.txt //zipfs:/testmount/src //zipfs:/testmount/src/tcltk //zipfs:/testmount/src/tcltk/wip //zipfs:/testmount/src/tcltk/wip/tcl //zipfs:/testmount/src/tcltk/wip/tcl/tests //zipfs:/testmount/src/tcltk/wip/tcl/tests/zipfiles //zipfs:/testmount/src/tcltk/wip/tcl/tests/zipfiles/abspath.txt //zipfs:/testmount/src/tcltk/wip/tcl/tests/zipfiles/fullpath.txt}

    #
    # zipfs list
    testnumargs "zipfs list" "" "?(-glob|-regexp)? ?pattern?"

    # Generates zipfs list tests for file, memory buffer cases for an archive
    proc testzipfslist {id cmdargs mounts resultpaths args} {
        set resultpaths [lmap path $resultpaths {
            file join [zipfs root] $path
        }]
        set resultpaths [lsort $resultpaths]
        test zipfs-list-$id "zipfs list $id" -body {
            lsort [zipfs list {*}$cmdargs]
        } -setup {
            foreach {zippath mountpoint} $mounts {
                zipfs mount [zippath $zippath] [file join [zipfs root] $mountpoint]
            }
        } -cleanup {
            cleanup
        } -result $resultpaths {*}$args

        # Mount memory buffer
        test zipfs-list-memory-$id "zipfs list memory $id" -body {
            lsort [zipfs list {*}$cmdargs]
        } -setup {
            foreach {zippath mountpoint} $mounts {
                zipfs mountdata [readbin [zippath $zippath]] [file join [zipfs root] $mountpoint]
            }
        } -cleanup {
            cleanup
        } -result $resultpaths {*}$args
    }
    # Some tests have !zipfslib constraint because otherwise they dump the entire Tcl library which is mounted on root
    testzipfslist no-mounts                 "" {} {} -constraints !zipfslib
    testzipfslist no-pattern                "" {test.zip testmountA} {testmountA testmountA/test testmountA/testdir testmountA/testdir/test2} -constraints !zipfslib
    testzipfslist no-pattern-mount-on-empty "" {test.zip {}} {{} test testdir testdir/test2} -constraints !zipfslib
    testzipfslist no-pattern-mount-on-root  "" [list test.zip [zipfs root]] {{} test testdir testdir/test2} -constraints !zipfslib
    testzipfslist no-pattern-mount-on-slash "" [list test.zip /] {{} test testdir testdir/test2} -constraints !zipfslib
    testzipfslist no-pattern-mount-on-mezzo "" [list test.zip testmt/a/b] {testmt/a/b testmt/a/b/test testmt/a/b/testdir testmt/a/b/testdir/test2} -constraints {!zipfslib}
    testzipfslist no-pattern-multiple       "" {test.zip testmountA test.zip testmountB/subdir} {
        testmountA testmountA/test testmountA/testdir testmountA/testdir/test2
        testmountB/subdir testmountB/subdir/test testmountB/subdir/testdir testmountB/subdir/testdir/test2
    } -constraints !zipfslib
    testzipfslist glob [list "*testmount*2*"] {test.zip testmountA test.zip testmountB/subdir} {
        testmountA/testdir/test2
        testmountB/subdir/testdir/test2
    }
    testzipfslist opt-glob [list -glob "*testmount*2*"] {test.zip testmountA test.zip testmountB/subdir} {
        testmountA/testdir/test2
        testmountB/subdir/testdir/test2
    }
    testzipfslist opt-regexp [list -regexp "testmount.*(A|2)"] {test.zip testmountA test.zip testmountB/subdir} {
        testmountA testmountA/test testmountA/testdir testmountA/testdir/test2
        testmountB/subdir/testdir/test2
    }

    #
    # zipfs exists
    testnumargs "zipfs exists" "filename" ""

    # Generates tests for zipfs exists
    proc testzipfsexists [list id path result [list mountpoint $defMountPt] args] {
        test zipfs-exists-$id "zipfs exists $id" -body {
            zipfs exists $path
        } -setup {
            mount [zippath test.zip] $mountpoint
        } -cleanup {
            zipfs unmount $mountpoint
            cleanup
        } -result $result {*}$args
    }
    testzipfsexists native-file  [info nameofexecutable]            0
    testzipfsexists enoent       [file join $defMountPt nosuchfile] 0
    testzipfsexists file         [file join $defMountPt test]       1
    testzipfsexists dir          [file join $defMountPt testdir]    1
    testzipfsexists mountpoint   $defMountPt                        1
    testzipfsexists root         [zipfs root]                       1 $defMountPt
    testzipfsexists mezzo        [file join $defMountPt a b]        1 [file join $defMountPt a b c]
    testzipfsexists mezzo-enoent [file join $defMountPt a c]        0 [file join $defMountPt a b c]

    #
    # zipfs find
    testnumargs "zipfs find" "directoryName" ""
    # Generates zipfs find tests for file, memory buffer cases for an archive
    proc testzipfsfind {id findtarget mounts resultpaths args} {
        set setup {
            foreach {zippath mountpoint} $mounts {
                zipfs mount [zippath $zippath] [file join [zipfs root] $mountpoint]
            }
        }
        set memory_setup {
            foreach {zippath mountpoint} $mounts {
                zipfs mountdata [readbin [zippath $zippath]] [file join [zipfs root] $mountpoint]
            }
        }
        if {[dict exists $args -setup]} {
            append setup \n[dict get $args -setup]
            append memory_setup \n[dict get $args -setup]
            dict unset args -setup
        }
        set cleanup cleanup
        if {[dict exists $args -cleanup]} {
            set cleanup "[dict get $args -cleanup]\n$cleanup"
            dict unset args -cleanup
        }
        set resultpaths [lsort $resultpaths]
        test zipfs-find-$id "zipfs find $id" -body {
            lsort [zipfs find $findtarget]
        } -setup $setup -cleanup $cleanup -result $resultpaths {*}$args

        # Mount memory buffer
        test zipfs-find-memory-$id "zipfs find memory $id" -body {
            lsort [zipfs find $findtarget]
        } -setup $memory_setup -cleanup $cleanup -result $resultpaths {*}$args
    }

    testzipfsfind nonexistingmount [file join [zipfs root] nosuchmount] {
        test.zip testmountA test.zip testmountB/subdir
    } {}

    testzipfsfind absolute-path    [file join [zipfs root] testmountA] {
        test.zip testmountA test.zip testmountB/subdir
    } [zipfspaths testmountA/test testmountA/testdir testmountA/testdir/test2]

    testzipfsfind relative-path   testdir {
        test.zip testmountA test.zip testmountB/subdir
    } { testdir/test2 } -setup {
        set cwd [pwd]
        cd [file join [zipfs root] testmountA]
    } -cleanup {
        cd $cwd
    }

    # bug-6183f535c8
    testzipfsfind root-path   [zipfs root] {
        test.zip {} test.zip testmountB/subdir
    } [zipfspaths test testdir testdir/test2 testmountB testmountB/subdir testmountB/subdir/test testmountB/subdir/testdir testmountB/subdir/testdir/test2] -constraints !zipfslib

    testzipfsfind mezzo [file join [zipfs root] testmt a] {
        test.zip testmt/a/b
    } [zipfspaths testmt/a/b testmt/a/b/test testmt/a/b/testdir testmt/a/b/testdir/test2]

    testzipfsfind mezzo-root [zipfs root] {
        test.zip testmt/a/b
    } [zipfspaths testmt testmt/a testmt/a/b testmt/a/b/test testmt/a/b/testdir testmt/a/b/testdir/test2] -constraints !zipfslib

    test zipfs-find-native-absolute "zipfs find on native file system" -setup {
        set dir [makeDirectory zipfs-native-absolute]
        set subdir [file join $dir subdir]
        file mkdir $subdir
        set file [file join $subdir native]
        close [open $file w]
    } -cleanup {
        removeDirectory zipfs-native-absolute
    } -body {
        string equal [zipfs find $dir] [list $subdir $file]
    } -result 1

    test zipfs-find-native-relative "zipfs find relative on native file system" -setup {
        set dir [makeDirectory zipfs-native-relative]
        set subdir [file join $dir subdir]
        file mkdir $subdir
        set file [file join $subdir native]
        close [open $file w]
        set cwd [pwd]
    } -cleanup {
        cd $cwd
        removeDirectory zipfs-native-relative
    } -body {
        cd [file dirname $dir]
        # string equal [zipfs find [file tail $subdir]] [list subdir subdir/native]
        zipfs find [file tail $dir]
    } -result {zipfs-native-relative/subdir zipfs-native-relative/subdir/native}

    #
    # zipfs info
    testnumargs "zipfs info" "filename" ""

    test zipfs-info-native-nosuchfile "zipfs info on non-existent native path" -body {
        zipfs info nosuchfile
    } -result {path "nosuchfile" not found in any zipfs volume} -returnCodes error

    test zipfs-info-native-file "zipfs info on native path" -body {
        zipfs info [info nameofexecutable]
    } -result "path \"[info nameofexecutable]\" not found in any zipfs volume" -returnCodes error

    test zipfs-info-nosuchfile "zipfs info non-existent path in mounted archive" -setup {
        mount [zippath test.zip]
    } -cleanup {
        cleanup
    } -body {
        zipfs info [file join $defMountPt nosuchfile]
    } -result "path \"[file join $defMountPt nosuchfile]\" not found in any zipfs volume" -returnCodes error

    test zipfs-info-file "zipfs info file within mounted archive" -setup {
        mount [zippath testdeflated2.zip]
    } -cleanup {
        cleanup
    } -body {
        zipfs info [file join $defMountPt abac-repeat.txt]
    } -result [list [zippath testdeflated2.zip] 60 17 108]

    test zipfs-info-dir "zipfs info dir within mounted archive" -setup {
        mount [zippath test.zip]
    } -cleanup {
        cleanup
    } -body {
        zipfs info [file join $defMountPt testdir]
    } -result [list [zippath test.zip] 0 0 119]

    test zipfs-info-mountpoint "zipfs info on mount point - verify correct offset of zip content" -setup {
        # zip starts at offset 4
        mount [zippath junk-at-start.zip]
    } -cleanup {
        cleanup
    } -body {
        zipfs info $defMountPt
    } -result [list [zippath junk-at-start.zip] 0 0 4]

    test zipfs-info-mezzo "zipfs info on mount point - verify correct offset of zip content" -setup {
        # zip starts at offset 4
        mount [zippath junk-at-start.zip] /testmt/a/b
    } -cleanup {
        cleanup
    } -body {
        zipfs info [file join [zipfs root] testmt a]
    } -result {path "//zipfs:/testmt/a" not found in any zipfs volume} -returnCodes error

    #
    # zipfs canonical
    test zipfs-canonical-minargs {zipfs canonical min args} -body {
        zipfs canonical
    } -returnCodes error -result {wrong # args: should be "zipfs canonical ?mountpoint? filename"}
    test zipfs-canonical-maxargs {zipfs canonical max args} -body {
        zipfs canonical a b c
    } -returnCodes error -result {wrong # args: should be "zipfs canonical ?mountpoint? filename"}
    proc testzipfscanonical {id cmdargs result args} {
        test zipfs-canonical-$id "zipfs canonical $id" \
            -body [list zipfs canonical {*}$cmdargs] \
            -result $result {*}$args
    }
    testzipfscanonical default-relative      [list a]               [file join [zipfs root] a]
    testzipfscanonical default-absolute      [list /a]              [file join [zipfs root] a]
    testzipfscanonical root-relative-1       [list [zipfs root] a]  [file join [zipfs root] a]
    testzipfscanonical root-relative-2       [list / a]             [file join [zipfs root] a]
    testzipfscanonical root-absolute-1       [list [zipfs root] /a] [file join [zipfs root] a]
    testzipfscanonical root-absolute-2       [list / /a]            [file join [zipfs root] a]







|
|
|
|





|




|
|
|
|
|
|




|




|



|
|
|
|
|
|



|











|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|



















|


|


|


|














|

|
|




|

|

|



|

|

|
|



|

|

|



|
|

|
|

|



|
|

|



|
|
|
|
|
|

|



|
|
|
|
|
|

|



|

|

|
|
|
|
|
|



|

|

|
|
|
|
|
|
|
|
|








|



|
|

|
|

|



|
|

|
|

|
|
|
|
|



|
|
|

|

|
|
|
|
|



|
|
|

|

|
|
|
|
|
|
|
|






|

|

|
|








|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|









|
|


|
|


|
|


|
|








|
|
|
|
|
|
|
|















|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|



|



|



|

|
|

|




|



|



|



|
|
|
|
|

|

|



|
|
|
|
|
|

|
|

|
|
|







|



|



|

|

|



|

|

|



|

|

|



|
|

|

|



|
|

|

|





|


|


|
|
|







373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
namespace eval test_ns_zipfs {
    namespace import ::tcltest::test
    namespace path ::tcltests
    variable zipTestDir [file normalize [file join [file dirname [info script]] zipfiles]]
    variable defMountPt [file join [zipfs root] testmount]

    proc readbin {path} {
	set fd [open $path rb]
	set data [read $fd]
	close $fd
	return $data
    }

    # Wrapper to ease transition if Tcl changes order of argument to zipfs mount
    # or the zipfs prefix
    proc mount [list zippath [list mountpoint $defMountPt]] {
	return [zipfs mount $zippath $mountpoint]
    }

    # Make full path to zip file
    proc zippath {zippath} {
	variable zipTestDir
	if {[file pathtype $zippath] eq "absolute"} {
	    return $zippath
	} else {
	    return [file join $zipTestDir $zippath]
	}
    }

    # list of paths -> list of paths under mount point mt
    proc zipfspathsmt {mt args} {
	return [lsort [lmap path $args {file join $mt $path}]]
    }

    # list of paths -> list of paths under [zipfs root]
    proc zipfspaths {args} {
	return [zipfspathsmt [zipfs root] {*}$args]
    }

    proc cleanup {} {
	dict for {mount -} [zipfs mount] {
	    if {[string match //zipfs:/test* $mount]} {
		zipfs unmount $mount
	    }
	}
	zipfs unmount [zipfs root]
    }

    proc mounttarget {mountpoint} {
	return [dict getdef [zipfs mount] $mountpoint ""]
    }

    #
    # zipfs root - only arg count check since do not want to assume
    # what it resolves to
    testnumargs "zipfs root" "" ""

    #
    # zipfs mount

    proc testbadmount {id zippath messagePattern args} {
	variable defMountPt
	set zippath [zippath $zippath]
	test zipfs-mount-$id $id -body {
	    list [catch {mount $zippath} message] \
		[string match $messagePattern $message] \
		[mounttarget $defMountPt]
	} -cleanup {
	    # In case mount succeeded when it should not
	    cleanup
	} -result {1 1 {}} {*}$args

	if {![file exists $zippath]} {
	    return
	}
	set data [readbin $zippath]
	test zipfs-mountdata-$id $id -body {
	    list [catch {zipfs mountdata $data $defMountPt} message] \
		[string match $messagePattern $message] \
		[mounttarget $defMountPt]
	} -cleanup {
	    # In case mount succeeded when it should not
	    cleanup
	} -result {1 1 {}} {*}$args
    }

    # Generates tests for file, file on root, memory buffer cases for an archive
    proc testmount {id zippath checkPath mountpoint args} {
	set zippath [zippath $zippath]
	test zipfs-mount-$id "zipfs mount $id" -body {
	    set canon [mount $zippath $mountpoint]
	    list [file exists [file join $canon $checkPath]] \
		[zipfs mount $canon] [zipfs mount $mountpoint]
	} -cleanup {
	    zipfs unmount $mountpoint
	} -result [list 1 $zippath $zippath] {*}$args

	# Mount memory buffer
	test zipfs-mountdata-$id "zipfs mountdata $id" -body {
	    set canon [zipfs mountdata [readbin $zippath] $mountpoint]
	    list [file exists [file join $canon $checkPath]] \
		[zipfs mount $canon] [zipfs mount $mountpoint]
	} -cleanup {
	    cleanup
	} -result [list 1 {Memory Buffer} {Memory Buffer}] {*}$args

    }

    testnumargs "zipfs mount" "" "?zipfile? ?mountpoint? ?password?"
    testnumargs "zipfs mountdata" "data mountpoint" ""

    # Not supported zip files
    testbadmount non-existent-file    nosuchfile.zip "couldn't open*nosuchfile.zip*no such file or directory"
    testbadmount not-zipfile          [file normalize [info script]]      "archive directory end signature not found"
    testbadmount zip64-unsupported    zip64.zip      "wrong header signature"

    # Inconsistent metadata
    testbadmount bad-directory-offset incons-cdoffset.zip          "archive directory truncated"
    testbadmount bad-directory-magic  incons-central-magic-bad.zip "wrong header signature"
    testbadmount bad-local-magic      incons-local-magic-bad.zip   "Failed to find local header"
    testbadmount bad-file-count-high  incons-file-count-high.zip   "truncated directory"
    testbadmount bad-file-count-low   incons-file-count-low.zip    "short file count"

    test zipfs-mount-on-drive "Mount point include drive" -body {
	zipfs mount [zippath test.zip] C:/foo
    } -result {Invalid mount path "C:/foo"} -returnCodes error -constraints win
    test zipfs-mountdata-on-drive "Mount point include drive" -body {
	zipfs mountdata [readbin [zippath test.zip]] C:/foo
    } -result {Invalid mount path "C:/foo"} -returnCodes error -constraints win
    test zipfs-mount-on-unc "Mount point is unc" -body {
	zipfs mount [zippath test.zip] //unc/share/foo
    } -result {Invalid mount path "//unc/share/foo"} -returnCodes error
    test zipfs-mountdata-on-unc "Mount point include unc" -body {
	zipfs mountdata [readbin [zippath test.zip]] //unc/share/foo
    } -result {Invalid mount path "//unc/share/foo"} -returnCodes error

    # Good mounts
    testmount basic             test.zip           testdir/test2 $defMountPt
    testmount basic-on-default  test.zip           testdir/test2 ""
    testmount basic-on-root     test.zip           testdir/test2 [zipfs root]
    testmount basic-on-slash    test.zip           testdir/test2 /
    testmount basic-on-bslash   test.zip           testdir/test2 \\ -constraints win
    testmount basic-on-relative test.zip           testdir/test2 testmount
    testmount basic-on-absolute test.zip           testdir/test2 /testmount
    testmount basic-on-absolute-bslash test.zip    testdir/test2 \\testmount -constraints win
    testmount zip-at-end        junk-at-start.zip  testdir/test2 $defMountPt
    testmount zip-at-start      junk-at-end.zip    testdir/test2 $defMountPt
    testmount zip-in-zip [file join [zipfs root] test2 test.zip] testdir/test2 $defMountPt -setup {
	mount [zippath test-zip-in-zip.zip] [file join [zipfs root] test2]
    } -cleanup {
	zipfs unmount $mountpoint
	zipfs unmount [file join [zipfs root] test2]
    }
    testmount relative-mount-point test.zip testdir/test2 ""

    test zipfs-mount-busy-1 "Attempt to mount on existing mount point" -setup {
	mount [zippath test.zip]
    } -cleanup {
	cleanup
    } -body {
	zipfs mount [zippath testfile-cp437.zip] $defMountPt
    } -result "[zippath test.zip] is already mounted on $defMountPt" -returnCodes error

    test zipfs-mount-no-args-1 "mount - get mount list" -setup {
	mount [zippath test.zip]
    } -cleanup {
	cleanup
    } -body {
	set mounts [zipfs mount]
	lsearch -inline -stride 2 $mounts $defMountPt
    } -result [list $defMountPt [zippath test.zip]]

    test zipfs-mount-one-arg-1 "mount - get mount target - absolute path" -setup {
	mount [zippath test.zip]
    } -cleanup {
	cleanup
    } -body {
	zipfs mount $defMountPt
    } -result [zippath test.zip]

    test zipfs-mount-one-arg-2 "mount - get mount target - relative path" -setup {
	file copy [zippath test.zip] test.zip
	mount ./test.zip
    } -cleanup {
	cleanup
	file delete ./test.zip
    } -body {
	zipfs mount $defMountPt
    } -result [file normalize ./test.zip]

    test zipfs-mount-password-1 "mount - verify plaintext readable without password" -body {
	zipfs mount [zippath test-password.zip] $defMountPt
	readbin [file join $defMountPt plain.txt]
    } -cleanup {
	cleanup
    } -result plaintext

    test zipfs-mount-password-2 "mount - verify uncompressed cipher unreadable without password" -body {
	zipfs mount [zippath test-password.zip] $defMountPt
	set chans [lsort [chan names]]; # Want to ensure open does not leave dangling channel
	set result [list ]
	lappend result [catch {open [file join $defMountPt cipher.bin]} message]
	lappend result $message
	lappend result [string equal $chans [lsort [chan names]]]
    } -cleanup {
	cleanup
    } -result {1 {decryption failed - no password provided} 1}

    test zipfs-mount-password-3 "mount - verify compressed cipher unreadable without password" -body {
	zipfs mount [zippath test-password.zip] $defMountPt
	set chans [lsort [chan names]]; # Want to ensure open does not leave dangling channel
	set result [list ]
	lappend result [catch {open [file join $defMountPt cipher-deflate.bin]} message]
	lappend result $message
	lappend result [string equal $chans [lsort [chan names]]]
    } -cleanup {
	cleanup
    } -result {1 {decryption failed - no password provided} 1}

    test zipfs-mount-nested-1 "mount - nested mount on non-existing path" -setup {
	mount [zippath test.zip]
    } -cleanup {
	cleanup
    } -body {
	set newmount [file join $defMountPt newdir]
	mount [zippath test-overlay.zip] $newmount
	list \
	    [lsort [glob -tails -dir $defMountPt *]] \
	    [lsort [glob -tails -dir $newmount *]] \
	    [readbin [file join $newmount test2]]
    } -result {{newdir test testdir} {test2 test3} test2-overlay}

    test zipfs-mount-nested-2 "mount - nested mount on existing path" -setup {
	mount [zippath test.zip]
    } -cleanup {
	cleanup
    } -body {
	set newmount [file join $defMountPt testdir]
	mount [zippath test-overlay.zip] $newmount
	# Note - file from existing mount is preserved (testdir/test2)
	# Not clear this is desired but defined as such by the
	# current implementation
	list \
	    [lsort [glob -tails -dir $defMountPt *]] \
	    [lsort [glob -tails -dir $newmount *]] \
	    [readbin [file join $newmount test2]]
    } -result [list {test testdir} {test2 test3} test\n]

    #
    # unmount - only special cases. Normal case already tested as part of other tests

    testnumargs "zipfs unmount" "mountpoint" ""

    test zipfs-unmount-1 "Unmount bogus mount" -body {
	zipfs unmount [file join [zipfs root] nosuchmount]
    } -result ""

    test zipfs-unmount-2 "Unmount mount with open files" -setup {
	mount [zippath test.zip]
	set fd [open [file join $defMountPt test]]
    } -cleanup {
	close $fd
	cleanup
    } -body {
	zipfs unmount $defMountPt
    } -result {filesystem is busy} -returnCodes error

    test zipfs-unmount-3 "Unmount mount with current directory" -setup {
	set cwd [pwd]
	mount [zippath test.zip]
    } -cleanup {
	cd $cwd
	cleanup
    } -body {
	# Current directory does not change on unmount.
	# This is the same behavior as when USB pen drive is unmounted
	set cwd2 [file join $defMountPt testdir]
	cd $cwd2
	list [pwd] [zipfs unmount $defMountPt] [string equal [pwd] $cwd2]
    } -result [list [file join $defMountPt testdir] {} 1]

    test zipfs-unmount-nested-1 "unmount parent of nested mount on new directory should not affect nested mount" -setup {
	mount [zippath test.zip]
	set newmount [file join [zipfs root] test newdir]
	mount [zippath test-overlay.zip] $newmount
    } -cleanup {
	cleanup
    } -body {
	zipfs unmount $defMountPt
	list \
	    [zipfs mount $defMountPt] \
	    [lsort [glob -tails -dir $newmount *]] \
	    [readbin [file join $newmount test2]]
    } -result {{} {test2 test3} test2-overlay}

    test zipfs-unmount-nested-2 "unmount parent of nested mount on existing directory should not affect nested mount" -setup {
	mount [zippath test.zip]
	set newmount [file join [zipfs root] test testdir]
	mount [zippath test-overlay.zip] $newmount
    } -constraints bug-4ae42446ab -cleanup {
	cleanup
    } -body {
	# KNOWN BUG. The test2 file is also present in parent mount.
	# After the unmount, the test2 in the nested mount is not
	# made available.
	zipfs unmount $defMountPt
	list \
	    [zipfs mount $defMountPt] \
	    [lsort [glob -tails -dir $newmount *]] \
	    [readbin [file join $newmount test2]]
    } -result {{} {test2 test3} test2-overlay}

    #
    # paths inside a zip
    # TODO - paths encoded in utf-8 vs fallback encoding
    test zipfs-content-paths-1 "Test absolute and full paths" -setup {
	mount [zippath test-paths.zip]
    } -cleanup {
	cleanup
    } -body {
	# Primarily verifies that drive letters are stripped and paths maintained
	lsort [zipfs find $defMountPt]
    } -result {//zipfs:/testmount/filename.txt //zipfs:/testmount/src //zipfs:/testmount/src/tcltk //zipfs:/testmount/src/tcltk/wip //zipfs:/testmount/src/tcltk/wip/tcl //zipfs:/testmount/src/tcltk/wip/tcl/tests //zipfs:/testmount/src/tcltk/wip/tcl/tests/zipfiles //zipfs:/testmount/src/tcltk/wip/tcl/tests/zipfiles/abspath.txt //zipfs:/testmount/src/tcltk/wip/tcl/tests/zipfiles/fullpath.txt}

    #
    # zipfs list
    testnumargs "zipfs list" "" "?(-glob|-regexp)? ?pattern?"

    # Generates zipfs list tests for file, memory buffer cases for an archive
    proc testzipfslist {id cmdargs mounts resultpaths args} {
	set resultpaths [lmap path $resultpaths {
	    file join [zipfs root] $path
	}]
	set resultpaths [lsort $resultpaths]
	test zipfs-list-$id "zipfs list $id" -body {
	    lsort [zipfs list {*}$cmdargs]
	} -setup {
	    foreach {zippath mountpoint} $mounts {
		zipfs mount [zippath $zippath] [file join [zipfs root] $mountpoint]
	    }
	} -cleanup {
	    cleanup
	} -result $resultpaths {*}$args

	# Mount memory buffer
	test zipfs-list-memory-$id "zipfs list memory $id" -body {
	    lsort [zipfs list {*}$cmdargs]
	} -setup {
	    foreach {zippath mountpoint} $mounts {
		zipfs mountdata [readbin [zippath $zippath]] [file join [zipfs root] $mountpoint]
	    }
	} -cleanup {
	    cleanup
	} -result $resultpaths {*}$args
    }
    # Some tests have !zipfslib constraint because otherwise they dump the entire Tcl library which is mounted on root
    testzipfslist no-mounts                 "" {} {} -constraints !zipfslib
    testzipfslist no-pattern                "" {test.zip testmountA} {testmountA testmountA/test testmountA/testdir testmountA/testdir/test2} -constraints !zipfslib
    testzipfslist no-pattern-mount-on-empty "" {test.zip {}} {{} test testdir testdir/test2} -constraints !zipfslib
    testzipfslist no-pattern-mount-on-root  "" [list test.zip [zipfs root]] {{} test testdir testdir/test2} -constraints !zipfslib
    testzipfslist no-pattern-mount-on-slash "" [list test.zip /] {{} test testdir testdir/test2} -constraints !zipfslib
    testzipfslist no-pattern-mount-on-mezzo "" [list test.zip testmt/a/b] {testmt/a/b testmt/a/b/test testmt/a/b/testdir testmt/a/b/testdir/test2} -constraints {!zipfslib}
    testzipfslist no-pattern-multiple       "" {test.zip testmountA test.zip testmountB/subdir} {
	testmountA testmountA/test testmountA/testdir testmountA/testdir/test2
	testmountB/subdir testmountB/subdir/test testmountB/subdir/testdir testmountB/subdir/testdir/test2
    } -constraints !zipfslib
    testzipfslist glob [list "*testmount*2*"] {test.zip testmountA test.zip testmountB/subdir} {
	testmountA/testdir/test2
	testmountB/subdir/testdir/test2
    }
    testzipfslist opt-glob [list -glob "*testmount*2*"] {test.zip testmountA test.zip testmountB/subdir} {
	testmountA/testdir/test2
	testmountB/subdir/testdir/test2
    }
    testzipfslist opt-regexp [list -regexp "testmount.*(A|2)"] {test.zip testmountA test.zip testmountB/subdir} {
	testmountA testmountA/test testmountA/testdir testmountA/testdir/test2
	testmountB/subdir/testdir/test2
    }

    #
    # zipfs exists
    testnumargs "zipfs exists" "filename" ""

    # Generates tests for zipfs exists
    proc testzipfsexists [list id path result [list mountpoint $defMountPt] args] {
	test zipfs-exists-$id "zipfs exists $id" -body {
	    zipfs exists $path
	} -setup {
	    mount [zippath test.zip] $mountpoint
	} -cleanup {
	    zipfs unmount $mountpoint
	    cleanup
	} -result $result {*}$args
    }
    testzipfsexists native-file  [info nameofexecutable]            0
    testzipfsexists enoent       [file join $defMountPt nosuchfile] 0
    testzipfsexists file         [file join $defMountPt test]       1
    testzipfsexists dir          [file join $defMountPt testdir]    1
    testzipfsexists mountpoint   $defMountPt                        1
    testzipfsexists root         [zipfs root]                       1 $defMountPt
    testzipfsexists mezzo        [file join $defMountPt a b]        1 [file join $defMountPt a b c]
    testzipfsexists mezzo-enoent [file join $defMountPt a c]        0 [file join $defMountPt a b c]

    #
    # zipfs find
    testnumargs "zipfs find" "directoryName" ""
    # Generates zipfs find tests for file, memory buffer cases for an archive
    proc testzipfsfind {id findtarget mounts resultpaths args} {
	set setup {
	    foreach {zippath mountpoint} $mounts {
		zipfs mount [zippath $zippath] [file join [zipfs root] $mountpoint]
	    }
	}
	set memory_setup {
	    foreach {zippath mountpoint} $mounts {
		zipfs mountdata [readbin [zippath $zippath]] [file join [zipfs root] $mountpoint]
	    }
	}
	if {[dict exists $args -setup]} {
	    append setup \n[dict get $args -setup]
	    append memory_setup \n[dict get $args -setup]
	    dict unset args -setup
	}
	set cleanup cleanup
	if {[dict exists $args -cleanup]} {
	    set cleanup "[dict get $args -cleanup]\n$cleanup"
	    dict unset args -cleanup
	}
	set resultpaths [lsort $resultpaths]
	test zipfs-find-$id "zipfs find $id" -body {
	    lsort [zipfs find $findtarget]
	} -setup $setup -cleanup $cleanup -result $resultpaths {*}$args

	# Mount memory buffer
	test zipfs-find-memory-$id "zipfs find memory $id" -body {
	    lsort [zipfs find $findtarget]
	} -setup $memory_setup -cleanup $cleanup -result $resultpaths {*}$args
    }

    testzipfsfind nonexistingmount [file join [zipfs root] nosuchmount] {
	test.zip testmountA test.zip testmountB/subdir
    } {}

    testzipfsfind absolute-path    [file join [zipfs root] testmountA] {
	test.zip testmountA test.zip testmountB/subdir
    } [zipfspaths testmountA/test testmountA/testdir testmountA/testdir/test2]

    testzipfsfind relative-path   testdir {
	test.zip testmountA test.zip testmountB/subdir
    } { testdir/test2 } -setup {
	set cwd [pwd]
	cd [file join [zipfs root] testmountA]
    } -cleanup {
	cd $cwd
    }

    # bug-6183f535c8
    testzipfsfind root-path   [zipfs root] {
	test.zip {} test.zip testmountB/subdir
    } [zipfspaths test testdir testdir/test2 testmountB testmountB/subdir testmountB/subdir/test testmountB/subdir/testdir testmountB/subdir/testdir/test2] -constraints !zipfslib

    testzipfsfind mezzo [file join [zipfs root] testmt a] {
	test.zip testmt/a/b
    } [zipfspaths testmt/a/b testmt/a/b/test testmt/a/b/testdir testmt/a/b/testdir/test2]

    testzipfsfind mezzo-root [zipfs root] {
	test.zip testmt/a/b
    } [zipfspaths testmt testmt/a testmt/a/b testmt/a/b/test testmt/a/b/testdir testmt/a/b/testdir/test2] -constraints !zipfslib

    test zipfs-find-native-absolute "zipfs find on native file system" -setup {
	set dir [makeDirectory zipfs-native-absolute]
	set subdir [file join $dir subdir]
	file mkdir $subdir
	set file [file join $subdir native]
	close [open $file w]
    } -cleanup {
	removeDirectory zipfs-native-absolute
    } -body {
	string equal [zipfs find $dir] [list $subdir $file]
    } -result 1

    test zipfs-find-native-relative "zipfs find relative on native file system" -setup {
	set dir [makeDirectory zipfs-native-relative]
	set subdir [file join $dir subdir]
	file mkdir $subdir
	set file [file join $subdir native]
	close [open $file w]
	set cwd [pwd]
    } -cleanup {
	cd $cwd
	removeDirectory zipfs-native-relative
    } -body {
	cd [file dirname $dir]
	# string equal [zipfs find [file tail $subdir]] [list subdir subdir/native]
	zipfs find [file tail $dir]
    } -result {zipfs-native-relative/subdir zipfs-native-relative/subdir/native}

    #
    # zipfs info
    testnumargs "zipfs info" "filename" ""

    test zipfs-info-native-nosuchfile "zipfs info on non-existent native path" -body {
	zipfs info nosuchfile
    } -result {path "nosuchfile" not found in any zipfs volume} -returnCodes error

    test zipfs-info-native-file "zipfs info on native path" -body {
	zipfs info [info nameofexecutable]
    } -result "path \"[info nameofexecutable]\" not found in any zipfs volume" -returnCodes error

    test zipfs-info-nosuchfile "zipfs info non-existent path in mounted archive" -setup {
	mount [zippath test.zip]
    } -cleanup {
	cleanup
    } -body {
	zipfs info [file join $defMountPt nosuchfile]
    } -result "path \"[file join $defMountPt nosuchfile]\" not found in any zipfs volume" -returnCodes error

    test zipfs-info-file "zipfs info file within mounted archive" -setup {
	mount [zippath testdeflated2.zip]
    } -cleanup {
	cleanup
    } -body {
	zipfs info [file join $defMountPt abac-repeat.txt]
    } -result [list [zippath testdeflated2.zip] 60 17 108]

    test zipfs-info-dir "zipfs info dir within mounted archive" -setup {
	mount [zippath test.zip]
    } -cleanup {
	cleanup
    } -body {
	zipfs info [file join $defMountPt testdir]
    } -result [list [zippath test.zip] 0 0 119]

    test zipfs-info-mountpoint "zipfs info on mount point - verify correct offset of zip content" -setup {
	# zip starts at offset 4
	mount [zippath junk-at-start.zip]
    } -cleanup {
	cleanup
    } -body {
	zipfs info $defMountPt
    } -result [list [zippath junk-at-start.zip] 0 0 4]

    test zipfs-info-mezzo "zipfs info on mount point - verify correct offset of zip content" -setup {
	# zip starts at offset 4
	mount [zippath junk-at-start.zip] /testmt/a/b
    } -cleanup {
	cleanup
    } -body {
	zipfs info [file join [zipfs root] testmt a]
    } -result {path "//zipfs:/testmt/a" not found in any zipfs volume} -returnCodes error

    #
    # zipfs canonical
    test zipfs-canonical-minargs {zipfs canonical min args} -body {
	zipfs canonical
    } -returnCodes error -result {wrong # args: should be "zipfs canonical ?mountpoint? filename"}
    test zipfs-canonical-maxargs {zipfs canonical max args} -body {
	zipfs canonical a b c
    } -returnCodes error -result {wrong # args: should be "zipfs canonical ?mountpoint? filename"}
    proc testzipfscanonical {id cmdargs result args} {
	test zipfs-canonical-$id "zipfs canonical $id" \
	    -body [list zipfs canonical {*}$cmdargs] \
	    -result $result {*}$args
    }
    testzipfscanonical default-relative      [list a]               [file join [zipfs root] a]
    testzipfscanonical default-absolute      [list /a]              [file join [zipfs root] a]
    testzipfscanonical root-relative-1       [list [zipfs root] a]  [file join [zipfs root] a]
    testzipfscanonical root-relative-2       [list / a]             [file join [zipfs root] a]
    testzipfscanonical root-absolute-1       [list [zipfs root] /a] [file join [zipfs root] a]
    testzipfscanonical root-absolute-2       [list / /a]            [file join [zipfs root] a]
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
    testzipfscanonical backslashes-1 [list X:/foo\\\\bar]    [file join [zipfs root] foo bar] -constraints win
    testzipfscanonical zipfspath     [list //zipfs:/x/y]     [file join [zipfs root] x y]
    testzipfscanonical zipfspath-1     [list MT //zipfs:/x/y]  [file join [zipfs root] x y]

    #
    # Read/uncompress
    proc testzipfsread {id zippath result {filename abac-repeat.txt} {openopts {}} args} {
        variable defMountPt
        set zippath [zippath $zippath]
        test zipfs-read-$id "zipfs read $id" -setup {
            unset -nocomplain fd
            zipfs mount $zippath $defMountPt
        } -cleanup {
            # In case open succeeded when it should not
            if {[info exists fd]} {
                close $fd
            }
            cleanup
        } -body {
            set fd [open [file join $defMountPt $filename] {*}$openopts]
            gets $fd
        } -result $result {*}$args

        set data [readbin $zippath]
        test zipfs-read-memory-$id "zipfs read in-memory $id" -setup {
            unset -nocomplain fd
            zipfs mountdata $data $defMountPt
        } -cleanup {
            # In case open succeeded when it should not
            if {[info exists fd]} {
                close $fd
            }
            cleanup
        } -body {
            set fd [open [file join $defMountPt $filename] {*}$openopts]
            gets $fd
        } -result $result {*}$args

    }
    testzipfsread stored    test.zip          test           test
    testzipfsread stored-1  teststored.zip    aaaaaaaaaaaaaa
    testzipfsread deflate   testdeflated2.zip aaaaaaaaaaaaaa
    testzipfsread bug-23dd83ce7c  empty.zip    {} empty.txt
    # Test open modes - see bug [4645658689]







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|







957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
    testzipfscanonical backslashes-1 [list X:/foo\\\\bar]    [file join [zipfs root] foo bar] -constraints win
    testzipfscanonical zipfspath     [list //zipfs:/x/y]     [file join [zipfs root] x y]
    testzipfscanonical zipfspath-1     [list MT //zipfs:/x/y]  [file join [zipfs root] x y]

    #
    # Read/uncompress
    proc testzipfsread {id zippath result {filename abac-repeat.txt} {openopts {}} args} {
	variable defMountPt
	set zippath [zippath $zippath]
	test zipfs-read-$id "zipfs read $id" -setup {
	    unset -nocomplain fd
	    zipfs mount $zippath $defMountPt
	} -cleanup {
	    # In case open succeeded when it should not
	    if {[info exists fd]} {
		close $fd
	    }
	    cleanup
	} -body {
	    set fd [open [file join $defMountPt $filename] {*}$openopts]
	    gets $fd
	} -result $result {*}$args

	set data [readbin $zippath]
	test zipfs-read-memory-$id "zipfs read in-memory $id" -setup {
	    unset -nocomplain fd
	    zipfs mountdata $data $defMountPt
	} -cleanup {
	    # In case open succeeded when it should not
	    if {[info exists fd]} {
		close $fd
	    }
	    cleanup
	} -body {
	    set fd [open [file join $defMountPt $filename] {*}$openopts]
	    gets $fd
	} -result $result {*}$args

    }
    testzipfsread stored    test.zip          test           test
    testzipfsread stored-1  teststored.zip    aaaaaaaaaaaaaa
    testzipfsread deflate   testdeflated2.zip aaaaaaaaaaaaaa
    testzipfsread bug-23dd83ce7c  empty.zip    {} empty.txt
    # Test open modes - see bug [4645658689]
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
    testzipfsread bzip2   testbzip2.zip     {unsupported compression method} abac-repeat.txt {} -returnCodes error
    testzipfsread lzma    testfile-lzma.zip {unsupported compression method} abac-repeat.txt {} -returnCodes error
    testzipfsread xz      testfile-xz.zip   {unsupported compression method} abac-repeat.txt {} -returnCodes error
    testzipfsread zstd    testfile-zstd.zip {unsupported compression method} abac-repeat.txt {} -returnCodes error
    testzipfsread deflate-error broken.zip  {decompression error} deflatezliberror {} -returnCodes error

    test zipfs-read-unwritable "Writes not allowed on file opened for read" -setup {
        mount [zippath test.zip]
    } -cleanup {
        close $fd
        cleanup
    } -body {
        set fd [open [file join $defMountPt test]]
        puts $fd blah
    } -result {channel "*" wasn't opened for writing} -match glob -returnCodes error

    #
    # Write
    proc testzipfswrite {id zippath result filename mode args} {
        variable defMountPt
        set zippath [zippath $zippath]
        set path [file join $defMountPt $filename]
        set body {
            set fd [open $path $mode]
            fconfigure $fd -translation binary
            puts -nonewline $fd XYZ
            seek $fd 0
            puts -nonewline $fd xyz
            close $fd
            set fd [open $path]
            fconfigure $fd -translation binary
            read $fd
        }
        test zipfs-write-$id "zipfs write $id" -setup {
            unset -nocomplain fd
            zipfs mount $zippath $defMountPt
        } -cleanup {
            # In case open succeeded when it should not
            if {[info exists fd]} {
                close $fd
            }
            cleanup
        } -body $body -result $result {*}$args

        set data [readbin $zippath]
        test zipfs-write-memory-$id "zipfs write in-memory $id" -setup {
            unset -nocomplain fd
            zipfs mountdata $data $defMountPt
        } -cleanup {
            # In case open succeeded when it should not
            if {[info exists fd]} {
                close $fd
            }
            cleanup
        } -body $body -result $result {*}$args

    }
    testzipfswrite create-w   test.zip          "file \"//zipfs:/testmount/newfile\" not created: operation not supported" newfile w -returnCodes error
    testzipfswrite create-w+  test.zip          "file \"//zipfs:/testmount/newfile\" not created: operation not supported" newfile w+ -returnCodes error
    testzipfswrite create-a   test.zip          "file \"$defMountPt/newfile\" not created: operation not supported" newfile a -returnCodes error
    testzipfswrite create-a+  test.zip          "file \"//zipfs:/testmount/newfile\" not created: operation not supported" newfile a+ -returnCodes error
    testzipfswrite store-w    teststored.zip    "xyz" abac-repeat.txt w
    testzipfswrite deflate-w  testdeflated2.zip "xyz" abac-repeat.txt w
    testzipfswrite store-w+   teststored.zip    "xyz" abac-repeat.txt w+
    testzipfswrite deflate-w+ testdeflated2.zip "xyz" abac-repeat.txt w+
    testzipfswrite stored-a   teststored.zip    "aaaaaaaaaaaaaa\nbbbbbbbbbbbbbb\naaaaaaaaaaaaaa\ncccccccccccccc\nXYZxyz" abac-repeat.txt a
    testzipfswrite deflate-a  testdeflated2.zip "aaaaaaaaaaaaaa\nbbbbbbbbbbbbbb\naaaaaaaaaaaaaa\ncccccccccccccc\nXYZxyz" abac-repeat.txt a
    testzipfswrite store-a+   teststored.zip    "xyzaaaaaaaaaaa\nbbbbbbbbbbbbbb\naaaaaaaaaaaaaa\ncccccccccccccc\nXYZ" abac-repeat.txt a+
    testzipfswrite deflate-a+ testdeflated2.zip "xyzaaaaaaaaaaa\nbbbbbbbbbbbbbb\naaaaaaaaaaaaaa\ncccccccccccccc\nXYZ" abac-repeat.txt a+
    testzipfswrite bug-23dd83ce7c-w  empty.zip  "xyz"   empty.txt w

    test zipfs-write-unreadable "Reads not allowed on file opened for write" -setup {
        mount [zippath test.zip]
    } -cleanup {
        close $fd
        cleanup
    } -body {
        set fd [open [file join $defMountPt test] w]
        read $fd
    } -result {channel "*" wasn't opened for reading} -match glob -returnCodes error

    test zipfs-write-persist "Writes persist ONLY while mounted" -setup {
        mount [zippath test.zip]
    } -cleanup {
        cleanup
    } -body {
        set path [file join $defMountPt test]
        set fd [open $path w]
        puts -nonewline $fd newtext
        close $fd
        set fd [open $path]
        set result [list [read $fd]]
        close $fd
        zipfs unmount $defMountPt
        mount [zippath test.zip]
        set fd [open $path]
        lappend result [read $fd]
        close $fd
        set result
    } -result [list newtext test\n]

    test zipfs-write-size-limit-0 "Writes more than size limit with flush" -setup {
        set origlimit $::tcl::zipfs::wrmax
        mount [zippath test.zip]
    } -cleanup {
        close $fd
        set ::tcl::zipfs::wrmax $origlimit
        cleanup
    } -body {
        set ::tcl::zipfs::wrmax 10
        set fd [open [file join $defMountPt test] w]
        puts $fd [string repeat x 11]
        flush $fd
    } -result {error flushing *: file too large} -match glob -returnCodes error

    test zipfs-write-size-limit-1 "Writes size limit on close" -setup {
        set origlimit $::tcl::zipfs::wrmax
        mount [zippath test.zip]
    } -cleanup {
        set ::tcl::zipfs::wrmax $origlimit
        cleanup
    } -body {
        set ::tcl::zipfs::wrmax 10
        set fd [open [file join $defMountPt test] w]
        puts $fd [string repeat x 11]
        close $fd
    } -result {file too large} -match glob -returnCodes error

    test zipfs-write-size-limit-2 "Writes max size" -setup {
        set origlimit $::tcl::zipfs::wrmax
        set ::tcl::zipfs::wrmax 10000000
        mount [zippath test.zip]
    } -cleanup {
        set ::tcl::zipfs::wrmax $origlimit
        cleanup
    } -body {
        set fd [open [file join $defMountPt test] w]
        puts -nonewline $fd [string repeat x $::tcl::zipfs::wrmax]
        close $fd
        file size [file join $defMountPt test]
    } -result 10000000

    test zipfs-write-size-limit-3 "Writes incrementally - buffer growth" -setup {
        mount [zippath test.zip]
    } -cleanup {
        cleanup
    } -body {
        set fd [open [file join $defMountPt test] w]
        fconfigure $fd -buffering none
        for {set i 0} {$i < 100000} {incr i} {
            puts -nonewline $fd 0123456789
        }
        close $fd
        readbin [file join $defMountPt test]
    } -result [string repeat 0123456789 100000]

    test zipfs-write-size-limit-4 "Writes disallowed" -setup {
        set origlimit $::tcl::zipfs::wrmax
        mount [zippath test.zip]
    } -cleanup {
        set ::tcl::zipfs::wrmax $origlimit
        cleanup
    } -body {
        set ::tcl::zipfs::wrmax -1
        open [file join $defMountPt test] w
    } -result {writes not permitted: permission denied} -returnCodes error

    #
    # read/seek/write
    proc testzipfsrw {id zippath expected filename mode args} {
        variable defMountPt
        set zippath [zippath $zippath]
        set path [file join $defMountPt $filename]
        set body {
            set result ""
            set fd [open $path $mode]
            fconfigure $fd -translation binary
            append result [gets $fd],
            set pos [tell $fd]
            append result $pos,
            puts -nonewline $fd "0123456789"
            append result [gets $fd],
            seek $fd $pos
            append result [gets $fd],
            seek $fd -6 end
            append result [read $fd]|
            close $fd
            # Reopen after closing - bug [f91ee30d3]
            set fd [open $path rb]
            append result [read $fd]
        }
        test zipfs-rw-$id "zipfs read/seek/write $id" -setup {
            unset -nocomplain fd
            zipfs mount $zippath $defMountPt
        } -cleanup {
            # In case open succeeded when it should not
            if {[info exists fd]} {
                close $fd
            }
            cleanup
        } -body $body -result $expected {*}$args

        set data [readbin $zippath]
        test zipfs-rw-memory-$id "zipfs read/seek/write in-memory $id" -setup {
            unset -nocomplain fd
            zipfs mountdata $data $defMountPt
        } -cleanup {
            # In case open succeeded when it should not
            if {[info exists fd]} {
                close $fd
            }
            cleanup
        } -body $body -result $expected {*}$args

    }
    testzipfsrw store-r+ teststored.zip      "aaaaaaaaaaaaaa,15,bbbb,0123456789bbbb,ccccc\n|aaaaaaaaaaaaaa\n0123456789bbbb\naaaaaaaaaaaaaa\ncccccccccccccc\n" abac-repeat.txt r+
    testzipfsrw store-w+ teststored.zip      ",0,,0123456789,456789|0123456789" abac-repeat.txt w+
    testzipfsrw store-a+ teststored.zip      ",60,,0123456789,456789|aaaaaaaaaaaaaa\nbbbbbbbbbbbbbb\naaaaaaaaaaaaaa\ncccccccccccccc\n0123456789" abac-repeat.txt a+
    testzipfsrw deflate-r+ testdeflated2.zip      "aaaaaaaaaaaaaa,15,bbbb,0123456789bbbb,ccccc\n|aaaaaaaaaaaaaa\n0123456789bbbb\naaaaaaaaaaaaaa\ncccccccccccccc\n" abac-repeat.txt r+
    testzipfsrw deflate-w+ testdeflated2.zip      ",0,,0123456789,456789|0123456789" abac-repeat.txt w+
    testzipfsrw deflate-a+ testdeflated2.zip      ",60,,0123456789,456789|aaaaaaaaaaaaaa\nbbbbbbbbbbbbbb\naaaaaaaaaaaaaa\ncccccccccccccc\n0123456789" abac-repeat.txt a+
    test zipfs-rw-bug-f91ee30d33 "Bug f91ee30d33 - truncates at last read" -setup {
        mount [zippath test.zip]
    } -cleanup {
        close $fd
        cleanup
    } -body {
        set path [file join $defMountPt test]
        set fd [open $path r+]
        puts -nonewline $fd X
        close $fd
        set fd [open $path r]
        read $fd
    } -result "Xest\n"

    #
    # Password protected
    proc testpasswordr {id zipfile filename password result args} {
        variable defMountPt
        set zippath [zippath $zipfile]
        test zipfs-password-read-$id "zipfs password read $id" -setup {
            unset -nocomplain fd
            if {$password ne ""} {
                zipfs mount $zippath $defMountPt $password
            } else {
                zipfs mount $zippath $defMountPt
            }
        } -cleanup {
            # In case open succeeded when it should not
            if {[info exists fd]} {
                close $fd
            }
            cleanup
        } -body {
            set fd [open [file join $defMountPt $filename]]
            gets $fd
        } -result $result {*}$args -constraints bbe7c6ff9e
    }
    # The bug bbe7c6ff9e only manifests on macos
    testConstraint bbe7c6ff9e [expr {$::tcl_platform(os) ne "Darwin"}]

    # NOTE: test-password.zip is the DOS time based encryption header validity check (infozip style)
    #       test-password2.zip is the CRC based encryption header validity check (pkware style)
    testpasswordr plain                  test-password.zip plain.txt password plaintext
    testpasswordr plain-nopass           test-password.zip plain.txt "" plaintext
    testpasswordr plain-badpass          test-password.zip plain.txt badpassword plaintext
    testpasswordr cipher-1               test-password.zip cipher.bin password ciphertext
    testpasswordr cipher-2               test-password2.zip cipher.bin password ciphertext
    testpasswordr cipher-nopass-1        test-password.zip cipher.bin {} "decryption failed - no password provided" -returnCodes error
    testpasswordr cipher-nopass-2        test-password2.zip cipher.bin {} "decryption failed - no password provided" -returnCodes error
    testpasswordr cipher-badpass-1       test-password.zip cipher.bin badpassword "invalid password" -returnCodes error
    testpasswordr cipher-badpass-2       test-password2.zip cipher.bin badpassword "invalid password" -returnCodes error
    testpasswordr cipher-deflate         test-password.zip cipher-deflate.bin password [lseq 100]
    testpasswordr cipher-deflate-nopass  test-password.zip cipher-deflate.bin {} "decryption failed - no password provided" -returnCodes error
    testpasswordr cipher-deflate-badpass test-password.zip cipher-deflate.bin badpassword "invalid password" -returnCodes error

    proc testpasswordw {id zippath filename password mode result args} {
        variable defMountPt
        set zippath [zippath $zippath]
        set path [file join $defMountPt $filename]
        set body {
            set fd [open $path $mode]
            fconfigure $fd -translation binary
            puts -nonewline $fd "xyz"
            close $fd
            set fd [open $path]
            fconfigure $fd -translation binary
            read $fd
        }
        test zipfs-password-write-$id "zipfs write $id" -setup {
            unset -nocomplain fd
            if {$password ne ""} {
                zipfs mount $zippath $defMountPt $password
            } else {
                zipfs mount $zippath $defMountPt
            }
        } -cleanup {
            # In case open succeeded when it should not
            if {[info exists fd]} {
                close $fd
            }
            cleanup
        } -body $body -result $result {*}$args -constraints bbe7c6ff9e
    }
    # NOTE: test-password.zip is the DOS time based encryption header validity check (infozip style)
    #       test-password2.zip is the CRC based encryption header validity check (pkware style)
    testpasswordw cipher-w-1               test-password.zip  cipher.bin password w xyz
    testpasswordw cipher-w-2               test-password2.zip cipher.bin password w xyz
    testpasswordw cipher-deflate-w         test-password2.zip cipher-deflate.bin password w xyz
    testpasswordw cipher-badpass-w-1       test-password.zip  cipher.bin badpass w {invalid password} -returnCodes error







|

|
|

|
|





|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|

















|

|
|

|
|



|

|

|
|
|
|
|
|
|
|
|
|
|
|
|



|
|

|
|
|

|
|
|
|



|
|

|
|

|
|
|
|



|
|
|

|
|

|
|
|
|



|

|

|
|
|
|
|
|
|



|
|

|
|

|
|





|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|









|

|
|

|
|
|
|
|
|





|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|




















|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
    testzipfsread bzip2   testbzip2.zip     {unsupported compression method} abac-repeat.txt {} -returnCodes error
    testzipfsread lzma    testfile-lzma.zip {unsupported compression method} abac-repeat.txt {} -returnCodes error
    testzipfsread xz      testfile-xz.zip   {unsupported compression method} abac-repeat.txt {} -returnCodes error
    testzipfsread zstd    testfile-zstd.zip {unsupported compression method} abac-repeat.txt {} -returnCodes error
    testzipfsread deflate-error broken.zip  {decompression error} deflatezliberror {} -returnCodes error

    test zipfs-read-unwritable "Writes not allowed on file opened for read" -setup {
	mount [zippath test.zip]
    } -cleanup {
	close $fd
	cleanup
    } -body {
	set fd [open [file join $defMountPt test]]
	puts $fd blah
    } -result {channel "*" wasn't opened for writing} -match glob -returnCodes error

    #
    # Write
    proc testzipfswrite {id zippath result filename mode args} {
	variable defMountPt
	set zippath [zippath $zippath]
	set path [file join $defMountPt $filename]
	set body {
	    set fd [open $path $mode]
	    fconfigure $fd -translation binary
	    puts -nonewline $fd XYZ
	    seek $fd 0
	    puts -nonewline $fd xyz
	    close $fd
	    set fd [open $path]
	    fconfigure $fd -translation binary
	    read $fd
	}
	test zipfs-write-$id "zipfs write $id" -setup {
	    unset -nocomplain fd
	    zipfs mount $zippath $defMountPt
	} -cleanup {
	    # In case open succeeded when it should not
	    if {[info exists fd]} {
		close $fd
	    }
	    cleanup
	} -body $body -result $result {*}$args

	set data [readbin $zippath]
	test zipfs-write-memory-$id "zipfs write in-memory $id" -setup {
	    unset -nocomplain fd
	    zipfs mountdata $data $defMountPt
	} -cleanup {
	    # In case open succeeded when it should not
	    if {[info exists fd]} {
		close $fd
	    }
	    cleanup
	} -body $body -result $result {*}$args

    }
    testzipfswrite create-w   test.zip          "file \"//zipfs:/testmount/newfile\" not created: operation not supported" newfile w -returnCodes error
    testzipfswrite create-w+  test.zip          "file \"//zipfs:/testmount/newfile\" not created: operation not supported" newfile w+ -returnCodes error
    testzipfswrite create-a   test.zip          "file \"$defMountPt/newfile\" not created: operation not supported" newfile a -returnCodes error
    testzipfswrite create-a+  test.zip          "file \"//zipfs:/testmount/newfile\" not created: operation not supported" newfile a+ -returnCodes error
    testzipfswrite store-w    teststored.zip    "xyz" abac-repeat.txt w
    testzipfswrite deflate-w  testdeflated2.zip "xyz" abac-repeat.txt w
    testzipfswrite store-w+   teststored.zip    "xyz" abac-repeat.txt w+
    testzipfswrite deflate-w+ testdeflated2.zip "xyz" abac-repeat.txt w+
    testzipfswrite stored-a   teststored.zip    "aaaaaaaaaaaaaa\nbbbbbbbbbbbbbb\naaaaaaaaaaaaaa\ncccccccccccccc\nXYZxyz" abac-repeat.txt a
    testzipfswrite deflate-a  testdeflated2.zip "aaaaaaaaaaaaaa\nbbbbbbbbbbbbbb\naaaaaaaaaaaaaa\ncccccccccccccc\nXYZxyz" abac-repeat.txt a
    testzipfswrite store-a+   teststored.zip    "xyzaaaaaaaaaaa\nbbbbbbbbbbbbbb\naaaaaaaaaaaaaa\ncccccccccccccc\nXYZ" abac-repeat.txt a+
    testzipfswrite deflate-a+ testdeflated2.zip "xyzaaaaaaaaaaa\nbbbbbbbbbbbbbb\naaaaaaaaaaaaaa\ncccccccccccccc\nXYZ" abac-repeat.txt a+
    testzipfswrite bug-23dd83ce7c-w  empty.zip  "xyz"   empty.txt w

    test zipfs-write-unreadable "Reads not allowed on file opened for write" -setup {
	mount [zippath test.zip]
    } -cleanup {
	close $fd
	cleanup
    } -body {
	set fd [open [file join $defMountPt test] w]
	read $fd
    } -result {channel "*" wasn't opened for reading} -match glob -returnCodes error

    test zipfs-write-persist "Writes persist ONLY while mounted" -setup {
	mount [zippath test.zip]
    } -cleanup {
	cleanup
    } -body {
	set path [file join $defMountPt test]
	set fd [open $path w]
	puts -nonewline $fd newtext
	close $fd
	set fd [open $path]
	set result [list [read $fd]]
	close $fd
	zipfs unmount $defMountPt
	mount [zippath test.zip]
	set fd [open $path]
	lappend result [read $fd]
	close $fd
	set result
    } -result [list newtext test\n]

    test zipfs-write-size-limit-0 "Writes more than size limit with flush" -setup {
	set origlimit $::tcl::zipfs::wrmax
	mount [zippath test.zip]
    } -cleanup {
	close $fd
	set ::tcl::zipfs::wrmax $origlimit
	cleanup
    } -body {
	set ::tcl::zipfs::wrmax 10
	set fd [open [file join $defMountPt test] w]
	puts $fd [string repeat x 11]
	flush $fd
    } -result {error flushing *: file too large} -match glob -returnCodes error

    test zipfs-write-size-limit-1 "Writes size limit on close" -setup {
	set origlimit $::tcl::zipfs::wrmax
	mount [zippath test.zip]
    } -cleanup {
	set ::tcl::zipfs::wrmax $origlimit
	cleanup
    } -body {
	set ::tcl::zipfs::wrmax 10
	set fd [open [file join $defMountPt test] w]
	puts $fd [string repeat x 11]
	close $fd
    } -result {file too large} -match glob -returnCodes error

    test zipfs-write-size-limit-2 "Writes max size" -setup {
	set origlimit $::tcl::zipfs::wrmax
	set ::tcl::zipfs::wrmax 10000000
	mount [zippath test.zip]
    } -cleanup {
	set ::tcl::zipfs::wrmax $origlimit
	cleanup
    } -body {
	set fd [open [file join $defMountPt test] w]
	puts -nonewline $fd [string repeat x $::tcl::zipfs::wrmax]
	close $fd
	file size [file join $defMountPt test]
    } -result 10000000

    test zipfs-write-size-limit-3 "Writes incrementally - buffer growth" -setup {
	mount [zippath test.zip]
    } -cleanup {
	cleanup
    } -body {
	set fd [open [file join $defMountPt test] w]
	fconfigure $fd -buffering none
	for {set i 0} {$i < 100000} {incr i} {
	    puts -nonewline $fd 0123456789
	}
	close $fd
	readbin [file join $defMountPt test]
    } -result [string repeat 0123456789 100000]

    test zipfs-write-size-limit-4 "Writes disallowed" -setup {
	set origlimit $::tcl::zipfs::wrmax
	mount [zippath test.zip]
    } -cleanup {
	set ::tcl::zipfs::wrmax $origlimit
	cleanup
    } -body {
	set ::tcl::zipfs::wrmax -1
	open [file join $defMountPt test] w
    } -result {writes not permitted: permission denied} -returnCodes error

    #
    # read/seek/write
    proc testzipfsrw {id zippath expected filename mode args} {
	variable defMountPt
	set zippath [zippath $zippath]
	set path [file join $defMountPt $filename]
	set body {
	    set result ""
	    set fd [open $path $mode]
	    fconfigure $fd -translation binary
	    append result [gets $fd],
	    set pos [tell $fd]
	    append result $pos,
	    puts -nonewline $fd "0123456789"
	    append result [gets $fd],
	    seek $fd $pos
	    append result [gets $fd],
	    seek $fd -6 end
	    append result [read $fd]|
	    close $fd
	    # Reopen after closing - bug [f91ee30d3]
	    set fd [open $path rb]
	    append result [read $fd]
	}
	test zipfs-rw-$id "zipfs read/seek/write $id" -setup {
	    unset -nocomplain fd
	    zipfs mount $zippath $defMountPt
	} -cleanup {
	    # In case open succeeded when it should not
	    if {[info exists fd]} {
		close $fd
	    }
	    cleanup
	} -body $body -result $expected {*}$args

	set data [readbin $zippath]
	test zipfs-rw-memory-$id "zipfs read/seek/write in-memory $id" -setup {
	    unset -nocomplain fd
	    zipfs mountdata $data $defMountPt
	} -cleanup {
	    # In case open succeeded when it should not
	    if {[info exists fd]} {
		close $fd
	    }
	    cleanup
	} -body $body -result $expected {*}$args

    }
    testzipfsrw store-r+ teststored.zip      "aaaaaaaaaaaaaa,15,bbbb,0123456789bbbb,ccccc\n|aaaaaaaaaaaaaa\n0123456789bbbb\naaaaaaaaaaaaaa\ncccccccccccccc\n" abac-repeat.txt r+
    testzipfsrw store-w+ teststored.zip      ",0,,0123456789,456789|0123456789" abac-repeat.txt w+
    testzipfsrw store-a+ teststored.zip      ",60,,0123456789,456789|aaaaaaaaaaaaaa\nbbbbbbbbbbbbbb\naaaaaaaaaaaaaa\ncccccccccccccc\n0123456789" abac-repeat.txt a+
    testzipfsrw deflate-r+ testdeflated2.zip      "aaaaaaaaaaaaaa,15,bbbb,0123456789bbbb,ccccc\n|aaaaaaaaaaaaaa\n0123456789bbbb\naaaaaaaaaaaaaa\ncccccccccccccc\n" abac-repeat.txt r+
    testzipfsrw deflate-w+ testdeflated2.zip      ",0,,0123456789,456789|0123456789" abac-repeat.txt w+
    testzipfsrw deflate-a+ testdeflated2.zip      ",60,,0123456789,456789|aaaaaaaaaaaaaa\nbbbbbbbbbbbbbb\naaaaaaaaaaaaaa\ncccccccccccccc\n0123456789" abac-repeat.txt a+
    test zipfs-rw-bug-f91ee30d33 "Bug f91ee30d33 - truncates at last read" -setup {
	mount [zippath test.zip]
    } -cleanup {
	close $fd
	cleanup
    } -body {
	set path [file join $defMountPt test]
	set fd [open $path r+]
	puts -nonewline $fd X
	close $fd
	set fd [open $path r]
	read $fd
    } -result "Xest\n"

    #
    # Password protected
    proc testpasswordr {id zipfile filename password result args} {
	variable defMountPt
	set zippath [zippath $zipfile]
	test zipfs-password-read-$id "zipfs password read $id" -setup {
	    unset -nocomplain fd
	    if {$password ne ""} {
		zipfs mount $zippath $defMountPt $password
	    } else {
		zipfs mount $zippath $defMountPt
	    }
	} -cleanup {
	    # In case open succeeded when it should not
	    if {[info exists fd]} {
		close $fd
	    }
	    cleanup
	} -body {
	    set fd [open [file join $defMountPt $filename]]
	    gets $fd
	} -result $result {*}$args -constraints bbe7c6ff9e
    }
    # The bug bbe7c6ff9e only manifests on macos
    testConstraint bbe7c6ff9e [expr {$::tcl_platform(os) ne "Darwin"}]

    # NOTE: test-password.zip is the DOS time based encryption header validity check (infozip style)
    #       test-password2.zip is the CRC based encryption header validity check (pkware style)
    testpasswordr plain                  test-password.zip plain.txt password plaintext
    testpasswordr plain-nopass           test-password.zip plain.txt "" plaintext
    testpasswordr plain-badpass          test-password.zip plain.txt badpassword plaintext
    testpasswordr cipher-1               test-password.zip cipher.bin password ciphertext
    testpasswordr cipher-2               test-password2.zip cipher.bin password ciphertext
    testpasswordr cipher-nopass-1        test-password.zip cipher.bin {} "decryption failed - no password provided" -returnCodes error
    testpasswordr cipher-nopass-2        test-password2.zip cipher.bin {} "decryption failed - no password provided" -returnCodes error
    testpasswordr cipher-badpass-1       test-password.zip cipher.bin badpassword "invalid password" -returnCodes error
    testpasswordr cipher-badpass-2       test-password2.zip cipher.bin badpassword "invalid password" -returnCodes error
    testpasswordr cipher-deflate         test-password.zip cipher-deflate.bin password [lseq 100]
    testpasswordr cipher-deflate-nopass  test-password.zip cipher-deflate.bin {} "decryption failed - no password provided" -returnCodes error
    testpasswordr cipher-deflate-badpass test-password.zip cipher-deflate.bin badpassword "invalid password" -returnCodes error

    proc testpasswordw {id zippath filename password mode result args} {
	variable defMountPt
	set zippath [zippath $zippath]
	set path [file join $defMountPt $filename]
	set body {
	    set fd [open $path $mode]
	    fconfigure $fd -translation binary
	    puts -nonewline $fd "xyz"
	    close $fd
	    set fd [open $path]
	    fconfigure $fd -translation binary
	    read $fd
	}
	test zipfs-password-write-$id "zipfs write $id" -setup {
	    unset -nocomplain fd
	    if {$password ne ""} {
		zipfs mount $zippath $defMountPt $password
	    } else {
		zipfs mount $zippath $defMountPt
	    }
	} -cleanup {
	    # In case open succeeded when it should not
	    if {[info exists fd]} {
		close $fd
	    }
	    cleanup
	} -body $body -result $result {*}$args -constraints bbe7c6ff9e
    }
    # NOTE: test-password.zip is the DOS time based encryption header validity check (infozip style)
    #       test-password2.zip is the CRC based encryption header validity check (pkware style)
    testpasswordw cipher-w-1               test-password.zip  cipher.bin password w xyz
    testpasswordw cipher-w-2               test-password2.zip cipher.bin password w xyz
    testpasswordw cipher-deflate-w         test-password2.zip cipher-deflate.bin password w xyz
    testpasswordw cipher-badpass-w-1       test-password.zip  cipher.bin badpass w {invalid password} -returnCodes error
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
    testpasswordw cipher-deflate-a+ test-password2.zip cipher-deflate.bin password a+ [lseq 100]xyz
    testpasswordw cipher-badpass-a+ test-password.zip cipher.bin badpass a+ {invalid password} -returnCodes error
    testpasswordw cipher-badpass-deflate-a+ test-password2.zip cipher-deflate.bin badpass a+ {invalid password} -returnCodes error

    #
    # CRC errors
    proc testcrc {id zippath filename result args} {
        variable defMountPt
        set zippath [zippath $zippath]
        test zipfs-crc-$id "zipfs crc $id" -setup {
            unset -nocomplain fd
            zipfs mount $zippath $defMountPt
        } -cleanup {
            # In case mount succeeded when it should not
            if {[info exists fd]} {
                close $fd
            }
            cleanup
        } -body {
            set fd [open [file join $defMountPt $filename]]
        } -result $result -returnCodes error {*}$args

        # Mount memory buffer
        test zipfs-crc-memory-$id "zipfs crc memory $id" -setup {
            zipfs mountdata [readbin [zippath $zippath]] $defMountPt
        } -cleanup {
            cleanup
        } -body {
            set fd [open [file join $defMountPt $filename]]
        } -result $result -returnCodes error {*}$args
    }
    testcrc local incons-local-crc.zip a "invalid CRC"
    testcrc store-crc broken.zip storedcrcerror "invalid CRC"
    testcrc deflate-crc broken.zip deflatecrcerror "invalid CRC"
    test zipfs-crc-false-positives {
        Verify no false positives in CRC checking
    } -constraints zipfslib -body {
        # Just loop ensuring no crc failures
        foreach f [zipfs list] {
            if {[file isfile $f]} {
                close [open $f]
                incr count
            }
        }
        expr {$count > 0}
    } -result 1

    #
    # file stat,lstat
    proc fixuptime {t} {
        # To compensate for the lack of timezone in zip, all dates
        # expressed as strings and translated to local time
        if {[regexp {^\d{4}-\d\d-\d\d \d\d:\d\d:\d\d} $t]} {
            return [clock scan $t -format "%Y-%m-%d %H:%M:%S"]
        }
        return $t
    }
    proc fixupstat {stat} {
        foreach key {atime ctime mtime} {
            # ZIP files have no TZ info so zipfs uses mktime which is localtime
            dict set stat $key [fixuptime [dict get $stat $key]]
        }
        if {$::tcl_platform(platform) ne "windows"} {
            dict set stat blksize 0
            dict set stat blocks 0
        }
        return [lsort -stride 2 $stat]
    }
    # Wraps stat and lstat
    proc testzipfsstat {id mountpoint target result args} {
        test zipfs-file-stat-$id "file stat $id" -setup {
            zipfs mount [zippath test.zip] $mountpoint
        } -cleanup cleanup -body {
            lsort -stride 2 [file stat [file join $mountpoint $target]]
        } -result $result {*}$args

        test zipfs-file-lstat-$id "file lstat $id" -setup {
            mount [zippath test.zip]
        } -cleanup cleanup -body {
            lsort -stride 2 [file lstat [file join $mountpoint $target]]
        } -result $result {*}$args
    }
    testzipfsstat enoent      $defMountPt enoent                  "could not read \"[file join $defMountPt enoent]\": no such file or directory" -returnCodes error
    testzipfsstat nosuchmount $defMountPt //zipfs:/notamount/test "could not read \"//zipfs:/notamount/test\": no such file or directory" -returnCodes error
    testzipfsstat file        $defMountPt test                    [fixupstat {atime {2003-10-06 15:46:42} ctime {2003-10-06 15:46:42} dev 0 gid 0 ino 0 mode 33133 mtime {2003-10-06 15:46:42} nlink 0 size 5 type file uid 0}]
    testzipfsstat dir         $defMountPt testdir                 [fixupstat {atime {2005-01-11 19:03:54} ctime {2005-01-11 19:03:54} dev 0 gid 0 ino 0 mode 16749 mtime {2005-01-11 19:03:54} nlink 0 size 0 type directory uid 0}]
    testzipfsstat root-mount  [zipfs root] [zipfs root]           [fixupstat {atime .* ctime .* dev 0 gid 0 ino 0 mode 16749 mtime .* nlink 0 size 0 type directory uid 0}] -match regexp
    testzipfsstat root-subdir-mount $defMountPt [zipfs root]      [fixupstat {atime .* ctime .* dev 0 gid 0 ino 0 mode 16749 mtime .* nlink 0 size 0 type directory uid 0}] -match regexp
    testzipfsstat mezzo       [file join $defMountPt mt2] $defMountPt [fixupstat {atime .* ctime .* dev 0 gid 0 ino 0 mode 16749 mtime .* nlink 0 size 0 type directory uid 0}] -match regexp

    #
    # glob of zipfs file
    proc testzipfsglob {id mounts cmdopts result args} {
        set setup {
            foreach {zippath mountpoint} $mounts {
                zipfs mount [zippath $zippath] [file join [zipfs root] $mountpoint]
            }
        }
        if {[dict exists $args -setup]} {
            append setup \n[dict get $args -setup]
            dict unset args -setup
        }
        set cleanup cleanup
        if {[dict exists $args -cleanup]} {
            set cleanup "[dict get $args -cleanup]\n$cleanup"
            dict unset args -cleanup
        }
        test zipfs-glob-$id "zipfs glob $id $cmdopts" -body {
            lsort [glob {*}$cmdopts]
        } -setup $setup -cleanup $cleanup -result $result {*}$args
    }

    set basicMounts [list test.zip $defMountPt]
    testzipfsglob basic           $basicMounts [list $defMountPt/*]              [zipfspathsmt $defMountPt test testdir]
    testzipfsglob basic-pat       $basicMounts [list $defMountPt/t*d*]           [zipfspathsmt $defMountPt testdir]
    testzipfsglob basic-deep      $basicMounts [list $defMountPt/tes*/*]         [zipfspathsmt $defMountPt testdir/test2]
    testzipfsglob basic-dir       $basicMounts [list -directory  $defMountPt *]  [zipfspathsmt $defMountPt test testdir]
    testzipfsglob basic-dir-tails $basicMounts [list -tails -dir $defMountPt *]  [list test testdir]
    testzipfsglob basic-type-d    $basicMounts [list -type d $defMountPt/*]      [zipfspathsmt $defMountPt testdir]
    testzipfsglob basic-type-f    $basicMounts [list -type f $defMountPt/*]      [zipfspathsmt $defMountPt test]
    testzipfsglob basic-type-d-f  $basicMounts [list -type {d f} $defMountPt/*]  [zipfspathsmt $defMountPt test testdir]
    testzipfsglob basic-type-l    $basicMounts [list -type l $defMountPt/*]      {}
    foreach type {b c l p s} {
        testzipfsglob basic-type-1-$type    $basicMounts [list -type $type $defMountPt/*]          {}
        testzipfsglob basic-type-f-$type  $basicMounts [list -type [list f $type] $defMountPt/*] [zipfspathsmt $defMountPt test]
        testzipfsglob basic-type-d-$type  $basicMounts [list -type [list d $type] $defMountPt/*] [zipfspathsmt $defMountPt testdir]
    }
    testzipfsglob basic-path      $basicMounts [list -path $defMountPt/t *d*]    [zipfspathsmt $defMountPt testdir]
    testzipfsglob basic-enoent    $basicMounts [list $defMountPt/x*]             {}
    testzipfsglob basic-enoent-ok $basicMounts [list -nocomplain $defMountPt/x*] {}

    # NOTE: test root mounts separately because some bugs only showed up on these
    set rootMounts [list test.zip /]







|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|





|

|
|
|
|
|
|
|
|





|
|
|
|
|
|


|
|
|
|
|
|
|
|
|



|
|
|
|
|

|
|
|
|
|












|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|













|
|
|







1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
    testpasswordw cipher-deflate-a+ test-password2.zip cipher-deflate.bin password a+ [lseq 100]xyz
    testpasswordw cipher-badpass-a+ test-password.zip cipher.bin badpass a+ {invalid password} -returnCodes error
    testpasswordw cipher-badpass-deflate-a+ test-password2.zip cipher-deflate.bin badpass a+ {invalid password} -returnCodes error

    #
    # CRC errors
    proc testcrc {id zippath filename result args} {
	variable defMountPt
	set zippath [zippath $zippath]
	test zipfs-crc-$id "zipfs crc $id" -setup {
	    unset -nocomplain fd
	    zipfs mount $zippath $defMountPt
	} -cleanup {
	    # In case mount succeeded when it should not
	    if {[info exists fd]} {
		close $fd
	    }
	    cleanup
	} -body {
	    set fd [open [file join $defMountPt $filename]]
	} -result $result -returnCodes error {*}$args

	# Mount memory buffer
	test zipfs-crc-memory-$id "zipfs crc memory $id" -setup {
	    zipfs mountdata [readbin [zippath $zippath]] $defMountPt
	} -cleanup {
	    cleanup
	} -body {
	    set fd [open [file join $defMountPt $filename]]
	} -result $result -returnCodes error {*}$args
    }
    testcrc local incons-local-crc.zip a "invalid CRC"
    testcrc store-crc broken.zip storedcrcerror "invalid CRC"
    testcrc deflate-crc broken.zip deflatecrcerror "invalid CRC"
    test zipfs-crc-false-positives {
	Verify no false positives in CRC checking
    } -constraints zipfslib -body {
	# Just loop ensuring no crc failures
	foreach f [zipfs list] {
	    if {[file isfile $f]} {
		close [open $f]
		incr count
	    }
	}
	expr {$count > 0}
    } -result 1

    #
    # file stat,lstat
    proc fixuptime {t} {
	# To compensate for the lack of timezone in zip, all dates
	# expressed as strings and translated to local time
	if {[regexp {^\d{4}-\d\d-\d\d \d\d:\d\d:\d\d} $t]} {
	    return [clock scan $t -format "%Y-%m-%d %H:%M:%S"]
	}
	return $t
    }
    proc fixupstat {stat} {
	foreach key {atime ctime mtime} {
	    # ZIP files have no TZ info so zipfs uses mktime which is localtime
	    dict set stat $key [fixuptime [dict get $stat $key]]
	}
	if {$::tcl_platform(platform) ne "windows"} {
	    dict set stat blksize 0
	    dict set stat blocks 0
	}
	return [lsort -stride 2 $stat]
    }
    # Wraps stat and lstat
    proc testzipfsstat {id mountpoint target result args} {
	test zipfs-file-stat-$id "file stat $id" -setup {
	    zipfs mount [zippath test.zip] $mountpoint
	} -cleanup cleanup -body {
	    lsort -stride 2 [file stat [file join $mountpoint $target]]
	} -result $result {*}$args

	test zipfs-file-lstat-$id "file lstat $id" -setup {
	    mount [zippath test.zip]
	} -cleanup cleanup -body {
	    lsort -stride 2 [file lstat [file join $mountpoint $target]]
	} -result $result {*}$args
    }
    testzipfsstat enoent      $defMountPt enoent                  "could not read \"[file join $defMountPt enoent]\": no such file or directory" -returnCodes error
    testzipfsstat nosuchmount $defMountPt //zipfs:/notamount/test "could not read \"//zipfs:/notamount/test\": no such file or directory" -returnCodes error
    testzipfsstat file        $defMountPt test                    [fixupstat {atime {2003-10-06 15:46:42} ctime {2003-10-06 15:46:42} dev 0 gid 0 ino 0 mode 33133 mtime {2003-10-06 15:46:42} nlink 0 size 5 type file uid 0}]
    testzipfsstat dir         $defMountPt testdir                 [fixupstat {atime {2005-01-11 19:03:54} ctime {2005-01-11 19:03:54} dev 0 gid 0 ino 0 mode 16749 mtime {2005-01-11 19:03:54} nlink 0 size 0 type directory uid 0}]
    testzipfsstat root-mount  [zipfs root] [zipfs root]           [fixupstat {atime .* ctime .* dev 0 gid 0 ino 0 mode 16749 mtime .* nlink 0 size 0 type directory uid 0}] -match regexp
    testzipfsstat root-subdir-mount $defMountPt [zipfs root]      [fixupstat {atime .* ctime .* dev 0 gid 0 ino 0 mode 16749 mtime .* nlink 0 size 0 type directory uid 0}] -match regexp
    testzipfsstat mezzo       [file join $defMountPt mt2] $defMountPt [fixupstat {atime .* ctime .* dev 0 gid 0 ino 0 mode 16749 mtime .* nlink 0 size 0 type directory uid 0}] -match regexp

    #
    # glob of zipfs file
    proc testzipfsglob {id mounts cmdopts result args} {
	set setup {
	    foreach {zippath mountpoint} $mounts {
		zipfs mount [zippath $zippath] [file join [zipfs root] $mountpoint]
	    }
	}
	if {[dict exists $args -setup]} {
	    append setup \n[dict get $args -setup]
	    dict unset args -setup
	}
	set cleanup cleanup
	if {[dict exists $args -cleanup]} {
	    set cleanup "[dict get $args -cleanup]\n$cleanup"
	    dict unset args -cleanup
	}
	test zipfs-glob-$id "zipfs glob $id $cmdopts" -body {
	    lsort [glob {*}$cmdopts]
	} -setup $setup -cleanup $cleanup -result $result {*}$args
    }

    set basicMounts [list test.zip $defMountPt]
    testzipfsglob basic           $basicMounts [list $defMountPt/*]              [zipfspathsmt $defMountPt test testdir]
    testzipfsglob basic-pat       $basicMounts [list $defMountPt/t*d*]           [zipfspathsmt $defMountPt testdir]
    testzipfsglob basic-deep      $basicMounts [list $defMountPt/tes*/*]         [zipfspathsmt $defMountPt testdir/test2]
    testzipfsglob basic-dir       $basicMounts [list -directory  $defMountPt *]  [zipfspathsmt $defMountPt test testdir]
    testzipfsglob basic-dir-tails $basicMounts [list -tails -dir $defMountPt *]  [list test testdir]
    testzipfsglob basic-type-d    $basicMounts [list -type d $defMountPt/*]      [zipfspathsmt $defMountPt testdir]
    testzipfsglob basic-type-f    $basicMounts [list -type f $defMountPt/*]      [zipfspathsmt $defMountPt test]
    testzipfsglob basic-type-d-f  $basicMounts [list -type {d f} $defMountPt/*]  [zipfspathsmt $defMountPt test testdir]
    testzipfsglob basic-type-l    $basicMounts [list -type l $defMountPt/*]      {}
    foreach type {b c l p s} {
	testzipfsglob basic-type-1-$type    $basicMounts [list -type $type $defMountPt/*]          {}
	testzipfsglob basic-type-f-$type  $basicMounts [list -type [list f $type] $defMountPt/*] [zipfspathsmt $defMountPt test]
	testzipfsglob basic-type-d-$type  $basicMounts [list -type [list d $type] $defMountPt/*] [zipfspathsmt $defMountPt testdir]
    }
    testzipfsglob basic-path      $basicMounts [list -path $defMountPt/t *d*]    [zipfspathsmt $defMountPt testdir]
    testzipfsglob basic-enoent    $basicMounts [list $defMountPt/x*]             {}
    testzipfsglob basic-enoent-ok $basicMounts [list -nocomplain $defMountPt/x*] {}

    # NOTE: test root mounts separately because some bugs only showed up on these
    set rootMounts [list test.zip /]
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
    testzipfsglob mezzo-mountgrandparent $mezzoMounts [list $defMountPt/*]   [list $defMountPt/a]
    testzipfsglob mezzo-mountparent      $mezzoMounts [list $defMountPt/a/*] [zipfspathsmt $defMountPt/a b c]
    testzipfsglob mezzo-overlay          [list test.zip $defMountPt/a/b test-overlay.zip $defMountPt/a] [list $defMountPt/a/*] [zipfspathsmt $defMountPt/a b test2 test3]

    #
    # file attributes
    proc testzipfsfileattr [list id path result [list mountpoint $defMountPt] args] {
        test zipfs-file-attrs-$id "zipfs file attrs $id" -setup {
            mount [zippath test.zip] $mountpoint
        } -cleanup cleanup -body {
            lsort -stride 2 [file attributes $path]
        } -result $result {*}$args
    }
    testzipfsfileattr noent [file join $defMountPt nosuchfile] \
        {file not found: no such file or directory} $defMountPt -returnCodes error
    testzipfsfileattr file [file join $defMountPt test] \
        [list -archive [zippath test.zip] -compsize 5 -crc [expr 0x3BB935C6] -mount $defMountPt -offset 55 -permissions 0o555 -uncompsize 5]
    testzipfsfileattr dir [file join $defMountPt testdir] \
        [list -archive [zippath test.zip] -compsize 0 -crc 0 -mount $defMountPt -offset 119 -permissions 0o555 -uncompsize 0]
    testzipfsfileattr root [zipfs root] {-archive {} -compsize 0 -crc 0 -mount {} -offset 0 -permissions 0o555 -uncompsize 0}
    testzipfsfileattr mountpoint $defMountPt \
        [list -archive [zippath test.zip] -compsize 0 -crc 0 -mount $defMountPt -offset 0 -permissions 0o555 -uncompsize 0]
    testzipfsfileattr mezzo [file join $defMountPt a b] {-archive {} -compsize 0 -crc 0 -mount {} -offset 0 -permissions 0o555 -uncompsize 0} [file join $defMountPt a b c]

    foreach attr {-uncompsize -compsize -offset -mount -archive -permissions -crc} {
        test zipfs-file-attrs-set$attr "Set zipfs file attribute $attr" -setup {
            mount [zippath test.zip]
        } -cleanup cleanup \
            -body "file attributes [file join $defMountPt test] $attr {}" \
            -result "unsupported operation" -returnCodes error
    }

    #
    # file normalize
    proc testzipfsnormalize {id path result {dir {}}} {
        if {$dir eq ""} {
            test zipfs-file-normalize-$id "zipfs file normalize $id" -body {
                file normalize $path
            } -result $result
        } else {
            test zipfs-file-normalize-$id "zipfs file normalize $id" -setup {
                set cwd [pwd]
                mount [zippath test.zip] [zipfs root]
                cd $dir
            } -cleanup {
                cd $cwd
                cleanup
            } -body {
                file normalize $path
            } -result $result
        }
    }
    # The parsing requires all these cases for various code paths
    # in particular, root, one below root and more than one below root
    testzipfsnormalize dot-1  [zipfs root] [zipfs root]
    testzipfsnormalize dot-2  [file join [zipfs root] .]        [zipfs root]
    testzipfsnormalize dot-3  [file join [zipfs root] . .]      [zipfs root]
    testzipfsnormalize dot-4  [file join [zipfs root] a .]      [file join [zipfs root] a]







|
|
|
|
|


|

|

|


|



|
|
|
|
|





|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
    testzipfsglob mezzo-mountgrandparent $mezzoMounts [list $defMountPt/*]   [list $defMountPt/a]
    testzipfsglob mezzo-mountparent      $mezzoMounts [list $defMountPt/a/*] [zipfspathsmt $defMountPt/a b c]
    testzipfsglob mezzo-overlay          [list test.zip $defMountPt/a/b test-overlay.zip $defMountPt/a] [list $defMountPt/a/*] [zipfspathsmt $defMountPt/a b test2 test3]

    #
    # file attributes
    proc testzipfsfileattr [list id path result [list mountpoint $defMountPt] args] {
	test zipfs-file-attrs-$id "zipfs file attrs $id" -setup {
	    mount [zippath test.zip] $mountpoint
	} -cleanup cleanup -body {
	    lsort -stride 2 [file attributes $path]
	} -result $result {*}$args
    }
    testzipfsfileattr noent [file join $defMountPt nosuchfile] \
	{file not found: no such file or directory} $defMountPt -returnCodes error
    testzipfsfileattr file [file join $defMountPt test] \
	[list -archive [zippath test.zip] -compsize 5 -crc [expr 0x3BB935C6] -mount $defMountPt -offset 55 -permissions 0o555 -uncompsize 5]
    testzipfsfileattr dir [file join $defMountPt testdir] \
	[list -archive [zippath test.zip] -compsize 0 -crc 0 -mount $defMountPt -offset 119 -permissions 0o555 -uncompsize 0]
    testzipfsfileattr root [zipfs root] {-archive {} -compsize 0 -crc 0 -mount {} -offset 0 -permissions 0o555 -uncompsize 0}
    testzipfsfileattr mountpoint $defMountPt \
	[list -archive [zippath test.zip] -compsize 0 -crc 0 -mount $defMountPt -offset 0 -permissions 0o555 -uncompsize 0]
    testzipfsfileattr mezzo [file join $defMountPt a b] {-archive {} -compsize 0 -crc 0 -mount {} -offset 0 -permissions 0o555 -uncompsize 0} [file join $defMountPt a b c]

    foreach attr {-uncompsize -compsize -offset -mount -archive -permissions -crc} {
	test zipfs-file-attrs-set$attr "Set zipfs file attribute $attr" -setup {
	    mount [zippath test.zip]
	} -cleanup cleanup \
	    -body "file attributes [file join $defMountPt test] $attr {}" \
	    -result "unsupported operation" -returnCodes error
    }

    #
    # file normalize
    proc testzipfsnormalize {id path result {dir {}}} {
	if {$dir eq ""} {
	    test zipfs-file-normalize-$id "zipfs file normalize $id" -body {
		file normalize $path
	    } -result $result
	} else {
	    test zipfs-file-normalize-$id "zipfs file normalize $id" -setup {
		set cwd [pwd]
		mount [zippath test.zip] [zipfs root]
		cd $dir
	    } -cleanup {
		cd $cwd
		cleanup
	    } -body {
		file normalize $path
	    } -result $result
	}
    }
    # The parsing requires all these cases for various code paths
    # in particular, root, one below root and more than one below root
    testzipfsnormalize dot-1  [zipfs root] [zipfs root]
    testzipfsnormalize dot-2  [file join [zipfs root] .]        [zipfs root]
    testzipfsnormalize dot-3  [file join [zipfs root] . .]      [zipfs root]
    testzipfsnormalize dot-4  [file join [zipfs root] a .]      [file join [zipfs root] a]
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
    testzipfsnormalize relative-12  dir/../a/      [file join [zipfs root] a]         [zipfs root]
    testzipfsnormalize relative-13  dir/../../../a [file join [zipfs root] a]         [zipfs root]
    testzipfsnormalize relative-14  a              [file join [zipfs root] testdir a] [file join [zipfs root] testdir]

    #
    # file copy
    test zipfs-file-copy-tozip-new {Copy native file to archive} -setup {
        mount [zippath test.zip]
    } -cleanup {
	removeFile $_
        cleanup
    } -body {
        file copy [set _ [makeFile "" source.tmp]] [file join $defMountPt X]
    } -result "error copying \"*source.tmp\" to \"[file join $defMountPt X]\": operation not supported" \
        -match glob -returnCodes error
    test zipfs-file-copy-tozip-existing {Copy native file to archive} -setup {
        mount [zippath test.zip]
    } -cleanup {
	removeFile $_
        cleanup
    } -body {
        file copy [set _ [makeFile "newtext" source.tmp]] [file join $defMountPt test]
    } -result "error copying *: file exists" -match glob -returnCodes error
    test zipfs-file-copy-tozip-existing-force {Copy native file to archive} -setup {
        mount [zippath test.zip]
    } -cleanup {
	removeFile $_
        cleanup
    } -body {
        set to [file join $defMountPt test]
        file copy -force [set _ [makeFile "newtext" source.tmp]] $to
        readbin $to
    } -result "newtext\n"
    test zipfs-file-copy-tozipdir {Copy native file to archive directory} -setup {
        mount [zippath test.zip]
    } -cleanup {
	removeFile $_
        cleanup
    } -body {
        file copy [set _ [makeFile "" source.tmp]] [file join $defMountPt testdir]
    } -result "error copying \"*source.tmp\" to \"[file join $defMountPt testdir]/source.tmp\": operation not supported" \
        -match glob -returnCodes error
    test zipfs-file-copydir-tozipdir {Copy native dir to archive directory} -setup {
        mount [zippath test.zip]
    } -cleanup {
        cleanup
    } -body {
        file copy [temporaryDirectory] [file join $defMountPt testdir]
    } -result "can't create directory *: operation not supported" \
        -match glob -returnCodes error
    test zipfs-file-copy-fromzip-new {Copy archive file to native} -setup {
        mount [zippath test.zip]
        set dst [file join [temporaryDirectory] dst.tmp]
        file delete $dst
    } -cleanup {
        file delete $dst
        cleanup
    } -body {
        file copy [file join $defMountPt test] $dst
        readbin $dst
    } -result "test\n"
    test zipfs-file-copydir-fromzip-1 {Copy archive dir to native} -setup {
        mount [zippath test.zip]
        set dst [file join [temporaryDirectory] dstdir.tmp]
        file delete -force $dst
    } -cleanup {
        file delete -force $dst
        cleanup
    } -body {
        file copy [file join $defMountPt testdir] $dst
        zipfs find $dst
    } -result [file join [temporaryDirectory] dstdir.tmp test2]
    test zipfs-file-copymount-fromzip-new {Copy archive mount to native} -setup {
        mount [zippath test.zip]
        set dst [file join [temporaryDirectory] dstdir2.tmp]
        file delete -force $dst
    } -cleanup {
        file delete -force $dst
        cleanup
    } -body {
        file copy $defMountPt $dst
        list [file isfile [file join $dst test]] \
                  [file isdirectory [file join $dst testdir]] \
                  [file isfile [file join $dst testdir test2]]
    } -result {1 1 1}

    #
    # file delete
    test zipfs-file-delete "Delete file in zip archive" -setup {
        mount [zippath test.zip]
    } -cleanup {
        cleanup
    } -body {
        set file [file join $defMountPt test]
        list \
            [file exists $file] \
            [catch {file delete $file} msg] \
            $msg \
            [file exists $file]
    } -result [list 1 1 {error deleting "//zipfs:/testmount/test": operation not supported} 1]

    test zipfs-file-delete-enoent "Delete nonexisting path in zip archive" -setup {
        mount [zippath test.zip]
    } -cleanup {
        cleanup
    } -body {
        set file [file join $defMountPt enoent]
        list \
            [file exists $file] \
            [catch {file delete $file} msg] \
            $msg \
            [file exists $file]
    } -result [list 0 0 {} 0]

    test zipfs-file-delete-dir "Delete dir in zip archive" -setup {
        mount [zippath test.zip]
    } -cleanup {
        cleanup
    } -body {
        set dir [file join $defMountPt testdir]
        list \
            [file isdirectory $dir] \
            [catch {file delete -force $dir} msg] \
            $msg \
            [file isdirectory $dir]
    } -result [list 1 1 {error deleting unknown file: operation not supported} 1]

    #
    # file join
    test zipfs-file-join-1 "Ensure file join recognizes zipfs path as absolute" -body {
        file join /abc [zipfs root]a/b/c
    } -result [zipfs root]a/b/c

    #
    # file mkdir
    test zipfs-file-mkdir {Make a directory in zip archive} -setup {
        mount [zippath test.zip]
    } -cleanup {
        cleanup
    } -body {
        file mkdir [file join $defMountPt newdir]
    } -result "can't create directory \"[file join $defMountPt newdir]\": operation not supported" -returnCodes error
    test zipfs-file-mkdir-existing {Make a an existing directory in zip archive} -setup {
        mount [zippath test.zip]
    } -cleanup {
        cleanup
    } -body {
        set dir [file join $defMountPt testdir]
        file mkdir $dir
        file isdirectory $dir
    } -result 1

    # Standard paths for file command tests. Because code paths are different,
    # we need tests for...
    set targetMountParent $defMountPt; # Parent of mount directory
    set targetMount [file join $targetMountParent mt] ; # Mount directory
    set targetFile [file join $targetMount test]; # Normal file
    set targetDir [file join $targetMount testdir]; # Directory
    set targetEnoent [file join $targetMount enoent]; # Non-existing path

    proc testzipfsfile {id cmdargs result args} {
        variable targetMount
        test zipfs-file-$id "file $id on zipfs" -setup {
            zipfs mount [zippath test.zip] $targetMount
        } -cleanup cleanup -body {
            file {*}$cmdargs
        } -result $result {*}$args
    }
    proc testzipfsenotsup {id cmdargs args} {
        testzipfsfile $id $cmdargs "*: operation not supported" -match glob -returnCodes error
    }

    #
    # file atime

    testzipfsfile atime-get-file   [list atime $targetFile]        [fixuptime {2003-10-06 15:46:42}]
    testzipfsfile atime-get-dir    [list atime $targetDir]         [fixuptime {2005-01-11 19:03:54}]
    testzipfsfile atime-get-mount  [list atime $targetMount]       {\d+} -match regexp
    testzipfsfile atime-get-mezzo  [list atime $targetMountParent] {\d+} -match regexp
    testzipfsfile atime-get-root   [list atime [zipfs root]]       {\d+} -match regexp
    testzipfsfile atime-get-enoent [list atime $targetEnoent] \
        "could not read \"$targetEnoent\": no such file or directory" -returnCodes error

    set t [clock seconds]
    testzipfsenotsup atime-set-file  [list atime $targetFile $t]
    testzipfsenotsup atime-set-dir   [list atime $targetDir $t]
    testzipfsenotsup atime-set-mount [list atime $targetMount $t]
    testzipfsenotsup atime-set-mezzo [list atime $targetMountParent $t]
    testzipfsenotsup atime-set-root  [list atime [zipfs root] $t]
    testzipfsfile atime-set-enoent   [list atime $targetEnoent $t] \
        "could not read \"$targetEnoent\": no such file or directory" -returnCodes error

    #
    # file dirname
    testzipfsfile dirname-file [list dirname $targetFile] $targetMount
    testzipfsfile dirname-dir [list dirname $targetDir] $targetMount
    testzipfsfile dirname-mount [list dirname $targetMount] $targetMountParent
    testzipfsfile dirname-mezzo [list dirname $targetMountParent] [zipfs root]







|


|

|

|

|


|

|


|


|

|
|
|


|


|

|

|

|

|

|

|

|
|
|

|
|

|
|


|
|
|

|
|

|
|


|
|
|

|
|

|
|
|
|





|

|

|
|
|
|
|
|



|

|

|
|
|
|
|
|



|

|

|
|
|
|
|
|





|





|

|

|


|

|

|
|
|











|
|
|
|
|
|


|











|








|







1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
    testzipfsnormalize relative-12  dir/../a/      [file join [zipfs root] a]         [zipfs root]
    testzipfsnormalize relative-13  dir/../../../a [file join [zipfs root] a]         [zipfs root]
    testzipfsnormalize relative-14  a              [file join [zipfs root] testdir a] [file join [zipfs root] testdir]

    #
    # file copy
    test zipfs-file-copy-tozip-new {Copy native file to archive} -setup {
	mount [zippath test.zip]
    } -cleanup {
	removeFile $_
	cleanup
    } -body {
	file copy [set _ [makeFile "" source.tmp]] [file join $defMountPt X]
    } -result "error copying \"*source.tmp\" to \"[file join $defMountPt X]\": operation not supported" \
	-match glob -returnCodes error
    test zipfs-file-copy-tozip-existing {Copy native file to archive} -setup {
	mount [zippath test.zip]
    } -cleanup {
	removeFile $_
	cleanup
    } -body {
	file copy [set _ [makeFile "newtext" source.tmp]] [file join $defMountPt test]
    } -result "error copying *: file exists" -match glob -returnCodes error
    test zipfs-file-copy-tozip-existing-force {Copy native file to archive} -setup {
	mount [zippath test.zip]
    } -cleanup {
	removeFile $_
	cleanup
    } -body {
	set to [file join $defMountPt test]
	file copy -force [set _ [makeFile "newtext" source.tmp]] $to
	readbin $to
    } -result "newtext\n"
    test zipfs-file-copy-tozipdir {Copy native file to archive directory} -setup {
	mount [zippath test.zip]
    } -cleanup {
	removeFile $_
	cleanup
    } -body {
	file copy [set _ [makeFile "" source.tmp]] [file join $defMountPt testdir]
    } -result "error copying \"*source.tmp\" to \"[file join $defMountPt testdir]/source.tmp\": operation not supported" \
	-match glob -returnCodes error
    test zipfs-file-copydir-tozipdir {Copy native dir to archive directory} -setup {
	mount [zippath test.zip]
    } -cleanup {
	cleanup
    } -body {
	file copy [temporaryDirectory] [file join $defMountPt testdir]
    } -result "can't create directory *: operation not supported" \
	-match glob -returnCodes error
    test zipfs-file-copy-fromzip-new {Copy archive file to native} -setup {
	mount [zippath test.zip]
	set dst [file join [temporaryDirectory] dst.tmp]
	file delete $dst
    } -cleanup {
	file delete $dst
	cleanup
    } -body {
	file copy [file join $defMountPt test] $dst
	readbin $dst
    } -result "test\n"
    test zipfs-file-copydir-fromzip-1 {Copy archive dir to native} -setup {
	mount [zippath test.zip]
	set dst [file join [temporaryDirectory] dstdir.tmp]
	file delete -force $dst
    } -cleanup {
	file delete -force $dst
	cleanup
    } -body {
	file copy [file join $defMountPt testdir] $dst
	zipfs find $dst
    } -result [file join [temporaryDirectory] dstdir.tmp test2]
    test zipfs-file-copymount-fromzip-new {Copy archive mount to native} -setup {
	mount [zippath test.zip]
	set dst [file join [temporaryDirectory] dstdir2.tmp]
	file delete -force $dst
    } -cleanup {
	file delete -force $dst
	cleanup
    } -body {
	file copy $defMountPt $dst
	list [file isfile [file join $dst test]] \
		  [file isdirectory [file join $dst testdir]] \
		  [file isfile [file join $dst testdir test2]]
    } -result {1 1 1}

    #
    # file delete
    test zipfs-file-delete "Delete file in zip archive" -setup {
	mount [zippath test.zip]
    } -cleanup {
	cleanup
    } -body {
	set file [file join $defMountPt test]
	list \
	    [file exists $file] \
	    [catch {file delete $file} msg] \
	    $msg \
	    [file exists $file]
    } -result [list 1 1 {error deleting "//zipfs:/testmount/test": operation not supported} 1]

    test zipfs-file-delete-enoent "Delete nonexisting path in zip archive" -setup {
	mount [zippath test.zip]
    } -cleanup {
	cleanup
    } -body {
	set file [file join $defMountPt enoent]
	list \
	    [file exists $file] \
	    [catch {file delete $file} msg] \
	    $msg \
	    [file exists $file]
    } -result [list 0 0 {} 0]

    test zipfs-file-delete-dir "Delete dir in zip archive" -setup {
	mount [zippath test.zip]
    } -cleanup {
	cleanup
    } -body {
	set dir [file join $defMountPt testdir]
	list \
	    [file isdirectory $dir] \
	    [catch {file delete -force $dir} msg] \
	    $msg \
	    [file isdirectory $dir]
    } -result [list 1 1 {error deleting unknown file: operation not supported} 1]

    #
    # file join
    test zipfs-file-join-1 "Ensure file join recognizes zipfs path as absolute" -body {
	file join /abc [zipfs root]a/b/c
    } -result [zipfs root]a/b/c

    #
    # file mkdir
    test zipfs-file-mkdir {Make a directory in zip archive} -setup {
	mount [zippath test.zip]
    } -cleanup {
	cleanup
    } -body {
	file mkdir [file join $defMountPt newdir]
    } -result "can't create directory \"[file join $defMountPt newdir]\": operation not supported" -returnCodes error
    test zipfs-file-mkdir-existing {Make a an existing directory in zip archive} -setup {
	mount [zippath test.zip]
    } -cleanup {
	cleanup
    } -body {
	set dir [file join $defMountPt testdir]
	file mkdir $dir
	file isdirectory $dir
    } -result 1

    # Standard paths for file command tests. Because code paths are different,
    # we need tests for...
    set targetMountParent $defMountPt; # Parent of mount directory
    set targetMount [file join $targetMountParent mt] ; # Mount directory
    set targetFile [file join $targetMount test]; # Normal file
    set targetDir [file join $targetMount testdir]; # Directory
    set targetEnoent [file join $targetMount enoent]; # Non-existing path

    proc testzipfsfile {id cmdargs result args} {
	variable targetMount
	test zipfs-file-$id "file $id on zipfs" -setup {
	    zipfs mount [zippath test.zip] $targetMount
	} -cleanup cleanup -body {
	    file {*}$cmdargs
	} -result $result {*}$args
    }
    proc testzipfsenotsup {id cmdargs args} {
	testzipfsfile $id $cmdargs "*: operation not supported" -match glob -returnCodes error
    }

    #
    # file atime

    testzipfsfile atime-get-file   [list atime $targetFile]        [fixuptime {2003-10-06 15:46:42}]
    testzipfsfile atime-get-dir    [list atime $targetDir]         [fixuptime {2005-01-11 19:03:54}]
    testzipfsfile atime-get-mount  [list atime $targetMount]       {\d+} -match regexp
    testzipfsfile atime-get-mezzo  [list atime $targetMountParent] {\d+} -match regexp
    testzipfsfile atime-get-root   [list atime [zipfs root]]       {\d+} -match regexp
    testzipfsfile atime-get-enoent [list atime $targetEnoent] \
	"could not read \"$targetEnoent\": no such file or directory" -returnCodes error

    set t [clock seconds]
    testzipfsenotsup atime-set-file  [list atime $targetFile $t]
    testzipfsenotsup atime-set-dir   [list atime $targetDir $t]
    testzipfsenotsup atime-set-mount [list atime $targetMount $t]
    testzipfsenotsup atime-set-mezzo [list atime $targetMountParent $t]
    testzipfsenotsup atime-set-root  [list atime [zipfs root] $t]
    testzipfsfile atime-set-enoent   [list atime $targetEnoent $t] \
	"could not read \"$targetEnoent\": no such file or directory" -returnCodes error

    #
    # file dirname
    testzipfsfile dirname-file [list dirname $targetFile] $targetMount
    testzipfsfile dirname-dir [list dirname $targetDir] $targetMount
    testzipfsfile dirname-mount [list dirname $targetMount] $targetMountParent
    testzipfsfile dirname-mezzo [list dirname $targetMountParent] [zipfs root]
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832

    testzipfsfile mtime-get-file   [list mtime $targetFile]        [fixuptime {2003-10-06 15:46:42}]
    testzipfsfile mtime-get-dir    [list mtime $targetDir]         [fixuptime {2005-01-11 19:03:54}]
    testzipfsfile mtime-get-mount  [list mtime $targetMount]       {\d+} -match regexp
    testzipfsfile mtime-get-mezzo  [list mtime $targetMountParent] {\d+} -match regexp
    testzipfsfile mtime-get-root   [list mtime [zipfs root]]       {\d+} -match regexp
    testzipfsfile mtime-set-enoent   [list mtime $targetEnoent $t] \
        "could not read \"$targetEnoent\": no such file or directory" -returnCodes error

    set t [clock seconds]
    testzipfsenotsup mtime-set-file   [list mtime $targetFile $t]
    testzipfsenotsup mtime-set-dir    [list mtime $targetDir $t]
    testzipfsenotsup mtime-set-mount  [list mtime $targetMount $t]
    testzipfsenotsup mtime-set-mezzo  [list mtime $targetMountParent $t]
    testzipfsenotsup mtime-set-root   [list mtime [zipfs root] $t]
    testzipfsfile    mtime-set-enoent-1 [list mtime $targetEnoent $t] \
        "could not read \"$targetEnoent\": no such file or directory" -returnCodes error

    #
    # file owned
    testzipfsfile owned-file   [list owned $targetFile]        1
    testzipfsfile owned-dir    [list owned $targetDir]         1
    testzipfsfile owned-mount  [list owned $targetMount]       1
    testzipfsfile owned-mezzo  [list owned $targetMountParent] 1







|








|







1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832

    testzipfsfile mtime-get-file   [list mtime $targetFile]        [fixuptime {2003-10-06 15:46:42}]
    testzipfsfile mtime-get-dir    [list mtime $targetDir]         [fixuptime {2005-01-11 19:03:54}]
    testzipfsfile mtime-get-mount  [list mtime $targetMount]       {\d+} -match regexp
    testzipfsfile mtime-get-mezzo  [list mtime $targetMountParent] {\d+} -match regexp
    testzipfsfile mtime-get-root   [list mtime [zipfs root]]       {\d+} -match regexp
    testzipfsfile mtime-set-enoent   [list mtime $targetEnoent $t] \
	"could not read \"$targetEnoent\": no such file or directory" -returnCodes error

    set t [clock seconds]
    testzipfsenotsup mtime-set-file   [list mtime $targetFile $t]
    testzipfsenotsup mtime-set-dir    [list mtime $targetDir $t]
    testzipfsenotsup mtime-set-mount  [list mtime $targetMount $t]
    testzipfsenotsup mtime-set-mezzo  [list mtime $targetMountParent $t]
    testzipfsenotsup mtime-set-root   [list mtime [zipfs root] $t]
    testzipfsfile    mtime-set-enoent-1 [list mtime $targetEnoent $t] \
	"could not read \"$targetEnoent\": no such file or directory" -returnCodes error

    #
    # file owned
    testzipfsfile owned-file   [list owned $targetFile]        1
    testzipfsfile owned-dir    [list owned $targetDir]         1
    testzipfsfile owned-mount  [list owned $targetMount]       1
    testzipfsfile owned-mezzo  [list owned $targetMountParent] 1
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
    # file size
    testzipfsfile size-file   [list size $targetFile]        5
    testzipfsfile size-dir    [list size $targetDir]         0
    testzipfsfile size-mount  [list size $targetMount]       0
    testzipfsfile size-mezzo  [list size $targetMountParent] 0
    testzipfsfile size-root   [list size [zipfs root]]       0
    testzipfsfile size-enoent [list size $targetEnoent]      \
        "could not read \"$targetEnoent\": no such file or directory" -returnCodes error

    #
    # file split
    testzipfsfile split-file   [list split $targetFile]        [list [zipfs root] testmount mt test]
    testzipfsfile split-root   [list split [zipfs root]]       [list [zipfs root]]
    testzipfsfile split-enoent [list split $targetEnoent]      [list [zipfs root] testmount mt enoent]








|







1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
    # file size
    testzipfsfile size-file   [list size $targetFile]        5
    testzipfsfile size-dir    [list size $targetDir]         0
    testzipfsfile size-mount  [list size $targetMount]       0
    testzipfsfile size-mezzo  [list size $targetMountParent] 0
    testzipfsfile size-root   [list size [zipfs root]]       0
    testzipfsfile size-enoent [list size $targetEnoent]      \
	"could not read \"$targetEnoent\": no such file or directory" -returnCodes error

    #
    # file split
    testzipfsfile split-file   [list split $targetFile]        [list [zipfs root] testmount mt test]
    testzipfsfile split-root   [list split [zipfs root]]       [list [zipfs root]]
    testzipfsfile split-enoent [list split $targetEnoent]      [list [zipfs root] testmount mt enoent]

1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
    testnumargs "zipfs mkzip" "outfile indir" "?strip? ?password?"
    testnumargs "zipfs lmkzip" "outfile inlist" "?password?"

    #
    # Bug regressions

    test bug-6ed3447a7e "Crash opening file in streamed archive" -setup {
        mount [zippath streamed.zip]
    } -cleanup {
        cleanup
    } -body {
        set fd [open [file join $defMountPt -]]
        list [catch {read $fd} message] [close $fd] $message
        close $fd
    } -result {file size error (may be zip64)} -returnCodes error

    test bug-8259d74a64 "Crash exiting with open files" -setup {
        set path [zippath test.zip]
        set script "zipfs mount $path /\n"
        append script {open [zipfs root]test} \n
        append script "exit\n"
    } -body {
        set fd [open |[info nameofexecutable] r+]
        puts $fd $script
        flush $fd
        read $fd
        close $fd
    } -result ""

    # Following will only show a leak with valgrind
    test bug-9525f4c8bc "Memory leak with long mount paths" -body {
        set mt //zipfs:[string repeat /x 240]
        zipfs mount [zippath test.zip] $mt
        zipfs unmount $mt
    } -result ""

    test bug-33b2486199 "zipfs unmounted on thread exit" -constraints {
        thread
    } -body {
        set before [lsort [zipfs mount]]
        thread::release [thread::create]
        after 100; # Needed to allow the spawned thread to exit to trigger bug
        string equal $before [lsort [zipfs mount]]
    } -result 1

    test bug-7d5f1c1308 "zipfs error on dotfiles" -setup {
        set basename bug-7d5f1c1308
        set mt //zipfs:/$basename-mt
        set zipfile $basename.zip
        set dir [makeDirectory $basename]
        close [open [file join $dir .ext] w]
    } -cleanup {
        zipfs unmount $mt
        file delete $zipfile
	removeDirectory $basename
    } -body {
        zipfs mkzip $zipfile $dir [file dirname $dir]
        zipfs mount $zipfile $mt
        lsort [zipfs list $mt/*]
    } -result {//zipfs:/bug-7d5f1c1308-mt/bug-7d5f1c1308 //zipfs:/bug-7d5f1c1308-mt/bug-7d5f1c1308/.ext}
}


::tcltest::cleanupTests
return

# Local Variables:
# mode: tcl
# End:







|

|

|
|
|



|
|
|
|

|
|
|
|
|




|
|
|



|

|
|
|
|



|
|
|
|
|

|
|


|
|
|










1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
    testnumargs "zipfs mkzip" "outfile indir" "?strip? ?password?"
    testnumargs "zipfs lmkzip" "outfile inlist" "?password?"

    #
    # Bug regressions

    test bug-6ed3447a7e "Crash opening file in streamed archive" -setup {
	mount [zippath streamed.zip]
    } -cleanup {
	cleanup
    } -body {
	set fd [open [file join $defMountPt -]]
	list [catch {read $fd} message] [close $fd] $message
	close $fd
    } -result {file size error (may be zip64)} -returnCodes error

    test bug-8259d74a64 "Crash exiting with open files" -setup {
	set path [zippath test.zip]
	set script "zipfs mount $path /\n"
	append script {open [zipfs root]test} \n
	append script "exit\n"
    } -body {
	set fd [open |[info nameofexecutable] r+]
	puts $fd $script
	flush $fd
	read $fd
	close $fd
    } -result ""

    # Following will only show a leak with valgrind
    test bug-9525f4c8bc "Memory leak with long mount paths" -body {
	set mt //zipfs:[string repeat /x 240]
	zipfs mount [zippath test.zip] $mt
	zipfs unmount $mt
    } -result ""

    test bug-33b2486199 "zipfs unmounted on thread exit" -constraints {
	thread
    } -body {
	set before [lsort [zipfs mount]]
	thread::release [thread::create]
	after 100; # Needed to allow the spawned thread to exit to trigger bug
	string equal $before [lsort [zipfs mount]]
    } -result 1

    test bug-7d5f1c1308 "zipfs error on dotfiles" -setup {
	set basename bug-7d5f1c1308
	set mt //zipfs:/$basename-mt
	set zipfile $basename.zip
	set dir [makeDirectory $basename]
	close [open [file join $dir .ext] w]
    } -cleanup {
	zipfs unmount $mt
	file delete $zipfile
	removeDirectory $basename
    } -body {
	zipfs mkzip $zipfile $dir [file dirname $dir]
	zipfs mount $zipfile $mt
	lsort [zipfs list $mt/*]
    } -result {//zipfs:/bug-7d5f1c1308-mt/bug-7d5f1c1308 //zipfs:/bug-7d5f1c1308-mt/bug-7d5f1c1308/.ext}
}


::tcltest::cleanupTests
return

# Local Variables:
# mode: tcl
# End:
Changes to tests/zlib.test.
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
    gets $f
} -cleanup {
    close $f
    removeFile $file
} -result ok
test zlib-8.3 {zlib transformation and fileevent} -constraints zlib -setup {
    set srv [socket -myaddr localhost -server {apply {{c a p} {
        fconfigure $c -translation binary -buffering none -blocking 0
        puts -nonewline $c [zlib gzip [string repeat a 81920]]
        close $c
    }}} 0]
    set port [lindex [fconfigure $srv -sockname] 2]
    set file [makeFile {} test.gz]
    set fout [open $file wb]
} -body {
    set sin [socket localhost $port]
    try {







|
|
|







224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
    gets $f
} -cleanup {
    close $f
    removeFile $file
} -result ok
test zlib-8.3 {zlib transformation and fileevent} -constraints zlib -setup {
    set srv [socket -myaddr localhost -server {apply {{c a p} {
	fconfigure $c -translation binary -buffering none -blocking 0
	puts -nonewline $c [zlib gzip [string repeat a 81920]]
	close $c
    }}} 0]
    set port [lindex [fconfigure $srv -sockname] 2]
    set file [makeFile {} test.gz]
    set fout [open $file wb]
} -body {
    set sin [socket localhost $port]
    try {
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
    fconfigure $outSide -blocking 1 -translation binary -buffering none
    fconfigure $inSide -blocking 1 -translation binary
    puts -nonewline $outSide $spdyHeaders
    chan pop $outSide
    chan close $outSide
    set compressed [read $inSide]
    catch {zlib decompress $compressed} err opt
    list [string length [zlib compress $spdyHeaders]] \
	[string length $compressed] \
	$err [dict get $opt -errorcode] [zlib adler32 $spdyDict]
} -cleanup {
    catch {close $outSide}
    catch {close $inSide}
} -result {260 222 {need dictionary} {TCL ZLIB NEED_DICT 2381337010} 2381337010}
test zlib-8.9 {transformation and fconfigure} -setup {
    lassign [chan pipe] inSide outSide
    set strm [zlib stream decompress]
} -constraints zlib -body {
    zlib push compress $outSide -dictionary $spdyDict
    fconfigure $outSide -blocking 1 -translation binary -buffering none
    fconfigure $inSide -blocking 1 -translation binary







|
<




|







316
317
318
319
320
321
322
323

324
325
326
327
328
329
330
331
332
333
334
335
    fconfigure $outSide -blocking 1 -translation binary -buffering none
    fconfigure $inSide -blocking 1 -translation binary
    puts -nonewline $outSide $spdyHeaders
    chan pop $outSide
    chan close $outSide
    set compressed [read $inSide]
    catch {zlib decompress $compressed} err opt
    list [string length [zlib decompress [zlib compress $spdyHeaders]]] \

	$err [dict get $opt -errorcode] [zlib adler32 $spdyDict]
} -cleanup {
    catch {close $outSide}
    catch {close $inSide}
} -result {358 {need dictionary} {TCL ZLIB NEED_DICT 2381337010} 2381337010}
test zlib-8.9 {transformation and fconfigure} -setup {
    lassign [chan pipe] inSide outSide
    set strm [zlib stream decompress]
} -constraints zlib -body {
    zlib push compress $outSide -dictionary $spdyDict
    fconfigure $outSide -blocking 1 -translation binary -buffering none
    fconfigure $inSide -blocking 1 -translation binary
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
    set file [makeFile {} test.gz]
} -constraints zlib -body {
    set f [open $file wb]
    fconfigure $f -buffering none
    zlib push gzip $f
    puts -nonewline $f $largeData
    close $f
    file size $file
} -cleanup {
    removeFile $file
} -result 57647
test zlib-8.17 {Bug dd260aaf: fconfigure} -setup {
    lassign [chan pipe] inSide outSide
} -constraints zlib -body {
    zlib push inflate $inSide
    zlib push deflate $outSide
    list [chan configure $inSide -dictionary] [chan configure $outSide -dictionary]
} -cleanup {







|


|







459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
    set file [makeFile {} test.gz]
} -constraints zlib -body {
    set f [open $file wb]
    fconfigure $f -buffering none
    zlib push gzip $f
    puts -nonewline $f $largeData
    close $f
    expr {[file size $file]<57648}
} -cleanup {
    removeFile $file
} -result 1
test zlib-8.17 {Bug dd260aaf: fconfigure} -setup {
    lassign [chan pipe] inSide outSide
} -constraints zlib -body {
    zlib push inflate $inSide
    zlib push deflate $outSide
    list [chan configure $inSide -dictionary] [chan configure $outSide -dictionary]
} -cleanup {
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
    list copied $total size [file size $file]
} -cleanup {
    removeFile $file
    removeFile $sfile
} -result {copied 81920 size 81920}
test zlib-9.2 "socket fcopy with push" -constraints zlib -setup {
    set srv [socket -myaddr localhost -server {apply {{c a p} {
        chan configure $c -translation binary -buffering none -blocking 0
        puts -nonewline $c [zlib gzip [string repeat a 81920]]
        close $c
        set ::total -1
    }}} 0]
    set file [makeFile {} test.gz]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    set sin [socket $addr $port]
    chan configure $sin -translation binary
    zlib push gunzip $sin







|
|
|
|







534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
    list copied $total size [file size $file]
} -cleanup {
    removeFile $file
    removeFile $sfile
} -result {copied 81920 size 81920}
test zlib-9.2 "socket fcopy with push" -constraints zlib -setup {
    set srv [socket -myaddr localhost -server {apply {{c a p} {
	chan configure $c -translation binary -buffering none -blocking 0
	puts -nonewline $c [zlib gzip [string repeat a 81920]]
	close $c
	set ::total -1
    }}} 0]
    set file [makeFile {} test.gz]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    set sin [socket $addr $port]
    chan configure $sin -translation binary
    zlib push gunzip $sin
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
    list read $total size [file size $file]
} -cleanup {
    close $srv
    removeFile $file
} -result {read 81920 size 81920}
test zlib-9.3 "socket fcopy bg (identity)" -constraints {tempNotWin zlib} -setup {
    set srv [socket -myaddr localhost -server {apply {{c a p} {
        #puts "connection from $a:$p on $c"
        chan configure $c -translation binary -buffering none -blocking 0
        puts -nonewline $c [string repeat a 81920]
        close $c
    }}} 0]
    set file [makeFile {} test.gz]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    #puts "listening for connections on $addr $port"
    set sin [socket localhost $port]
    chan configure $sin -translation binary
    update
    set fout [open $file wb]
    after 1000 {set ::total timeout}
    fcopy $sin $fout -command {apply {{c {e {}}} {
        set ::total [expr {$e eq {} ? $c : $e}]
    }}}
    vwait ::total
    after cancel {set ::total timeout}
    close $sin; close $fout
    list read $::total size [file size $file]
} -cleanup {
    close $srv
    removeFile $file
} -returnCodes {ok error} -result {read 81920 size 81920}
test zlib-9.4 "socket fcopy bg (gzip)" -constraints zlib -setup {
    set srv [socket -myaddr localhost -server {apply {{c a p} {
        chan configure $c -translation binary -buffering none -blocking 0
        puts -nonewline $c [zlib gzip [string repeat a 81920]]
        close $c
    }}} 0]
    set file [makeFile {} test.gz]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    set sin [socket $addr $port]
    chan configure $sin -translation binary
    zlib push gunzip $sin
    update
    set fout [open $file wb]
    after 1000 {set ::total timeout}
    fcopy $sin $fout -command {apply {{c {e {}}} {
        set ::total [expr {$e eq {} ? $c : $e}]
    }}}
    vwait ::total
    after cancel {set ::total timeout}
    close $sin; close $fout
    list read $::total size [file size $file]
} -cleanup {
    close $srv
    removeFile $file
} -result {read 81920 size 81920}
test zlib-9.5 "socket fcopy incremental (gzip)" -constraints zlib -setup {
    set srv [socket -myaddr localhost -server {apply {{c a p} {
        chan configure $c -translation binary -buffering none -blocking 0
        puts -nonewline $c [zlib gzip [string repeat a 81920]]
        close $c
    }}} 0]
    proc zlib95copy {i o t c {e {}}} {
        incr t $c
        if {$e ne {}} {
            set ::total [list error $e]
        } elseif {[eof $i]} {
            set ::total [list eof $t]
        } else {
            fcopy $i $o -size 8192 -command [list zlib95copy $i $o $t]
        }
    }
    set file [makeFile {} test.gz]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    set sin [socket $addr $port]
    chan configure $sin -translation binary
    zlib push gunzip $sin







|
|
|
|











|











|
|
|











|











|
|
|


|
|
|
|
|
|
|
|







559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
    list read $total size [file size $file]
} -cleanup {
    close $srv
    removeFile $file
} -result {read 81920 size 81920}
test zlib-9.3 "socket fcopy bg (identity)" -constraints {tempNotWin zlib} -setup {
    set srv [socket -myaddr localhost -server {apply {{c a p} {
	#puts "connection from $a:$p on $c"
	chan configure $c -translation binary -buffering none -blocking 0
	puts -nonewline $c [string repeat a 81920]
	close $c
    }}} 0]
    set file [makeFile {} test.gz]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    #puts "listening for connections on $addr $port"
    set sin [socket localhost $port]
    chan configure $sin -translation binary
    update
    set fout [open $file wb]
    after 1000 {set ::total timeout}
    fcopy $sin $fout -command {apply {{c {e {}}} {
	set ::total [expr {$e eq {} ? $c : $e}]
    }}}
    vwait ::total
    after cancel {set ::total timeout}
    close $sin; close $fout
    list read $::total size [file size $file]
} -cleanup {
    close $srv
    removeFile $file
} -returnCodes {ok error} -result {read 81920 size 81920}
test zlib-9.4 "socket fcopy bg (gzip)" -constraints zlib -setup {
    set srv [socket -myaddr localhost -server {apply {{c a p} {
	chan configure $c -translation binary -buffering none -blocking 0
	puts -nonewline $c [zlib gzip [string repeat a 81920]]
	close $c
    }}} 0]
    set file [makeFile {} test.gz]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    set sin [socket $addr $port]
    chan configure $sin -translation binary
    zlib push gunzip $sin
    update
    set fout [open $file wb]
    after 1000 {set ::total timeout}
    fcopy $sin $fout -command {apply {{c {e {}}} {
	set ::total [expr {$e eq {} ? $c : $e}]
    }}}
    vwait ::total
    after cancel {set ::total timeout}
    close $sin; close $fout
    list read $::total size [file size $file]
} -cleanup {
    close $srv
    removeFile $file
} -result {read 81920 size 81920}
test zlib-9.5 "socket fcopy incremental (gzip)" -constraints zlib -setup {
    set srv [socket -myaddr localhost -server {apply {{c a p} {
	chan configure $c -translation binary -buffering none -blocking 0
	puts -nonewline $c [zlib gzip [string repeat a 81920]]
	close $c
    }}} 0]
    proc zlib95copy {i o t c {e {}}} {
	incr t $c
	if {$e ne {}} {
	    set ::total [list error $e]
	} elseif {[eof $i]} {
	    set ::total [list eof $t]
	} else {
	    fcopy $i $o -size 8192 -command [list zlib95copy $i $o $t]
	}
    }
    set file [makeFile {} test.gz]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    set sin [socket $addr $port]
    chan configure $sin -translation binary
    zlib push gunzip $sin
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
} -cleanup {
    close $srv
    rename zlib95copy {}
    removeFile $file
} -result {{eof 81920} size 81920}
test zlib-9.6 "bug #2818131 (gzip)" -constraints zlib -setup {
    set srv [socket -myaddr localhost -server {apply {{c a p} {
        chan configure $c -translation binary -buffering none -blocking 0
        zlib push gzip $c
        puts -nonewline $c [string repeat hello 100]
        close $c
    }}} 0]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    after 1000 {set ::total timeout}
    set s [socket $addr $port]
    chan configure $s -translation binary
    zlib push gunzip $s
    chan event $s readable [list apply {{s} {
        set d [read $s]
        if {[eof $s]} {
            chan event $s readable {}
            set ::total [list eof [string length $d]]
        }
    }} $s]
    vwait ::total
    after cancel {set ::total timeout}
    close $s
    set ::total
} -cleanup {
    close $srv
    unset -nocomplain total
} -result {eof 500}
test zlib-9.7 "bug #2818131 (compress)" -constraints zlib -setup {
    set srv [socket -myaddr localhost -server {apply {{c a p} {
        chan configure $c -translation binary -buffering none -blocking 0
        zlib push compress $c
        puts -nonewline $c [string repeat hello 100]
        close $c
    }}} 0]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    after 1000 {set ::total timeout}
    set s [socket $addr $port]
    chan configure $s -translation binary
    zlib push decompress $s
    chan event $s readable [list apply {{s} {
        set d [read $s]
        if {[eof $s]} {
            chan event $s readable {}
            set ::total [list eof [string length $d]]
        }
    }} $s]
    vwait ::total
    after cancel {set ::total timeout}
    close $s
    set ::total
} -cleanup {
    close $srv
    unset -nocomplain total
} -result {eof 500}
test zlib-9.8 "bug #2818131 (deflate)" -constraints zlib -setup {
    set srv [socket -myaddr localhost -server {apply {{c a p} {
        chan configure $c -translation binary -buffering none -blocking 0
        zlib push deflate $c
        puts -nonewline $c [string repeat hello 100]
        close $c
    }}} 0]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    after 1000 {set ::total timeout}
    set s [socket $addr $port]
    chan configure $s -translation binary
    zlib push inflate $s
    chan event $s readable [list apply {{s} {
        set d [read $s]
        if {[eof $s]} {
            chan event $s readable {}
            set ::total [list eof [string length $d]]
        }
    }} $s]
    vwait ::total
    after cancel {set ::total timeout}
    close $s
    set ::total
} -cleanup {
    unset -nocomplain total
    close $srv
} -result {eof 500}
test zlib-9.9 "bug #2818131 (gzip mismatch)" -constraints zlib -setup {
    proc bgerror {s} {set ::total [list error $s]}
    set srv [socket -myaddr localhost -server {apply {{c a p} {
        chan configure $c -translation binary -buffering none -blocking 0
        zlib push gzip $c
        puts -nonewline $c [string repeat hello 100]
        close $c
    }}} 0]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    after 1000 {set ::total timeout}
    set s [socket $addr $port]
    try {
        chan configure $s -translation binary
        zlib push inflate $s
        chan event $s readable [list apply {{s} {
            set d [read $s]
            if {[eof $s]} {
                chan event $s readable {}
                set ::total [list eof [string length $d]]
            }
        }} $s]
        vwait ::total
    } finally {
	after cancel {set ::total timeout}
        close $s
    }
    set ::total
} -cleanup {
    unset -nocomplain total
    close $srv
    rename bgerror {}
} -result {error {invalid block type}}
test zlib-9.10 "bug #2818131 (compress mismatch)" -constraints zlib -setup {
    proc bgerror {s} {set ::total [list error $s]}
    set srv [socket -myaddr localhost -server {apply {{c a p} {
        chan configure $c -translation binary -buffering none -blocking 0
        zlib push compress $c
        puts -nonewline $c [string repeat hello 100]
        close $c
    }}} 0]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    after 1000 {set ::total timeout}
    set s [socket $addr $port]
    try {
        chan configure $s -translation binary
        zlib push inflate $s
        chan event $s readable [list apply {{s} {
            set d [read $s]
            if {[eof $s]} {
                chan event $s readable {}
                set ::total [list eof [string length $d]]
            }
        }} $s]
        vwait ::total
    } finally {
	after cancel {set ::total timeout}
        close $s
    }
    set ::total
} -cleanup {
    unset -nocomplain total
    close $srv
    rename bgerror {}
} -result {error {invalid stored block lengths}}
test zlib-9.11 "bug #2818131 (deflate mismatch)" -constraints zlib -setup {
    proc bgerror {s} {set ::total [list error $s]}
    set srv [socket -myaddr localhost -server {apply {{c a p} {
        chan configure $c -translation binary -buffering none -blocking 0
        zlib push deflate $c
        puts -nonewline $c [string repeat hello 100]
        close $c
    }}} 0]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    after 1000 {set ::total timeout}
    set s [socket $addr $port]
    try {
        chan configure $s -translation binary
        zlib push gunzip $s
        chan event $s readable [list apply {{s} {
            set d [read $s]
            if {[eof $s]} {
                chan event $s readable {}
                set ::total [list eof [string length $d]]
            }
        }} $s]
        vwait ::total
    } finally {
	after cancel {set ::total timeout}
        close $s
    }
    set ::total
} -cleanup {
    unset -nocomplain total
    close $srv
    rename bgerror {}
} -result {error {incorrect header check}}

test zlib-10.0 "bug #2818131 (close with null interp)" -constraints {
    zlib
} -setup {
    proc bgerror {s} {set ::total [list error $s]}
    set srv [socket -myaddr localhost -server {apply {{c a p} {
        chan configure $c -translation binary
        zlib push inflate $c
        chan event $c readable [list apply {{c} {
            set d [read $c]
            if {[eof $c]} {
                chan event $c readable {}
                close $c
                set ::total [list eof [string length $d]]
            }
        }} $c]
    }}} 0]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    after 1000 {set ::total timeout}
    set s [socket $addr $port]
    chan configure $s -translation binary -buffering none -blocking 0
    zlib push gzip $s
    chan event $s xyzzy [list apply {{s} {
        if {[gets $s line] < 0} {
            chan close $s
        }
    }} $s]
    after idle [list apply {{s} {
        puts $s test
        chan close $s
        after 100 {set ::total done}
    }} $s]
    vwait ::total
    after cancel {set ::total timeout}
    after cancel {set ::total done}
    set ::total
} -cleanup {
    close $srv
    rename bgerror {}
} -returnCodes error \
  -result {bad event name "xyzzy": must be readable or writable}
test zlib-10.1 "bug #2818131 (mismatch read)" -constraints {
    zlib
} -setup {
    proc bgerror {s} {set ::total [list error $s]}
    proc zlibRead {c} {
        set d [read $c]
        if {[eof $c]} {
            chan event $c readable {}
            close $c
            set ::total [list eof [string length $d]]
        }
    }
    set srv [socket -myaddr localhost -server {apply {{c a p} {
        chan configure $c -translation binary
        zlib push inflate $c
        chan event $c readable [list zlibRead $c]
    }}} 0]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    after 1000 {set ::total timeout}
    set s [socket $addr $port]
    chan configure $s -translation binary -buffering none -blocking 0
    zlib push gzip $s
    chan event $s readable [list zlibRead $s]
    after idle [list apply {{s} {
        puts $s test
        chan close $s
        after 100 {set ::total done}
    }} $s]
    vwait ::total
    after cancel {set ::total timeout}
    after cancel {set ::total done}
    set ::total
} -cleanup {
    close $srv
    rename bgerror {}
    rename zlibRead {}
} -result {error {invalid block type}}
test zlib-10.2 "bug #2818131 (mismatch gets)" -constraints {
    zlib
} -setup {
    proc bgerror {s} {set ::total [list error $s]}
    proc zlibRead {c} {
        if {[gets $c line] < 0} {
            close $c
            set ::total [list error -1]
        } elseif {[eof $c]} {
            chan event $c readable {}
            close $c
            set ::total [list eof 0]
        }
    }
    set srv [socket -myaddr localhost -server {apply {{c a p} {
        chan configure $c -translation binary
        zlib push inflate $c
        chan event $c readable [list zlibRead $c]
    }}} 0]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    after 1000 {set ::total timeout}
    set s [socket $addr $port]
    chan configure $s -translation binary -buffering none -blocking 0
    zlib push gzip $s
    chan event $s readable [list zlibRead $s]
    after idle [list apply {{s} {
        puts $s test
        chan close $s
        after 100 {set ::total done}
    }} $s]
    vwait ::total
    after cancel {set ::total timeout}
    after cancel {set ::total done}
    set ::total
} -cleanup {
    close $srv







|
|
|
|








|
|
|
|
|











|
|
|
|








|
|
|
|
|











|
|
|
|








|
|
|
|
|












|
|
|
|






|
|
|
|
|
|
|
|
|
|


|










|
|
|
|






|
|
|
|
|
|
|
|
|
|


|










|
|
|
|






|
|
|
|
|
|
|
|
|
|


|













|
|
|
|
|
|
|
|
|
|








|
|
|


|
|
|















|
|
|
|
|
|


|
|
|









|
|
|















|
|
|
|
|
|
|
|


|
|
|









|
|
|







647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
} -cleanup {
    close $srv
    rename zlib95copy {}
    removeFile $file
} -result {{eof 81920} size 81920}
test zlib-9.6 "bug #2818131 (gzip)" -constraints zlib -setup {
    set srv [socket -myaddr localhost -server {apply {{c a p} {
	chan configure $c -translation binary -buffering none -blocking 0
	zlib push gzip $c
	puts -nonewline $c [string repeat hello 100]
	close $c
    }}} 0]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    after 1000 {set ::total timeout}
    set s [socket $addr $port]
    chan configure $s -translation binary
    zlib push gunzip $s
    chan event $s readable [list apply {{s} {
	set d [read $s]
	if {[eof $s]} {
	    chan event $s readable {}
	    set ::total [list eof [string length $d]]
	}
    }} $s]
    vwait ::total
    after cancel {set ::total timeout}
    close $s
    set ::total
} -cleanup {
    close $srv
    unset -nocomplain total
} -result {eof 500}
test zlib-9.7 "bug #2818131 (compress)" -constraints zlib -setup {
    set srv [socket -myaddr localhost -server {apply {{c a p} {
	chan configure $c -translation binary -buffering none -blocking 0
	zlib push compress $c
	puts -nonewline $c [string repeat hello 100]
	close $c
    }}} 0]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    after 1000 {set ::total timeout}
    set s [socket $addr $port]
    chan configure $s -translation binary
    zlib push decompress $s
    chan event $s readable [list apply {{s} {
	set d [read $s]
	if {[eof $s]} {
	    chan event $s readable {}
	    set ::total [list eof [string length $d]]
	}
    }} $s]
    vwait ::total
    after cancel {set ::total timeout}
    close $s
    set ::total
} -cleanup {
    close $srv
    unset -nocomplain total
} -result {eof 500}
test zlib-9.8 "bug #2818131 (deflate)" -constraints zlib -setup {
    set srv [socket -myaddr localhost -server {apply {{c a p} {
	chan configure $c -translation binary -buffering none -blocking 0
	zlib push deflate $c
	puts -nonewline $c [string repeat hello 100]
	close $c
    }}} 0]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    after 1000 {set ::total timeout}
    set s [socket $addr $port]
    chan configure $s -translation binary
    zlib push inflate $s
    chan event $s readable [list apply {{s} {
	set d [read $s]
	if {[eof $s]} {
	    chan event $s readable {}
	    set ::total [list eof [string length $d]]
	}
    }} $s]
    vwait ::total
    after cancel {set ::total timeout}
    close $s
    set ::total
} -cleanup {
    unset -nocomplain total
    close $srv
} -result {eof 500}
test zlib-9.9 "bug #2818131 (gzip mismatch)" -constraints zlib -setup {
    proc bgerror {s} {set ::total [list error $s]}
    set srv [socket -myaddr localhost -server {apply {{c a p} {
	chan configure $c -translation binary -buffering none -blocking 0
	zlib push gzip $c
	puts -nonewline $c [string repeat hello 100]
	close $c
    }}} 0]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    after 1000 {set ::total timeout}
    set s [socket $addr $port]
    try {
	chan configure $s -translation binary
	zlib push inflate $s
	chan event $s readable [list apply {{s} {
	    set d [read $s]
	    if {[eof $s]} {
		chan event $s readable {}
		set ::total [list eof [string length $d]]
	    }
	}} $s]
	vwait ::total
    } finally {
	after cancel {set ::total timeout}
	close $s
    }
    set ::total
} -cleanup {
    unset -nocomplain total
    close $srv
    rename bgerror {}
} -result {error {invalid block type}}
test zlib-9.10 "bug #2818131 (compress mismatch)" -constraints zlib -setup {
    proc bgerror {s} {set ::total [list error $s]}
    set srv [socket -myaddr localhost -server {apply {{c a p} {
	chan configure $c -translation binary -buffering none -blocking 0
	zlib push compress $c
	puts -nonewline $c [string repeat hello 100]
	close $c
    }}} 0]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    after 1000 {set ::total timeout}
    set s [socket $addr $port]
    try {
	chan configure $s -translation binary
	zlib push inflate $s
	chan event $s readable [list apply {{s} {
	    set d [read $s]
	    if {[eof $s]} {
		chan event $s readable {}
		set ::total [list eof [string length $d]]
	    }
	}} $s]
	vwait ::total
    } finally {
	after cancel {set ::total timeout}
	close $s
    }
    set ::total
} -cleanup {
    unset -nocomplain total
    close $srv
    rename bgerror {}
} -result {error {invalid stored block lengths}}
test zlib-9.11 "bug #2818131 (deflate mismatch)" -constraints zlib -setup {
    proc bgerror {s} {set ::total [list error $s]}
    set srv [socket -myaddr localhost -server {apply {{c a p} {
	chan configure $c -translation binary -buffering none -blocking 0
	zlib push deflate $c
	puts -nonewline $c [string repeat hello 100]
	close $c
    }}} 0]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    after 1000 {set ::total timeout}
    set s [socket $addr $port]
    try {
	chan configure $s -translation binary
	zlib push gunzip $s
	chan event $s readable [list apply {{s} {
	    set d [read $s]
	    if {[eof $s]} {
		chan event $s readable {}
		set ::total [list eof [string length $d]]
	    }
	}} $s]
	vwait ::total
    } finally {
	after cancel {set ::total timeout}
	close $s
    }
    set ::total
} -cleanup {
    unset -nocomplain total
    close $srv
    rename bgerror {}
} -result {error {incorrect header check}}

test zlib-10.0 "bug #2818131 (close with null interp)" -constraints {
    zlib
} -setup {
    proc bgerror {s} {set ::total [list error $s]}
    set srv [socket -myaddr localhost -server {apply {{c a p} {
	chan configure $c -translation binary
	zlib push inflate $c
	chan event $c readable [list apply {{c} {
	    set d [read $c]
	    if {[eof $c]} {
		chan event $c readable {}
		close $c
		set ::total [list eof [string length $d]]
	    }
	}} $c]
    }}} 0]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    after 1000 {set ::total timeout}
    set s [socket $addr $port]
    chan configure $s -translation binary -buffering none -blocking 0
    zlib push gzip $s
    chan event $s xyzzy [list apply {{s} {
	if {[gets $s line] < 0} {
	    chan close $s
	}
    }} $s]
    after idle [list apply {{s} {
	puts $s test
	chan close $s
	after 100 {set ::total done}
    }} $s]
    vwait ::total
    after cancel {set ::total timeout}
    after cancel {set ::total done}
    set ::total
} -cleanup {
    close $srv
    rename bgerror {}
} -returnCodes error \
  -result {bad event name "xyzzy": must be readable or writable}
test zlib-10.1 "bug #2818131 (mismatch read)" -constraints {
    zlib
} -setup {
    proc bgerror {s} {set ::total [list error $s]}
    proc zlibRead {c} {
	set d [read $c]
	if {[eof $c]} {
	    chan event $c readable {}
	    close $c
	    set ::total [list eof [string length $d]]
	}
    }
    set srv [socket -myaddr localhost -server {apply {{c a p} {
	chan configure $c -translation binary
	zlib push inflate $c
	chan event $c readable [list zlibRead $c]
    }}} 0]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    after 1000 {set ::total timeout}
    set s [socket $addr $port]
    chan configure $s -translation binary -buffering none -blocking 0
    zlib push gzip $s
    chan event $s readable [list zlibRead $s]
    after idle [list apply {{s} {
	puts $s test
	chan close $s
	after 100 {set ::total done}
    }} $s]
    vwait ::total
    after cancel {set ::total timeout}
    after cancel {set ::total done}
    set ::total
} -cleanup {
    close $srv
    rename bgerror {}
    rename zlibRead {}
} -result {error {invalid block type}}
test zlib-10.2 "bug #2818131 (mismatch gets)" -constraints {
    zlib
} -setup {
    proc bgerror {s} {set ::total [list error $s]}
    proc zlibRead {c} {
	if {[gets $c line] < 0} {
	    close $c
	    set ::total [list error -1]
	} elseif {[eof $c]} {
	    chan event $c readable {}
	    close $c
	    set ::total [list eof 0]
	}
    }
    set srv [socket -myaddr localhost -server {apply {{c a p} {
	chan configure $c -translation binary
	zlib push inflate $c
	chan event $c readable [list zlibRead $c]
    }}} 0]
} -body {
    lassign [chan configure $srv -sockname] addr name port
    after 1000 {set ::total timeout}
    set s [socket $addr $port]
    chan configure $s -translation binary -buffering none -blocking 0
    zlib push gzip $s
    chan event $s readable [list zlibRead $s]
    after idle [list apply {{s} {
	puts $s test
	chan close $s
	after 100 {set ::total done}
    }} $s]
    vwait ::total
    after cancel {set ::total timeout}
    after cancel {set ::total done}
    set ::total
} -cleanup {
    close $srv
Changes to tools/encoding/txt2enc.c.
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
	fputs("    -s\tsymbol+ascii encoding\n", stderr);
	fputs("    -m\tdon't implicitly include 007F\n", stderr);
	return 1;
    }

    fp = fopen(argv[argc - 1], "r");
    if (fp == NULL) {
        perror(argv[argc - 1]);
	return 1;
    }

    for (i = 0; i < 256; i++) {
        toUnicode[i] = NULL;
    }

    maxEnc = 0;
    width = 0;
    multiByte = 0;
    while (fgets(buf, sizeof(buf), fp) != NULL) {
	str = buf;







|




|







108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
	fputs("    -s\tsymbol+ascii encoding\n", stderr);
	fputs("    -m\tdon't implicitly include 007F\n", stderr);
	return 1;
    }

    fp = fopen(argv[argc - 1], "r");
    if (fp == NULL) {
	perror(argv[argc - 1]);
	return 1;
    }

    for (i = 0; i < 256; i++) {
	toUnicode[i] = NULL;
    }

    maxEnc = 0;
    width = 0;
    multiByte = 0;
    while (fgets(buf, sizeof(buf), fp) != NULL) {
	str = buf;
236
237
238
239
240
241
242
243
244
245
246
247
248
249
		    putchar('\n');
		}
	    }
	}
    }

    for (hi = 0; hi < 256; hi++) {
        if (toUnicode[hi] != NULL) {
            free(toUnicode[hi]);
            toUnicode[hi] = NULL;
        }
    }
    return 0;
}







|
|
|
|



236
237
238
239
240
241
242
243
244
245
246
247
248
249
		    putchar('\n');
		}
	    }
	}
    }

    for (hi = 0; hi < 256; hi++) {
	if (toUnicode[hi] != NULL) {
	    free(toUnicode[hi]);
	    toUnicode[hi] = NULL;
	}
    }
    return 0;
}
Changes to tools/installVfs.tcl.
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
    if {![info exists result]} {
      set result {}
    }
    set queue [list $prefix $filepath]
    while {[llength $queue]} {
      set queue [lassign $queue qprefix qpath]
      foreach ftail [glob -directory $qpath -nocomplain -tails *] {
          set f [file join $qpath $ftail]
          if {[file isdirectory $f]} {
            if {$ftail eq "CVS"} continue
            lappend queue [file join $qprefix $ftail] $f
          } elseif {[file isfile $f]} {
              if {$ftail eq "pkgIndex.tcl"} continue
              if {$ftail eq "manifest.txt"} {
                lappend result $f [file join $qprefix pkgIndex.tcl]
              } else {
                lappend result $f [file join $qprefix $ftail]
              }
          }
       }
    }
}
if {[llength $argv]<4} {
  error "Usage: [file tail [info script]] IMG_OUTPUT IMG_INPUT PREFIX FILE_SYSTEM ?PREFIX FILE_SYSTEM?..."
}








|
|
|
|
|
|
|
|
|
|
|
|







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
    if {![info exists result]} {
      set result {}
    }
    set queue [list $prefix $filepath]
    while {[llength $queue]} {
      set queue [lassign $queue qprefix qpath]
      foreach ftail [glob -directory $qpath -nocomplain -tails *] {
	  set f [file join $qpath $ftail]
	  if {[file isdirectory $f]} {
	    if {$ftail eq "CVS"} continue
	    lappend queue [file join $qprefix $ftail] $f
	  } elseif {[file isfile $f]} {
	      if {$ftail eq "pkgIndex.tcl"} continue
	      if {$ftail eq "manifest.txt"} {
		lappend result $f [file join $qprefix pkgIndex.tcl]
	      } else {
		lappend result $f [file join $qprefix $ftail]
	      }
	  }
       }
    }
}
if {[llength $argv]<4} {
  error "Usage: [file tail [info script]] IMG_OUTPUT IMG_INPUT PREFIX FILE_SYSTEM ?PREFIX FILE_SYSTEM?..."
}

Changes to tools/makeTestCases.tcl.
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487

    set longdays {Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday}
    set shortdays {Sun Mon Tue Wed Thu Fri Sat Sun}

    puts $f2 "test clock-3.[incr case] {ISO week-based calendar [format %04d-W%02d-%d $G $V $u]} {"
    puts $f2 "    clock format $secs -format {%a %A %g %G %u %U %V %w %W} -gmt true; \# $G-W[format %02d $V]-$u"
    puts $f2 "} {[lindex $shortdays $u] [lindex $longdays $u]\
             [format %02d [expr { $G % 100 }]] $G\
             $u\
             [clock format $secs -format %U -gmt true]\
             [format %02d $V] [expr { $u % 7 }]\
             [clock format $secs -format %W -gmt true]}"

}

#----------------------------------------------------------------------
#
# testcases4 --
#







|
|
|
|
|







469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487

    set longdays {Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday}
    set shortdays {Sun Mon Tue Wed Thu Fri Sat Sun}

    puts $f2 "test clock-3.[incr case] {ISO week-based calendar [format %04d-W%02d-%d $G $V $u]} {"
    puts $f2 "    clock format $secs -format {%a %A %g %G %u %U %V %w %W} -gmt true; \# $G-W[format %02d $V]-$u"
    puts $f2 "} {[lindex $shortdays $u] [lindex $longdays $u]\
	     [format %02d [expr { $G % 100 }]] $G\
	     $u\
	     [clock format $secs -format %U -gmt true]\
	     [format %02d $V] [expr { $u % 7 }]\
	     [clock format $secs -format %W -gmt true]}"

}

#----------------------------------------------------------------------
#
# testcases4 --
#
Changes to tools/mkVfs.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
proc cat fname {
    set fname [open $fname r]
    set data [read $fname]
    close $fname
    return $data
}

proc pkgIndexDir {root fout d1} {

    puts [format {%*sIndexing %s} [expr {4 * [info level]}] {} \
	      [file tail $d1]]
    set idx [string length $root]
    foreach ftail [glob -directory $d1 -nocomplain -tails *] {
        set f [file join $d1 $ftail]
        if {[file isdirectory $f] && [string compare CVS $ftail]} {
            pkgIndexDir $root $fout $f
        } elseif {[file tail $f] eq "pkgIndex.tcl"} {
      	    puts $fout "set dir \${VFSROOT}[string range $d1 $idx end]"
	          puts $fout [cat $f]
	      }
    }
}

###
# Script to build the VFS file system
###
proc copyDir {d1 d2} {

    puts [format {%*sCreating %s} [expr {4 * [info level]}] {} \
	      [file tail $d2]]

    file delete -force -- $d2
    file mkdir $d2

    foreach ftail [glob -directory $d1 -nocomplain -tails *] {
        set f [file join $d1 $ftail]
        if {[file isdirectory $f] && [string compare CVS $ftail]} {
            copyDir $f [file join $d2 $ftail]
        } elseif {[file isfile $f]} {
      	    file copy -force $f [file join $d2 $ftail]
	          if {$::tcl_platform(platform) eq {unix}} {
            		file attributes [file join $d2 $ftail] -permissions 0o644
      	    } else {
            		file attributes [file join $d2 $ftail] -readonly 1
	          }
	      }
    }

    if {$::tcl_platform(platform) eq {unix}} {
      	file attributes $d2 -permissions 0o755
    } else {
	      file attributes $d2 -readonly 1
    }
}

if {[llength $argv] < 3} {
    puts "Usage: VFS_ROOT TCLSRC_ROOT PLATFORM"
    exit 1
}
set TCL_SCRIPT_DIR [lindex $argv 0]
set TCLSRC_ROOT    [lindex $argv 1]
set PLATFORM       [lindex $argv 2]
set TKDLL          [lindex $argv 3]
set TKVER          [lindex $argv 4]

puts "Building [file tail $TCL_SCRIPT_DIR] for $PLATFORM"
copyDir ${TCLSRC_ROOT}/library ${TCL_SCRIPT_DIR}

if {$PLATFORM == "windows"} {
    set ddedll [glob -nocomplain ${TCLSRC_ROOT}/win/tcldde*.dll]
    puts "DDE DLL $ddedll"
    if {$ddedll != {}} {
      	file copy $ddedll ${TCL_SCRIPT_DIR}/dde
    }
    set regdll [glob -nocomplain ${TCLSRC_ROOT}/win/tclreg*.dll]
    puts "REG DLL $ddedll"
    if {$regdll != {}} {
      	file copy $regdll ${TCL_SCRIPT_DIR}/reg
    }
} else {
    # Remove the dde and reg package paths
    file delete -force ${TCL_SCRIPT_DIR}/dde
    file delete -force ${TCL_SCRIPT_DIR}/reg
}














|
|
|
|
|
|
|















|
|
|
|
|
|
|
|
|
|
|



|

|




















|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
proc cat fname {
    set fname [open $fname r]
    set data [read $fname]
    close $fname
    return $data
}

proc pkgIndexDir {root fout d1} {

    puts [format {%*sIndexing %s} [expr {4 * [info level]}] {} \
	      [file tail $d1]]
    set idx [string length $root]
    foreach ftail [glob -directory $d1 -nocomplain -tails *] {
	set f [file join $d1 $ftail]
	if {[file isdirectory $f] && [string compare CVS $ftail]} {
	    pkgIndexDir $root $fout $f
	} elseif {[file tail $f] eq "pkgIndex.tcl"} {
	    puts $fout "set dir \${VFSROOT}[string range $d1 $idx end]"
	    puts $fout [cat $f]
	}
    }
}

###
# Script to build the VFS file system
###
proc copyDir {d1 d2} {

    puts [format {%*sCreating %s} [expr {4 * [info level]}] {} \
	      [file tail $d2]]

    file delete -force -- $d2
    file mkdir $d2

    foreach ftail [glob -directory $d1 -nocomplain -tails *] {
	set f [file join $d1 $ftail]
	if {[file isdirectory $f] && [string compare CVS $ftail]} {
	    copyDir $f [file join $d2 $ftail]
	} elseif {[file isfile $f]} {
	    file copy -force $f [file join $d2 $ftail]
	    if {$::tcl_platform(platform) eq {unix}} {
		file attributes [file join $d2 $ftail] -permissions 0o644
	    } else {
		file attributes [file join $d2 $ftail] -readonly 1
	    }
	}
    }

    if {$::tcl_platform(platform) eq {unix}} {
	file attributes $d2 -permissions 0o755
    } else {
	file attributes $d2 -readonly 1
    }
}

if {[llength $argv] < 3} {
    puts "Usage: VFS_ROOT TCLSRC_ROOT PLATFORM"
    exit 1
}
set TCL_SCRIPT_DIR [lindex $argv 0]
set TCLSRC_ROOT    [lindex $argv 1]
set PLATFORM       [lindex $argv 2]
set TKDLL          [lindex $argv 3]
set TKVER          [lindex $argv 4]

puts "Building [file tail $TCL_SCRIPT_DIR] for $PLATFORM"
copyDir ${TCLSRC_ROOT}/library ${TCL_SCRIPT_DIR}

if {$PLATFORM == "windows"} {
    set ddedll [glob -nocomplain ${TCLSRC_ROOT}/win/tcldde*.dll]
    puts "DDE DLL $ddedll"
    if {$ddedll != {}} {
	file copy $ddedll ${TCL_SCRIPT_DIR}/dde
    }
    set regdll [glob -nocomplain ${TCLSRC_ROOT}/win/tclreg*.dll]
    puts "REG DLL $ddedll"
    if {$regdll != {}} {
	file copy $regdll ${TCL_SCRIPT_DIR}/reg
    }
} else {
    # Remove the dde and reg package paths
    file delete -force ${TCL_SCRIPT_DIR}/dde
    file delete -force ${TCL_SCRIPT_DIR}/reg
}

Changes to tools/mkdepend.tcl.
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#
# Results:
#	None.

proc closeOutput {} {
    global output
    if {[string match stdout $output] != 0} {
        close $output
    }
}

# readDepends --
#
#	Read off CCP pipe for #line references.
#
# Arguments:
#	chan	The pipe channel we are reading in.
#
# Results:
#	Raw dependency list pairs.

proc readDepends {chan} {
    set line ""
    array set depends {}

    while {[gets $chan line] >= 0} {
        if {[regexp {^#line [0-9]+ \"(.*)\"$} $line dummy fname] != 0} {
	    set fname [file normalize $fname]
            if {![info exists target]} {
		# this is ourself
		set target $fname
		puts stderr "processing [file tail $fname]"
            } else {
		# don't include ourselves as a dependency of ourself.
		if {![string compare $fname $target]} {continue}
		# store in an array so multiple occurrences are not counted.
                set depends($target|$fname) ""
            }
        }
    }

    set result {}
    foreach n [array names depends] {
        set pair [split $n "|"]
        lappend result [list [lindex $pair 0] [lindex $pair 1]]
    }

    return $result
}

# writeDepends --
#
#	Write the processed list out to the file.
#
# Arguments:
#	out		The channel to write to.
#	depends		The list of dependency pairs
#
# Results:
#	None.

proc writeDepends {out depends} {
    foreach pair $depends {
        puts $out "[lindex $pair 0] : \\\n\t[join [lindex $pair 1] " \\\n\t"]"
    }
}

# stringStartsWith --
#
#	Compares second string to the beginning of the first.
#
# Arguments:
#	str		The string to test the beginning of.
#	prefix		The string to test against
#
# Results:
#	the result of the comparison.

proc stringStartsWith {str prefix} {
    set front [string range $str 0 [expr {[string length $prefix] - 1}]]
    return [expr {[string compare [string tolower $prefix] \
                                  [string tolower $front]] == 0}]
}

# filterExcludes --
#
#	Remove non-project header files.
#
# Arguments:
#	depends		List of dependency pairs.
#	excludes	List of directories that should be removed
#
# Results:
#	the processed dependency list.

proc filterExcludes {depends excludes} {
    set filtered {}

    foreach pair $depends {
        set excluded 0
        set file [lindex $pair 1]

        foreach dir $excludes {
            if [stringStartsWith $file $dir] {
                set excluded 1
                break;
            }
        }

        if {!$excluded} {
            lappend filtered $pair
        }
    }

    return $filtered
}

# replacePrefix --
#







|


















|

|



|



|
|
|




|
|


















|

















|

















|
|

|
|
|
|
|
|

|
|
|







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#
# Results:
#	None.

proc closeOutput {} {
    global output
    if {[string match stdout $output] != 0} {
	close $output
    }
}

# readDepends --
#
#	Read off CCP pipe for #line references.
#
# Arguments:
#	chan	The pipe channel we are reading in.
#
# Results:
#	Raw dependency list pairs.

proc readDepends {chan} {
    set line ""
    array set depends {}

    while {[gets $chan line] >= 0} {
	if {[regexp {^#line [0-9]+ \"(.*)\"$} $line dummy fname] != 0} {
	    set fname [file normalize $fname]
	    if {![info exists target]} {
		# this is ourself
		set target $fname
		puts stderr "processing [file tail $fname]"
	    } else {
		# don't include ourselves as a dependency of ourself.
		if {![string compare $fname $target]} {continue}
		# store in an array so multiple occurrences are not counted.
		set depends($target|$fname) ""
	    }
	}
    }

    set result {}
    foreach n [array names depends] {
	set pair [split $n "|"]
	lappend result [list [lindex $pair 0] [lindex $pair 1]]
    }

    return $result
}

# writeDepends --
#
#	Write the processed list out to the file.
#
# Arguments:
#	out		The channel to write to.
#	depends		The list of dependency pairs
#
# Results:
#	None.

proc writeDepends {out depends} {
    foreach pair $depends {
	puts $out "[lindex $pair 0] : \\\n\t[join [lindex $pair 1] " \\\n\t"]"
    }
}

# stringStartsWith --
#
#	Compares second string to the beginning of the first.
#
# Arguments:
#	str		The string to test the beginning of.
#	prefix		The string to test against
#
# Results:
#	the result of the comparison.

proc stringStartsWith {str prefix} {
    set front [string range $str 0 [expr {[string length $prefix] - 1}]]
    return [expr {[string compare [string tolower $prefix] \
				  [string tolower $front]] == 0}]
}

# filterExcludes --
#
#	Remove non-project header files.
#
# Arguments:
#	depends		List of dependency pairs.
#	excludes	List of directories that should be removed
#
# Results:
#	the processed dependency list.

proc filterExcludes {depends excludes} {
    set filtered {}

    foreach pair $depends {
	set excluded 0
	set file [lindex $pair 1]

	foreach dir $excludes {
	    if [stringStartsWith $file $dir] {
		set excluded 1
		break;
	    }
	}

	if {!$excluded} {
	    lappend filtered $pair
	}
    }

    return $filtered
}

# replacePrefix --
#
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
#
# Results:
#	The processed dependency pair list.

proc rebaseFiles {depends} {
    set rebased {}
    foreach pair $depends {
        lappend rebased [list \
                [replacePrefix [lindex $pair 0]] \
		[replacePrefix [lindex $pair 1]]]

    }
    return $rebased
}

# compressDeps --







|
|







209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
#
# Results:
#	The processed dependency pair list.

proc rebaseFiles {depends} {
    set rebased {}
    foreach pair $depends {
	lappend rebased [list \
		[replacePrefix [lindex $pair 0]] \
		[replacePrefix [lindex $pair 1]]]

    }
    return $rebased
}

# compressDeps --
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251

    foreach pair $depends {
	lappend compressed([lindex $pair 0]) [lindex $pair 1]
    }

    set result [list]
    foreach n [array names compressed] {
        lappend result [list $n [lsort $compressed($n)]]
    }

    return $result
}

# addSearchPath --
#







|







237
238
239
240
241
242
243
244
245
246
247
248
249
250
251

    foreach pair $depends {
	lappend compressed([lindex $pair 0]) [lindex $pair 1]
    }

    set result [list]
    foreach n [array names compressed] {
	lappend result [list $n [lsort $compressed($n)]]
    }

    return $result
}

# addSearchPath --
#
Changes to tools/tclOOScript.tcl.
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
    # Note that the ::oo::define namespace is semi-public and a bit weird
    # anyway, so we don't regard the namespace path as being under control:
    # fully qualified names are used for everything.
    #
    # ----------------------------------------------------------------------

    proc define::classmethod {name args} {
        # Create the method on the class if the caller gave arguments and body
        ::set argc [::llength [::info level 0]]
        ::if {$argc == 3} {
            ::return -code error -errorcode {TCL WRONGARGS} [::format \
		{wrong # args: should be "%s name ?args body?"} \
                [::lindex [::info level 0] 0]]
        }
        ::set cls [::uplevel 1 self]
        ::if {$argc == 4} {
            ::oo::define [::oo::DelegateName $cls] method $name {*}$args
        }
        # Make the connection by forwarding
        ::tailcall forward $name myclass $name
    }

    # ----------------------------------------------------------------------
    #
    # oo::define::initialise, oo::define::initialize --
    #
    #	Do specific initialisation for a class. See define(n) for details.
    #
    # Note that the ::oo::define namespace is semi-public and a bit weird
    # anyway, so we don't regard the namespace path as being under control:
    # fully qualified names are used for everything.
    #
    # ----------------------------------------------------------------------

    proc define::initialise {body} {
        ::set clsns [::info object namespace [::uplevel 1 self]]
        ::tailcall apply [::list {} $body $clsns]
    }

    # Make the [initialise] definition appear as [initialize] too
    namespace eval define {
	::namespace export initialise
	::namespace eval tmp {::namespace import ::oo::define::initialise}
	::namespace export -clear







|
|
|
|

|
|
|
|
|
|
|
|















|
|







192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
    # Note that the ::oo::define namespace is semi-public and a bit weird
    # anyway, so we don't regard the namespace path as being under control:
    # fully qualified names are used for everything.
    #
    # ----------------------------------------------------------------------

    proc define::classmethod {name args} {
	# Create the method on the class if the caller gave arguments and body
	::set argc [::llength [::info level 0]]
	::if {$argc == 3} {
	    ::return -code error -errorcode {TCL WRONGARGS} [::format \
		{wrong # args: should be "%s name ?args body?"} \
		[::lindex [::info level 0] 0]]
	}
	::set cls [::uplevel 1 self]
	::if {$argc == 4} {
	    ::oo::define [::oo::DelegateName $cls] method $name {*}$args
	}
	# Make the connection by forwarding
	::tailcall forward $name myclass $name
    }

    # ----------------------------------------------------------------------
    #
    # oo::define::initialise, oo::define::initialize --
    #
    #	Do specific initialisation for a class. See define(n) for details.
    #
    # Note that the ::oo::define namespace is semi-public and a bit weird
    # anyway, so we don't regard the namespace path as being under control:
    # fully qualified names are used for everything.
    #
    # ----------------------------------------------------------------------

    proc define::initialise {body} {
	::set clsns [::info object namespace [::uplevel 1 self]]
	::tailcall apply [::list {} $body $clsns]
    }

    # Make the [initialise] definition appear as [initialize] too
    namespace eval define {
	::namespace export initialise
	::namespace eval tmp {::namespace import ::oo::define::initialise}
	::namespace export -clear
Changes to tools/tclZIC.tcl.
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
#----------------------------------------------------------------------
#
# MAIN PROGRAM
#
#----------------------------------------------------------------------

puts "Compiling time zones -- [clock format [clock seconds] \
                                   -format {%x %X} -locale system]"

# Determine directories

lassign $argv inDir outDir

puts "Olson files in $inDir"
puts "Tcl files to be placed in $outDir"







|







1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
#----------------------------------------------------------------------
#
# MAIN PROGRAM
#
#----------------------------------------------------------------------

puts "Compiling time zones -- [clock format [clock seconds] \
	                           -format {%x %X} -locale system]"

# Determine directories

lassign $argv inDir outDir

puts "Olson files in $inDir"
puts "Tcl files to be placed in $outDir"
Changes to tools/tcltk-man2html.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/env tclsh

if {[catch {package require Tcl 8.6-} msg]} {
    puts stderr "ERROR: $msg"
    puts stderr "If running this script from 'make html', set the\
	NATIVE_TCLSH environment\nvariable to point to an installed\
	tclsh8.6 (or the equivalent tclsh86.exe\non Windows)."
    exit 1
}

# Convert Ousterhout format man pages into highly crosslinked hypertext.
#
# Along the way detect many unmatched font changes and other odd things.
#






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/env tclsh

if {[catch {package require Tcl 8.6-} msg]} {
    puts stderr "ERROR: $msg"
    puts stderr "If running this script from 'make html', set the\
	NATIVE_TCLSH environment\nvariable to point to an installed\
	tclsh9.0 (or the equivalent tclsh90.exe\non Windows)."
    exit 1
}

# Convert Ousterhout format man pages into highly crosslinked hypertext.
#
# Along the way detect many unmatched font changes and other odd things.
#
Changes to unix/Makefile.in.
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
	@echo "Installing package opt0.4 files to $(SCRIPT_INSTALL_DIR)/opt0.4/"
	@for i in $(TOP_DIR)/library/opt/*.tcl; do \
	    $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)/opt0.4"; \
	done
	@echo "Installing package msgcat 1.7.1 as a Tcl Module"
	@$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl \
		"$(MODULE_INSTALL_DIR)/9.0/msgcat-1.7.1.tm"
	@echo "Installing package tcltest 2.5.8 as a Tcl Module"
	@$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl \
		"$(MODULE_INSTALL_DIR)/9.0/tcltest-2.5.8.tm"
	@echo "Installing package platform 1.0.19 as a Tcl Module"
	@$(INSTALL_DATA) $(TOP_DIR)/library/platform/platform.tcl \
		"$(MODULE_INSTALL_DIR)/9.0/platform-1.0.19.tm"
	@echo "Installing package platform::shell 1.1.4 as a Tcl Module"
	@$(INSTALL_DATA) $(TOP_DIR)/library/platform/shell.tcl \
		"$(MODULE_INSTALL_DIR)/9.0/platform/shell-1.1.4.tm"
	@echo "Installing encoding files to $(SCRIPT_INSTALL_DIR)/encoding/"







|

|







1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
	@echo "Installing package opt0.4 files to $(SCRIPT_INSTALL_DIR)/opt0.4/"
	@for i in $(TOP_DIR)/library/opt/*.tcl; do \
	    $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)/opt0.4"; \
	done
	@echo "Installing package msgcat 1.7.1 as a Tcl Module"
	@$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl \
		"$(MODULE_INSTALL_DIR)/9.0/msgcat-1.7.1.tm"
	@echo "Installing package tcltest 2.5.9 as a Tcl Module"
	@$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl \
		"$(MODULE_INSTALL_DIR)/9.0/tcltest-2.5.9.tm"
	@echo "Installing package platform 1.0.19 as a Tcl Module"
	@$(INSTALL_DATA) $(TOP_DIR)/library/platform/platform.tcl \
		"$(MODULE_INSTALL_DIR)/9.0/platform-1.0.19.tm"
	@echo "Installing package platform::shell 1.1.4 as a Tcl Module"
	@$(INSTALL_DATA) $(TOP_DIR)/library/platform/shell.tcl \
		"$(MODULE_INSTALL_DIR)/9.0/platform/shell-1.1.4.tm"
	@echo "Installing encoding files to $(SCRIPT_INSTALL_DIR)/encoding/"
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/*.vc $(DISTDIR)/win
	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/tcl.ds* $(DISTDIR)/win
	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/README $(DISTDIR)/win
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(DISTDIR)/win
	$(INSTALL_DATA_DIR) $(DISTDIR)/macosx
	$(DIST_INSTALL_DATA) $(MAC_OSX_DIR)/GNUmakefile $(MAC_OSX_DIR)/README \
		$(MAC_OSX_DIR)/*.c $(MAC_OSX_DIR)/*.in \
		$(MAC_OSX_DIR)/*.ac $(MAC_OSX_DIR)/*.xcconfig \
		$(DISTDIR)/macosx
	$(DIST_INSTALL_SCRIPT) $(MAC_OSX_DIR)/configure $(DISTDIR)/macosx
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(DISTDIR)/macosx
	$(INSTALL_DATA_DIR) $(DISTDIR)/macosx/Tcl.xcodeproj
	$(DIST_INSTALL_DATA) $(MAC_OSX_DIR)/Tcl.xcodeproj/project.pbxproj \
		$(MAC_OSX_DIR)/Tcl.xcodeproj/default.pbxuser \
		$(DISTDIR)/macosx/Tcl.xcodeproj
	$(INSTALL_DATA_DIR) $(DISTDIR)/unix/dltest
	$(DIST_INSTALL_DATA) $(UNIX_DIR)/dltest/*.c $(UNIX_DIR)/dltest/Makefile.in \
		$(UNIX_DIR)/dltest/README $(DISTDIR)/unix/dltest
	$(INSTALL_DATA_DIR) $(DISTDIR)/tools
	$(DIST_INSTALL_DATA) $(TOOL_DIR)/README $(TOOL_DIR)/*.c $(TOOL_DIR)/*.svg \
		$(TOOL_DIR)/*.tcl $(TOOL_DIR)/*.bmp $(TOOL_DIR)/valgrind_suppress \
		$(TOOL_DIR)/valgrind_check_success $(DISTDIR)/tools







|



<
<
<
<







2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412




2413
2414
2415
2416
2417
2418
2419
	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/*.vc $(DISTDIR)/win
	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/tcl.ds* $(DISTDIR)/win
	$(DIST_INSTALL_DATA) $(TOP_DIR)/win/README $(DISTDIR)/win
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(DISTDIR)/win
	$(INSTALL_DATA_DIR) $(DISTDIR)/macosx
	$(DIST_INSTALL_DATA) $(MAC_OSX_DIR)/GNUmakefile $(MAC_OSX_DIR)/README \
		$(MAC_OSX_DIR)/*.c $(MAC_OSX_DIR)/*.in \
		$(MAC_OSX_DIR)/*.ac \
		$(DISTDIR)/macosx
	$(DIST_INSTALL_SCRIPT) $(MAC_OSX_DIR)/configure $(DISTDIR)/macosx
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(DISTDIR)/macosx




	$(INSTALL_DATA_DIR) $(DISTDIR)/unix/dltest
	$(DIST_INSTALL_DATA) $(UNIX_DIR)/dltest/*.c $(UNIX_DIR)/dltest/Makefile.in \
		$(UNIX_DIR)/dltest/README $(DISTDIR)/unix/dltest
	$(INSTALL_DATA_DIR) $(DISTDIR)/tools
	$(DIST_INSTALL_DATA) $(TOOL_DIR)/README $(TOOL_DIR)/*.c $(TOOL_DIR)/*.svg \
		$(TOOL_DIR)/*.tcl $(TOOL_DIR)/*.bmp $(TOOL_DIR)/valgrind_suppress \
		$(TOOL_DIR)/valgrind_check_success $(DISTDIR)/tools
Changes to unix/configure.
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
else case e in #(
  e) tcl_ok=0 ;;
esac
fi
rm -rf conftest*


    # See also memmove check below for a place where NO_STRING_H can be
    # set and why.

    if test $tcl_ok = 0; then

printf "%s\n" "#define NO_STRING_H 1" >>confdefs.h

    fi

    ac_fn_c_check_header_compile "$LINENO" "sys/wait.h" "ac_cv_header_sys_wait_h" "$ac_includes_default"
if test "x$ac_cv_header_sys_wait_h" = xyes
then :

else case e in #(
  e)
printf "%s\n" "#define NO_SYS_WAIT_H 1" >>confdefs.h







<
<
<
<
<
<
<
<
<







4252
4253
4254
4255
4256
4257
4258









4259
4260
4261
4262
4263
4264
4265
else case e in #(
  e) tcl_ok=0 ;;
esac
fi
rm -rf conftest*











    ac_fn_c_check_header_compile "$LINENO" "sys/wait.h" "ac_cv_header_sys_wait_h" "$ac_includes_default"
if test "x$ac_cv_header_sys_wait_h" = xyes
then :

else case e in #(
  e)
printf "%s\n" "#define NO_SYS_WAIT_H 1" >>confdefs.h
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
  ZLIB_INCLUDE=-I\${ZLIB_DIR}


printf "%s\n" "#define TCL_WITH_INTERNAL_ZLIB 1" >>confdefs.h


fi

printf "%s\n" "#define HAVE_ZLIB 1" >>confdefs.h


#------------------------------------------------------------------------
#	Add stuff for libtommath

libtommath_ok=yes

# Check whether --with-system-libtommath was given.







<
<
<







5196
5197
5198
5199
5200
5201
5202



5203
5204
5205
5206
5207
5208
5209
  ZLIB_INCLUDE=-I\${ZLIB_DIR}


printf "%s\n" "#define TCL_WITH_INTERNAL_ZLIB 1" >>confdefs.h


fi




#------------------------------------------------------------------------
#	Add stuff for libtommath

libtommath_ok=yes

# Check whether --with-system-libtommath was given.
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754

		    fat_32_64=yes
fi
	     ;;
esac
fi
	    SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS}'
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if ld accepts -single_module flag" >&5
printf %s "checking if ld accepts -single_module flag... " >&6; }
if test ${tcl_cv_ld_single_module+y}
then :
  printf %s "(cached) " >&6
else case e in #(
  e)
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main (void)
{
int i;
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
  tcl_cv_ld_single_module=yes
else case e in #(
  e) tcl_cv_ld_single_module=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
    conftest$ac_exeext conftest.$ac_ext
		LDFLAGS=$hold_ldflags ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_single_module" >&5
printf "%s\n" "$tcl_cv_ld_single_module" >&6; }
	    if test $tcl_cv_ld_single_module = yes
then :

		SHLIB_LD="${SHLIB_LD} -Wl,-single_module"

fi
	    SHLIB_SUFFIX=".dylib"
	    DL_OBJS="tclLoadDyld.o"
	    DL_LIBS=""
	    LDFLAGS="$LDFLAGS -headerpad_max_install_names"
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if ld accepts -search_paths_first flag" >&5
printf %s "checking if ld accepts -search_paths_first flag... " >&6; }
if test ${tcl_cv_ld_search_paths_first+y}







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







6689
6690
6691
6692
6693
6694
6695








































6696
6697
6698
6699
6700
6701
6702

		    fat_32_64=yes
fi
	     ;;
esac
fi
	    SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS}'








































	    SHLIB_SUFFIX=".dylib"
	    DL_OBJS="tclLoadDyld.o"
	    DL_LIBS=""
	    LDFLAGS="$LDFLAGS -headerpad_max_install_names"
	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if ld accepts -search_paths_first flag" >&5
printf %s "checking if ld accepts -search_paths_first flag... " >&6; }
if test ${tcl_cv_ld_search_paths_first+y}
9883
9884
9885
9886
9887
9888
9889
9890
9891
9892
9893
9894
9895
9896
9897
9898
9899
9900
9901
9902
9903
9904
9905
9906
9907
9908
9909
9910
9911
9912
9913
9914
9915
9916
9917
9918
else case e in #(
  e)
printf "%s\n" "#define NO_FSTATFS 1" >>confdefs.h
 ;;
esac
fi


#--------------------------------------------------------------------
#       Some system like SunOS 4 and other BSD like systems have no memmove
#       (we assume they have bcopy instead). {The replacement define is in
#       compat/string.h}
#--------------------------------------------------------------------

ac_fn_c_check_func "$LINENO" "memmove" "ac_cv_func_memmove"
if test "x$ac_cv_func_memmove" = xyes
then :

else case e in #(
  e)

printf "%s\n" "#define NO_MEMMOVE 1" >>confdefs.h


printf "%s\n" "#define NO_STRING_H 1" >>confdefs.h
  ;;
esac
fi


#--------------------------------------------------------------------
#	Check for various typedefs and provide substitutes if
#	they don't exist.
#--------------------------------------------------------------------

ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default"







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







9831
9832
9833
9834
9835
9836
9837






















9838
9839
9840
9841
9842
9843
9844
else case e in #(
  e)
printf "%s\n" "#define NO_FSTATFS 1" >>confdefs.h
 ;;
esac
fi
























#--------------------------------------------------------------------
#	Check for various typedefs and provide substitutes if
#	they don't exist.
#--------------------------------------------------------------------

ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default"
11018
11019
11020
11021
11022
11023
11024
11025
11026
11027
11028
11029
11030
11031
11032
11033
11034
11035
11036

int
main (void)
{

	int index,regsPtr[4];
    __asm__ __volatile__("mov %%ebx, %%edi     \n\t"
                 "cpuid            \n\t"
                 "mov %%ebx, %%esi   \n\t"
                 "mov %%edi, %%ebx  \n\t"
                 : "=a"(regsPtr[0]), "=S"(regsPtr[1]), "=c"(regsPtr[2]), "=d"(regsPtr[3])
                 : "a"(index) : "edi");

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :







|
|
|
|
|







10944
10945
10946
10947
10948
10949
10950
10951
10952
10953
10954
10955
10956
10957
10958
10959
10960
10961
10962

int
main (void)
{

	int index,regsPtr[4];
    __asm__ __volatile__("mov %%ebx, %%edi     \n\t"
		 "cpuid            \n\t"
		 "mov %%ebx, %%esi   \n\t"
		 "mov %%edi, %%ebx  \n\t"
		 : "=a"(regsPtr[0]), "=S"(regsPtr[1]), "=c"(regsPtr[2]), "=d"(regsPtr[3])
		 : "a"(index) : "edi");

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
11134
11135
11136
11137
11138
11139
11140
11141
11142
11143
11144
11145
11146
11147
11148
11149
11150
11151
11152
11153
11154
    # Construct a fake local framework structure to make linking with
    # '-framework Tcl' and running of tcltest work
    ac_config_commands="$ac_config_commands Tcl.framework"

    LD_LIBRARY_PATH_VAR="DYLD_FRAMEWORK_PATH"
    # default install directory for bundled packages
    if test "${libdir}" = '${exec_prefix}/lib' -o "`basename ${libdir}`" = 'Frameworks'; then
        PACKAGE_DIR="/Library/Tcl"
    else
        PACKAGE_DIR="$libdir"
    fi
    if test "${libdir}" = '${exec_prefix}/lib'; then
        # override libdir default
        libdir="/Library/Frameworks"
    fi
    TCL_LIB_FILE="Tcl"
    TCL_LIB_FLAG="-framework Tcl"
    TCL_BUILD_LIB_SPEC="-F`pwd | sed -e 's/ /\\\\ /g'` -framework Tcl"
    TCL_LIB_SPEC="-F${libdir} -framework Tcl"
    libdir="${libdir}/Tcl.framework/Versions/\${VERSION}"
    TCL_LIBRARY="${libdir}/Resources/Scripts"







|

|


|
|







11060
11061
11062
11063
11064
11065
11066
11067
11068
11069
11070
11071
11072
11073
11074
11075
11076
11077
11078
11079
11080
    # Construct a fake local framework structure to make linking with
    # '-framework Tcl' and running of tcltest work
    ac_config_commands="$ac_config_commands Tcl.framework"

    LD_LIBRARY_PATH_VAR="DYLD_FRAMEWORK_PATH"
    # default install directory for bundled packages
    if test "${libdir}" = '${exec_prefix}/lib' -o "`basename ${libdir}`" = 'Frameworks'; then
	PACKAGE_DIR="/Library/Tcl"
    else
	PACKAGE_DIR="$libdir"
    fi
    if test "${libdir}" = '${exec_prefix}/lib'; then
	# override libdir default
	libdir="/Library/Frameworks"
    fi
    TCL_LIB_FILE="Tcl"
    TCL_LIB_FLAG="-framework Tcl"
    TCL_BUILD_LIB_SPEC="-F`pwd | sed -e 's/ /\\\\ /g'` -framework Tcl"
    TCL_LIB_SPEC="-F${libdir} -framework Tcl"
    libdir="${libdir}/Tcl.framework/Versions/\${VERSION}"
    TCL_LIBRARY="${libdir}/Resources/Scripts"
11167
11168
11169
11170
11171
11172
11173
11174
11175
11176
11177
11178
11179
11180
11181
11182
11183
    EXTRA_CC_SWITCHES='-DTCL_FRAMEWORK_VERSION=\"$(VERSION)\"'
else
    # libdir must be a fully qualified path and not ${exec_prefix}/lib
    eval libdir="$libdir"
    # default install directory for bundled packages
    PACKAGE_DIR="$libdir"
    if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
        TCL_LIB_FLAG="-ltcl${TCL_VERSION}"
    else
        TCL_LIB_FLAG="-ltcl`echo ${TCL_VERSION} | tr -d .`"
    fi
    TCL_BUILD_LIB_SPEC="-L`pwd | sed -e 's/ /\\\\ /g'` ${TCL_LIB_FLAG}"
    TCL_LIB_SPEC="-L${libdir} ${TCL_LIB_FLAG}"
fi
VERSION='${VERSION}'
eval "CFG_TCL_SHARED_LIB_SUFFIX=${TCL_SHARED_LIB_SUFFIX}"
eval "CFG_TCL_UNSHARED_LIB_SUFFIX=${TCL_UNSHARED_LIB_SUFFIX}"







|

|







11093
11094
11095
11096
11097
11098
11099
11100
11101
11102
11103
11104
11105
11106
11107
11108
11109
    EXTRA_CC_SWITCHES='-DTCL_FRAMEWORK_VERSION=\"$(VERSION)\"'
else
    # libdir must be a fully qualified path and not ${exec_prefix}/lib
    eval libdir="$libdir"
    # default install directory for bundled packages
    PACKAGE_DIR="$libdir"
    if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
	TCL_LIB_FLAG="-ltcl${TCL_VERSION}"
    else
	TCL_LIB_FLAG="-ltcl`echo ${TCL_VERSION} | tr -d .`"
    fi
    TCL_BUILD_LIB_SPEC="-L`pwd | sed -e 's/ /\\\\ /g'` ${TCL_LIB_FLAG}"
    TCL_LIB_SPEC="-L${libdir} ${TCL_LIB_FLAG}"
fi
VERSION='${VERSION}'
eval "CFG_TCL_SHARED_LIB_SUFFIX=${TCL_SHARED_LIB_SUFFIX}"
eval "CFG_TCL_UNSHARED_LIB_SUFFIX=${TCL_UNSHARED_LIB_SUFFIX}"
12618
12619
12620
12621
12622
12623
12624
12625
12626
12627
12628
12629
12630
12631
12632
12633
12634
12635
12636
printf "%s\n" "$as_me: executing $ac_file commands" >&6;}
 ;;
  esac


  case $ac_file$ac_mode in
    "Tcl.framework":C) n=Tcl &&
        f=$n.framework && v=Versions/$VERSION &&
        rm -rf $f && mkdir -p $f/$v/Resources &&
        ln -s $v/$n $v/Resources $f && ln -s ../../../$n $f/$v &&
        ln -s ../../../../$n-Info.plist $f/$v/Resources/Info.plist &&
        unset n f v
     ;;

  esac
done # for ac_tag


as_fn_exit 0







|
|
|
|
|







12544
12545
12546
12547
12548
12549
12550
12551
12552
12553
12554
12555
12556
12557
12558
12559
12560
12561
12562
printf "%s\n" "$as_me: executing $ac_file commands" >&6;}
 ;;
  esac


  case $ac_file$ac_mode in
    "Tcl.framework":C) n=Tcl &&
	f=$n.framework && v=Versions/$VERSION &&
	rm -rf $f && mkdir -p $f/$v/Resources &&
	ln -s $v/$n $v/Resources $f && ln -s ../../../$n $f/$v &&
	ln -s ../../../../$n-Info.plist $f/$v/Resources/Info.plist &&
	unset n f v
     ;;

  esac
done # for ac_tag


as_fn_exit 0
Changes to unix/configure.ac.
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
  ])])
AS_IF([test $zlib_ok = no], [
  AC_SUBST(ZLIB_OBJS,[\${ZLIB_OBJS}])
  AC_SUBST(ZLIB_SRCS,[\${ZLIB_SRCS}])
  AC_SUBST(ZLIB_INCLUDE,[-I\${ZLIB_DIR}])
  AC_DEFINE(TCL_WITH_INTERNAL_ZLIB, 1, [Tcl with internal zlib])
])
AC_DEFINE(HAVE_ZLIB, 1, [Is there an installed zlib?])

#------------------------------------------------------------------------
#	Add stuff for libtommath

libtommath_ok=yes
AC_ARG_WITH(system-libtommath,
AS_HELP_STRING([--with-system-libtommath],







<







163
164
165
166
167
168
169

170
171
172
173
174
175
176
  ])])
AS_IF([test $zlib_ok = no], [
  AC_SUBST(ZLIB_OBJS,[\${ZLIB_OBJS}])
  AC_SUBST(ZLIB_SRCS,[\${ZLIB_SRCS}])
  AC_SUBST(ZLIB_INCLUDE,[-I\${ZLIB_DIR}])
  AC_DEFINE(TCL_WITH_INTERNAL_ZLIB, 1, [Tcl with internal zlib])
])


#------------------------------------------------------------------------
#	Add stuff for libtommath

libtommath_ok=yes
AC_ARG_WITH(system-libtommath,
AS_HELP_STRING([--with-system-libtommath],
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398

if test "$ac_cv_cygwin" != "yes"; then
    AC_CHECK_MEMBERS([struct stat.st_blocks, struct stat.st_blksize, struct stat.st_rdev])
fi
AC_CHECK_TYPES([blkcnt_t])
AC_CHECK_FUNC(fstatfs, , [AC_DEFINE(NO_FSTATFS, 1, [Do we have fstatfs()?])])

#--------------------------------------------------------------------
#       Some system like SunOS 4 and other BSD like systems have no memmove
#       (we assume they have bcopy instead). {The replacement define is in
#       compat/string.h}
#--------------------------------------------------------------------

AC_CHECK_FUNC(memmove, , [
    AC_DEFINE(NO_MEMMOVE, 1, [Do we have memmove()?])
    AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?]) ])

#--------------------------------------------------------------------
#	Check for various typedefs and provide substitutes if
#	they don't exist.
#--------------------------------------------------------------------

AC_TYPE_MODE_T
AC_TYPE_PID_T







<
<
<
<
<
<
<
<
<
<







374
375
376
377
378
379
380










381
382
383
384
385
386
387

if test "$ac_cv_cygwin" != "yes"; then
    AC_CHECK_MEMBERS([struct stat.st_blocks, struct stat.st_blksize, struct stat.st_rdev])
fi
AC_CHECK_TYPES([blkcnt_t])
AC_CHECK_FUNC(fstatfs, , [AC_DEFINE(NO_FSTATFS, 1, [Do we have fstatfs()?])])











#--------------------------------------------------------------------
#	Check for various typedefs and provide substitutes if
#	they don't exist.
#--------------------------------------------------------------------

AC_TYPE_MODE_T
AC_TYPE_PID_T
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
# The check below checks whether the cpuid instruction is usable.
#--------------------------------------------------------------------

AC_CACHE_CHECK([whether the cpuid instruction is usable], tcl_cv_cpuid, [
    AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
	int index,regsPtr[4];
    __asm__ __volatile__("mov %%ebx, %%edi     \n\t"
                 "cpuid            \n\t"
                 "mov %%ebx, %%esi   \n\t"
                 "mov %%edi, %%ebx  \n\t"
                 : "=a"(regsPtr[0]), "=S"(regsPtr[1]), "=c"(regsPtr[2]), "=d"(regsPtr[3])
                 : "a"(index) : "edi");
    ]])],[tcl_cv_cpuid=yes],[tcl_cv_cpuid=no])])
if test $tcl_cv_cpuid = yes; then
    AC_DEFINE(HAVE_CPUID, 1, [Is the cpuid instruction usable?])
fi

#--------------------------------------------------------------------
#	The statements below define a collection of symbols related to







|
|
|
|
|







713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
# The check below checks whether the cpuid instruction is usable.
#--------------------------------------------------------------------

AC_CACHE_CHECK([whether the cpuid instruction is usable], tcl_cv_cpuid, [
    AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
	int index,regsPtr[4];
    __asm__ __volatile__("mov %%ebx, %%edi     \n\t"
		 "cpuid            \n\t"
		 "mov %%ebx, %%esi   \n\t"
		 "mov %%edi, %%ebx  \n\t"
		 : "=a"(regsPtr[0]), "=S"(regsPtr[1]), "=c"(regsPtr[2]), "=d"(regsPtr[3])
		 : "a"(index) : "edi");
    ]])],[tcl_cv_cpuid=yes],[tcl_cv_cpuid=no])])
if test $tcl_cv_cpuid = yes; then
    AC_DEFINE(HAVE_CPUID, 1, [Is the cpuid instruction usable?])
fi

#--------------------------------------------------------------------
#	The statements below define a collection of symbols related to
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
fi

if test "$FRAMEWORK_BUILD" = "1" ; then
    AC_DEFINE(TCL_FRAMEWORK, 1, [Is Tcl built as a framework?])
    # Construct a fake local framework structure to make linking with
    # '-framework Tcl' and running of tcltest work
    AC_CONFIG_COMMANDS([Tcl.framework], [n=Tcl &&
        f=$n.framework && v=Versions/$VERSION &&
        rm -rf $f && mkdir -p $f/$v/Resources &&
        ln -s $v/$n $v/Resources $f && ln -s ../../../$n $f/$v &&
        ln -s ../../../../$n-Info.plist $f/$v/Resources/Info.plist &&
        unset n f v
    ], VERSION=${TCL_VERSION})
    LD_LIBRARY_PATH_VAR="DYLD_FRAMEWORK_PATH"
    # default install directory for bundled packages
    if test "${libdir}" = '${exec_prefix}/lib' -o "`basename ${libdir}`" = 'Frameworks'; then
        PACKAGE_DIR="/Library/Tcl"
    else
        PACKAGE_DIR="$libdir"
    fi
    if test "${libdir}" = '${exec_prefix}/lib'; then
        # override libdir default
        libdir="/Library/Frameworks"
    fi
    TCL_LIB_FILE="Tcl"
    TCL_LIB_FLAG="-framework Tcl"
    TCL_BUILD_LIB_SPEC="-F`pwd | sed -e 's/ /\\\\ /g'` -framework Tcl"
    TCL_LIB_SPEC="-F${libdir} -framework Tcl"
    libdir="${libdir}/Tcl.framework/Versions/\${VERSION}"
    TCL_LIBRARY="${libdir}/Resources/Scripts"







|
|
|
|
|




|

|


|
|







763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
fi

if test "$FRAMEWORK_BUILD" = "1" ; then
    AC_DEFINE(TCL_FRAMEWORK, 1, [Is Tcl built as a framework?])
    # Construct a fake local framework structure to make linking with
    # '-framework Tcl' and running of tcltest work
    AC_CONFIG_COMMANDS([Tcl.framework], [n=Tcl &&
	f=$n.framework && v=Versions/$VERSION &&
	rm -rf $f && mkdir -p $f/$v/Resources &&
	ln -s $v/$n $v/Resources $f && ln -s ../../../$n $f/$v &&
	ln -s ../../../../$n-Info.plist $f/$v/Resources/Info.plist &&
	unset n f v
    ], VERSION=${TCL_VERSION})
    LD_LIBRARY_PATH_VAR="DYLD_FRAMEWORK_PATH"
    # default install directory for bundled packages
    if test "${libdir}" = '${exec_prefix}/lib' -o "`basename ${libdir}`" = 'Frameworks'; then
	PACKAGE_DIR="/Library/Tcl"
    else
	PACKAGE_DIR="$libdir"
    fi
    if test "${libdir}" = '${exec_prefix}/lib'; then
	# override libdir default
	libdir="/Library/Frameworks"
    fi
    TCL_LIB_FILE="Tcl"
    TCL_LIB_FLAG="-framework Tcl"
    TCL_BUILD_LIB_SPEC="-F`pwd | sed -e 's/ /\\\\ /g'` -framework Tcl"
    TCL_LIB_SPEC="-F${libdir} -framework Tcl"
    libdir="${libdir}/Tcl.framework/Versions/\${VERSION}"
    TCL_LIBRARY="${libdir}/Resources/Scripts"
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
    EXTRA_CC_SWITCHES='-DTCL_FRAMEWORK_VERSION=\"$(VERSION)\"'
else
    # libdir must be a fully qualified path and not ${exec_prefix}/lib
    eval libdir="$libdir"
    # default install directory for bundled packages
    PACKAGE_DIR="$libdir"
    if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
        TCL_LIB_FLAG="-ltcl${TCL_VERSION}"
    else
        TCL_LIB_FLAG="-ltcl`echo ${TCL_VERSION} | tr -d .`"
    fi
    TCL_BUILD_LIB_SPEC="-L`pwd | sed -e 's/ /\\\\ /g'` ${TCL_LIB_FLAG}"
    TCL_LIB_SPEC="-L${libdir} ${TCL_LIB_FLAG}"
fi
VERSION='${VERSION}'
eval "CFG_TCL_SHARED_LIB_SUFFIX=${TCL_SHARED_LIB_SUFFIX}"
eval "CFG_TCL_UNSHARED_LIB_SUFFIX=${TCL_UNSHARED_LIB_SUFFIX}"







|

|







805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
    EXTRA_CC_SWITCHES='-DTCL_FRAMEWORK_VERSION=\"$(VERSION)\"'
else
    # libdir must be a fully qualified path and not ${exec_prefix}/lib
    eval libdir="$libdir"
    # default install directory for bundled packages
    PACKAGE_DIR="$libdir"
    if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
	TCL_LIB_FLAG="-ltcl${TCL_VERSION}"
    else
	TCL_LIB_FLAG="-ltcl`echo ${TCL_VERSION} | tr -d .`"
    fi
    TCL_BUILD_LIB_SPEC="-L`pwd | sed -e 's/ /\\\\ /g'` ${TCL_LIB_FLAG}"
    TCL_LIB_SPEC="-L${libdir} ${TCL_LIB_FLAG}"
fi
VERSION='${VERSION}'
eval "CFG_TCL_SHARED_LIB_SUFFIX=${TCL_SHARED_LIB_SUFFIX}"
eval "CFG_TCL_UNSHARED_LIB_SUFFIX=${TCL_UNSHARED_LIB_SUFFIX}"
Changes to unix/tcl.m4.
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
	    ], [
		# Check for combined 32-bit and 64-bit fat build
		AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64|arm64) ' \
		    && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
		    fat_32_64=yes])
	    ])
	    SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS}'
	    AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
		AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[int i;]])],[tcl_cv_ld_single_module=yes],
		    [tcl_cv_ld_single_module=no])
		LDFLAGS=$hold_ldflags])
	    AS_IF([test $tcl_cv_ld_single_module = yes], [
		SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
	    ])
	    SHLIB_SUFFIX=".dylib"
	    DL_OBJS="tclLoadDyld.o"
	    DL_LIBS=""
	    LDFLAGS="$LDFLAGS -headerpad_max_install_names"
	    AC_CACHE_CHECK([if ld accepts -search_paths_first flag],
		    tcl_cv_ld_search_paths_first, [
		hold_ldflags=$LDFLAGS







<
<
<
<
<
<
<
<
<







1420
1421
1422
1423
1424
1425
1426









1427
1428
1429
1430
1431
1432
1433
	    ], [
		# Check for combined 32-bit and 64-bit fat build
		AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64|arm64) ' \
		    && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
		    fat_32_64=yes])
	    ])
	    SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS}'









	    SHLIB_SUFFIX=".dylib"
	    DL_OBJS="tclLoadDyld.o"
	    DL_LIBS=""
	    LDFLAGS="$LDFLAGS -headerpad_max_install_names"
	    AC_CACHE_CHECK([if ld accepts -search_paths_first flag],
		    tcl_cv_ld_search_paths_first, [
		hold_ldflags=$LDFLAGS
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
#
# Arguments:
#	none
#
# Results:
#
#	Defines some of the following vars:
#		NO_STRING_H
#		NO_SYS_WAIT_H
#		NO_DLFCN_H
#		HAVE_SYS_PARAM_H
#		HAVE_STRING_H ?
#
#--------------------------------------------------------------------

AC_DEFUN([SC_MISSING_POSIX_HEADERS], [
    AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
    AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
    AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)

    # See also memmove check below for a place where NO_STRING_H can be
    # set and why.

    if test $tcl_ok = 0; then
	AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
    fi

    AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
    AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])

    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
    AC_CHECK_HEADERS([sys/param.h])
])








<












<
<
<
<
<
<
<







1918
1919
1920
1921
1922
1923
1924

1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936







1937
1938
1939
1940
1941
1942
1943
#
# Arguments:
#	none
#
# Results:
#
#	Defines some of the following vars:

#		NO_SYS_WAIT_H
#		NO_DLFCN_H
#		HAVE_SYS_PARAM_H
#		HAVE_STRING_H ?
#
#--------------------------------------------------------------------

AC_DEFUN([SC_MISSING_POSIX_HEADERS], [
    AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
    AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
    AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)








    AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
    AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])

    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
    AC_CHECK_HEADERS([sys/param.h])
])

Changes to unix/tclConfig.h.in.
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319

/* Define to 1 if you have the 'waitpid' function. */
#undef HAVE_WAITPID

/* Is weak import available? */
#undef HAVE_WEAK_IMPORT

/* Is there an installed zlib? */
#undef HAVE_ZLIB

/* Is this a Mac I see before me? */
#undef MAC_OSX_TCL

/* No Compiler support for module scope symbols */
#undef MODULE_SCOPE

/* Default libtommath precision. */







<
<
<







303
304
305
306
307
308
309



310
311
312
313
314
315
316

/* Define to 1 if you have the 'waitpid' function. */
#undef HAVE_WAITPID

/* Is weak import available? */
#undef HAVE_WEAK_IMPORT




/* Is this a Mac I see before me? */
#undef MAC_OSX_TCL

/* No Compiler support for module scope symbols */
#undef MODULE_SCOPE

/* Default libtommath precision. */
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376

/* Do we have gettimeofday()? */
#undef NO_GETTOD

/* Do we have getwd() */
#undef NO_GETWD

/* Do we have memmove()? */
#undef NO_MEMMOVE

/* Do we have mknod() */
#undef NO_MKNOD

/* Do we have realpath() */
#undef NO_REALPATH

/* Do we have strerror() */
#undef NO_STRERROR

/* Do we have <string.h>? */
#undef NO_STRING_H

/* Do we have <sys/wait.h>? */
#undef NO_SYS_WAIT_H

/* Do we have tcdrain() */
#undef NO_TCDRAIN

/* Do we have uname() */







<
<
<









<
<
<







345
346
347
348
349
350
351



352
353
354
355
356
357
358
359
360



361
362
363
364
365
366
367

/* Do we have gettimeofday()? */
#undef NO_GETTOD

/* Do we have getwd() */
#undef NO_GETWD




/* Do we have mknod() */
#undef NO_MKNOD

/* Do we have realpath() */
#undef NO_REALPATH

/* Do we have strerror() */
#undef NO_STRERROR




/* Do we have <sys/wait.h>? */
#undef NO_SYS_WAIT_H

/* Do we have tcdrain() */
#undef NO_TCDRAIN

/* Do we have uname() */
Changes to unix/tclLoadShl.c.
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
    const char *native;
    char *fileName = TclGetString(pathPtr);

    /*
     * The flags below used to be BIND_IMMEDIATE; they were changed at the
     * suggestion of Wolfgang Kechel (wolfgang@prs.de): "This enables
     * verbosity for missing symbols when loading a shared lib and allows to
     * load libtk8.0.sl into tclsh8.0 without problems.  In general, this
     * delays resolving symbols until they are actually needed.  Shared libs
     * do no longer need all libraries linked in when they are build."
     */

    /*
     * First try the full path the user gave us.  This is particularly
     * important if the cwd is inside a vfs, and we are trying to load using a







|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
    const char *native;
    char *fileName = TclGetString(pathPtr);

    /*
     * The flags below used to be BIND_IMMEDIATE; they were changed at the
     * suggestion of Wolfgang Kechel (wolfgang@prs.de): "This enables
     * verbosity for missing symbols when loading a shared lib and allows to
     * load libtk9.0.sl into tclsh9.0 without problems.  In general, this
     * delays resolving symbols until they are actually needed.  Shared libs
     * do no longer need all libraries linked in when they are build."
     */

    /*
     * First try the full path the user gave us.  This is particularly
     * important if the cwd is inside a vfs, and we are trying to load using a
Changes to unix/tclUnixChan.c.
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
    }

    native = (const char *)Tcl_FSGetNativePath(pathPtr);
    if (native == NULL) {
	if (interp != (Tcl_Interp *) NULL) {
	    /*
	     * We need this just to ensure we return the correct error messages under
	     * some circumstances (relative paths only), so because the normalization 
	     * is very expensive, don't invoke it for native or absolute paths.
	     * Note: since paths starting with ~ are absolute, it also considers tilde expansion,
	     * (proper error message of tests *io-40.17 "tilde substitution in open")
	     */
	    if (
		(
		  (







|







1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
    }

    native = (const char *)Tcl_FSGetNativePath(pathPtr);
    if (native == NULL) {
	if (interp != (Tcl_Interp *) NULL) {
	    /*
	     * We need this just to ensure we return the correct error messages under
	     * some circumstances (relative paths only), so because the normalization
	     * is very expensive, don't invoke it for native or absolute paths.
	     * Note: since paths starting with ~ are absolute, it also considers tilde expansion,
	     * (proper error message of tests *io-40.17 "tilde substitution in open")
	     */
	    if (
		(
		  (
Changes to win/Makefile.in.
22
23
24
25
26
27
28



29
30
31
32
33
34
35
bindir			= @bindir@
libdir			= @libdir@
includedir		= @includedir@
datarootdir		= @datarootdir@
runstatedir		= @runstatedir@
mandir			= @mandir@




# The following definition can be set to non-null for special systems like AFS
# with replication. It allows the pathnames used for installation to be
# different than those used for actually reference files at run-time.
# INSTALL_ROOT is prepended to $prefix and $exec_prefix when installing files.
INSTALL_ROOT	=

# Directory from which applications will reference the library of Tcl scripts







>
>
>







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
bindir			= @bindir@
libdir			= @libdir@
includedir		= @includedir@
datarootdir		= @datarootdir@
runstatedir		= @runstatedir@
mandir			= @mandir@

# Configure arguments
PKG_CFG_ARGS		= @PKG_CFG_ARGS@

# The following definition can be set to non-null for special systems like AFS
# with replication. It allows the pathnames used for installation to be
# different than those used for actually reference files at run-time.
# INSTALL_ROOT is prepended to $prefix and $exec_prefix when installing files.
INSTALL_ROOT	=

# Directory from which applications will reference the library of Tcl scripts
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597




598
599
600
601

602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
# library or static library

${TCL_STUB_LIB_FILE}: ${STUB_OBJS} ${DDE_OBJS} ${REG_OBJS}
	@$(RM) ${TCL_STUB_LIB_FILE}
	@MAKE_STUB_LIB@ ${STUB_OBJS} ${DDE_OBJS} ${REG_OBJS}
	@POST_MAKE_LIB@

${TCL_DLL_FILE}: ${TCL_OBJS} tcl.$(RES) @ZLIB_DLL_FILE@ @TOMMATH_DLL_FILE@ ${TCL_ZIP_FILE}
	@$(RM) ${TCL_DLL_FILE} $(TCL_LIB_FILE)
	@MAKE_DLL@ ${TCL_OBJS} tcl.$(RES) $(SHLIB_LD_LIBS)
	$(COPY) tclsh.exe.manifest ${TCL_DLL_FILE}.manifest
	@VC_MANIFEST_EMBED_DLL@
	@if test "${ZIPFS_BUILD}" = "1" ; then \
		cat ${TCL_ZIP_FILE} >> ${TCL_DLL_FILE}; \
		${NATIVE_ZIP} -A ${TCL_DLL_FILE} \
		  || echo 'ignore zip-error by adjust sfx process (not executable?)'; \
	fi





${TCL_LIB_FILE}: ${TCL_OBJS} tclWinPanic.$(OBJEXT) ${DDE_OBJS} ${REG_OBJS}
	@$(RM) ${TCL_LIB_FILE}
	@MAKE_LIB@ ${TCL_OBJS} tclWinPanic.$(OBJEXT) ${DDE_OBJS} ${REG_OBJS}
	@POST_MAKE_LIB@


${DDE_DLL_FILE}: ${TCL_STUB_LIB_FILE} ${DDE_OBJS}
	@MAKE_DLL@ ${DDE_OBJS} $(TCL_STUB_LIB_FILE) $(SHLIB_LD_LIBS)
	$(COPY) tclsh.exe.manifest ${DDE_DLL_FILE}.manifest

${REG_DLL_FILE}: ${TCL_STUB_LIB_FILE} ${REG_OBJS}
	@MAKE_DLL@ ${REG_OBJS} $(TCL_STUB_LIB_FILE) $(SHLIB_LD_LIBS)
	$(COPY) tclsh.exe.manifest ${REG_DLL_FILE}.manifest

${TEST_DLL_FILE}: ${TCL_STUB_LIB_FILE} ${TCLTEST_OBJS}
	@$(RM) ${TEST_DLL_FILE} ${TEST_LIB_FILE}
	@MAKE_DLL@ ${TCLTEST_OBJS} $(TCL_STUB_LIB_FILE) $(SHLIB_LD_LIBS)
	$(COPY) tclsh.exe.manifest ${TEST_DLL_FILE}.manifest

${TEST_EXE_FILE}: ${TCL_STUB_LIB_FILE} ${TCLTEST_OBJS} tclTestMain.${OBJEXT}
	@$(RM) ${TEST_EXE_FILE}
	$(CC) $(CFLAGS) $(TCLTEST_OBJS) tclTestMain.$(OBJEXT) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \
	tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE)
	$(COPY) tclsh.exe.manifest ${TEST_EXE_FILE}.manifest

# use prebuilt zlib1.dll
${ZLIB_DLL_FILE}: ${TCL_STUB_LIB_FILE}







|










>
>
>
>




>














|







583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
# library or static library

${TCL_STUB_LIB_FILE}: ${STUB_OBJS} ${DDE_OBJS} ${REG_OBJS}
	@$(RM) ${TCL_STUB_LIB_FILE}
	@MAKE_STUB_LIB@ ${STUB_OBJS} ${DDE_OBJS} ${REG_OBJS}
	@POST_MAKE_LIB@

${TCL_DLL_FILE}: ${TCL_LIB_FILE} ${TCL_OBJS} tcl.$(RES) @ZLIB_DLL_FILE@ @TOMMATH_DLL_FILE@ ${TCL_ZIP_FILE}
	@$(RM) ${TCL_DLL_FILE} $(TCL_LIB_FILE)
	@MAKE_DLL@ ${TCL_OBJS} tcl.$(RES) $(SHLIB_LD_LIBS)
	$(COPY) tclsh.exe.manifest ${TCL_DLL_FILE}.manifest
	@VC_MANIFEST_EMBED_DLL@
	@if test "${ZIPFS_BUILD}" = "1" ; then \
		cat ${TCL_ZIP_FILE} >> ${TCL_DLL_FILE}; \
		${NATIVE_ZIP} -A ${TCL_DLL_FILE} \
		  || echo 'ignore zip-error by adjust sfx process (not executable?)'; \
	fi

ifeq (,$(findstring --disable-shared,$(PKG_CFG_ARGS)))
${TCL_LIB_FILE}:
	@$(RM) ${TCL_DLL_FILE} $(TCL_LIB_FILE)
else
${TCL_LIB_FILE}: ${TCL_OBJS} tclWinPanic.$(OBJEXT) ${DDE_OBJS} ${REG_OBJS}
	@$(RM) ${TCL_LIB_FILE}
	@MAKE_LIB@ ${TCL_OBJS} tclWinPanic.$(OBJEXT) ${DDE_OBJS} ${REG_OBJS}
	@POST_MAKE_LIB@
endif

${DDE_DLL_FILE}: ${TCL_STUB_LIB_FILE} ${DDE_OBJS}
	@MAKE_DLL@ ${DDE_OBJS} $(TCL_STUB_LIB_FILE) $(SHLIB_LD_LIBS)
	$(COPY) tclsh.exe.manifest ${DDE_DLL_FILE}.manifest

${REG_DLL_FILE}: ${TCL_STUB_LIB_FILE} ${REG_OBJS}
	@MAKE_DLL@ ${REG_OBJS} $(TCL_STUB_LIB_FILE) $(SHLIB_LD_LIBS)
	$(COPY) tclsh.exe.manifest ${REG_DLL_FILE}.manifest

${TEST_DLL_FILE}: ${TCL_STUB_LIB_FILE} ${TCLTEST_OBJS}
	@$(RM) ${TEST_DLL_FILE} ${TEST_LIB_FILE}
	@MAKE_DLL@ ${TCLTEST_OBJS} $(TCL_STUB_LIB_FILE) $(SHLIB_LD_LIBS)
	$(COPY) tclsh.exe.manifest ${TEST_DLL_FILE}.manifest

${TEST_EXE_FILE}: @LIBRARIES@ ${TCL_STUB_LIB_FILE} ${TCLTEST_OBJS} tclTestMain.${OBJEXT}
	@$(RM) ${TEST_EXE_FILE}
	$(CC) $(CFLAGS) $(TCLTEST_OBJS) tclTestMain.$(OBJEXT) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \
	tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE)
	$(COPY) tclsh.exe.manifest ${TEST_EXE_FILE}.manifest

# use prebuilt zlib1.dll
${ZLIB_DLL_FILE}: ${TCL_STUB_LIB_FILE}
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
	@$(COPY) $(ROOT_DIR)/library/http/http.tcl "$(MODULE_INSTALL_DIR)/9.0/http-2.10.0.tm";
	@echo "Installing package opt 0.4.7";
	@for j in $(ROOT_DIR)/library/opt/*.tcl; do \
	    $(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/opt0.4"; \
	    done;
	@echo "Installing package msgcat 1.7.1 as a Tcl Module";
	@$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl "$(MODULE_INSTALL_DIR)/9.0/msgcat-1.7.1.tm";
	@echo "Installing package tcltest 2.5.8 as a Tcl Module";
	@$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl "$(MODULE_INSTALL_DIR)/9.0/tcltest-2.5.8.tm";
	@echo "Installing package platform 1.0.19 as a Tcl Module";
	@$(COPY) $(ROOT_DIR)/library/platform/platform.tcl "$(MODULE_INSTALL_DIR)/9.0/platform-1.0.19.tm";
	@echo "Installing package platform::shell 1.1.4 as a Tcl Module";
	@$(COPY) $(ROOT_DIR)/library/platform/shell.tcl "$(MODULE_INSTALL_DIR)/9.0/platform/shell-1.1.4.tm";
	@echo "Installing encodings";
	@for i in $(ROOT_DIR)/library/encoding/*.enc ; do \
		$(COPY) "$$i" "$(SCRIPT_INSTALL_DIR)/encoding"; \







|
|







933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
	@$(COPY) $(ROOT_DIR)/library/http/http.tcl "$(MODULE_INSTALL_DIR)/9.0/http-2.10.0.tm";
	@echo "Installing package opt 0.4.7";
	@for j in $(ROOT_DIR)/library/opt/*.tcl; do \
	    $(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/opt0.4"; \
	    done;
	@echo "Installing package msgcat 1.7.1 as a Tcl Module";
	@$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl "$(MODULE_INSTALL_DIR)/9.0/msgcat-1.7.1.tm";
	@echo "Installing package tcltest 2.5.9 as a Tcl Module";
	@$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl "$(MODULE_INSTALL_DIR)/9.0/tcltest-2.5.9.tm";
	@echo "Installing package platform 1.0.19 as a Tcl Module";
	@$(COPY) $(ROOT_DIR)/library/platform/platform.tcl "$(MODULE_INSTALL_DIR)/9.0/platform-1.0.19.tm";
	@echo "Installing package platform::shell 1.1.4 as a Tcl Module";
	@$(COPY) $(ROOT_DIR)/library/platform/shell.tcl "$(MODULE_INSTALL_DIR)/9.0/platform/shell-1.1.4.tm";
	@echo "Installing encodings";
	@for i in $(ROOT_DIR)/library/encoding/*.enc ; do \
		$(COPY) "$$i" "$(SCRIPT_INSTALL_DIR)/encoding"; \
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
	$(RM) Makefile config.status config.cache config.log tclConfig.sh \
		config.status.lineno tclsh.exe.manifest tclUuid.h

#
# Bundled package targets
#

PKG_CFG_ARGS		= @PKG_CFG_ARGS@
PKG_DIR			= ./pkgs

packages:
	@builddir=`$(CYGPATH) $$(pwd -P)`; \
	for i in $(PKGS_DIR)/*; do \
	  if [ -d $$i ] ; then \
	    if [ -x $$i/configure ] ; then \







<







1056
1057
1058
1059
1060
1061
1062

1063
1064
1065
1066
1067
1068
1069
	$(RM) Makefile config.status config.cache config.log tclConfig.sh \
		config.status.lineno tclsh.exe.manifest tclUuid.h

#
# Bundled package targets
#


PKG_DIR			= ./pkgs

packages:
	@builddir=`$(CYGPATH) $$(pwd -P)`; \
	for i in $(PKGS_DIR)/*; do \
	  if [ -d $$i ] ; then \
	    if [ -x $$i/configure ] ; then \
Changes to win/configure.
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006

    if test "$do64bit" = "arm64"
then :

      if test "$GCC" = "yes"
then :

        ZLIB_LIBS=\${ZLIB_DIR_NATIVE}/win64-arm/libz.dll.a

        TOMMATH_LIBS=\${TOMMATH_DIR_NATIVE}/win64-arm/libtommath.dll.a

        zlib_lib_name=libz.dll.a
        tommath_lib_name=libtommath.dll.a

else case e in #(
  e)
        ZLIB_LIBS=\${ZLIB_DIR_NATIVE}/win64-arm/zdll.lib

        TOMMATH_LIBS=\${TOMMATH_DIR_NATIVE}/win64-arm/tommath.lib

       ;;
esac
fi

else case e in #(
  e)
      if test "$GCC" = "yes"
then :

        ZLIB_LIBS=\${ZLIB_DIR_NATIVE}/win64/libz.dll.a

        TOMMATH_LIBS=\${TOMMATH_DIR_NATIVE}/win64/libtommath.dll.a

        zlib_lib_name=libz.dll.a
        tommath_lib_name=libtommath.dll.a

else case e in #(
  e)
        ZLIB_LIBS=\${ZLIB_DIR_NATIVE}/win64/zdll.lib

        TOMMATH_LIBS=\${TOMMATH_DIR_NATIVE}/win64/tommath.lib

       ;;
esac
fi
     ;;
esac
fi







|

|

|
|



|

|










|

|

|
|



|

|







4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006

    if test "$do64bit" = "arm64"
then :

      if test "$GCC" = "yes"
then :

	ZLIB_LIBS=\${ZLIB_DIR_NATIVE}/win64-arm/libz.dll.a

	TOMMATH_LIBS=\${TOMMATH_DIR_NATIVE}/win64-arm/libtommath.dll.a

	zlib_lib_name=libz.dll.a
	tommath_lib_name=libtommath.dll.a

else case e in #(
  e)
	ZLIB_LIBS=\${ZLIB_DIR_NATIVE}/win64-arm/zdll.lib

	TOMMATH_LIBS=\${TOMMATH_DIR_NATIVE}/win64-arm/tommath.lib

       ;;
esac
fi

else case e in #(
  e)
      if test "$GCC" = "yes"
then :

	ZLIB_LIBS=\${ZLIB_DIR_NATIVE}/win64/libz.dll.a

	TOMMATH_LIBS=\${TOMMATH_DIR_NATIVE}/win64/libtommath.dll.a

	zlib_lib_name=libz.dll.a
	tommath_lib_name=libtommath.dll.a

else case e in #(
  e)
	ZLIB_LIBS=\${ZLIB_DIR_NATIVE}/win64/zdll.lib

	TOMMATH_LIBS=\${TOMMATH_DIR_NATIVE}/win64/tommath.lib

       ;;
esac
fi
     ;;
esac
fi
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
  ZLIB_OBJS=\${ZLIB_OBJS}

  TOMMATH_OBJS=\${TOMMATH_OBJS}

 ;;
esac
fi

printf "%s\n" "#define HAVE_ZLIB 1" >>confdefs.h

TCL_ZLIB_LIB_NAME=$zlib_lib_name

TCL_TOMMATH_LIB_NAME=$tommath_lib_name

ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "
#include <stdint.h>








<
<
<







5023
5024
5025
5026
5027
5028
5029



5030
5031
5032
5033
5034
5035
5036
  ZLIB_OBJS=\${ZLIB_OBJS}

  TOMMATH_OBJS=\${TOMMATH_OBJS}

 ;;
esac
fi



TCL_ZLIB_LIB_NAME=$zlib_lib_name

TCL_TOMMATH_LIB_NAME=$tommath_lib_name

ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "
#include <stdint.h>

Changes to win/configure.ac.
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
  AC_SUBST(ZLIB_DLL_FILE,[\${ZLIB_DLL_FILE}])
  AC_SUBST(TOMMATH_DLL_FILE,[\${TOMMATH_DLL_FILE}])
  AC_DEFINE(TCL_WITH_EXTERNAL_TOMMATH, 1, [Tcl with external libtommath])
  AS_IF([test "$do64bit" != "no"], [
    AC_DEFINE(MP_64BIT, 1, [Using libtommath.dll in 64-bit mode])
    AS_IF([test "$do64bit" = "arm64"], [
      AS_IF([test "$GCC" = "yes"],[
        AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR_NATIVE}/win64-arm/libz.dll.a])
        AC_SUBST(TOMMATH_LIBS,[\${TOMMATH_DIR_NATIVE}/win64-arm/libtommath.dll.a])
        zlib_lib_name=libz.dll.a
        tommath_lib_name=libtommath.dll.a
      ], [
        AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR_NATIVE}/win64-arm/zdll.lib])
        AC_SUBST(TOMMATH_LIBS,[\${TOMMATH_DIR_NATIVE}/win64-arm/tommath.lib])
      ])
    ], [
      AS_IF([test "$GCC" = "yes"],[
        AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR_NATIVE}/win64/libz.dll.a])
        AC_SUBST(TOMMATH_LIBS,[\${TOMMATH_DIR_NATIVE}/win64/libtommath.dll.a])
        zlib_lib_name=libz.dll.a
        tommath_lib_name=libtommath.dll.a
      ], [
        AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR_NATIVE}/win64/zdll.lib])
        AC_SUBST(TOMMATH_LIBS,[\${TOMMATH_DIR_NATIVE}/win64/tommath.lib])
      ])
    ])
  ], [
    AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR_NATIVE}/win32/zdll.lib])
    AC_SUBST(TOMMATH_LIBS,[\${TOMMATH_DIR_NATIVE}/win32/tommath.lib])
  ])
], [
  AC_DEFINE(TCL_WITH_INTERNAL_ZLIB, 1, [Tcl with internal zlib])
  AC_SUBST(ZLIB_OBJS,[\${ZLIB_OBJS}])
  AC_SUBST(TOMMATH_OBJS,[\${TOMMATH_OBJS}])
])
AC_DEFINE(HAVE_ZLIB, 1, [Is there an installed zlib?])
AC_SUBST(TCL_ZLIB_LIB_NAME, $zlib_lib_name)
AC_SUBST(TCL_TOMMATH_LIB_NAME, $tommath_lib_name)
AC_CHECK_TYPES([intptr_t, uintptr_t],,,[[
#include <stdint.h>
]])

#--------------------------------------------------------------------







|
|
|
|

|
|



|
|
|
|

|
|











<







127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161

162
163
164
165
166
167
168
  AC_SUBST(ZLIB_DLL_FILE,[\${ZLIB_DLL_FILE}])
  AC_SUBST(TOMMATH_DLL_FILE,[\${TOMMATH_DLL_FILE}])
  AC_DEFINE(TCL_WITH_EXTERNAL_TOMMATH, 1, [Tcl with external libtommath])
  AS_IF([test "$do64bit" != "no"], [
    AC_DEFINE(MP_64BIT, 1, [Using libtommath.dll in 64-bit mode])
    AS_IF([test "$do64bit" = "arm64"], [
      AS_IF([test "$GCC" = "yes"],[
	AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR_NATIVE}/win64-arm/libz.dll.a])
	AC_SUBST(TOMMATH_LIBS,[\${TOMMATH_DIR_NATIVE}/win64-arm/libtommath.dll.a])
	zlib_lib_name=libz.dll.a
	tommath_lib_name=libtommath.dll.a
      ], [
	AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR_NATIVE}/win64-arm/zdll.lib])
	AC_SUBST(TOMMATH_LIBS,[\${TOMMATH_DIR_NATIVE}/win64-arm/tommath.lib])
      ])
    ], [
      AS_IF([test "$GCC" = "yes"],[
	AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR_NATIVE}/win64/libz.dll.a])
	AC_SUBST(TOMMATH_LIBS,[\${TOMMATH_DIR_NATIVE}/win64/libtommath.dll.a])
	zlib_lib_name=libz.dll.a
	tommath_lib_name=libtommath.dll.a
      ], [
	AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR_NATIVE}/win64/zdll.lib])
	AC_SUBST(TOMMATH_LIBS,[\${TOMMATH_DIR_NATIVE}/win64/tommath.lib])
      ])
    ])
  ], [
    AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR_NATIVE}/win32/zdll.lib])
    AC_SUBST(TOMMATH_LIBS,[\${TOMMATH_DIR_NATIVE}/win32/tommath.lib])
  ])
], [
  AC_DEFINE(TCL_WITH_INTERNAL_ZLIB, 1, [Tcl with internal zlib])
  AC_SUBST(ZLIB_OBJS,[\${ZLIB_OBJS}])
  AC_SUBST(TOMMATH_OBJS,[\${TOMMATH_OBJS}])
])

AC_SUBST(TCL_ZLIB_LIB_NAME, $zlib_lib_name)
AC_SUBST(TCL_TOMMATH_LIB_NAME, $tommath_lib_name)
AC_CHECK_TYPES([intptr_t, uintptr_t],,,[[
#include <stdint.h>
]])

#--------------------------------------------------------------------
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
  FINDEX_SEARCH_OPS j;
]])],
    [tcl_cv_findex_enums=yes],
    [tcl_cv_findex_enums=no])
)
if test "$tcl_cv_findex_enums" = "no"; then
    AC_DEFINE(HAVE_NO_FINDEX_ENUMS, 1,
            [Defined when enums are missing from winbase.h])
fi

# See if the compiler supports intrinsics.

AC_CACHE_CHECK(for intrinsics support in compiler,
    tcl_cv_intrinsics,
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#include <intrin.h>
]], [[
  __cpuidex(0,0,0);
]])],
    [tcl_cv_intrinsics=yes],
    [tcl_cv_intrinsics=no])
)
if test "$tcl_cv_intrinsics" = "yes"; then
    AC_DEFINE(HAVE_INTRIN_H, 1,
            [Defined when the compilers supports intrinsics])
fi

# See if the <wspiapi.h> header file is present

AC_CACHE_CHECK(for wspiapi.h,
    tcl_cv_wspiapi_h,
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <wspiapi.h>
]], [[]])],
    [tcl_cv_wspiapi_h=yes],
    [tcl_cv_wspiapi_h=no])
)
if test "$tcl_cv_wspiapi_h" = "yes"; then
    AC_DEFINE(HAVE_WSPIAPI_H, 1,
            [Defined when wspiapi.h exists])
fi

# See if declarations like FINDEX_INFO_LEVELS are
# missing from winbase.h. This is known to be
# a problem with VC++ 5.2.

AC_CACHE_CHECK(for FINDEX_INFO_LEVELS in winbase.h,







|



















|














|







228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
  FINDEX_SEARCH_OPS j;
]])],
    [tcl_cv_findex_enums=yes],
    [tcl_cv_findex_enums=no])
)
if test "$tcl_cv_findex_enums" = "no"; then
    AC_DEFINE(HAVE_NO_FINDEX_ENUMS, 1,
	    [Defined when enums are missing from winbase.h])
fi

# See if the compiler supports intrinsics.

AC_CACHE_CHECK(for intrinsics support in compiler,
    tcl_cv_intrinsics,
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#include <intrin.h>
]], [[
  __cpuidex(0,0,0);
]])],
    [tcl_cv_intrinsics=yes],
    [tcl_cv_intrinsics=no])
)
if test "$tcl_cv_intrinsics" = "yes"; then
    AC_DEFINE(HAVE_INTRIN_H, 1,
	    [Defined when the compilers supports intrinsics])
fi

# See if the <wspiapi.h> header file is present

AC_CACHE_CHECK(for wspiapi.h,
    tcl_cv_wspiapi_h,
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <wspiapi.h>
]], [[]])],
    [tcl_cv_wspiapi_h=yes],
    [tcl_cv_wspiapi_h=no])
)
if test "$tcl_cv_wspiapi_h" = "yes"; then
    AC_DEFINE(HAVE_WSPIAPI_H, 1,
	    [Defined when wspiapi.h exists])
fi

# See if declarations like FINDEX_INFO_LEVELS are
# missing from winbase.h. This is known to be
# a problem with VC++ 5.2.

AC_CACHE_CHECK(for FINDEX_INFO_LEVELS in winbase.h,
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
  FINDEX_SEARCH_OPS j;
]])],
    [tcl_cv_findex_enums=yes],
    [tcl_cv_findex_enums=no])
)
if test "$tcl_cv_findex_enums" = "no"; then
    AC_DEFINE(HAVE_NO_FINDEX_ENUMS, 1,
            [Defined when enums are missing from winbase.h])
fi

#--------------------------------------------------------------------
# Set the default compiler switches based on the --enable-symbols
# option.  This macro depends on C flags, and should be called
# after SC_CONFIG_CFLAGS macro is called.
#--------------------------------------------------------------------







|







285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
  FINDEX_SEARCH_OPS j;
]])],
    [tcl_cv_findex_enums=yes],
    [tcl_cv_findex_enums=no])
)
if test "$tcl_cv_findex_enums" = "no"; then
    AC_DEFINE(HAVE_NO_FINDEX_ENUMS, 1,
	    [Defined when enums are missing from winbase.h])
fi

#--------------------------------------------------------------------
# Set the default compiler switches based on the --enable-symbols
# option.  This macro depends on C flags, and should be called
# after SC_CONFIG_CFLAGS macro is called.
#--------------------------------------------------------------------
Changes to win/makefile.vc.
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482

LIBTCLVFSSUBDIR = libtcl.vfs
LIBTCLVFS = $(OUT_DIR)\$(LIBTCLVFSSUBDIR)

# Additional include and C macro definitions for the implicit rules
# defined in rules.vc
PRJ_INCLUDES	= -I"$(TOMMATHDIR)"
PRJ_DEFINES	= /DMP_PREC=4 /Dinline=__inline /DHAVE_ZLIB=1 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /DMP_FIXED_CUTOFFS

!if $(STATIC_BUILD)
PRJ_DEFINES = $(PRJ_DEFINES) /DTCL_WITH_INTERNAL_ZLIB
!endif

# Additional Link libraries needed beyond those in rules.vc
PRJ_LIBS   = netapi32.lib user32.lib userenv.lib ws2_32.lib







|







468
469
470
471
472
473
474
475
476
477
478
479
480
481
482

LIBTCLVFSSUBDIR = libtcl.vfs
LIBTCLVFS = $(OUT_DIR)\$(LIBTCLVFSSUBDIR)

# Additional include and C macro definitions for the implicit rules
# defined in rules.vc
PRJ_INCLUDES	= -I"$(TOMMATHDIR)"
PRJ_DEFINES	= /DMP_PREC=4 /Dinline=__inline /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /DMP_FIXED_CUTOFFS

!if $(STATIC_BUILD)
PRJ_DEFINES = $(PRJ_DEFINES) /DTCL_WITH_INTERNAL_ZLIB
!endif

# Additional Link libraries needed beyond those in rules.vc
PRJ_LIBS   = netapi32.lib user32.lib userenv.lib ws2_32.lib
Changes to win/nmakehlp.c.
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
			&dwWritten, NULL);
		return 2;
	    }
	    return CheckForCompilerFeature(argv[2]);
	case 'l':
	    if (argc < 3) {
		chars = snprintf(msg, sizeof(msg) - 1,
	       		"usage: %s -l <linker option> ?<mandatory option> ...?\n"
			"Tests for whether link.exe supports an option\n"
			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
			&dwWritten, NULL);
		return 2;
	    }
	    return CheckForLinkerFeature(&argv[2], argc-2);







|







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
			&dwWritten, NULL);
		return 2;
	    }
	    return CheckForCompilerFeature(argv[2]);
	case 'l':
	    if (argc < 3) {
		chars = snprintf(msg, sizeof(msg) - 1,
			"usage: %s -l <linker option> ?<mandatory option> ...?\n"
			"Tests for whether link.exe supports an option\n"
			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
			&dwWritten, NULL);
		return 2;
	    }
	    return CheckForLinkerFeature(&argv[2], argc-2);
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
    const char *substring)
{
    return (strstr(string, substring) != NULL);
}

/*
 * GetVersionFromFile --
 * 	Looks for a match string in a file and then returns the version
 * 	following the match where a version is anything acceptable to
 * 	package provide or package ifneeded.
 */

static const char *
GetVersionFromFile(
    const char *filename,
    const char *match,
    int numdots)







|
|
|







489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
    const char *substring)
{
    return (strstr(string, substring) != NULL);
}

/*
 * GetVersionFromFile --
 *	Looks for a match string in a file and then returns the version
 *	following the match where a version is anything acceptable to
 *	package provide or package ifneeded.
 */

static const char *
GetVersionFromFile(
    const char *filename,
    const char *match,
    int numdots)
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
    int keylen, ret;
    WIN32_FIND_DATA finfo;

    if (dir == NULL || keypath == NULL) {
	return 2; /* Have no real error reporting mechanism into nmake */
    }
    dirlen = strlen(dir);
    if ((dirlen + 3) > sizeof(path)) {
	return 2;
    }
    strncpy(path, dir, dirlen);
    strncpy(path+dirlen, "\\*", 3);	/* Including terminating \0 */
    keylen = strlen(keypath);

#if 0 /* This function is not available in Visual C++ 6 */







|







726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
    int keylen, ret;
    WIN32_FIND_DATA finfo;

    if (dir == NULL || keypath == NULL) {
	return 2; /* Have no real error reporting mechanism into nmake */
    }
    dirlen = strlen(dir);
    if (dirlen > sizeof(path) - 3) {
	return 2;
    }
    strncpy(path, dir, dirlen);
    strncpy(path+dirlen, "\\*", 3);	/* Including terminating \0 */
    keylen = strlen(keypath);

#if 0 /* This function is not available in Visual C++ 6 */
Changes to win/rules.vc.
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
!ifndef _RULES_VC
_RULES_VC = 1

# The following macros define the version of the rules.vc nmake build system
# For modifications that are not backward-compatible, you *must* change
# the major version.
RULES_VERSION_MAJOR = 1
RULES_VERSION_MINOR = 11

# The PROJECT macro must be defined by parent makefile.
!if "$(PROJECT)" == ""
!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
!endif

!if "$(PRJ_PACKAGE_TCLNAME)" == ""







|







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
!ifndef _RULES_VC
_RULES_VC = 1

# The following macros define the version of the rules.vc nmake build system
# For modifications that are not backward-compatible, you *must* change
# the major version.
RULES_VERSION_MAJOR = 1
RULES_VERSION_MINOR = 12

# The PROJECT macro must be defined by parent makefile.
!if "$(PROJECT)" == ""
!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
!endif

!if "$(PRJ_PACKAGE_TCLNAME)" == ""
1290
1291
1292
1293
1294
1295
1296

1297
1298
1299
1300
1301
1302
1303
1304

!endif # $(DOING_TK)
!endif # $(DOING_TK) || $(NEED_TK)

# Various output paths
PRJIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
PRJLIBNAME8	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)

PRJLIBNAME9	= tcl9$(PROJECT)$(VERSION)$(SUFX).$(EXT)
!if $(TCL_MAJOR_VERSION) == 8 || "$(TCL_BUILD_FOR)" == "8"
PRJLIBNAME	= $(PRJLIBNAME8)
!else
PRJLIBNAME	= $(PRJLIBNAME9)
!endif
PRJLIB		= $(OUT_DIR)\$(PRJLIBNAME)








>
|







1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305

!endif # $(DOING_TK)
!endif # $(DOING_TK) || $(NEED_TK)

# Various output paths
PRJIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
PRJLIBNAME8	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
# Even when building against Tcl 8, PRJLIBNAME9 must not have "t"
PRJLIBNAME9	= tcl9$(PROJECT)$(VERSION)$(SUFX:t=).$(EXT)
!if $(TCL_MAJOR_VERSION) == 8 || "$(TCL_BUILD_FOR)" == "8"
PRJLIBNAME	= $(PRJLIBNAME8)
!else
PRJLIBNAME	= $(PRJLIBNAME9)
!endif
PRJLIB		= $(OUT_DIR)\$(PRJLIBNAME)

Changes to win/tclWinChan.c.
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
    TclFile readFile = NULL, writeFile = NULL;

    nativeName = (const WCHAR *)Tcl_FSGetNativePath(pathPtr);
    if (nativeName == NULL) {
	if (interp) {
	    /*
	     * We need this just to ensure we return the correct error messages under
	     * some circumstances (relative paths only), so because the normalization 
	     * is very expensive, don't invoke it for native or absolute paths.
	     * Note: since paths starting with ~ are relative in 9.0 for windows,
	     * it doesn't need to consider tilde expansion (in opposite to 8.x).
	     */
	    if (
		(
		    !TclFSCwdIsNative() &&







|







995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
    TclFile readFile = NULL, writeFile = NULL;

    nativeName = (const WCHAR *)Tcl_FSGetNativePath(pathPtr);
    if (nativeName == NULL) {
	if (interp) {
	    /*
	     * We need this just to ensure we return the correct error messages under
	     * some circumstances (relative paths only), so because the normalization
	     * is very expensive, don't invoke it for native or absolute paths.
	     * Note: since paths starting with ~ are relative in 9.0 for windows,
	     * it doesn't need to consider tilde expansion (in opposite to 8.x).
	     */
	    if (
		(
		    !TclFSCwdIsNative() &&
Changes to win/tclWinInit.c.
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/*
 *---------------------------------------------------------------------------
 *
 * AppendEnvironment --
 *
 *	Append the value of the TCL_LIBRARY environment variable onto the path
 *	pointer. If the env variable points to another version of tcl (e.g.
 *	"tcl7.6") also append the path to this version (e.g.,
 *	"tcl7.6/../tcl8.2")
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *







|
|







177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/*
 *---------------------------------------------------------------------------
 *
 * AppendEnvironment --
 *
 *	Append the value of the TCL_LIBRARY environment variable onto the path
 *	pointer. If the env variable points to another version of tcl (e.g.
 *	"tcl8.6") also append the path to this version (e.g.,
 *	"tcl8.6/../tcl9.0")
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
    Tcl_Obj *objPtr;
    Tcl_DString ds;
    const char **pathv;
    char *shortlib;

    /*
     * The shortlib value needs to be the tail component of the lib path. For
     * example, "lib/tcl8.4" -> "tcl8.4" while "usr/share/tcl8.5" -> "tcl8.5".
     */

    for (shortlib = (char *) &lib[strlen(lib)-1]; shortlib>lib ; shortlib--) {
	if (*shortlib == '/') {
	    if ((size_t)(shortlib - lib) == strlen(lib) - 1) {
		Tcl_Panic("last character in lib cannot be '/'");
	    }







|







204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
    Tcl_Obj *objPtr;
    Tcl_DString ds;
    const char **pathv;
    char *shortlib;

    /*
     * The shortlib value needs to be the tail component of the lib path. For
     * example, "lib/tcl9.0" -> "tcl9.0" while "usr/share/tcl9.0" -> "tcl9.0".
     */

    for (shortlib = (char *) &lib[strlen(lib)-1]; shortlib>lib ; shortlib--) {
	if (*shortlib == '/') {
	    if ((size_t)(shortlib - lib) == strlen(lib) - 1) {
		Tcl_Panic("last character in lib cannot be '/'");
	    }
Changes to win/vctool.bat.
1
2
3
4
5
6
7
8
9
10
11


12
13
14
15
16
17
18
@echo off
REM Pass /? as argument for usage.

IF DEFINED VCINSTALLDIR goto setup

echo "Not in a Visual Studio command prompt."
exit /B 1


:setup
setlocal



REM Get the current directory
set "currentDir=%CD%"

REM Use FOR command to get the parent directory
for %%I in ("%currentDir%") do set "parentDir=%%~dpI"









<


>
>







1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16
17
18
19
@echo off
REM Pass /? as argument for usage.

IF DEFINED VCINSTALLDIR goto setup

echo "Not in a Visual Studio command prompt."
exit /B 1


:setup
setlocal

set "tool=%0"

REM Get the current directory
set "currentDir=%CD%"

REM Use FOR command to get the parent directory
for %%I in ("%currentDir%") do set "parentDir=%%~dpI"

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
if "%1" == "static" goto static
if "%1" == "shared_noembed" goto shared_noembed
if "%1" == "static_noembed" goto static_noembed
if "%1" == "compile" goto compile
if "%1" == "test" goto targets
if "%1" == "install" goto targets
if "%1" == "runshell" goto targets
if "%1" == "pdbs" goto pdbs
goto help

:pdbs
set pdbs=1
shift
goto options

:shared
set shared=1
shift
goto options







|


|
|







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
if "%1" == "static" goto static
if "%1" == "shared_noembed" goto shared_noembed
if "%1" == "static_noembed" goto static_noembed
if "%1" == "compile" goto compile
if "%1" == "test" goto targets
if "%1" == "install" goto targets
if "%1" == "runshell" goto targets
if "%1" == "debug" goto debug
goto help

:debug
set debug=1
shift
goto options

:shared
set shared=1
shift
goto options
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

:error
endlocal
exit /b 1

:: call :runmake dir opts
:runmake
if "%pdbs%" == "" (
    nmake /s /f makefile.vc OUT_DIR=%currentDir%\vc-%ARCH%-%1 TMP_DIR=%currentDir%\vc-%ARCH%-%1\objs OPTS=pdbs,%2 INSTALLDIR=%INSTROOT%-%1 %TARGETS% && goto error
) else (
    nmake /s /f makefile.vc OUT_DIR=%currentDir%\vc-%ARCH%-%1-debug TMP_DIR=%currentDir%\vc-%ARCH%-%1-debug\objs OPTS=pdbs,%2 cdebug="-Zi -Od" INSTALLDIR=%INSTROOT%-%1-debug %TARGETS% && goto error
)
goto eof

:help







|







127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

:error
endlocal
exit /b 1

:: call :runmake dir opts
:runmake
if "%debug%" == "" (
    nmake /s /f makefile.vc OUT_DIR=%currentDir%\vc-%ARCH%-%1 TMP_DIR=%currentDir%\vc-%ARCH%-%1\objs OPTS=pdbs,%2 INSTALLDIR=%INSTROOT%-%1 %TARGETS% && goto error
) else (
    nmake /s /f makefile.vc OUT_DIR=%currentDir%\vc-%ARCH%-%1-debug TMP_DIR=%currentDir%\vc-%ARCH%-%1-debug\objs OPTS=pdbs,%2 cdebug="-Zi -Od" INSTALLDIR=%INSTROOT%-%1-debug %TARGETS% && goto error
)
goto eof

:help
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
echo If environment variable TCLINSTALLROOT is defined, install target
echo will be subdirectory under it named after the grandparent of the
echo current directory. TCLINSTALLROOT defaults to the X:\Tcl where
echo X is the current drive.
echo.
echo For example, if the current directory C:\src\core-8-branch\tcl\win,
echo install directories will be echo under c:\Tcl\core-8-branch\ as
echo x64-shared, x64-static etc. or x64-shared-debug etc. if "pdbs" passed.
echo.
echo Examples:
echo    %0 shared                       (Builds default "shared" config)
echo    %0 shared test                  (Tests shared build)
echo    %0 static compile test          (Builds and tests static build)
echo    %0 all debug                    (Build debug versions of all configs)
echo    %0 all compile install debug    (Builds and installs all configs)
echo    %0 shared static shared_noembed (Builds three configs)
goto done







|


|
|
|
|
|
|

158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
echo If environment variable TCLINSTALLROOT is defined, install target
echo will be subdirectory under it named after the grandparent of the
echo current directory. TCLINSTALLROOT defaults to the X:\Tcl where
echo X is the current drive.
echo.
echo For example, if the current directory C:\src\core-8-branch\tcl\win,
echo install directories will be echo under c:\Tcl\core-8-branch\ as
echo x64-shared, x64-static etc. or x64-shared-debug etc. if "debug" passed.
echo.
echo Examples:
echo    %tool% shared                       (Builds default "shared" config)
echo    %tool% shared test                  (Tests shared build)
echo    %tool% static compile test          (Builds and tests static build)
echo    %tool% all debug                    (Build debug versions of all configs)
echo    %tool% all compile install debug    (Builds and installs all configs)
echo    %tool% shared static shared_noembed (Builds three configs)
goto done