Tcl Source Code

Check-in [5d027d1163]
Login
Bounty program for improvements to Tcl and certain Tcl packages.

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

Overview
Comment:Merge trunk
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | novem
Files: files | file ages | folders
SHA3-256: 5d027d116399d1b3c3fc2afc6c1a764e05104d7b2a101eab45b9b4acfc5686fb
User & Date: jan.nijtmans 2020-06-29 10:39:27
Context
2020-06-29
10:39
Merge trunk Leaf check-in: 5d027d1163 user: jan.nijtmans tags: novem
10:38
Merge 8.7 check-in: a056d0ed75 user: jan.nijtmans tags: trunk
2020-06-23
06:21
Merge trunk check-in: 2c5fa114f8 user: jan.nijtmans tags: novem
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to .fossil-settings/ignore-glob.

9
10
11
12
13
14
15

16
17
18
19
20
21
22
..
38
39
40
41
42
43
44

45
46






47
48


49
50
51
52
53
54
55
56
*.o
*.obj
*.pdb
*.res
*.sl
*.so
*/Makefile

*/config.cache
*/config.log
*/config.status
*/tclConfig.sh
*/tclsh*
*/tcltest*
*/versions.vc
................................................................................
libtommath/pics/*
libtommath/mtest/*
libtommath/logs/*
libtommath/etc/*
libtommath/demo/*
libtommath/*.out
libtommath/*.tex

unix/autoMkindex.tcl
unix/dltest.marker






unix/tcl.pc
unix/tclIndex


unix/pkgs/*
win/Debug*
win/Release*
win/*.manifest
win/pkgs/*
win/coffbase.txt
win/tcl.hpj
win/nmhlp-out.txt







>







 







>


>
>
>
>
>
>


>
>








9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
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
*.o
*.obj
*.pdb
*.res
*.sl
*.so
*/Makefile
*/autom4te.cache
*/config.cache
*/config.log
*/config.status
*/tclConfig.sh
*/tclsh*
*/tcltest*
*/versions.vc
................................................................................
libtommath/pics/*
libtommath/mtest/*
libtommath/logs/*
libtommath/etc/*
libtommath/demo/*
libtommath/*.out
libtommath/*.tex
macosx/configure
unix/autoMkindex.tcl
unix/dltest.marker
unix/dltest/*.bundle
unix/dltest/*.dll
unix/dltest/*.dylib
unix/dltest/*.o
unix/dltest/*.sl
unix/dltest/*.so
unix/tcl.pc
unix/tclIndex
unix/Tcl-Info.plist
unix/Tclsh-Info.plist
unix/pkgs/*
win/Debug*
win/Release*
win/*.manifest
win/pkgs/*
win/coffbase.txt
win/tcl.hpj
win/nmhlp-out.txt

Added .fossil-settings/manifest.



>
1
u

Changes to .gitignore.

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
..
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53
54
55
56
57
*.a

*.dll
*.dylib
*.exe
*.exp
*.lib
*.o
*.obj
*.pdb
*.res
*.sl
*.so

*/Makefile


*/config.cache
*/config.log
*/config.status
*/config.status.lineno



*/tclConfig.sh
*/tclsh*
*/tcltest*
*/versions.vc
*/version.vc
*/libtcl.vfs
*/libtcl_*.zip
.fslckout
_FOSSIL_
html
libtommath/bn.ilg
libtommath/bn.ind
libtommath/pretty.build
libtommath/tommath.src
libtommath/*.log
libtommath/*.pdf
libtommath/*.pl
................................................................................
libtommath/pics/*
libtommath/mtest/*
libtommath/logs/*
libtommath/etc/*
libtommath/demo/*
libtommath/*.out
libtommath/*.tex

unix/autoMkindex.tcl
unix/dltest.marker
unix/tcl.pc
unix/tclIndex
unix/pkgs/*
win/Debug*
win/Release*
win/*.manifest
win/pkgs/*
win/coffbase.txt
win/tcl.hpj
win/nmhlp-out.txt

>











>
|
>
>
|
|
|
|
>
>
>







<
<
<







 







>












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
..
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
*.a
*.bundle
*.dll
*.dylib
*.exe
*.exp
*.lib
*.o
*.obj
*.pdb
*.res
*.sl
*.so
.fslckout
Makefile
Tcl-Info.plist
autom4te.cache
config.cache
config.log
config.status
config.status.lineno
html
manifest.uuid
_FOSSIL_
*/tclConfig.sh
*/tclsh*
*/tcltest*
*/versions.vc
*/version.vc
*/libtcl.vfs
*/libtcl_*.zip



libtommath/bn.ilg
libtommath/bn.ind
libtommath/pretty.build
libtommath/tommath.src
libtommath/*.log
libtommath/*.pdf
libtommath/*.pl
................................................................................
libtommath/pics/*
libtommath/mtest/*
libtommath/logs/*
libtommath/etc/*
libtommath/demo/*
libtommath/*.out
libtommath/*.tex
macosx/configure
unix/autoMkindex.tcl
unix/dltest.marker
unix/tcl.pc
unix/tclIndex
unix/pkgs/*
win/Debug*
win/Release*
win/*.manifest
win/pkgs/*
win/coffbase.txt
win/tcl.hpj
win/nmhlp-out.txt

Changes to .travis.yml.

378
379
380
381
382
383
384









385
386
387
388
389
390
391
392
393
394
395
    - name: "Windows/GCC-x86/Mem-Debug"
      os: windows
      compiler: gcc
      env:
        - BUILD_DIR=win
        - CFGOPT="--enable-symbols=mem"
      before_install: *makepreinst









before_install:
  - cd ${BUILD_DIR}
install:
  - mkdir "$HOME/install dir"
  - ./configure ${CFGOPT} "--prefix=$HOME/install dir" || (cat config.log && exit 1)
before_script:
  - export ERROR_ON_FAILURES=1
script:
  - make all tcltest
  - make test
  - make install







>
>
>
>
>
>
>
>
>











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
    - name: "Windows/GCC-x86/Mem-Debug"
      os: windows
      compiler: gcc
      env:
        - BUILD_DIR=win
        - CFGOPT="--enable-symbols=mem"
      before_install: *makepreinst
# "make dist" only
    - name: "Linux: make dist"
      os: linux
      dist: bionic
      compiler: gcc
      env:
        - BUILD_DIR=unix
      script:
        - make dist
before_install:
  - cd ${BUILD_DIR}
install:
  - mkdir "$HOME/install dir"
  - ./configure ${CFGOPT} "--prefix=$HOME/install dir" || (cat config.log && exit 1)
before_script:
  - export ERROR_ON_FAILURES=1
script:
  - make all tcltest
  - make test
  - make install

Changes to compat/strstr.c.

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
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
strstr(
    char *string,		/* String to search. */
    char *substring)		/* Substring to try to find in string. */
{
    char *a, *b;

    /*
     * First scan quickly through the two strings looking for a
     * single-character match. When it's found, then compare the rest of the
     * substring.
     */

    b = substring;
    if (*b == 0) {
	return string;
    }
    for ( ; *string != 0; string += 1) {
	if (*string != *b) {
	    continue;
	}
	a = string;
	while (1) {
	    if (*b == 0) {
		return string;
	    }
	    if (*a++ != *b++) {
		break;
	    }
	}
	b = substring;
    }
    return NULL;
}







|
|

|









|








|









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
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
strstr(
    const char *string,		/* String to search. */
    const char *substring)		/* Substring to try to find in string. */
{
    const char *a, *b;

    /*
     * First scan quickly through the two strings looking for a
     * single-character match. When it's found, then compare the rest of the
     * substring.
     */

    b = substring;
    if (*b == 0) {
	return (char *)string;
    }
    for ( ; *string != 0; string += 1) {
	if (*string != *b) {
	    continue;
	}
	a = string;
	while (1) {
	    if (*b == 0) {
		return (char *)string;
	    }
	    if (*a++ != *b++) {
		break;
	    }
	}
	b = substring;
    }
    return NULL;
}

Changes to doc/zlib.n.

189
190
191
192
193
194
195
196
197

198
199








200
201
202
203
204
205
206
...
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
\fB\-level\fI compressionLevel\fR
.
How hard to compress the data. Must be an integer from 0 (uncompressed) to 9
(maximally compressed).
.TP
\fB\-limit\fI readaheadLimit\fR
.
The maximum number of bytes ahead to read when decompressing. This defaults to
1, which ensures that data is always decompressed correctly, but may be

increased to improve performance. This is more useful when the channel is
non-blocking.








.PP
Both compressing and decompressing channel transformations add extra
configuration options that may be accessed through \fBchan configure\fR. The
options are:
.TP
\fB\-checksum\fI checksum\fR
.
................................................................................
This read-only option, only valid for decompressing transforms that are
processing gzip-format data, returns the dictionary describing the header read
off the data stream.
.TP
\fB\-limit\fI readaheadLimit\fR
.
This read-write option is used by decompressing channels to control the
maximum number of bytes ahead to read from the underlying data source. This
defaults to 1, which ensures that data is always decompressed correctly, but
may be increased to improve performance. This is more useful when the channel
is non-blocking.
.RE
.SS "STREAMING SUBCOMMAND"
.TP
\fBzlib stream\fI mode\fR ?\fIoptions\fR?
.
Creates a streaming compression or decompression command based on the
\fImode\fR, and return the name of the command. For a description of how that







