Tcl Source Code

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

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

Overview
Comment:Fix compilation on Visual C++ 6.0, which doesn't have LLONG_MIN/LLONG_MAX
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | core-8-branch
Files: files | file ages | folders
SHA3-256: 28c1c59dbb6e5a8bd3c119e8f4699dc784d6e7c8055b0957f82efff3842e03ba
User & Date: jan.nijtmans 2018-10-29 19:57:29
Context
2018-10-30
20:42
Merge 8.6 check-in: 5547022128 user: jan.nijtmans tags: core-8-branch
15:07
merge core-8-branch check-in: ccef542a42 user: dkf tags: info-linkedname
2018-10-29
21:00
Another attempt using cross-compile check-in: 7ab351a773 user: jan.nijtmans tags: travis-8.7-wine
19:58
Merge 8.7 check-in: f96f19e7e4 user: jan.nijtmans tags: trunk
19:57
Fix compilation on Visual C++ 6.0, which doesn't have LLONG_MIN/LLONG_MAX check-in: 28c1c59dbb user: jan.nijtmans tags: core-8-branch
19:55
merge-mark check-in: bf56d48b86 user: jan.nijtmans tags: core-8-6-branch
14:39
merge mark check-in: 14ebe914be user: dgp tags: core-8-branch
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tclUtil.c.

3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
....
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
....
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
....
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
....
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
....
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
....
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
	    *widePtr = (Tcl_WideInt)(*(Tcl_WideInt *)cd);
	    return TCL_OK;
	}
	if (numType == TCL_NUMBER_BIG) {
	    /* objPtr holds an integer outside the signed wide range */
	    /* Truncate to the signed wide range. */
	    if (mp_isneg((mp_int *)cd)) {
		*widePtr = LLONG_MIN;
	    } else {
		*widePtr = LLONG_MAX;
	    }
	    return TCL_OK;
	}
	/* Must be a double -> not a valid index */
	goto parseError;
    }

................................................................................
	TclFreeIntRep(objPtr);

	if (t1 && t2) {
	    /* We have both integer values */
	    if ((t1 == TCL_NUMBER_INT) && (t2 == TCL_NUMBER_INT)) {
		/* Both are wide, do wide-integer math */
		if (*opPtr == '-') {
		    if ((w2 == LLONG_MIN) && (interp != NULL)) {
			goto extreme;
		    }
		    w2 = -w2;
		}

		if ((w1 ^ w2) < 0) {
		    /* Different signs, sum cannot overflow */
		    *widePtr = w1 + w2;
		} else if (w1 >= 0) {
		    if (w1 < LLONG_MAX - w2) {
			*widePtr = w1 + w2;
		    } else {
			*widePtr = LLONG_MAX;
		    }
		} else {
		    if (w1 > LLONG_MIN - w2) {
			*widePtr = w1 + w2;
		    } else {
			*widePtr = LLONG_MIN;
		    }
		}
	    } else if (interp == NULL) {
		/*
		 * We use an interp to do bignum index calculations.
		 * If we don't get one, call all indices with bignums errors,
		 * and rely on callers to handle it.
................................................................................
		if (numType == TCL_NUMBER_INT) {
		    /* sum holds an integer in the signed wide range */
		    *widePtr = (Tcl_WideInt)(*(Tcl_WideInt *)cd);
		} else {
		    /* sum holds an integer outside the signed wide range */
		    /* Truncate to the signed wide range. */
		    if (mp_isneg((mp_int *)cd)) {
			*widePtr = LLONG_MIN;
		    } else {
			*widePtr = LLONG_MAX;
		    }
		}
		Tcl_DecrRefCount(sum);
	    }
	    return TCL_OK;
	}
    }
