Changes On Branch tip-656-simpl
Not logged in

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

Changes In Branch tip-656-simpl Excluding Merge-Ins

This is equivalent to a diff from 8cf18cec8c to d91f112024

2023-09-25
07:17
Merge 8.7 (2023-05-03) Closed-Leaf check-in: d91f112024 user: jan.nijtmans tags: tip-656-simpl
06:51
Merge 8.7 (2023-05-02) check-in: da2443a61a user: jan.nijtmans tags: tip-656-simpl
2023-05-03
15:51
Backport "Comments only. Fix blatantly obsolete ones". And a few more improvements from the same fil... check-in: 797753b302 user: jan.nijtmans tags: core-8-branch
14:47
TIP #666 implementation check-in: 380064f5c8 user: jan.nijtmans tags: tip-666
04:06
Merge mark 8.7 check-in: f39569fb40 user: apnadkarni tags: trunk, main
03:31
Changed CHANNEL_PROFILE_* to ENCODING_PROFILE_* and moved out of tclIO.h. See below. For whatever r... check-in: 8cf18cec8c user: apnadkarni tags: core-8-branch
2023-05-02
16:48
Merge 8.6 - [ab123cfd3d] and [784befb0ba] check-in: 4039ba5278 user: apnadkarni tags: core-8-branch

Changes to generic/tcl.h.
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
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







+
+
+
-
+
+









-
-
-
-
+
+
+
+







 * NOTE: THESE BIT DEFINITIONS SHOULD NOT OVERLAP WITH INTERNAL USE BITS
 * DEFINED IN tclEncoding.c (ENCODING_INPUT et al). Be cognizant of this
 * when adding bits.
 */

#define TCL_ENCODING_START		0x01
#define TCL_ENCODING_END		0x02
#if TCL_MAJOR_VERSION > 8
#   define TCL_ENCODING_STOPONERROR	0x0 /* Not used any more */
#else
#define TCL_ENCODING_STOPONERROR	0x04
#   define TCL_ENCODING_STOPONERROR	0x04
#endif
#define TCL_ENCODING_NO_TERMINATE	0x08
#define TCL_ENCODING_CHAR_LIMIT		0x10
/* Internal use bits, do not define bits in this space. See above comment */
#define TCL_ENCODING_INTERNAL_USE_MASK  0xFF00
/* 
 * Reserve top byte for profile values (disjoint, not a mask). In case of
 * changes, ensure ENCODING_PROFILE_* macros in tclInt.h are modified if
 * necessary.
 */
#define TCL_ENCODING_PROFILE_TCL8     0x01000000
#define TCL_ENCODING_PROFILE_STRICT   0x02000000
#define TCL_ENCODING_PROFILE_REPLACE  0x03000000
#define TCL_ENCODING_PROFILE_DEFAULT  TCL_ENCODING_PROFILE_TCL8
#define TCL_ENCODING_PROFILE_STRICT   TCL_ENCODING_STOPONERROR
#define TCL_ENCODING_PROFILE_TCL8     0x01000000
#define TCL_ENCODING_PROFILE_REPLACE  0x02000000
#define TCL_ENCODING_PROFILE_DEFAULT  0

/*
 * The following definitions are the error codes returned by the conversion
 * routines:
 *
 * TCL_OK -			All characters were converted.
 * TCL_CONVERT_NOSPACE -	The output buffer would not have been large
Changes to generic/tclCmdAH.c.
671
672
673
674
675
676
677
678


679
680
681
682
683
684
685
671
672
673
674
675
676
677

678
679
680
681
682
683
684
685
686







-
+
+







	return TCL_ERROR;
    }

    /*
     * Convert the string into a byte array in 'ds'.
     */