|
<
>
|
|
>
>
>
>
>
>
>
>







 







|
|
<
<







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
...
242
243
244
245
246
247
248
249
250


251
252
253
254
255
256
257
\fB\-level\fI compressionLevel\fR
.
How hard to compress the data. Must be an integer from 0 (uncompressed) to 9
(maximally compressed).
.TP
\fB\-limit\fI readaheadLimit\fR
.
The maximum number of bytes ahead to read when decompressing.

.RS
.PP
This option has become \fBirrelevant\fR. It was originally introduced
to prevent Tcl from reading beyond the end of a compressed stream in
multi-stream channels to ensure that the data after was left alone for
further reading, at the cost of speed.
.PP
Tcl now automatically returns any bytes it has read beyond the end of
a compressed stream back to the channel, making them appear as unread
to further readers.
.RE
.PP
Both compressing and decompressing channel transformations add extra
configuration options that may be accessed through \fBchan configure\fR. The
options are:
.TP
\fB\-checksum\fI checksum\fR
.
................................................................................
This read-only option, only valid for decompressing transforms that are
processing gzip-format data, returns the dictionary describing the header read
off the data stream.
.TP
\fB\-limit\fI readaheadLimit\fR
.
This read-write option is used by decompressing channels to control the
maximum number of bytes ahead to read from the underlying data source. See
above for more information.


.RE
.SS "STREAMING SUBCOMMAND"
.TP
\fBzlib stream\fI mode\fR ?\fIoptions\fR?
.
Creates a streaming compression or decompression command based on the
\fImode\fR, and return the name of the command. For a description of how that

Changes to generic/tclDate.c.

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
...
205
206
207
208
209
210
211



212
213
214
215
216
217
218
 * Meridian: am, pm, or 24-hour style.
 */

typedef enum _MERIDIAN {
    MERam, MERpm, MER24
} MERIDIAN;




/*
 * yyparse will accept a 'struct DateInfo' as its parameter; that's where the
 * parsed fields will be returned.
 */

typedef struct DateInfo {

................................................................................
/*
 * Daylight-savings mode: on, off, or not yet known.
 */

typedef enum _DSTMODE {
    DSTon, DSToff, DSTmaybe
} DSTMODE;




# ifndef YY_NULLPTR
#  if defined __cplusplus && 201103L <= __cplusplus
#   define YY_NULLPTR nullptr
#  else
#   define YY_NULLPTR 0
#  endif







<
<
<







 







>
>
>







98
99
100
101
102
103
104



105
106
107
108
109
110
111
...
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
 * Meridian: am, pm, or 24-hour style.
 */

typedef enum _MERIDIAN {
    MERam, MERpm, MER24
} MERIDIAN;




/*
 * yyparse will accept a 'struct DateInfo' as its parameter; that's where the
 * parsed fields will be returned.
 */

typedef struct DateInfo {

................................................................................
/*
 * Daylight-savings mode: on, off, or not yet known.
 */

typedef enum _DSTMODE {
    DSTon, DSToff, DSTmaybe
} DSTMODE;




# ifndef YY_NULLPTR
#  if defined __cplusplus && 201103L <= __cplusplus
#   define YY_NULLPTR nullptr
#  else
#   define YY_NULLPTR 0
#  endif

Changes to generic/tclGetDate.y.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

%parse-param {DateInfo* info}
%lex-param {DateInfo* info}
%pure-parser
 /* %error-verbose would be nice, but our token names are meaningless */
%locations

%{
/*
 * tclDate.c --
 *
................................................................................

    if (objc != 5) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"stringToParse baseYear baseMonth baseDay" );
	return TCL_ERROR;
    }

    yyInput = Tcl_GetString( objv[1] );
    dateInfo.dateStart = yyInput;

    yyHaveDate = 0;
    if (Tcl_GetIntFromObj(interp, objv[2], &yr) != TCL_OK
	    || Tcl_GetIntFromObj(interp, objv[3], &mo) != TCL_OK
	    || Tcl_GetIntFromObj(interp, objv[4], &da) != TCL_OK) {
	return TCL_ERROR;







|







 







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

%parse-param {DateInfo* info}
%lex-param {DateInfo* info}
%define api.pure
 /* %error-verbose would be nice, but our token names are meaningless */
%locations

%{
/*
 * tclDate.c --
 *
................................................................................

    if (objc != 5) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"stringToParse baseYear baseMonth baseDay" );
	return TCL_ERROR;
    }

    yyInput = TclGetString(objv[1]);
    dateInfo.dateStart = yyInput;

    yyHaveDate = 0;
    if (Tcl_GetIntFromObj(interp, objv[2], &yr) != TCL_OK
	    || Tcl_GetIntFromObj(interp, objv[3], &mo) != TCL_OK
	    || Tcl_GetIntFromObj(interp, objv[4], &da) != TCL_OK) {
	return TCL_ERROR;

Changes to generic/tclZlib.c.

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
...
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
....
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
....
3001
3002
3003
3004
3005
3006
3007









3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
....
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
....
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
....
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
....
3710
3711
3712
3713
3714
3715
3716



3717
3718
3719
3720
3721
3722
3723
....
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
....
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
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839

3840
3841
3842
3843
3844
3845


3846
3847
3848
3849
3850
3851
3852

3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865

3866
3867

3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898





3899
3900







3901
3902
3903
3904
3905
3906
3907
....
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923










3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
    int mode;			/* Either the value TCL_ZLIB_STREAM_DEFLATE
				 * for compression on output, or
				 * TCL_ZLIB_STREAM_INFLATE for decompression
				 * on input. */
    int format;			/* What format of data is going on the wire.
				 * Needed so that the correct [fconfigure]
				 * options can be enabled. */
    int readAheadLimit;		/* The maximum number of bytes to read from
				 * the underlying stream in one go. */
    z_stream inStream;		/* Structure used by zlib for decompression of
				 * input. */
    z_stream outStream;		/* Structure used by zlib for compression of
				 * output. */
    char *inBuffer, *outBuffer;	/* Working buffers. */
    size_t inAllocated, outAllocated;
				/* Sizes of working buffers. */
    GzipHeader inHeader;	/* Header read from input stream, when
				 * decompressing a gzip stream. */
    GzipHeader outHeader;	/* Header to write to an output stream, when
				 * compressing a gzip stream. */
    Tcl_TimerToken timer;	/* Timer used for keeping events fresh. */
    Tcl_DString decompressed;	/* Buffer for decompression results. */
    Tcl_Obj *compDictObj;	/* Byte-array object containing compression
				 * dictionary (not dictObj!) to use if
				 * necessary. */
} ZlibChannelData;

/*
 * Value bits for the flags field. Definitions are:
 *	ASYNC -		Whether this is an asynchronous channel.
 *	IN_HEADER -	Whether the inHeader field has been registered with
 *			the input compressor.
 *	OUT_HEADER -	Whether the outputHeader field has been registered
 *			with the output decompressor.


 */

#define ASYNC			0x1
#define IN_HEADER		0x2
#define OUT_HEADER		0x4



/*
 * Size of buffers allocated by default, and the range it can be set to.  The
 * same sorts of values apply to streams, except with different limits (they
 * permit byte-level activity). Channels always use bytes unless told to use
 * larger buffers.
 */
................................................................................
static inline int	Deflate(z_streamp strm, void *bufferPtr,
			    size_t bufferSize, int flush, size_t *writtenPtr);
static void		ExtractHeader(gz_header *headerPtr, Tcl_Obj *dictObj);
static int		GenerateHeader(Tcl_Interp *interp, Tcl_Obj *dictObj,
			    GzipHeader *headerPtr, int *extraSizePtr);
static int		ZlibPushSubcmd(Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static inline int	ResultCopy(ZlibChannelData *cd, char *buf,
			    size_t toRead);
static int		ResultGenerate(ZlibChannelData *cd, int n, int flush,
			    int *errorCodePtr);
static Tcl_Channel	ZlibStackChannelTransform(Tcl_Interp *interp,
			    int mode, int format, int level, int limit,
			    Tcl_Channel channel, Tcl_Obj *gzipHeaderDictPtr,
			    Tcl_Obj *compDictObj);
static void		ZlibStreamCleanup(ZlibStreamHandle *zshPtr);
static int		ZlibStreamSubcmd(Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
................................................................................
    };
    static const char *const pushDecompressOptions[] = {
	"-dictionary", "-header", "-level", "-limit", NULL
    };
    const char *const *pushOptions = pushDecompressOptions;
    enum pushOptions {poDictionary, poHeader, poLevel, poLimit};
    Tcl_Obj *headerObj = NULL, *compDictObj = NULL;
    int limit = 1, dummy;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "mode channel ?options...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[2], stream_formats, "mode", 0,
................................................................................
		}
		result = TCL_ERROR;
		break;
	    }
	} while (e != Z_STREAM_END);
	(void) deflateEnd(&cd->outStream);
    } else {









	(void) inflateEnd(&cd->inStream);
    }

    /*
     * Release all memory.
     */

    if (cd->compDictObj) {
	Tcl_DecrRefCount(cd->compDictObj);
	cd->compDictObj = NULL;
    }
    Tcl_DStringFree(&cd->decompressed);

    if (cd->inBuffer) {
	Tcl_Free(cd->inBuffer);
	cd->inBuffer = NULL;
    }
    if (cd->outBuffer) {
	Tcl_Free(cd->outBuffer);
................................................................................
    char *buf,
    int toRead,
    int *errorCodePtr)
{
    ZlibChannelData *cd = (ZlibChannelData *)instanceData;
    Tcl_DriverInputProc *inProc =
	    Tcl_ChannelInputProc(Tcl_GetChannelType(cd->parent));
    int readBytes, gotBytes, copied;

    if (cd->mode == TCL_ZLIB_STREAM_DEFLATE) {
	return inProc(Tcl_GetChannelInstanceData(cd->parent), buf, toRead,
		errorCodePtr);
    }

    gotBytes = 0;
    while (toRead > 0) {
	/*
	 * Loop until the request is satisfied (or no data available from
	 * below, possibly EOF).
	 */

	copied = ResultCopy(cd, buf, toRead);
	toRead -= copied;
	buf += copied;
	gotBytes += copied;

	if (toRead == 0) {
	    return gotBytes;
	}


	/*
	 * The buffer is exhausted, but the caller wants even more. We now
	 * have to go to the underlying channel, get more bytes and then
	 * transform them for delivery. We may not get what we want (full EOF
	 * or temporarily out of data).
	 *
	 * Length (cd->decompressed) == 0, toRead > 0 here.
	 *

	 * The zlib transform allows us to read at most one character from the
	 * underlying channel to properly identify Z_STREAM_END without
	 * reading over the border.

	 */






	readBytes = Tcl_ReadRaw(cd->parent, cd->inBuffer, cd->readAheadLimit);

	/*
	 * Three cases here:
	 *  1.	Got some data from the underlying channel (readBytes > 0) so
	 *	it should be fed through the decompression engine.
	 *  2.	Got an error (readBytes == -1) which we should report up except
	 *	for the case where we can convert it to a short read.
................................................................................
	 *	it is EOF, try flushing the data out of the decompressor.
	 */

	if (readBytes == -1) {

	    /* See ReflectInput() in tclIORTrans.c */
	    if (Tcl_InputBlocked(cd->parent) && (gotBytes > 0)) {
		return gotBytes;
	    }

	    *errorCodePtr = Tcl_GetErrno();
	    return -1;
	}

	if (readBytes == 0) {
	    /*
	     * Eof in parent.
	     *
	     * Now this is a bit different. The partial data waiting is






	     * converted and returned.
	     */

	    if (ResultGenerate(cd, 0, Z_SYNC_FLUSH, errorCodePtr) != TCL_OK) {




		return -1;
	    }




	    if (Tcl_DStringLength(&cd->decompressed) == 0) {

		/*

		 * The drain delivered nothing. Time to deliver what we've
		 * got.
		 */







		return gotBytes;
	    }
	} else /* readBytes > 0 */ {



	    /*
	     * Transform the read chunk, which was not empty. Anything we get
	     * back is a transformation result to be put into our buffers, and
	     * the next iteration will put it into the result.


	     */

	    if (ResultGenerate(cd, readBytes, Z_NO_FLUSH,
		    errorCodePtr) != TCL_OK) {
		return -1;
	    }
	}
    }
    return gotBytes;
}
 
