Changes On Branch a4e62ef88ddbe8d2
Not logged in

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

Changes In Branch bug-39f6304c2e Through [a4e62ef88d] Excluding Merge-Ins

This is equivalent to a diff from 3fe8ec5fd6 to a4e62ef88d

2017-01-27
14:31
Some code cleanup: More internal use of size_t, less type casts (because of this). No functional cha... check-in: 0867ec3f75 user: jan.nijtmans tags: trunk
10:11
Slightly better implementation: re-use the function SetInvalidRealFromAny() in the double/float hand... check-in: 86e7f474f3 user: jan.nijtmans tags: bug-39f6304c2e
2017-01-26
11:49
Extend booleans to accept "+" and "-" as valid representation. And extend Tcl_LinkVar to accept bool... check-in: a4e62ef88d user: jan.nijtmans tags: bug-39f6304c2e
2017-01-25
12:50
Convert Tcl_SetResult() to a macro check-in: 36aa4f35f8 user: jan.nijtmans tags: novem
12:22
If TCL_NO_DEPRECATED is defined, remove the "case" statement, and use much less interp->result. Impl... check-in: 3fe8ec5fd6 user: jan.nijtmans tags: trunk
2017-01-20
16:21
Fix [39f6304c2e90549c209cd11a7920dc9921b9f48e|39f6304c2e] follow-up: Make Tcl_LinkVar toleranto to t... check-in: a1398bebc9 user: jan.nijtmans tags: trunk
2016-12-22
10:26
Merge trunk. Implement sequences like "0x", "0b" and "0o" as well. And also the "." for doubles and ... check-in: 8b14191fae user: jan.nijtmans tags: bug-39f6304c2e

Changes to doc/GetInt.3.
85
86
87
88
89
90
91
92

93
94
95

96
97
98
99
100
101
85
86
87
88
89
90
91

92
93
94

95
96
97
98
99
100
101







-
+


-
+






initial sequence of digits should take one of the forms that
\fBTcl_GetInt\fR supports, described above. The use of
.QW \fB,\fR
as a decimal point is not supported nor should any other sort of
inter-digit separator be present.
.PP
\fBTcl_GetBoolean\fR expects \fIsrc\fR to specify a boolean
value.  If \fIsrc\fR is any of \fB0\fR, \fBfalse\fR,
value.  If \fIsrc\fR is any of \fB0\fR, \fB-\fR, \fBfalse\fR,
\fBno\fR, or \fBoff\fR, then \fBTcl_GetBoolean\fR stores a zero
value at \fI*boolPtr\fR.
If \fIsrc\fR is any of \fB1\fR, \fBtrue\fR, \fByes\fR, or \fBon\fR,
If \fIsrc\fR is any of \fB1\fR, \fB+\fR, \fBtrue\fR, \fByes\fR, or \fBon\fR,
then 1 is stored at \fI*boolPtr\fR.
Any of these values may be abbreviated, and upper-case spellings
are also acceptable.

.SH KEYWORDS
boolean, conversion, double, floating-point, integer
Changes to generic/tclGet.c.
121
122
123
124
125
126
127
128

129
130
131
132
133
134
135
121
122
123
124
125
126
127

128
129
130
131
132
133
134
135







-
+







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