................................................................................

	    /* Got an integer offset; pull it from where parser left it. */
	    TclGetNumberFromObj(NULL, objPtr, &cd, &t);

	    if (t == TCL_NUMBER_BIG) {
		/* Truncate to the signed wide range. */
		if (mp_isneg((mp_int *)cd)) {
		    offset = (bytes[3] == '-') ? LLONG_MAX : LLONG_MIN;
		} else {
		    offset = (bytes[3] == '-') ? LLONG_MIN : LLONG_MAX;
		}
	    } else {
		/* assert (t == TCL_NUMBER_INT); */
		offset = (*(Tcl_WideInt *)cd);
		if (bytes[3] == '-') {
		    offset = (offset == LLONG_MIN) ? LLONG_MAX : -offset;
		}
	    }
	}

	/* Success. Free the old internal rep and set the new one. */
	TclFreeIntRep(objPtr);
	objPtr->internalRep.wideValue = offset;
................................................................................

    offset = objPtr->internalRep.wideValue;

    if ((endValue ^ offset) < 0) {
        /* Different signs, sum cannot overflow */
        *widePtr = endValue + offset;
    } else if (endValue >= 0) {
        if (endValue < LLONG_MAX - offset) {
            *widePtr = endValue + offset;
        } else {
            *widePtr = LLONG_MAX;
        }
    } else {
        if (endValue > LLONG_MIN - offset) {
            *widePtr = endValue + offset;
        } else {
            *widePtr = LLONG_MIN;
        }
    }
    return TCL_OK;
}
 
/*
 *----------------------------------------------------------------------
................................................................................
    int *indexPtr)	/* Where to write the encoded answer, not NULL */
{
    ClientData cd;
    Tcl_WideInt wide;
    int idx, numType, code = TclGetNumberFromObj(NULL, objPtr, &cd, &numType);

    if ((code == TCL_OK) && (numType == TCL_NUMBER_INT)) {
        /* We parsed a value in the range LLONG_MIN...LLONG_MAX */
	wide = (*(Tcl_WideInt *)cd);
    integerEncode:
        if (wide < TCL_INDEX_START) {
            /* All negative absolute indices are "before the beginning" */
            idx = before;
        } else if (wide >= INT_MAX) {
            /* This index value is always "after the end" */
................................................................................
        } else {
	    idx = (int) wide;
	}
        /* usual case, the absolute index value encodes itself */
    } else if (TCL_OK == GetEndOffsetFromObj(objPtr, 0, &wide)) {
        /*
         * We parsed an end+offset index value.
         * wide holds the offset value in the range LLONG_MIN...LLONG_MAX.
         */
        if (wide > 0) {
            /*
             * All end+postive or end-negative expressions
             * always indicate "after the end".
             */
            idx = after;






|

|







 







|









|


|


|


|







 







|

|







 







|

|





|







 







|


|


|


|







 







|







 







|







3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
....
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
....
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
....
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
....
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
....
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
....
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
	    *widePtr = (Tcl_WideInt)(*(Tcl_WideInt *)cd);
	    return TCL_OK;
	}
	if (numType == TCL_NUMBER_BIG) {
	    /* objPtr holds an integer outside the signed wide range */
	    /* Truncate to the signed wide range. */
	    if (mp_isneg((mp_int *)cd)) {
		*widePtr = WIDE_MIN;
	    } else {
		*widePtr = WIDE_MAX;
	    }
	    return TCL_OK;
	}
	/* Must be a double -> not a valid index */
	goto parseError;
    }

................................................................................
	TclFreeIntRep(objPtr);

	if (t1 && t2) {
	    /* We have both integer values */
	    if ((t1 == TCL_NUMBER_INT) && (t2 == TCL_NUMBER_INT)) {
		/* Both are wide, do wide-integer math */
		if (*opPtr == '-') {
		    if ((w2 == WIDE_MIN) && (interp != NULL)) {
			goto extreme;
		    }
		    w2 = -w2;
		}

		if ((w1 ^ w2) < 0) {
		    /* Different signs, sum cannot overflow */
		    *widePtr = w1 + w2;
		} else if (w1 >= 0) {
		    if (w1 < WIDE_MAX - w2) {
			*widePtr = w1 + w2;
		    } else {
			*widePtr = WIDE_MAX;
		    }
		} else {
		    if (w1 > WIDE_MIN - w2) {
			*widePtr = w1 + w2;
		    } else {
			*widePtr = WIDE_MIN;
		    }
		}
	    } else if (interp == NULL) {
		/*
		 * We use an interp to do bignum index calculations.
		 * If we don't get one, call all indices with bignums errors,
		 * and rely on callers to handle it.
................................................................................
		if (numType == TCL_NUMBER_INT) {
		    /* sum holds an integer in the signed wide range */
		    *widePtr = (Tcl_WideInt)(*(Tcl_WideInt *)cd);
		} else {
		    /* sum holds an integer outside the signed wide range */
		    /* Truncate to the signed wide range. */
		    if (mp_isneg((mp_int *)cd)) {
			*widePtr = WIDE_MIN;
		    } else {
			*widePtr = WIDE_MAX;
		    }
		}
		Tcl_DecrRefCount(sum);
	    }
	    return TCL_OK;
	}
    }