/*
 *----------------------------------------------------------------------
 *
 * ZlibTransformOutput --
................................................................................
    /*
     * This code is based on the code in tclIORTrans.c
     */

    watchProc = Tcl_ChannelWatchProc(Tcl_GetChannelType(cd->parent));
    watchProc(Tcl_GetChannelInstanceData(cd->parent), mask);

    if (!(mask & TCL_READABLE) || Tcl_DStringLength(&cd->decompressed) == 0) {
	ZlibTransformEventTimerKill(cd);
    } else if (cd->timer == NULL) {
	cd->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME,
		ZlibTransformTimerRun, cd);
    }
}

................................................................................
     */

    if (mode == TCL_ZLIB_STREAM_INFLATE) {
	if (inflateInit2(&cd->inStream, wbits) != Z_OK) {
	    goto error;
	}
	cd->inAllocated = DEFAULT_BUFFER_SIZE;



	cd->inBuffer = (char *)Tcl_Alloc(cd->inAllocated);
	if (cd->flags & IN_HEADER) {
	    if (inflateGetHeader(&cd->inStream, &cd->inHeader.header) != Z_OK) {
		goto error;
	    }
	}
	if (cd->format == TCL_ZLIB_FORMAT_RAW && cd->compDictObj) {
................................................................................
	if (cd->compDictObj) {
	    if (SetDeflateDictionary(&cd->outStream, cd->compDictObj) != Z_OK) {
		goto error;
	    }
	}
    }

    Tcl_DStringInit(&cd->decompressed);

    chan = Tcl_StackChannel(interp, &zlibChannelType, cd,
	    Tcl_GetChannelMode(channel), channel);
    if (chan == NULL) {
	goto error;
    }
    cd->chan = chan;
    cd->parent = Tcl_GetStackedChannel(chan);
................................................................................
    Tcl_Free(cd);
    return NULL;
}
 
/*
 *----------------------------------------------------------------------
 *
 * ResultCopy --
 *
 *	Copies the requested number of bytes from the buffer into the
 *	specified array and removes them from the buffer afterward. Copies
 *	less if there is not enough data in the buffer.
 *
 * Side effects:
 *	See above.
 *
 * Result:
 *	The number of actually copied bytes, possibly less than 'toRead'.
 *
 *----------------------------------------------------------------------
 */

static inline int
ResultCopy(
    ZlibChannelData *cd,	/* The location of the buffer to read from. */
    char *buf,			/* The buffer to copy into */
    size_t toRead)			/* Number of requested bytes */
{
    size_t have = Tcl_DStringLength(&cd->decompressed);

    if (have == 0) {
	/*
	 * Nothing to copy in the case of an empty buffer.
	 */

	return 0;
    } else if (have > toRead) {
	/*
	 * The internal buffer contains more than requested. Copy the
	 * requested subset to the caller, shift the remaining bytes down, and
	 * truncate.
	 */

	char *src = Tcl_DStringValue(&cd->decompressed);

	memcpy(buf, src, toRead);
	memmove(src, src + toRead, have - toRead);

	Tcl_DStringSetLength(&cd->decompressed, have - toRead);
	return toRead;
    } else /* have <= toRead */ {
	/*
	 * There is just or not enough in the buffer to fully satisfy the
	 * caller, so take everything as best effort.
	 */

	memcpy(buf, Tcl_DStringValue(&cd->decompressed), have);
	TclDStringClear(&cd->decompressed);
	return have;
    }
}
 
/*
 *----------------------------------------------------------------------
 *
 * ResultGenerate --
 *
 *	Extract uncompressed bytes from the compression engine and store them
 *	in our working buffer.

 *
 * Result:
 *	TCL_OK/TCL_ERROR (with *errorCodePtr updated with reason).
 *
 * Side effects:
 *	See above.


 *
 *----------------------------------------------------------------------
 */

static int
ResultGenerate(
    ZlibChannelData *cd,

    int n,
    int flush,
    int *errorCodePtr)
{
#define MAXBUF	1024
    unsigned char buf[MAXBUF];
    int e, written;
    Tcl_Obj *errObj;

    cd->inStream.next_in = (Bytef *) cd->inBuffer;
    cd->inStream.avail_in = n;

    while (1) {

	cd->inStream.next_out = (Bytef *) buf;
	cd->inStream.avail_out = MAXBUF;


	e = inflate(&cd->inStream, flush);
	if (e == Z_NEED_DICT && cd->compDictObj) {
	    e = SetInflateDictionary(&cd->inStream, cd->compDictObj);
	    if (e == Z_OK) {
		/*
		 * A repetition of Z_NEED_DICT is just an error.
		 */

		cd->inStream.next_out = (Bytef *) buf;
		cd->inStream.avail_out = MAXBUF;
		e = inflate(&cd->inStream, flush);
	    }
	}

	/*
	 * avail_out is now the left over space in the output.  Therefore
	 * "MAXBUF - avail_out" is the amount of bytes generated.
	 */

	written = MAXBUF - cd->inStream.avail_out;
	if (written) {
	    Tcl_DStringAppend(&cd->decompressed, (char *) buf, written);
	}

	/*
	 * The cases where we're definitely done.
	 */

	if (((flush == Z_SYNC_FLUSH) && (e == Z_BUF_ERROR))
		|| (e == Z_STREAM_END)





		|| (e == Z_OK && written == 0)) {
	    return TCL_OK;







	}

	/*
	 * Z_BUF_ERROR can be ignored as per http://www.zlib.net/zlib_how.html
	 *
	 * Just indicates that the zlib couldn't consume input/produce output,
	 * and is fixed by supplying more input.
................................................................................
	}

	/*
	 * Check if the inflate stopped early.
	 */

	if (cd->inStream.avail_in <= 0 && flush != Z_SYNC_FLUSH) {
	    return TCL_OK;
	}
    }











  handleError:
    errObj = Tcl_NewListObj(0, NULL);
    Tcl_ListObjAppendElement(NULL, errObj, Tcl_NewStringObj("-errorcode",-1));
    Tcl_ListObjAppendElement(NULL, errObj,
	    ConvertErrorToList(e, cd->inStream.adler));
    Tcl_ListObjAppendElement(NULL, errObj,
	    Tcl_NewStringObj(cd->inStream.msg, -1));
    Tcl_SetChannelError(cd->parent, errObj);
    *errorCodePtr = EINVAL;
    return TCL_ERROR;
}
 