int
Tcl_GetBoolean(
    Tcl_Interp *interp,		/* Interpreter used for error reporting. */
    const char *src,		/* String containing one of the boolean values
				 * 1, 0, true, false, yes, no, on, off. */
				 * 1, 0, +, -, true, false, yes, no, on, off. */
    int *boolPtr)		/* Place to store converted result, which will
				 * be 0 or 1. */
{
    Tcl_Obj obj;
    int code;

    obj.refCount = 1;
Changes to generic/tclLink.c.
63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77







-
+







/*
 * Forward references to functions defined later in this file:
 */

static char *		LinkTraceProc(ClientData clientData,Tcl_Interp *interp,
			    const char *name1, const char *name2, int flags);
static Tcl_Obj *	ObjValue(Link *linkPtr);
static int		GetInvalidIntFromObj(Tcl_Obj *objPtr,
static int		GetInvalidIntOrBooleanFromObj(Tcl_Obj *objPtr,
				int *intPtr);
static int		GetInvalidDoubleFromObj(Tcl_Obj *objPtr,
				double *doublePtr);

/*
 * Convenience macro for accessing the value of the C variable pointed to by a
 * link. Note that this macro produces something that may be regarded as an
380
381
382
383
384
385
386
387

388
389
390
391

392
393
394
395
396
397
398
399
400

401
402
403
404

405
406
407
408
409
410
411
380
381
382
383
384
385
386

387
388
389
390

391
392
393
394
395
396
397
398
399

400
401
402
403

404
405
406
407
408
409
410
411







-
+



-
+








-
+



-
+







	return (char *) "internal error: linked variable couldn't be read";
    }

    switch (linkPtr->type) {
    case TCL_LINK_INT:
	if (Tcl_GetIntFromObj(NULL, valueObj, &linkPtr->lastValue.i)
		!= TCL_OK) {
	    if (GetInvalidIntFromObj(valueObj, &linkPtr->lastValue.i)
	    if (GetInvalidIntOrBooleanFromObj(valueObj, &linkPtr->lastValue.i)
		    != TCL_OK) {
		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
		    TCL_GLOBAL_ONLY);
		return (char *) "variable must have integer value";
		return (char *) "variable must have integer or boolean value";
	    }
	}
	LinkedVar(int) = linkPtr->lastValue.i;
	break;

    case TCL_LINK_WIDE_INT:
	if (Tcl_GetWideIntFromObj(NULL, valueObj, &linkPtr->lastValue.w)
		!= TCL_OK) {
	    if (GetInvalidIntFromObj(valueObj, &valueInt)
	    if (GetInvalidIntOrBooleanFromObj(valueObj, &valueInt)
		    != TCL_OK) {
		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
		    TCL_GLOBAL_ONLY);
		return (char *) "variable must have integer value";
		return (char *) "variable must have integer or boolean value";
	    }
	    linkPtr->lastValue.w = (Tcl_WideInt) valueInt;
	}
	LinkedVar(Tcl_WideInt) = linkPtr->lastValue.w;
	break;

    case TCL_LINK_DOUBLE:
437
438
439
440
441
442
443
444

445
446
447
448

449
450
451
452
453
454
455
456
457
458

459
460
461
462

463
464
465
466
467
468
469
470
471
472

473
474
475
476

477
478
479
480
481
482
483
484
485
486

487
488
489
490

491
492
493
494
495
496
497
498
499
500

501
502
503
504

505
506
507
508
509
510
511
512
513
514
515
516

517
518
519
520

521
522
523
524
525
526
527
528
529
530
531
532

533
534
535
536

537
538
539
540
541
542
543
544
545
546
547
548
549
550

551
552
553
554

555
556
557
558
559
560
561
437
438
439
440
441
442
443

444
445
446
447

448
449
450
451
452
453
454
455
456
457

458
459
460
461

462
463
464
465
466
467
468
469
470
471

472
473
474
475

476
477
478
479
480
481
482
483
484
485

486
487
488
489

490
491
492
493
494
495
496
497
498
499

500
501
502
503

504
505
506
507
508
509
510
511
512
513
514
515

516
517
518
519

520
521
522
523
524
525
526
527
528
529
530
531

532
533
534
535

536
537
538
539
540
541
542
543
544
545
546
547
548
549

550
551
552
553

554
555
556
557
558
559
560
561







-
+



-
+









-
+



-
+









-
+



-
+









-
+



-
+









-
+



-
+











-
+



-
+











-
+



-
+













-
+



-
+







	}
	LinkedVar(int) = linkPtr->lastValue.i;
	break;

    case TCL_LINK_CHAR:
	if (Tcl_GetIntFromObj(NULL, valueObj, &valueInt) != TCL_OK
		|| valueInt < SCHAR_MIN || valueInt > SCHAR_MAX) {
	    if (GetInvalidIntFromObj(valueObj, &valueInt)
	    if (GetInvalidIntOrBooleanFromObj(valueObj, &valueInt)
		    != TCL_OK) {
		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
			TCL_GLOBAL_ONLY);
		return (char *) "variable must have char value";
		return (char *) "variable must have char or boolean value";
	    }
	}
	linkPtr->lastValue.c = (char)valueInt;
	LinkedVar(char) = linkPtr->lastValue.c;
	break;

    case TCL_LINK_UCHAR:
	if (Tcl_GetIntFromObj(NULL, valueObj, &valueInt) != TCL_OK
		|| valueInt < 0 || valueInt > UCHAR_MAX) {
	    if (GetInvalidIntFromObj(valueObj, &valueInt)
	    if (GetInvalidIntOrBooleanFromObj(valueObj, &valueInt)
		    != TCL_OK) {
		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
			TCL_GLOBAL_ONLY);
		return (char *) "variable must have unsigned char value";
		return (char *) "variable must have unsigned char or boolean value";
	    }
	}
	linkPtr->lastValue.uc = (unsigned char) valueInt;
	LinkedVar(unsigned char) = linkPtr->lastValue.uc;
	break;

    case TCL_LINK_SHORT:
	if (Tcl_GetIntFromObj(NULL, valueObj, &valueInt) != TCL_OK
		|| valueInt < SHRT_MIN || valueInt > SHRT_MAX) {
	    if (GetInvalidIntFromObj(valueObj, &valueInt)
	    if (GetInvalidIntOrBooleanFromObj(valueObj, &valueInt)
		    != TCL_OK) {
		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
			TCL_GLOBAL_ONLY);
		return (char *) "variable must have short value";
		return (char *) "variable must have short or boolean value";
	    }
	}
	linkPtr->lastValue.s = (short)valueInt;
	LinkedVar(short) = linkPtr->lastValue.s;
	break;

    case TCL_LINK_USHORT:
	if (Tcl_GetIntFromObj(NULL, valueObj, &valueInt) != TCL_OK
		|| valueInt < 0 || valueInt > USHRT_MAX) {
	    if (GetInvalidIntFromObj(valueObj, &valueInt)
	    if (GetInvalidIntOrBooleanFromObj(valueObj, &valueInt)
		    != TCL_OK) {
		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
			TCL_GLOBAL_ONLY);
		return (char *) "variable must have unsigned short value";
		return (char *) "variable must have unsigned short or boolean value";
	    }
	}
	linkPtr->lastValue.us = (unsigned short)valueInt;
	LinkedVar(unsigned short) = linkPtr->lastValue.us;
	break;

    case TCL_LINK_UINT:
	if (Tcl_GetWideIntFromObj(NULL, valueObj, &valueWide) != TCL_OK
		|| valueWide < 0 || valueWide > UINT_MAX) {
	    if (GetInvalidIntFromObj(valueObj, &valueInt)
	    if (GetInvalidIntOrBooleanFromObj(valueObj, &valueInt)
		    != TCL_OK) {
		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
			TCL_GLOBAL_ONLY);
		return (char *) "variable must have unsigned int value";
		return (char *) "variable must have unsigned int or boolean value";
	    }
	    linkPtr->lastValue.ui = (unsigned int)valueInt;
	} else {
	    linkPtr->lastValue.ui = (unsigned int)valueWide;
	}
	LinkedVar(unsigned int) = linkPtr->lastValue.ui;
	break;

    case TCL_LINK_LONG:
	if (Tcl_GetWideIntFromObj(NULL, valueObj, &valueWide) != TCL_OK
		|| valueWide < LONG_MIN || valueWide > LONG_MAX) {
	    if (GetInvalidIntFromObj(valueObj, &valueInt)
	    if (GetInvalidIntOrBooleanFromObj(valueObj, &valueInt)
		    != TCL_OK) {
		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
			TCL_GLOBAL_ONLY);
		return (char *) "variable must have long value";
		return (char *) "variable must have long or boolean value";
	    }
	    linkPtr->lastValue.l = (long)valueInt;
	} else {
	    linkPtr->lastValue.l = (long)valueWide;
	}
	LinkedVar(long) = linkPtr->lastValue.l;
	break;

    case TCL_LINK_ULONG:
	if (Tcl_GetWideIntFromObj(NULL, valueObj, &valueWide) != TCL_OK
		|| valueWide < 0 || (Tcl_WideUInt) valueWide > ULONG_MAX) {
	    if (GetInvalidIntFromObj(valueObj, &valueInt)
	    if (GetInvalidIntOrBooleanFromObj(valueObj, &valueInt)
		    != TCL_OK) {
		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
			TCL_GLOBAL_ONLY);
		return (char *) "variable must have unsigned long value";
		return (char *) "variable must have unsigned long or boolean value";
	    }
	    linkPtr->lastValue.ul = (unsigned long)valueInt;
	} else {
	    linkPtr->lastValue.ul = (unsigned long)valueWide;
	}
	LinkedVar(unsigned long) = linkPtr->lastValue.ul;
	break;

    case TCL_LINK_WIDE_UINT:
	/*
	 * FIXME: represent as a bignum.
	 */
	if (Tcl_GetWideIntFromObj(NULL, valueObj, &valueWide) != TCL_OK) {
	    if (GetInvalidIntFromObj(valueObj, &valueInt)
	    if (GetInvalidIntOrBooleanFromObj(valueObj, &valueInt)
		    != TCL_OK) {
		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
			TCL_GLOBAL_ONLY);
		return (char *) "variable must have unsigned wide int value";
		return (char *) "variable must have unsigned wide int or boolean value";
	    }
	    linkPtr->lastValue.uw = (Tcl_WideUInt)valueInt;
	} else {
	    linkPtr->lastValue.uw = (Tcl_WideUInt)valueWide;
	}
	LinkedVar(Tcl_WideUInt) = linkPtr->lastValue.uw;
	break;
684
685
686
687
688
689
690
691
692
693
694
695
696


697
698
699
700
701

702
703
704
705
706
707
708
684
685
686
687
688
689
690

691
692
693


694
695
696
697
698
699

700
701
702
703
704
705
706
707







-



-
-
+
+




-
+







    NULL,				/* dupIntRepProc */
    NULL,				/* updateStringProc */
    SetInvalidRealFromAny		/* setFromAnyProc */
};

static int
SetInvalidRealFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr) {
    int length;
    const char *str;
    const char *endPtr;

    str = TclGetStringFromObj(objPtr, &length);
    if ((length == 1) && (str[0] == '.')){
    str = TclGetString(objPtr);
    if ((objPtr->length == 1) && (str[0] == '.')){
	objPtr->typePtr = &invalidRealType;
	objPtr->internalRep.doubleValue = 0.0;
	return TCL_OK;
    }
    if (TclParseNumber(NULL, objPtr, NULL, str, length, &endPtr,
    if (TclParseNumber(NULL, objPtr, NULL, str, objPtr->length, &endPtr,
	    TCL_PARSE_DECIMAL_ONLY) == TCL_OK) {
	/* If number is followed by [eE][+-]?, then it is an invalid
	 * double, but it could be the start of a valid double. */
	if (*endPtr == 'e' || *endPtr == 'E') {
	    ++endPtr;
	    if (*endPtr == '+' || *endPtr == '-') ++endPtr;
	    if (*endPtr == 0) {
716
717
718
719
720
721
722
723
724
725
726




727
728
729

730
731
732
733

734
735
736
737
738
739


740
741
742
743

744
745
746
747
748
749
750
751
752
753
754
755
756

757
758
759
760
761
762
763
764
765








766
767

768
769
770
771
772
773
774
775
776
715
716
717
718
719
720
721




722
723
724
725
726
727

728
729
730


731
732





733
734
735
736
737

738
739
740
741
742
743
744
745
746
747
748
749
750

751
752
753
754
755
756
757



758
759
760
761
762
763
764
765
766

767
768
769
770
771
772
773
774
775
776







-
-
-
-
+
+
+
+


-
+


-
-
+

-
-
-
-
-
+
+



-
+












-
+






-
-
-
+
+
+
+
+
+
+
+

-
+









	}
    }
    return TCL_ERROR;
}


/*
 * This function checks for integer representations, which are valid
 * when linking with C variables, but which are invalid in other
 * contexts in Tcl. Handled are "", "+", "-", "0x", "0b" and "0o"
 * (upperand lowercase). See bug [39f6304c2e].
 * This function checks for integer or boolean representations,
 * which are valid when linking with C variables, but which are
 * invalid in other contexts in Tcl. Handled are "", "0x", "0b"
 * and "0o" (upperand lowercase). See bug [39f6304c2e].
 */
int
GetInvalidIntFromObj(Tcl_Obj *objPtr,
GetInvalidIntOrBooleanFromObj(Tcl_Obj *objPtr,
				int *intPtr)
{
    int length;
    const char *str = TclGetStringFromObj(objPtr, &length);
    const char *str = TclGetString(objPtr);

    if ((length == 1) && strchr("+-", str[0])) {
	*intPtr = (str[0] == '+');
	return TCL_OK;
    } else if ((length == 0) ||
	    ((length == 2) && (str[0] == '0') && strchr("xXbBoO", str[1]))) {
    if ((objPtr->length == 0) ||
	    ((objPtr->length == 2) && (str[0] == '0') && strchr("xXbBoO", str[1]))) {
	*intPtr = 0;
	return TCL_OK;
    }
    return TCL_ERROR;
    return Tcl_GetBooleanFromObj(NULL, objPtr, intPtr);
}

/*
 * This function checks for double representations, which are valid
 * when linking with C variables, but which are invalid in other
 * contexts in Tcl. Handled are ".", "+", "-", "0x", "0b" and "0o"
 * (upper- and lowercase) and sequences like "1e-". See bug [39f6304c2e].
 */
int
GetInvalidDoubleFromObj(Tcl_Obj *objPtr,
				double *doublePtr)
{
    int intValue, result;
    const char *str;

    if ((objPtr->typePtr == &invalidRealType) ||
	    (SetInvalidRealFromAny(NULL, objPtr) == TCL_OK)) {
	*doublePtr = objPtr->internalRep.doubleValue;
	return TCL_OK;
    }
    result = GetInvalidIntFromObj(objPtr, &intValue);
    if (result == TCL_OK) {
	*doublePtr = (double) intValue;
    str = TclGetString(objPtr);
    if ((objPtr->length == 1) && strchr("+-", str[0])) {
       *doublePtr = (double)(str[0] == '+');
       return TCL_OK;
    } else if ((objPtr->length == 0) ||
           ((objPtr->length == 2) && (str[0] == '0') && strchr("xXbBoO", str[1]))) {
       *doublePtr = 0.0;
       return TCL_OK;
    }
    return result;
    return TCL_ERROR;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to generic/tclObj.c.
2000
2001
2002
2003
2004
2005
2006
2007

2008
2009


2010
2011
2012
2013
2014
2015
2016
2000
2001
2002
2003
2004
2005
2006

2007
2008

2009
2010
2011
2012
2013
2014
2015
2016
2017







-
+

-
+
+







    return TCL_ERROR;
}

static int
ParseBoolean(
    register Tcl_Obj *objPtr)	/* The object to parse/convert. */
{
    int i, length, newBool;
    int newBool;
    char lowerCase[6];
    const char *str = TclGetStringFromObj(objPtr, &length);
    const char *str = TclGetString(objPtr);
    size_t i, length = objPtr->length;

    if ((length == 0) || (length > 5)) {
	/*
         * Longest valid boolean string rep. is "false".
         */

	return TCL_ERROR;
2024
2025
2026
2027
2028
2029
2030












2031
2032
2033
2034
2035
2036
2037
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050







+
+
+
+
+
+
+
+
+
+
+
+







	}
	return TCL_ERROR;
    case '1':
	if (length == 1) {
	    newBool = 1;
	    goto numericBoolean;
	}
	return TCL_ERROR;
    case '-':
	if (length == 1) {
	    newBool = 0;
	    goto goodBoolean;
	}
	return TCL_ERROR;
    case '+':
	if (length == 1) {
	    newBool = 1;
	    goto goodBoolean;
	}
	return TCL_ERROR;
    }

    /*
     * Force to lower case for case-insensitive detection. Filter out known
     * invalid characters at the same time.
     */
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089


2090
2091
2092


2093
2094
2095
2096
2097
2098
2099
2091
2092
2093
2094
2095
2096
2097





2098
2099
2100


2101
2102
2103
2104
2105
2106
2107
2108
2109







-
-
-
-
-
+
+

-
-
+
+







    case 'f':
	if (strncmp(lowerCase, "false", (size_t) length) == 0) {
	    newBool = 0;
	    goto goodBoolean;
	}
	return TCL_ERROR;
    case 'o':
	if (length < 2) {
	    return TCL_ERROR;
	}
	if (strncmp(lowerCase, "on", (size_t) length) == 0) {
	    newBool = 1;
	if (strncmp(lowerCase, "off", (size_t) length) == 0) {
	    newBool = 0;
	    goto goodBoolean;
	} else if (strncmp(lowerCase, "off", (size_t) length) == 0) {
	    newBool = 0;
	} else if (strncmp(lowerCase, "on", (size_t) length) == 0) {
	    newBool = 1;
	    goto goodBoolean;
	}
	return TCL_ERROR;
    default:
	return TCL_ERROR;
    }

Changes to tests/link.test.
63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

92
93
94
95
96
97
98
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98







-
+




















-
+







} -result {465 -10.5 1 abcdef 135135 79 161 8000 40000 -1073628482 34543 567890 1.0987653732299805 357357357357 | 0o0721 -10.5 true abcdef 135135 79 161 8000 40000 0xc001babe 34543 567890 1.0987654321 357357357357}
test link-2.2 {writing bad values into variables} -setup {
    testlink delete
} -constraints {testlink} -body {
    testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    list [catch {set int 09a} msg] $msg $int
} -result {1 {can't set "int": variable must have integer value} 43}
} -result {1 {can't set "int": variable must have integer or boolean value} 43}
test link-2.3 {writing bad values into variables} -setup {
    testlink delete
} -constraints {testlink} -body {
    testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    list [catch {set real 1.x3} msg] $msg $real
} -result {1 {can't set "real": variable must have real value} 1.23}
test link-2.4 {writing bad values into variables} -setup {
    testlink delete
} -constraints {testlink} -body {
    testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    list [catch {set bool gorp} msg] $msg $bool
} -result {1 {can't set "bool": variable must have boolean value} 1}
test link-2.5 {writing bad values into variables} -setup {
    testlink delete
} -constraints {testlink} -body {
    testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    list [catch {set wide gorp} msg] $msg $bool
} -result {1 {can't set "wide": variable must have integer value} 1}
} -result {1 {can't set "wide": variable must have integer or boolean value} 1}
test link-2.6 {writing C variables from Tcl} -constraints {testlink} -setup {
    testlink delete
} -body {
    testlink set 43 1.21 4 - 56785678 64 250 30000 60000 0xbaadbeef 12321 32123 3.25 1231231234
    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    set int "+"
    set real "+"
305
306
307
308
309
310
311
312

313
314
315
316
317
318
319
305
306
307
308
309
310
311

312
313
314
315
316
317
318
319







-
+







    proc x {} {
	upvar int y
	set y abc
    }
    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    testlink set -4 {} {} {} {} {} {} {} {} {} {} {} {} {}
    list [catch x msg] $msg $int
} -result {1 {can't set "y": variable must have integer value} -4}
} -result {1 {can't set "y": variable must have integer or boolean value} -4}
test link-7.5 {access to linked variables via upvar} -setup {
    testlink delete
} -constraints {testlink} -body {
    proc x {} {
	upvar real y
	set y abc
    }
338
339
340
341
342
343
344
345

346
347
348
349
350
351
352
338
339
340
341
342
343
344

345
346
347
348
349
350
351
352







-
+







    proc x {} {
	upvar wide y
	set y abc
    }
    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    testlink set -4 16.3 1 {} 778899 {} {} {} {} {} {} {} {} {}
    list [catch x msg] $msg $wide
} -result {1 {can't set "y": variable must have integer value} 778899}
} -result {1 {can't set "y": variable must have integer or boolean value} 778899}

test link-8.1 {Tcl_UpdateLinkedVar procedure} {testlink} {
    proc x args {
	global x int real bool string wide
	lappend x $args $int $real $bool $string $wide
    }
    set x {}