................................................................................

	    /* Got an integer offset; pull it from where parser left it. */
	    TclGetNumberFromObj(NULL, objPtr, &cd, &t);

	    if (t == TCL_NUMBER_BIG) {
		/* Truncate to the signed wide range. */
		if (mp_isneg((mp_int *)cd)) {
		    offset = (bytes[3] == '-') ? WIDE_MAX : WIDE_MIN;
		} else {
		    offset = (bytes[3] == '-') ? WIDE_MIN : WIDE_MAX;
		}
	    } else {
		/* assert (t == TCL_NUMBER_INT); */
		offset = (*(Tcl_WideInt *)cd);
		if (bytes[3] == '-') {
		    offset = (offset == WIDE_MIN) ? WIDE_MAX : -offset;
		}
	    }
	}

	/* Success. Free the old internal rep and set the new one. */
	TclFreeIntRep(objPtr);
	objPtr->internalRep.wideValue = offset;
................................................................................

    offset = objPtr->internalRep.wideValue;

    if ((endValue ^ offset) < 0) {
        /* Different signs, sum cannot overflow */
        *widePtr = endValue + offset;
    } else if (endValue >= 0) {
        if (endValue < WIDE_MAX - offset) {
            *widePtr = endValue + offset;
        } else {
            *widePtr = WIDE_MAX;
        }
    } else {
        if (endValue > WIDE_MIN - offset) {
            *widePtr = endValue + offset;
        } else {
            *widePtr = WIDE_MIN;
        }
    }
    return TCL_OK;
}
 
/*
 *----------------------------------------------------------------------
................................................................................
    int *indexPtr)	/* Where to write the encoded answer, not NULL */
{
    ClientData cd;
    Tcl_WideInt wide;
    int idx, numType, code = TclGetNumberFromObj(NULL, objPtr, &cd, &numType);

    if ((code == TCL_OK) && (numType == TCL_NUMBER_INT)) {
        /* We parsed a value in the range WIDE_MIN...WIDE_MAX */
	wide = (*(Tcl_WideInt *)cd);
    integerEncode:
        if (wide < TCL_INDEX_START) {
            /* All negative absolute indices are "before the beginning" */
            idx = before;
        } else if (wide >= INT_MAX) {
            /* This index value is always "after the end" */
................................................................................
        } else {
	    idx = (int) wide;
	}
        /* usual case, the absolute index value encodes itself */
    } else if (TCL_OK == GetEndOffsetFromObj(objPtr, 0, &wide)) {
        /*
         * We parsed an end+offset index value.
         * wide holds the offset value in the range WIDE_MIN...WIDE_MAX.
         */
        if (wide > 0) {
            /*
             * All end+postive or end-negative expressions
             * always indicate "after the end".
             */
            idx = after;