/*
 *----------------------------------------------------------------------
 *	Finally, the TclZlibInit function. Used to install the zlib API.
 *----------------------------------------------------------------------
 */







|













<












>
>


|
|
|
>
>







 







|
<
<
|







 







|







 







>
>
>
>
>
>
>
>
>











<







 







|







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





|
<
|
>
|
|
|
>
|
>
>
|
>
>
>
|







 







|





>
|
<
|
|
|
>
>
>
>
>
>
|
|

<
>
>
>
>
|
|
>
>
>

<
>
|
>
|
<
|
>
>
>
>
>
|
>
|

<
>
>
>
|
<
<
<
>
>
|
|
<
<
<
|
<
<







 







|







 







>
>
>







 







<
<







 







<
<
<
<
<
<
<
<
<
|
<

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

<
>


|


<
>
>





|

>
|



<
<
|


<
<

<
>
|
|
>








<
<
<






|


|
<
<
<





<
|
>
>
>
>
>
|
<
>
>
>
>
>
>
>







 







|


>
>
>
>
>
>
>
>
>
>










|







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
...
183
184
185
186
187
188
189
190


191
192
193
194
195
196
197
198
....
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
....
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028

3029
3030
3031
3032
3033
3034
3035
....
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
....
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
....
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
....
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
....
3773
3774
3775
3776
3777
3778
3779


3780
3781
3782
3783
3784
3785
3786
....
3802
3803
3804
3805
3806
3807
3808









3809

3810
















































3811

3812
3813
3814
3815
3816
3817

3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831


3832
3833
3834


3835

3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847



3848
3849
3850
3851
3852
3853
3854
3855
3856
3857



3858
3859
3860
3861
3862

3863
3864
3865
3866
3867
3868
3869

3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
....
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
    int mode;			/* Either the value TCL_ZLIB_STREAM_DEFLATE
				 * for compression on output, or
				 * TCL_ZLIB_STREAM_INFLATE for decompression
				 * on input. */
    int format;			/* What format of data is going on the wire.
				 * Needed so that the correct [fconfigure]
				 * options can be enabled. */
    unsigned int readAheadLimit;/* The maximum number of bytes to read from
				 * the underlying stream in one go. */
    z_stream inStream;		/* Structure used by zlib for decompression of
				 * input. */
    z_stream outStream;		/* Structure used by zlib for compression of
				 * output. */
    char *inBuffer, *outBuffer;	/* Working buffers. */
    size_t inAllocated, outAllocated;
				/* Sizes of working buffers. */
    GzipHeader inHeader;	/* Header read from input stream, when
				 * decompressing a gzip stream. */
    GzipHeader outHeader;	/* Header to write to an output stream, when
				 * compressing a gzip stream. */
    Tcl_TimerToken timer;	/* Timer used for keeping events fresh. */

    Tcl_Obj *compDictObj;	/* Byte-array object containing compression
				 * dictionary (not dictObj!) to use if
				 * necessary. */
} ZlibChannelData;

/*
 * Value bits for the flags field. Definitions are:
 *	ASYNC -		Whether this is an asynchronous channel.
 *	IN_HEADER -	Whether the inHeader field has been registered with
 *			the input compressor.
 *	OUT_HEADER -	Whether the outputHeader field has been registered
 *			with the output decompressor.
 *	STREAM_DECOMPRESS - Signal decompress pending data.
 *	STREAM_DONE -	Flag to signal stream end up to transform input.
 */

#define ASYNC			0x01
#define IN_HEADER		0x02
#define OUT_HEADER		0x04
#define STREAM_DECOMPRESS	0x08
#define STREAM_DONE		0x10

/*
 * Size of buffers allocated by default, and the range it can be set to.  The
 * same sorts of values apply to streams, except with different limits (they
 * permit byte-level activity). Channels always use bytes unless told to use
 * larger buffers.
 */
................................................................................
static inline int	Deflate(z_streamp strm, void *bufferPtr,
			    size_t bufferSize, int flush, size_t *writtenPtr);
static void		ExtractHeader(gz_header *headerPtr, Tcl_Obj *dictObj);
static int		GenerateHeader(Tcl_Interp *interp, Tcl_Obj *dictObj,
			    GzipHeader *headerPtr, int *extraSizePtr);
static int		ZlibPushSubcmd(Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		ResultDecompress(ZlibChannelData *cd, char *buf,


			    int toRead, int flush, int *errorCodePtr);
static Tcl_Channel	ZlibStackChannelTransform(Tcl_Interp *interp,
			    int mode, int format, int level, int limit,
			    Tcl_Channel channel, Tcl_Obj *gzipHeaderDictPtr,
			    Tcl_Obj *compDictObj);
static void		ZlibStreamCleanup(ZlibStreamHandle *zshPtr);
static int		ZlibStreamSubcmd(Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
................................................................................
    };
    static const char *const pushDecompressOptions[] = {
	"-dictionary", "-header", "-level", "-limit", NULL
    };
    const char *const *pushOptions = pushDecompressOptions;
    enum pushOptions {poDictionary, poHeader, poLevel, poLimit};
    Tcl_Obj *headerObj = NULL, *compDictObj = NULL;
    int limit = DEFAULT_BUFFER_SIZE, dummy;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "mode channel ?options...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[2], stream_formats, "mode", 0,
................................................................................
		}
		result = TCL_ERROR;
		break;
	    }
	} while (e != Z_STREAM_END);
	(void) deflateEnd(&cd->outStream);
    } else {
	/*
	 * If we have unused bytes from the read input (overshot by
	 * Z_STREAM_END or on possible error), unget them back to the parent
	 * channel, so that they appear as not being read yet.
	 */
	if (cd->inStream.avail_in) {
	    Tcl_Ungets (cd->parent, (char *)cd->inStream.next_in, cd->inStream.avail_in, 0);
	}

	(void) inflateEnd(&cd->inStream);
    }

    /*
     * Release all memory.
     */

    if (cd->compDictObj) {
	Tcl_DecrRefCount(cd->compDictObj);
	cd->compDictObj = NULL;
    }


    if (cd->inBuffer) {
	Tcl_Free(cd->inBuffer);
	cd->inBuffer = NULL;
    }
    if (cd->outBuffer) {
	Tcl_Free(cd->outBuffer);
................................................................................
    char *buf,
    int toRead,
    int *errorCodePtr)
{
    ZlibChannelData *cd = (ZlibChannelData *)instanceData;
    Tcl_DriverInputProc *inProc =
	    Tcl_ChannelInputProc(Tcl_GetChannelType(cd->parent));
    int readBytes, gotBytes;

    if (cd->mode == TCL_ZLIB_STREAM_DEFLATE) {
	return inProc(Tcl_GetChannelInstanceData(cd->parent), buf, toRead,
		errorCodePtr);
    }

    gotBytes = 0;
    readBytes = cd->inStream.avail_in; /* how many bytes in buffer now */
    while (!(cd->flags & STREAM_DONE) && toRead > 0) {
    	unsigned int n; int decBytes;

	/* if starting from scratch or continuation after full decompression */
	if (!cd->inStream.avail_in) {
	    /* buffer to start, we can read to whole available buffer */
	    cd->inStream.next_in = (Bytef *) cd->inBuffer;
	}
	/*
	 * If done - no read needed anymore, check we have to copy rest of
	 * decompressed data, otherwise return with size (or 0 for Eof)
	 */
	if (cd->flags & STREAM_DECOMPRESS) {
	    goto copyDecompressed;
	}
	/*
	 * The buffer is exhausted, but the caller wants even more. We now
	 * have to go to the underlying channel, get more bytes and then
	 * transform them for delivery. We may not get what we want (full EOF
	 * or temporarily out of data).
	 */


	/* Check free buffer size and adjust size of next chunk to read. */
	n = cd->inAllocated - ((char *)cd->inStream.next_in - cd->inBuffer);
	if (n <= 0) {
	    /* Normally unreachable: not enough input buffer to uncompress.
	     * Todo: firstly try to realloc inBuffer upto MAX_BUFFER_SIZE.
	     */
	    *errorCodePtr = ENOBUFS;
	    return -1;
	}
	if (n > cd->readAheadLimit) {
	    n = cd->readAheadLimit;
	}
	readBytes = Tcl_ReadRaw(cd->parent, (char *)cd->inStream.next_in, n);

	/*
	 * Three cases here:
	 *  1.	Got some data from the underlying channel (readBytes > 0) so
	 *	it should be fed through the decompression engine.
	 *  2.	Got an error (readBytes == -1) which we should report up except
	 *	for the case where we can convert it to a short read.
................................................................................
	 *	it is EOF, try flushing the data out of the decompressor.
	 */

	if (readBytes == -1) {

	    /* See ReflectInput() in tclIORTrans.c */
	    if (Tcl_InputBlocked(cd->parent) && (gotBytes > 0)) {
		break;
	    }

	    *errorCodePtr = Tcl_GetErrno();
	    return -1;
	}

	/* more bytes (or Eof if readBytes == 0) */

	cd->inStream.avail_in += readBytes;

copyDecompressed:

	/*
	 * Transform the read chunk, if not empty. Anything we get
	 * back is a transformation result to be put into our buffers, and
	 * the next iteration will put it into the result.
	 * For the case readBytes is 0 which signaling Eof in parent, the
	 * partial data waiting is converted and returned.
	 */


	decBytes = ResultDecompress(cd, buf, toRead,
		    (readBytes != 0) ? Z_NO_FLUSH : Z_SYNC_FLUSH,
		    errorCodePtr);
	if (decBytes == -1) {
	    return -1;
	}
	gotBytes += decBytes;
	buf += decBytes;
	toRead -= decBytes;


	if (((decBytes == 0) || (cd->flags & STREAM_DECOMPRESS))) {
	    /*
	     * The drain delivered nothing (or buffer too small to decompress).
	     * Time to deliver what we've got.

	     */
	    if (!gotBytes && !(cd->flags & STREAM_DONE)) {
		/* if no-data, but not ready - avoid signaling Eof,
		 * continue in blocking mode, otherwise EAGAIN */
		if (Tcl_InputBlocked(cd->parent)) {
		    continue;
		}
		*errorCodePtr = EAGAIN;
		return -1;
	    }

	    break;
	}

	/*



	 * Loop until the request is satisfied (or no data available from
	 * above, possibly EOF).
	 */
    }






    return gotBytes;
}
 