#if !defined(TCL_NO_DEPRECATED) && (TCL_MAJOR_VERSION < 9)
    if (ENCODING_PROFILE_GET(flags) == TCL_ENCODING_PROFILE_TCL8) {
    if (ENCODING_PROFILE_GET(flags) != TCL_ENCODING_PROFILE_REPLACE
	    && !(flags & TCL_ENCODING_STOPONERROR)) {
	/* Permits high bits to be non-0 in byte array (Tcl 8 style) */
	bytesPtr = (char *) Tcl_GetByteArrayFromObj(data, &length);
    } else
#endif
	bytesPtr = (char *) TclGetBytesFromObj(interp, data, &length);

    if (bytesPtr == NULL) {
Changes to generic/tclEncoding.c.
195
196
197
198
199
200
201
202


203
204
205
206
207
208
209
195
196
197
198
199
200
201

202
203
204
205
206
207
208
209
210







-
+
+







    int value;
} encodingProfiles[] = {
    {"replace", TCL_ENCODING_PROFILE_REPLACE},
    {"strict", TCL_ENCODING_PROFILE_STRICT},
    {"tcl8", TCL_ENCODING_PROFILE_TCL8},
};
#define PROFILE_STRICT(flags_)                                         \
    (ENCODING_PROFILE_GET(flags_) == TCL_ENCODING_PROFILE_STRICT)
    ((ENCODING_PROFILE_GET(flags_) == (TCL_ENCODING_PROFILE_STRICT & ENCODING_PROFILE_MASK)) \
	    && ((flags) && TCL_ENCODING_STOPONERROR))

#define PROFILE_REPLACE(flags_)                                         \
    (ENCODING_PROFILE_GET(flags_) == TCL_ENCODING_PROFILE_REPLACE)

#define UNICODE_REPLACE_CHAR ((Tcl_UniChar)0xFFFD)
#define SURROGATE(c_)      (((c_) & ~0x7FF) == 0xD800)
#define HIGH_SURROGATE(c_) (((c_) & ~0x3FF) == 0xD800)
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2443
2444
2445
2446
2447
2448
2449

2450
2451
2452
2453
2454
2455
2456







-







    int result;

    result = TCL_OK;
    dstLen -= TCL_UTF_MAX - 1;
    if (dstLen < 0) {
	dstLen = 0;
    }
    flags = TclEncodingSetProfileFlags(flags);
    if ((flags & TCL_ENCODING_CHAR_LIMIT) && srcLen > *dstCharsPtr) {
	srcLen = *dstCharsPtr;
    }
    if (srcLen > dstLen) {
	srcLen = dstLen;
	result = TCL_CONVERT_NOSPACE;
    }
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2510
2511
2512
2513
2514
2515
2516

2517
2518
2519
2520
2521
2522
2523







-







    int profile;

    result = TCL_OK;

    srcStart = src;
    srcEnd = src + srcLen;
    srcClose = srcEnd;
    flags = TclEncodingSetProfileFlags(flags);
    if ((flags & TCL_ENCODING_END) == 0) {
	srcClose -= 6;
    }
    if (flags & TCL_ENCODING_CHAR_LIMIT) {
	charLimit = *dstCharsPtr;
    }

2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2725
2726
2727
2728
2729
2730
2731

2732
2733
2734
2735
2736
2737
2738







-







				 * output buffer. */
{
    const char *srcStart, *srcEnd;
    const char *dstEnd, *dstStart;
    int result, numChars, charLimit = INT_MAX;
    int ch = 0, bytesLeft = srcLen % 4;

    flags = TclEncodingSetProfileFlags(flags);
    flags |= PTR2INT(clientData);
    if (flags & TCL_ENCODING_CHAR_LIMIT) {
	charLimit = *dstCharsPtr;
    }
    result = TCL_OK;

    /*
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2881
2882
2883
2884
2885
2886
2887

2888
2889
2890
2891
2892
2893
2894







-







    const char *srcStart, *srcEnd, *srcClose, *dstStart, *dstEnd;
    int result, numChars;
    int ch, len;

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

    dstStart = dst;
    dstEnd = dst + dstLen - sizeof(Tcl_UniChar);
    flags |= PTR2INT(clientData);
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2978
2979
2980
2981
2982
2983
2984

2985
2986
2987
2988
2989
2990
2991







-







				 * output buffer. */
{
    const char *srcStart, *srcEnd;
    const char *dstEnd, *dstStart;
    int result, numChars, charLimit = INT_MAX;
    unsigned short ch = 0;

    flags = TclEncodingSetProfileFlags(flags);
    flags |= PTR2INT(clientData);
    if (flags & TCL_ENCODING_CHAR_LIMIT) {
	charLimit = *dstCharsPtr;
    }
    result = TCL_OK;

    /*
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3138
3139
3140
3141
3142
3143
3144

3145
3146
3147
3148
3149
3150
3151







-







    const char *srcStart, *srcEnd, *srcClose, *dstStart, *dstEnd;
    int result, numChars;
    int ch, len;

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

    dstStart = dst;
    dstEnd   = dst + dstLen - sizeof(Tcl_UniChar);
    flags |= PTR2INT(clientData);
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3243
3244
3245
3246
3247
3248
3249

3250
3251
3252
3253
3254
3255
3256







-







				 * correspond to the bytes stored in the
				 * output buffer. */
{
    const char *srcStart, *srcEnd, *srcClose, *dstStart, *dstEnd;
    int result, numChars, len;
    Tcl_UniChar ch = 0;

    flags = TclEncodingSetProfileFlags(flags);
    flags |= PTR2INT(clientData);
    srcStart = src;
    srcEnd = src + srcLen;
    srcClose = srcEnd;
    if ((flags & TCL_ENCODING_END) == 0) {
	srcClose -= TCL_UTF_MAX;
    }
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3365
3366
3367
3368
3369
3370
3371

3372
3373
3374
3375
3376
3377
3378







-







    const char *dstEnd, *dstStart, *prefixBytes;
    int result, byte, numChars, charLimit = INT_MAX;
    Tcl_UniChar ch = 0;
    const unsigned short *const *toUnicode;
    const unsigned short *pageZero;
    TableEncodingData *dataPtr = (TableEncodingData *)clientData;

    flags = TclEncodingSetProfileFlags(flags);
    if (flags & TCL_ENCODING_CHAR_LIMIT) {
	charLimit = *dstCharsPtr;
    }
    srcStart = src;
    srcEnd = src + srcLen;

    dstStart = dst;
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3498
3499
3500
3501
3502
3503
3504

3505
3506
3507
3508
3509
3510
3511







-








    prefixBytes = dataPtr->prefixBytes;
    fromUnicode = (const unsigned short *const *) dataPtr->fromUnicode;

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

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

3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3604
3605
3606
3607
3608
3609
3610

3611
3612
3613
3614
3615
3616
3617







-







				 * correspond to the bytes stored in the
				 * output buffer. */
{
    const char *srcStart, *srcEnd;
    const char *dstEnd, *dstStart;
    int result, numChars, charLimit = INT_MAX;

    flags = TclEncodingSetProfileFlags(flags);
    if (flags & TCL_ENCODING_CHAR_LIMIT) {
	charLimit = *dstCharsPtr;
    }
    srcStart = src;
    srcEnd = src + srcLen;

    dstStart = dst;
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3688
3689
3690
3691
3692
3693
3694

3695
3696
3697
3698
3699
3700
3701







-







    const char *dstStart, *dstEnd;
    int result = TCL_OK, numChars;
    Tcl_UniChar ch = 0;

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

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

3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3835
3836
3837
3838
3839
3840
3841

3842
3843
3844
3845
3846
3847
3848







-







    EscapeEncodingData *dataPtr = (EscapeEncodingData *)clientData;
    const char *prefixBytes, *tablePrefixBytes, *srcStart, *srcEnd;
    const unsigned short *const *tableToUnicode;
    const Encoding *encodingPtr;
    int state, result, numChars, charLimit = INT_MAX;
    const char *dstStart, *dstEnd;

    flags = TclEncodingSetProfileFlags(flags);
    if (flags & TCL_ENCODING_CHAR_LIMIT) {
	charLimit = *dstCharsPtr;
    }
    result = TCL_OK;
    tablePrefixBytes = NULL;
    tableToUnicode = NULL;
    prefixBytes = dataPtr->prefixBytes;
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4058
4059
4060
4061
4062
4063
4064

4065
4066
4067
4068
4069
4070
4071







-







    Tcl_UniChar ch = 0;

    result = TCL_OK;

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

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

4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
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
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4502
4503
4504
4505
4506
4507
4508










































4509
4510
4511
4512
4513
4514
4515







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







		"Internal error. Bad profile id \"%d\".",
		profileValue));
	Tcl_SetErrorCode(
	    interp, "TCL", "ENCODING", "PROFILEID", NULL);
    }
    return NULL;
}

/*
 *------------------------------------------------------------------------
 *
 * TclEncodingSetProfileFlags --
 *
 *	Maps the flags supported in the encoding C API's to internal flags.
 *
 *	For backward compatibility reasons, TCL_ENCODING_STOPONERROR is
 *	is mapped to the TCL_ENCODING_PROFILE_STRICT overwriting any profile
 *	specified.
 *
 *	If no profile or an invalid profile is specified, it is set to
 *	the default.
 *
 * Results:
 *    Internal encoding flag mask.
 *
 * Side effects:
 *    None.
 *
 *------------------------------------------------------------------------
 */
int TclEncodingSetProfileFlags(int flags)
{
    if (flags & TCL_ENCODING_STOPONERROR) {
	ENCODING_PROFILE_SET(flags, TCL_ENCODING_PROFILE_STRICT);
    } else {
	int profile = ENCODING_PROFILE_GET(flags);
	switch (profile) {
	case TCL_ENCODING_PROFILE_TCL8:
	case TCL_ENCODING_PROFILE_STRICT:
	case TCL_ENCODING_PROFILE_REPLACE:
	    break;
	case 0: /* Unspecified by caller */
	default:
	    ENCODING_PROFILE_SET(flags, TCL_ENCODING_PROFILE_TCL8);
	    break;
	}
    }
    return flags;
}

/*
 *------------------------------------------------------------------------
 *
 * TclGetEncodingProfiles --
 *
 *	Get the list of supported encoding profiles.
Changes to generic/tclIO.c.
9461
9462
9463
9464
9465
9466
9467






9468
9469
9470
9471
9472
9473
9474


9475
9476
9477
9478
9479
9480
9481
9461
9462
9463
9464
9465
9466
9467
9468
9469
9470
9471
9472
9473
9474
9475
9476
9477
9478


9479
9480
9481
9482
9483
9484
9485
9486
9487







+
+
+
+
+
+





-
-
+
+







    SetFlag(outStatePtr, CHANNEL_UNBUFFERED);

    /*
     * Test for conditions where we know we can just move bytes from input
     * channel to output channel with no transformation or even examination
     * of the bytes themselves.
     */

#define PROFILE_STRICT(flags_)                                         \
    ((ENCODING_PROFILE_GET(flags_) == (TCL_ENCODING_PROFILE_STRICT & ENCODING_PROFILE_MASK)) \
	    && ((flags_) && TCL_ENCODING_STOPONERROR))
#define PROFILE_REPLACE(flags_)                                         \
    (ENCODING_PROFILE_GET(flags_) == TCL_ENCODING_PROFILE_REPLACE)

    moveBytes = inStatePtr->inEofChar == '\0'	/* No eofChar to stop input */
	    && inStatePtr->inputTranslation == TCL_TRANSLATE_LF
	    && outStatePtr->outputTranslation == TCL_TRANSLATE_LF
	    && inStatePtr->encoding == outStatePtr->encoding
	    && ENCODING_PROFILE_GET(inStatePtr->inputEncodingFlags) == TCL_ENCODING_PROFILE_TCL8
	    && ENCODING_PROFILE_GET(outStatePtr->outputEncodingFlags) == TCL_ENCODING_PROFILE_TCL8;
	    && (!PROFILE_STRICT(inStatePtr->inputEncodingFlags) && !PROFILE_REPLACE(inStatePtr->inputEncodingFlags))
	    && (!PROFILE_STRICT(outStatePtr->outputEncodingFlags) && !PROFILE_REPLACE(outStatePtr->outputEncodingFlags));

    /*
     * Allocate a new CopyState to maintain info about the current copy in
     * progress. This structure will be deallocated when the copy is
     * completed.
     */

9795
9796
9797
9798
9799
9800
9801
9802
9803


9804
9805
9806
9807
9808
9809
9810
9801
9802
9803
9804
9805
9806
9807


9808
9809
9810
9811
9812
9813
9814
9815
9816







-
-
+
+







     * the copying. The caller uses Tcl_GetChannel to access it, and thus gets
     * the bottom of the stack.
     */

    inBinary = (inStatePtr->encoding == NULL);
    outBinary = (outStatePtr->encoding == NULL);
    sameEncoding = inStatePtr->encoding == outStatePtr->encoding
	    && ENCODING_PROFILE_GET(inStatePtr->inputEncodingFlags) == TCL_ENCODING_PROFILE_TCL8
	    && ENCODING_PROFILE_GET(outStatePtr->outputEncodingFlags) == TCL_ENCODING_PROFILE_TCL8;
	    && (!PROFILE_STRICT(inStatePtr->inputEncodingFlags) && !PROFILE_REPLACE(inStatePtr->inputEncodingFlags))
	    && (!PROFILE_STRICT(outStatePtr->outputEncodingFlags) && !PROFILE_REPLACE(outStatePtr->outputEncodingFlags));

    if (!(inBinary || sameEncoding)) {
	TclNewObj(bufObj);
	Tcl_IncrRefCount(bufObj);
    }

    while (csPtr->toRead != (Tcl_WideInt) 0) {
Changes to generic/tclInt.h.
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874




2875
2876
2877
2878
2879
2880
2881
2864
2865
2866
2867
2868
2869
2870




2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881







-
-
-
-
+
+
+
+







 * Internal convenience macros for manipulating encoding flags. See
 * TCL_ENCODING_PROFILE_* in tcl.h
 *----------------------------------------------------------------------
 */

#define ENCODING_PROFILE_MASK     0xFF000000
#define ENCODING_PROFILE_GET(flags_)  ((flags_) & ENCODING_PROFILE_MASK)
#define ENCODING_PROFILE_SET(flags_, profile_) \
    do {                                       \
	(flags_) &= ~ENCODING_PROFILE_MASK;    \
	(flags_) |= profile_;                  \
#define ENCODING_PROFILE_SET(flags_, profile_)      \
    do {                                            \
	(flags_) &= ~ENCODING_PROFILE_MASK;             \
	(flags_) |= (profile_) & ENCODING_PROFILE_MASK; \
    } while (0)

/*
 *----------------------------------------------------------------
 * Variables shared among Tcl modules but not used by the outside world.
 *----------------------------------------------------------------
 */
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2892
2893
2894
2895
2896
2897
2898

2899
2900
2901
2902
2903
2904
2905







-







MODULE_SCOPE Tcl_Encoding tclIdentityEncoding;
MODULE_SCOPE int
TclEncodingProfileNameToId(Tcl_Interp *interp,
			   const char *profileName,
			   int *profilePtr);
MODULE_SCOPE const char *TclEncodingProfileIdToName(Tcl_Interp *interp,
						    int profileId);
MODULE_SCOPE int TclEncodingSetProfileFlags(int flags);
MODULE_SCOPE void TclGetEncodingProfiles(Tcl_Interp *interp);

/*
 * TIP #233 (Virtualized Time)
 * Data for the time hooks, if any.
 */