/*
 *----------------------------------------------------------------------
 *
 * ZlibTransformOutput --
................................................................................
    /*
     * This code is based on the code in tclIORTrans.c
     */

    watchProc = Tcl_ChannelWatchProc(Tcl_GetChannelType(cd->parent));
    watchProc(Tcl_GetChannelInstanceData(cd->parent), mask);

    if (!(mask & TCL_READABLE) || !(cd->flags & STREAM_DECOMPRESS)) {
	ZlibTransformEventTimerKill(cd);
    } else if (cd->timer == NULL) {
	cd->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME,
		ZlibTransformTimerRun, cd);
    }
}

................................................................................
     */

    if (mode == TCL_ZLIB_STREAM_INFLATE) {
	if (inflateInit2(&cd->inStream, wbits) != Z_OK) {
	    goto error;
	}
	cd->inAllocated = DEFAULT_BUFFER_SIZE;
	if (cd->inAllocated < cd->readAheadLimit) {
	    cd->inAllocated = cd->readAheadLimit;
	}
	cd->inBuffer = (char *)Tcl_Alloc(cd->inAllocated);
	if (cd->flags & IN_HEADER) {
	    if (inflateGetHeader(&cd->inStream, &cd->inHeader.header) != Z_OK) {
		goto error;
	    }
	}
	if (cd->format == TCL_ZLIB_FORMAT_RAW && cd->compDictObj) {
................................................................................
	if (cd->compDictObj) {
	    if (SetDeflateDictionary(&cd->outStream, cd->compDictObj) != Z_OK) {
		goto error;
	    }
	}
    }



    chan = Tcl_StackChannel(interp, &zlibChannelType, cd,
	    Tcl_GetChannelMode(channel), channel);
    if (chan == NULL) {
	goto error;
    }
    cd->chan = chan;
    cd->parent = Tcl_GetStackedChannel(chan);
................................................................................
    Tcl_Free(cd);
    return NULL;
}
 
/*
 *----------------------------------------------------------------------
 *









 * ResultDecompress --

 *
















































 *	Extract uncompressed bytes from the compression engine and store them

 *	in our buffer (buf) up to toRead bytes.
 *
 * Result:
 *	Number of bytes decompressed or -1 if error (with *errorCodePtr updated with reason).
 *
 * Side effects:

 *	After execution it updates cd->inStream (next_in, avail_in) to reflect
 *	the data that has been decompressed.
 *
 *----------------------------------------------------------------------
 */

static int
ResultDecompress(
    ZlibChannelData *cd,
    char *buf,
    int toRead,
    int flush,
    int *errorCodePtr)
{


    int e, written, resBytes = 0;
    Tcl_Obj *errObj;





    cd->flags &= ~STREAM_DECOMPRESS;
    cd->inStream.next_out = (Bytef *) buf;
    cd->inStream.avail_out = toRead;
    while (cd->inStream.avail_out > 0) {

	e = inflate(&cd->inStream, flush);
	if (e == Z_NEED_DICT && cd->compDictObj) {
	    e = SetInflateDictionary(&cd->inStream, cd->compDictObj);
	    if (e == Z_OK) {
		/*
		 * A repetition of Z_NEED_DICT is just an error.
		 */



		e = inflate(&cd->inStream, flush);
	    }
	}

	/*
	 * avail_out is now the left over space in the output.  Therefore
	 * "toRead - avail_out" is the amount of bytes generated.
	 */

	written = toRead - cd->inStream.avail_out;




	/*
	 * The cases where we're definitely done.
	 */


	if (e == Z_STREAM_END) {
	    cd->flags |= STREAM_DONE;
	    resBytes += written;
	    break;
	}
	if (e == Z_OK) {
	    if (written == 0) {

		break;
	    }
	    resBytes += written;
	}

	if ((flush == Z_SYNC_FLUSH) && (e == Z_BUF_ERROR)) {
	    break;
	}

	/*
	 * Z_BUF_ERROR can be ignored as per http://www.zlib.net/zlib_how.html
	 *
	 * Just indicates that the zlib couldn't consume input/produce output,
	 * and is fixed by supplying more input.
................................................................................
	}

	/*
	 * Check if the inflate stopped early.
	 */

	if (cd->inStream.avail_in <= 0 && flush != Z_SYNC_FLUSH) {
	    break;
	}
    }

    if (!(cd->flags & STREAM_DONE)) {
	/* if we have pending input data, but no available output buffer */
	if (cd->inStream.avail_in && !cd->inStream.avail_out) {
	    /* next time try to decompress it got readable (new output buffer) */
	    cd->flags |= STREAM_DECOMPRESS;
	}
    }

    return resBytes;

  handleError:
    errObj = Tcl_NewListObj(0, NULL);
    Tcl_ListObjAppendElement(NULL, errObj, Tcl_NewStringObj("-errorcode",-1));
    Tcl_ListObjAppendElement(NULL, errObj,
	    ConvertErrorToList(e, cd->inStream.adler));
    Tcl_ListObjAppendElement(NULL, errObj,
	    Tcl_NewStringObj(cd->inStream.msg, -1));
    Tcl_SetChannelError(cd->parent, errObj);
    *errorCodePtr = EINVAL;
    return -1;
}
 
/*
 *----------------------------------------------------------------------
 *	Finally, the TclZlibInit function. Used to install the zlib API.
 *----------------------------------------------------------------------
 */

Changes to library/init.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
84
# Also add the directory ../lib relative to the directory where the
# executable is located.  This is meant to find binary packages for the
# same architecture as the current executable.
#
# tcl_pkgPath, which is set by the platform-specific initialization routines
#	On UNIX it is compiled in
#       On Windows, it is not used





if {![info exists auto_path]} {
    if {[info exists env(TCLLIBPATH)]} {
	set auto_path $env(TCLLIBPATH)
    } else {
	set auto_path ""
    }
}
namespace eval tcl {

    variable Dir
    foreach Dir [list $::tcl_library [file dirname $::tcl_library]] {
	if {$Dir ni $::auto_path} {
	    lappend ::auto_path $Dir
	}
    }
    set Dir [file join [file dirname [file dirname \
	    [info nameofexecutable]]] lib]
    if {$Dir ni $::auto_path} {
	lappend ::auto_path $Dir
    }
    if {[info exists ::tcl_pkgPath]} { catch {
	foreach Dir $::tcl_pkgPath {
	    if {$Dir ni $::auto_path} {
		lappend ::auto_path $Dir
	    }
	}











    }}

    if {![interp issafe]} {
        variable Path [encoding dirs]
        set Dir [file join $::tcl_library encoding]
        if {$Dir ni $Path} {
	    lappend Path $Dir
	    encoding dirs $Path
        }

    }
}

namespace eval tcl::Pkg {}


# Setup the unknown package handler







|
>
>
>
>

|






>
|
|
<
<
<
<
<
<
<
<
<
<
<




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

<
|
|
|


|
>







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
# Also add the directory ../lib relative to the directory where the
# executable is located.  This is meant to find binary packages for the
# same architecture as the current executable.
#
# tcl_pkgPath, which is set by the platform-specific initialization routines
#	On UNIX it is compiled in
#       On Windows, it is not used
#
# (Ticket 41c9857bdd) In a safe interpreter, this file does not set
# ::auto_path (other than to {} if it is undefined). The caller, typically
# a Safe Base command, is responsible for setting ::auto_path.

if {![info exists auto_path]} {
    if {[info exists env(TCLLIBPATH)] && (![interp issafe])} {
	set auto_path $env(TCLLIBPATH)
    } else {
	set auto_path ""
    }
}
namespace eval tcl {
    if {![interp issafe]} {
	variable Dir
	foreach Dir [list $::tcl_library [file dirname $::tcl_library]] {











	    if {$Dir ni $::auto_path} {
		lappend ::auto_path $Dir
	    }
	}
	set Dir [file join [file dirname [file dirname \
		[info nameofexecutable]]] lib]
	if {$Dir ni $::auto_path} {
	    lappend ::auto_path $Dir
	}
	if {[info exists ::tcl_pkgPath]} { catch {
	    foreach Dir $::tcl_pkgPath {
		if {$Dir ni $::auto_path} {
		    lappend ::auto_path $Dir
		}
	    }
	}}


	variable Path [encoding dirs]
	set Dir [file join $::tcl_library encoding]
	if {$Dir ni $Path} {
	    lappend Path $Dir
	    encoding dirs $Path
	}
	unset Dir Path
    }
}

namespace eval tcl::Pkg {}


# Setup the unknown package handler

Changes to tests/zlib.test.

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
....
1001
1002
1003
1004
1005
1006
1007
1008
















































































1009
1010
1011
1012
1013
1014
    set ::total
} -cleanup {
    close $srv
    rename bgerror {}
    rename zlibRead {}
} -result {error {invalid block type}}

test zlib-11.1 "Bug #3390073: mis-appled gzip filtering" -setup {
    set file [makeFile {} test.input]
} -constraints zlib -body {
    set f [open $file wb]
    puts -nonewline [zlib push gzip $f] [string repeat "hello" 1000]
    close $f
    set f [open $file rb]
    set d [read $f]
    close $f
    set d [zlib gunzip $d]
    list [regexp -all "hello" $d] [string length [regsub -all "hello" $d {}]]
} -cleanup {
    removeFile $file
} -result {1000 0}
test zlib-11.2 "Bug #3390073: mis-appled gzip filtering" -setup {
    set file [makeFile {} test.input]
} -constraints zlib -body {
    set f [open $file wb]
    puts -nonewline [zlib push gzip $f -header {filename /foo/bar}] \
	[string repeat "hello" 1000]
    close $f
    set f [open $file rb]
................................................................................
	close $fout
    }
    file size $filedst
} -cleanup {
    removeFile $filesrc
    removeFile $filedst
} -result 56
 
















































































::tcltest::cleanupTests
return

# Local Variables:
# mode: tcl
# End:







|













|







 







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






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
....
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
    set ::total
} -cleanup {
    close $srv
    rename bgerror {}
    rename zlibRead {}
} -result {error {invalid block type}}

test zlib-11.1 "Bug #3390073: mis-applied gzip filtering" -setup {
    set file [makeFile {} test.input]
} -constraints zlib -body {
    set f [open $file wb]
    puts -nonewline [zlib push gzip $f] [string repeat "hello" 1000]
    close $f
    set f [open $file rb]
    set d [read $f]
    close $f
    set d [zlib gunzip $d]
    list [regexp -all "hello" $d] [string length [regsub -all "hello" $d {}]]
} -cleanup {
    removeFile $file
} -result {1000 0}
test zlib-11.2 "Bug #3390073: mis-applied gzip filtering" -setup {
    set file [makeFile {} test.input]
} -constraints zlib -body {
    set f [open $file wb]
    puts -nonewline [zlib push gzip $f -header {filename /foo/bar}] \
	[string repeat "hello" 1000]
    close $f
    set f [open $file rb]
................................................................................
	close $fout
    }
    file size $filedst
} -cleanup {
    removeFile $filesrc
    removeFile $filedst
} -result 56

set zlibbinf ""
proc _zlibbinf {} {
  # inlined zlib.bin file creator:
  variable zlibbinf
  if {$zlibbinf eq ""} {
    set zlibbinf [makeFile {} test-zlib-13.bin]
    set f [open $zlibbinf wb]
    puts -nonewline $f [zlib decompress [binary decode base64 {
      eJx7e+6s1+EAgYaLjK3ratptGmOck0vT/y/ZujHAd0qJelDBXfUPJ3tfrtLbpX+wOOFHmtn03/tizm
      /+tXROXU3d203b79p5X6/0cvUyFzTsqOj4sa9r8SrZI5zT7265e2Xzq595Fb9LbpgffVy7cZaJ/d15
      4U9L7LLM2vdqut8+aSU/r6q9Ltv6+T9mBhTgIK97bH33m/O1C1eBwf9FDKNgaIDaj9wA+5hToA==
    }]]
    close $f
  }
  return $zlibbinf
}
test zlib-13.1 {Ticket [8af92dfb66] - zlib stream mis-expansion} -constraints zlib -setup {
    set pathin  [_zlibbinf]
    set chanin  [open $pathin rb]
    set pathout [makeFile {} test-zlib-13.deflated]
    set chanout [open $pathout wb]
    zlib push inflate $chanin
    fcopy $chanin $chanout
    close $chanin
    close $chanout
} -body {
    file size $pathout
} -cleanup {
    removeFile $pathout
    unset chanin pathin chanout pathout
} -result 458752

test zlib-13.2 {Ticket [f70ce1fead] - zlib multi-stream expansion} -constraints zlib -setup {
    # Start from the basic asset
    set pathin  [_zlibbinf]
    set chanin  [open $pathin rb]
    # Create a multi-stream by copying the asset twice into it.
    set pathout [makeFile {} test-zlib-13.multi]
    set chanout [open $pathout wb]
    fcopy $chanin $chanout
    seek  $chanin 0 start
    fcopy $chanin $chanout
    close $chanin
    close $chanout
    # The multi-stream file shall be our input
    set pathin $pathout
    set chanin [open $pathin rb]
    # And our destinations
    set pathout1 [makeFile {} test-zlib-13.multi-1]
    set pathout2 [makeFile {} test-zlib-13.multi-2]
} -body {
    # Decode first stream
    set chanout [open $pathout1 wb]
    zlib push inflate $chanin
    fcopy $chanin $chanout
    chan pop $chanin
    close $chanout
    # Decode second stream
    set chanout [open $pathout2 wb]
    zlib push inflate $chanin
    fcopy $chanin $chanout
    chan pop $chanin
    close $chanout
    #
    list [file size $pathout1] [file size $pathout2]
} -cleanup {
    close $chanin
    removeFile $pathout
    removeFile $pathout1
    removeFile $pathout2
    unset chanin pathin chanout pathout pathout1 pathout2
} -result {458752 458752}

if {$zlibbinf ne ""} {
   removeFile $zlibbinf
}
unset zlibbinf
rename _zlibbinf {}

 
::tcltest::cleanupTests
return

# Local Variables:
# mode: tcl
# End:

Changes to unix/Makefile.in.

2220
2221
2222
2223
2224
2225
2226




2227
2228

2229
2230

2231
2232
2233
2234
2235
2236
2237
....
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
		$(UNIX_DIR)/aclocal.m4
	cd $(UNIX_DIR); autoconf
$(MAC_OSX_DIR)/configure: $(MAC_OSX_DIR)/configure.ac $(UNIX_DIR)/configure
	cd $(MAC_OSX_DIR); autoconf
$(UNIX_DIR)/tclConfig.h.in: $(MAC_OSX_DIR)/configure
	cd $(MAC_OSX_DIR); autoheader; touch $@





dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in \
		$(MAC_OSX_DIR)/configure genstubs dist-packages ${NATIVE_TCLSH}

	rm -rf $(DISTDIR)
	$(INSTALL_DATA_DIR) $(DISTDIR)/unix

	$(DIST_INSTALL_DATA) $(UNIX_DIR)/*.[ch] $(DISTDIR)/unix
	$(DIST_INSTALL_DATA) $(UNIX_DIR)/Makefile.in $(DISTDIR)/unix
	$(DIST_INSTALL_DATA) $(UNIX_DIR)/configure.ac \
		$(UNIX_DIR)/tcl.m4 $(UNIX_DIR)/aclocal.m4 \
		$(UNIX_DIR)/tclConfig.sh.in $(UNIX_DIR)/tclooConfig.sh \
		$(UNIX_DIR)/install-sh \
		$(UNIX_DIR)/README $(UNIX_DIR)/tcl.spec \
................................................................................
	$(DIST_INSTALL_DATA) $(TOOL_DIR)/Makefile.in $(TOOL_DIR)/README \
		$(TOOL_DIR)/configure $(TOOL_DIR)/configure.ac \
		$(TOOL_DIR)/*.tcl $(TOOL_DIR)/man2tcl.c \
		$(TOOL_DIR)/*.bmp $(TOOL_DIR)/tcl.hpj.in \
		$(DISTDIR)/tools
	chmod 755 $(DISTDIR)/tools/checkLibraryDoc.tcl \
		$(DISTDIR)/tools/configure $(DISTDIR)/tools/findBadExternals.tcl \
		$(DISTDIR)/tools/fix_tommath_h.tcl $(DISTDIR)/tools/loadICU.tcl \
		$(DISTDIR)/tools/makeTestCases.tcl $(DISTDIR)/tools/tclZIC.tcl \
		$(DISTDIR)/tools/tcltk-man2html.tcl
	$(INSTALL_DATA_DIR) $(DISTDIR)/libtommath
	$(DIST_INSTALL_DATA) $(TOMMATH_SRCS) $(TOMMATH_DIR)/*.h $(DISTDIR)/libtommath
	$(INSTALL_DATA_DIR) $(DISTDIR)/pkgs
	$(DIST_INSTALL_DATA) $(TOP_DIR)/pkgs/README $(DISTDIR)/pkgs
	$(DIST_INSTALL_DATA) $(TOP_DIR)/pkgs/package.list.txt $(DISTDIR)/pkgs







>
>
>
>
|
<
>


>







 







|







2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231

2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
....
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
		$(UNIX_DIR)/aclocal.m4
	cd $(UNIX_DIR); autoconf
$(MAC_OSX_DIR)/configure: $(MAC_OSX_DIR)/configure.ac $(UNIX_DIR)/configure
	cd $(MAC_OSX_DIR); autoconf
$(UNIX_DIR)/tclConfig.h.in: $(MAC_OSX_DIR)/configure
	cd $(MAC_OSX_DIR); autoheader; touch $@

$(TOP_DIR)/manifest.uuid:
	printf "git." >$(TOP_DIR)/manifest.uuid
	git rev-parse HEAD >>$(TOP_DIR)/manifest.uuid

dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in genstubs \

		$(MAC_OSX_DIR)/configure $(TOP_DIR)/manifest.uuid dist-packages ${NATIVE_TCLSH}
	rm -rf $(DISTDIR)
	$(INSTALL_DATA_DIR) $(DISTDIR)/unix
	$(DIST_INSTALL_DATA) $(TOP_DIR)/manifest.uuid $(DISTDIR)
	$(DIST_INSTALL_DATA) $(UNIX_DIR)/*.[ch] $(DISTDIR)/unix
	$(DIST_INSTALL_DATA) $(UNIX_DIR)/Makefile.in $(DISTDIR)/unix
	$(DIST_INSTALL_DATA) $(UNIX_DIR)/configure.ac \
		$(UNIX_DIR)/tcl.m4 $(UNIX_DIR)/aclocal.m4 \
		$(UNIX_DIR)/tclConfig.sh.in $(UNIX_DIR)/tclooConfig.sh \
		$(UNIX_DIR)/install-sh \
		$(UNIX_DIR)/README $(UNIX_DIR)/tcl.spec \
................................................................................
	$(DIST_INSTALL_DATA) $(TOOL_DIR)/Makefile.in $(TOOL_DIR)/README \
		$(TOOL_DIR)/configure $(TOOL_DIR)/configure.ac \
		$(TOOL_DIR)/*.tcl $(TOOL_DIR)/man2tcl.c \
		$(TOOL_DIR)/*.bmp $(TOOL_DIR)/tcl.hpj.in \
		$(DISTDIR)/tools
	chmod 755 $(DISTDIR)/tools/checkLibraryDoc.tcl \
		$(DISTDIR)/tools/configure $(DISTDIR)/tools/findBadExternals.tcl \
		$(DISTDIR)/tools/loadICU.tcl \
		$(DISTDIR)/tools/makeTestCases.tcl $(DISTDIR)/tools/tclZIC.tcl \
		$(DISTDIR)/tools/tcltk-man2html.tcl
	$(INSTALL_DATA_DIR) $(DISTDIR)/libtommath
	$(DIST_INSTALL_DATA) $(TOMMATH_SRCS) $(TOMMATH_DIR)/*.h $(DISTDIR)/libtommath
	$(INSTALL_DATA_DIR) $(DISTDIR)/pkgs
	$(DIST_INSTALL_DATA) $(TOP_DIR)/pkgs/README $(DISTDIR)/pkgs
	$(DIST_INSTALL_DATA) $(TOP_DIR)/pkgs/package.list.txt $(DISTDIR)/pkgs

Changes to unix/configure.

8890
8891
8892
8893
8894
8895
8896



8897
8898
8899
8900
8901
8902
8903
8904
8905
....
8949
8950
8951
8952
8953
8954
8955



8956
8957
8958
8959
8960
8961
8962
8963
8964
....
9507
9508
9509
9510
9511
9512
9513

9514
9515
9516
9517
9518
9519
9520
  $as_echo_n "(cached) " >&6
else
  if test "$cross_compiling" = yes; then :
  tcl_cv_strstr_unbroken=unknown
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */



int main() {
    extern int strstr();
    exit(strstr("\0test", "test") ? 1 : 0);
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
  tcl_cv_strstr_unbroken=ok
else
  tcl_cv_strstr_unbroken=broken
................................................................................
  $as_echo_n "(cached) " >&6
else
  if test "$cross_compiling" = yes; then :
  tcl_cv_strtoul_unbroken=unknown
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */



int main() {
    extern int strtoul();
    char *term, *string = "0";
    exit(strtoul(string,&term,0) != 0 || term != string+1);
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
  tcl_cv_strtoul_unbroken=ok
else
................................................................................
    if test "$cross_compiling" = yes; then :
  tcl_cv_putenv_copy=no
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

	#include <stdlib.h>

	#define OURVAR "havecopy=yes"
	int main (int argc, char *argv[])
	{
	    char *foo, *bar;
	    foo = (char *)strdup(OURVAR);
	    putenv(foo);
	    strcpy((char *)(strchr(foo, '=') + 1), "no");







>
>
>

<







 







>
>
>

<







 







>







8890
8891
8892
8893
8894
8895
8896
8897
8898
8899
8900

8901
8902
8903
8904
8905
8906
8907
....
8951
8952
8953
8954
8955
8956
8957
8958
8959
8960
8961

8962
8963
8964
8965
8966
8967
8968
....
9511
9512
9513
9514
9515
9516
9517
9518
9519
9520
9521
9522
9523
9524
9525
  $as_echo_n "(cached) " >&6
else
  if test "$cross_compiling" = yes; then :
  tcl_cv_strstr_unbroken=unknown
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

#include <stdlib.h>
#include <string.h>
int main() {

    exit(strstr("\0test", "test") ? 1 : 0);
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
  tcl_cv_strstr_unbroken=ok
else
  tcl_cv_strstr_unbroken=broken
................................................................................
  $as_echo_n "(cached) " >&6
else
  if test "$cross_compiling" = yes; then :
  tcl_cv_strtoul_unbroken=unknown
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

#include <stdlib.h>
#include <string.h>
int main() {

    char *term, *string = "0";
    exit(strtoul(string,&term,0) != 0 || term != string+1);
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
  tcl_cv_strtoul_unbroken=ok
else
................................................................................
    if test "$cross_compiling" = yes; then :
  tcl_cv_putenv_copy=no
else
  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

	#include <stdlib.h>
	#include <string.h>
	#define OURVAR "havecopy=yes"
	int main (int argc, char *argv[])
	{
	    char *foo, *bar;
	    foo = (char *)strdup(OURVAR);
	    putenv(foo);
	    strcpy((char *)(strchr(foo, '=') + 1), "no");

Changes to unix/configure.ac.

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
...
541
542
543
544
545
546
547

548
549
550
551
552
553
554

#--------------------------------------------------------------------
#	On some systems strstr is broken: it returns a pointer even even if
#	the original string is empty.
#--------------------------------------------------------------------

SC_TCL_CHECK_BROKEN_FUNC(strstr, [
    extern int strstr();
    exit(strstr("\0test", "test") ? 1 : 0);
])

#--------------------------------------------------------------------
#	Check for strtoul function.  This is tricky because under some
#	versions of AIX strtoul returns an incorrect terminator
#	pointer for the string "0".
#--------------------------------------------------------------------

SC_TCL_CHECK_BROKEN_FUNC(strtoul, [
    extern int strtoul();
    char *term, *string = "0";
    exit(strtoul(string,&term,0) != 0 || term != string+1);
])

#--------------------------------------------------------------------
#	Check for various typedefs and provide substitutes if
#	they don't exist.
................................................................................
#--------------------------------------------------------------------
#  Does putenv() copy or not?  We need to know to avoid memory leaks.
#--------------------------------------------------------------------

AC_CACHE_CHECK([for a putenv() that copies the buffer], tcl_cv_putenv_copy, [
    AC_TRY_RUN([
	#include <stdlib.h>

	#define OURVAR "havecopy=yes"
	int main (int argc, char *argv[])
	{
	    char *foo, *bar;
	    foo = (char *)strdup(OURVAR);
	    putenv(foo);
	    strcpy((char *)(strchr(foo, '=') + 1), "no");







<










<







 







>







384
385
386
387
388
389
390

391
392
393
394
395
396
397
398
399
400

401
402
403
404
405
406
407
...
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553

#--------------------------------------------------------------------
#	On some systems strstr is broken: it returns a pointer even even if
#	the original string is empty.
#--------------------------------------------------------------------

SC_TCL_CHECK_BROKEN_FUNC(strstr, [

    exit(strstr("\0test", "test") ? 1 : 0);
])

#--------------------------------------------------------------------
#	Check for strtoul function.  This is tricky because under some
#	versions of AIX strtoul returns an incorrect terminator
#	pointer for the string "0".
#--------------------------------------------------------------------

SC_TCL_CHECK_BROKEN_FUNC(strtoul, [

    char *term, *string = "0";
    exit(strtoul(string,&term,0) != 0 || term != string+1);
])

#--------------------------------------------------------------------
#	Check for various typedefs and provide substitutes if
#	they don't exist.
................................................................................
#--------------------------------------------------------------------
#  Does putenv() copy or not?  We need to know to avoid memory leaks.
#--------------------------------------------------------------------

AC_CACHE_CHECK([for a putenv() that copies the buffer], tcl_cv_putenv_copy, [
    AC_TRY_RUN([
	#include <stdlib.h>
	#include <string.h>
	#define OURVAR "havecopy=yes"
	int main (int argc, char *argv[])
	{
	    char *foo, *bar;
	    foo = (char *)strdup(OURVAR);
	    putenv(foo);
	    strcpy((char *)(strchr(foo, '=') + 1), "no");

Changes to unix/installManPage.

110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
Name=`basename $ManPage .$Section`
SrcDir=`dirname $ManPage`

########################################################################
### Process Page to Create Target Pages
###

Specials="DString Thread Notifier RegExp library packagens pkgMkIndex safesock"
for n in $Specials; do
    if [ "$Name" = "$n" ] ; then
	Names="$n $Names"
    fi
done

First=""







|







110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
Name=`basename $ManPage .$Section`
SrcDir=`dirname $ManPage`

########################################################################
### Process Page to Create Target Pages
###

Specials="DString Thread Notifier RegExp library packagens pkgMkIndex safesock FindPhoto FontId MeasureChar"
for n in $Specials; do
    if [ "$Name" = "$n" ] ; then
	Names="$n $Names"
    fi
done

First=""

Changes to unix/tcl.m4.

2473
2474
2475
2476
2477
2478
2479



2480
2481
2482
2483
2484
2485
2486
2487
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_CHECK_BROKEN_FUNC],[
    AC_CHECK_FUNC($1, tcl_ok=1, tcl_ok=0)
    if test ["$tcl_ok"] = 1; then
	AC_CACHE_CHECK([proper ]$1[ implementation], [tcl_cv_]$1[_unbroken],



	    AC_TRY_RUN([[int main() {]$2[}]],[tcl_cv_]$1[_unbroken]=ok,
		[tcl_cv_]$1[_unbroken]=broken,[tcl_cv_]$1[_unbroken]=unknown))
	if test ["$tcl_cv_]$1[_unbroken"] = "ok"; then
	    tcl_ok=1
	else
	    tcl_ok=0
	fi
    fi







>
>
>
|







2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_CHECK_BROKEN_FUNC],[
    AC_CHECK_FUNC($1, tcl_ok=1, tcl_ok=0)
    if test ["$tcl_ok"] = 1; then
	AC_CACHE_CHECK([proper ]$1[ implementation], [tcl_cv_]$1[_unbroken],
	    AC_TRY_RUN([[
#include <stdlib.h>
#include <string.h>
int main() {]$2[}]],[tcl_cv_]$1[_unbroken]=ok,
		[tcl_cv_]$1[_unbroken]=broken,[tcl_cv_]$1[_unbroken]=unknown))
	if test ["$tcl_cv_]$1[_unbroken"] = "ok"; then
	    tcl_ok=1
	else
	    tcl_ok=0
	fi
    fi

Changes to unix/tclConfig.h.in.

1
2
3
4
5



6
7
8
9
10
11
12
...
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
...
302
303
304
305
306
307
308



309
310
311
312
313
314
315
...
377
378
379
380
381
382
383



384
385
386
387
388
389
390
...
428
429
430
431
432
433
434



435
436
437
438
439
440
441
...
447
448
449
450
451
452
453
454
455






456


457
458
459
460
461
462
463
...
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
/* ../unix/tclConfig.h.in.  Generated from configure.ac by autoheader.  */


    #ifndef _TCLCONFIG
    #define _TCLCONFIG




/* Is gettimeofday() actually declared in <sys/time.h>? */
#undef GETTOD_NOT_DECLARED

/* Define to 1 if you have the <AvailabilityMacros.h> header file. */
#undef HAVE_AVAILABILITYMACROS_H

................................................................................

/* Define to 1 if the system has the type `struct sockaddr_storage'. */
#undef HAVE_STRUCT_SOCKADDR_STORAGE

/* Is 'struct stat64' in <sys/stat.h>? */
#undef HAVE_STRUCT_STAT64

/* Define to 1 if `st_blksize' is member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_BLKSIZE

/* Define to 1 if `st_blocks' is member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_BLOCKS

/* Define to 1 if you have the <sys/epoll.h> header file. */
#undef HAVE_SYS_EPOLL_H

/* Define to 1 if you have the <sys/eventfd.h> header file. */
#undef HAVE_SYS_EVENTFD_H
................................................................................
#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




/* Is no debugging enabled? */
#undef NDEBUG

/* Use compat implementation of getaddrinfo() and friends */
#undef NEED_FAKE_RFC2553

................................................................................
#undef PACKAGE_NAME

/* Define to the full name and version of this package. */
#undef PACKAGE_STRING

/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME




/* Define to the version of this package. */
#undef PACKAGE_VERSION

/* Is this a static build? */
#undef STATIC_BUILD

................................................................................
#undef TCL_WIDE_CLICKS

/* Do 'long' and 'long long' have the same size (64-bit)? */
#undef TCL_WIDE_INT_IS_LONG

/* What type should be used to define wide integers? */
#undef TCL_WIDE_INT_TYPE




/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME

/* Is getcwd Posix-compliant? */
#undef USEGETWD

................................................................................

/* Should we use FIONBIO? */
#undef USE_FIONBIO

/* Should we use vfork() instead of fork()? */
#undef USE_VFORK

/* Define to 1 if your processor stores words with the most significant byte
   first (like Motorola and SPARC, unlike Intel and VAX). */






#undef WORDS_BIGENDIAN



/* Are we building with zipfs enabled? */
#undef ZIPFS_BUILD

/* Are Darwin SUSv3 extensions available? */
#undef _DARWIN_C_SOURCE

................................................................................

/* Define to `int' if <sys/types.h> does not define. */
#undef mode_t

/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t

/* Define to `unsigned' if <sys/types.h> does not define. */
#undef size_t

/* Define as int if socklen_t is not available */
#undef socklen_t

/* Define to `int' if <sys/types.h> doesn't define. */
#undef uid_t





>
>
>







 







|


|







 







>
>
>







 







>
>
>







 







>
>
>







 







|
|
>
>
>
>
>
>
|
>
>







 







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
...
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
...
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
...
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
...
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
...
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
/* ../unix/tclConfig.h.in.  Generated from configure.ac by autoheader.  */


    #ifndef _TCLCONFIG
    #define _TCLCONFIG

/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD

/* Is gettimeofday() actually declared in <sys/time.h>? */
#undef GETTOD_NOT_DECLARED

/* Define to 1 if you have the <AvailabilityMacros.h> header file. */
#undef HAVE_AVAILABILITYMACROS_H

................................................................................

/* Define to 1 if the system has the type `struct sockaddr_storage'. */
#undef HAVE_STRUCT_SOCKADDR_STORAGE

/* Is 'struct stat64' in <sys/stat.h>? */
#undef HAVE_STRUCT_STAT64

/* Define to 1 if `st_blksize' is a member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_BLKSIZE

/* Define to 1 if `st_blocks' is a member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_BLOCKS

/* Define to 1 if you have the <sys/epoll.h> header file. */
#undef HAVE_SYS_EPOLL_H

/* Define to 1 if you have the <sys/eventfd.h> header file. */
#undef HAVE_SYS_EVENTFD_H
................................................................................
#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. */
#undef MP_PREC

/* Is no debugging enabled? */
#undef NDEBUG

/* Use compat implementation of getaddrinfo() and friends */
#undef NEED_FAKE_RFC2553

................................................................................
#undef PACKAGE_NAME

/* Define to the full name and version of this package. */
#undef PACKAGE_STRING

/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME

/* Define to the home page for this package. */
#undef PACKAGE_URL

/* Define to the version of this package. */
#undef PACKAGE_VERSION

/* Is this a static build? */
#undef STATIC_BUILD

................................................................................
#undef TCL_WIDE_CLICKS

/* Do 'long' and 'long long' have the same size (64-bit)? */
#undef TCL_WIDE_INT_IS_LONG

/* What type should be used to define wide integers? */
#undef TCL_WIDE_INT_TYPE

/* Tcl with external libtommath */
#undef TCL_WITH_EXTERNAL_TOMMATH

/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME

/* Is getcwd Posix-compliant? */
#undef USEGETWD

................................................................................

/* Should we use FIONBIO? */
#undef USE_FIONBIO

/* Should we use vfork() instead of fork()? */
#undef USE_VFORK

/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
   significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
#  define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
#  undef WORDS_BIGENDIAN
# endif
#endif

/* Are we building with zipfs enabled? */
#undef ZIPFS_BUILD

/* Are Darwin SUSv3 extensions available? */
#undef _DARWIN_C_SOURCE

................................................................................

/* Define to `int' if <sys/types.h> does not define. */
#undef mode_t

/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t

/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t

/* Define as int if socklen_t is not available */
#undef socklen_t

/* Define to `int' if <sys/types.h> doesn't define. */
#undef uid_t