Index: doc/GetInt.3 ================================================================== --- doc/GetInt.3 +++ doc/GetInt.3 @@ -55,20 +55,23 @@ followed by white space. If the first two characters of \fIsrc\fR after the optional white space and sign are .QW \fB0x\fR then \fIsrc\fR is expected to be in hexadecimal form; otherwise, if the first such characters are +.QW \fB0d\fR +then \fIsrc\fR is expected to be in decimal form; otherwise, +if the first such characters are .QW \fB0o\fR then \fIsrc\fR is expected to be in octal form; otherwise, if the first such characters are .QW \fB0b\fR then \fIsrc\fR is expected to be in binary form; otherwise, if the first such character is .QW \fB0\fR then \fIsrc\fR -is expected to be in octal form; otherwise, \fIsrc\fR is -expected to be in decimal form. +is expected to be in octal form; otherwise, \fIsrc\fR +is expected to be in decimal form. .PP \fBTcl_GetDouble\fR expects \fIsrc\fR to consist of a floating-point number, which is: white space; a sign; a sequence of digits; a decimal point .QW \fB.\fR ; Index: doc/expr.n ================================================================== --- doc/expr.n +++ doc/expr.n @@ -41,11 +41,12 @@ A Tcl expression consists of a combination of operands, operators, parentheses and commas. White space may be used between the operands and operators and parentheses (or commas); it is ignored by the expression's instructions. Where possible, operands are interpreted as integer values. -Integer values may be specified in decimal (the normal case), in binary +Integer values may be specified in decimal (the normal case, the optional +first two characters are \fB0d\fR), in binary (if the first two characters of the operand are \fB0b\fR), in octal (if the first two characters of the operand are \fB0o\fR), or in hexadecimal (if the first two characters of the operand are \fB0x\fR). For compatibility with older Tcl releases, an octal integer value is also indicated simply when the first character of the operand is \fB0\fR, Index: doc/format.n ================================================================== --- doc/format.n +++ doc/format.n @@ -87,10 +87,12 @@ conversions it guarantees that the first digit is always \fB0\fR. For \fBx\fR or \fBX\fR conversions, \fB0x\fR or \fB0X\fR (respectively) will be added to the beginning of the result unless it is zero. For \fBb\fR conversions, \fB0b\fR will be added to the beginning of the result unless it is zero. +For \fBd\fR conversions, \fB0d\fR will be added to the beginning +of the result unless it is zero. For all floating-point conversions (\fBe\fR, \fBE\fR, \fBf\fR, \fBg\fR, and \fBG\fR) it guarantees that the result always has a decimal point. For \fBg\fR and \fBG\fR conversions it specifies that trailing zeroes should not be removed. Index: generic/tclLink.c ================================================================== --- generic/tclLink.c +++ generic/tclLink.c @@ -675,21 +675,21 @@ /* * 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" + * contexts in Tcl. Handled are "+", "-", "", "0x", "0b", "0d" and "0o" * (upperand lowercase). See bug [39f6304c2e]. */ int GetInvalidIntFromObj(Tcl_Obj *objPtr, int *intPtr) { const char *str = TclGetString(objPtr); if ((objPtr->length == 0) || - ((objPtr->length == 2) && (str[0] == '0') && strchr("xXbBoO", str[1]))) { + ((objPtr->length == 2) && (str[0] == '0') && strchr("xXbBoOdD", str[1]))) { *intPtr = 0; return TCL_OK; } else if ((objPtr->length == 1) && strchr("+-", str[0])) { *intPtr = (str[0] == '+'); return TCL_OK; Index: generic/tclStrToD.c ================================================================== --- generic/tclStrToD.c +++ generic/tclStrToD.c @@ -487,11 +487,11 @@ * that terminated the scan. */ int flags) /* Flags governing the parse. */ { enum State { INITIAL, SIGNUM, ZERO, ZERO_X, - ZERO_O, ZERO_B, BINARY, + ZERO_O, ZERO_B, ZERO_D, BINARY, HEXADECIMAL, OCTAL, BAD_OCTAL, DECIMAL, LEADING_RADIX_POINT, FRACTION, EXPONENT_START, EXPONENT_SIGNUM, EXPONENT, sI, sIN, sINF, sINFI, sINFIN, sINFINI, sINFINIT, sINFINITY #ifdef IEEE_FLOATING_POINT @@ -654,10 +654,14 @@ } if (c == 'o' || c == 'O') { explicitOctal = 1; state = ZERO_O; break; + } + if (c == 'd' || c == 'D') { + state = ZERO_D; + break; } #ifdef KILL_OCTAL goto decimal; #endif /* FALLTHROUGH */ @@ -871,10 +875,20 @@ } numTrailZeros = 0; state = BINARY; break; + case ZERO_D: + if (c == '0') { + numTrailZeros++; + } else if ( ! isdigit(UCHAR(c))) { + goto endgame; + } + state = DECIMAL; + flags |= TCL_PARSE_INTEGER_ONLY; + /* FALLTHROUGH */ + case DECIMAL: /* * Scanned an optional + or - followed by a string of decimal * digits. */ @@ -1167,10 +1181,11 @@ case SIGNUM: case BAD_OCTAL: case ZERO_X: case ZERO_O: case ZERO_B: + case ZERO_D: case LEADING_RADIX_POINT: case EXPONENT_START: case EXPONENT_SIGNUM: case sI: case sIN: Index: generic/tclStringObj.c ================================================================== --- generic/tclStringObj.c +++ generic/tclStringObj.c @@ -2034,10 +2034,14 @@ break; case 'b': Tcl_AppendToObj(segment, "0b", 2); segmentLimit -= 2; break; + case 'd': + Tcl_AppendToObj(segment, "0d", 2); + segmentLimit -= 2; + break; } } switch (ch) { case 'd': { Index: tests/cmdIL.test ================================================================== --- tests/cmdIL.test +++ tests/cmdIL.test @@ -217,12 +217,12 @@ } -returnCodes error -result {expected integer but got "x"} test cmdIL-3.10 {SortCompare procedure, -integer option} -body { lsort -integer {3 q} } -returnCodes error -result {expected integer but got "q"} test cmdIL-3.11 {SortCompare procedure, -integer option} { - lsort -integer {35 21 0x20 30 0o23 100 8} -} {8 0o23 21 30 0x20 35 100} + lsort -integer {35 21 0x20 0d30 0o23 100 8} +} {8 0o23 21 0d30 0x20 35 100} test cmdIL-3.12 {SortCompare procedure, -real option} -body { lsort -real {6...4 3} } -returnCodes error -result {expected floating-point number but got "6...4"} test cmdIL-3.13 {SortCompare procedure, -real option} -body { lsort -real {3 1x7} Index: tests/format.test ================================================================== --- tests/format.test +++ tests/format.test @@ -78,26 +78,26 @@ test format-1.12 {integer formatting} { format "%b %#b %#b %llb" 5 0 5 [expr {2**100}] } {101 0b0 0b101 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000} test format-1.13 {integer formatting} longIs32bit { format "%#d %#d %#d %#d %#d" 0 6 34 16923 -12 -1 -} {0 6 34 16923 -12} +} {0d0 0d6 0d34 0d16923 -0d12} test format-1.13.1 {integer formatting} longIs64bit { format "%#d %#d %#d %#d %#d" 0 6 34 16923 -12 -1 -} {0 6 34 16923 -12} +} {0d0 0d6 0d34 0d16923 -0d12} test format-1.14 {integer formatting} longIs32bit { format "%#5d %#20d %#20d %#20d %#20d" 0 6 34 16923 -12 -1 -} { 0 6 34 16923 -12} +} { 0d0 0d6 0d34 0d16923 -0d12} test format-1.14.1 {integer formatting} longIs64bit { format "%#5d %#20d %#20d %#20d %#20d" 0 6 34 16923 -12 -1 -} { 0 6 34 16923 -12} +} { 0d0 0d6 0d34 0d16923 -0d12} test format-1.15 {integer formatting} longIs32bit { format "%-#5d %-#20d %-#20d %-#20d %-#20d" 0 6 34 16923 -12 -1 -} {0 6 34 16923 -12 } +} {0d0 0d6 0d34 0d16923 -0d12 } test format-1.15.1 {integer formatting} longIs64bit { format "%-#5d %-#20d %-#20d %-#20d %-#20d" 0 6 34 16923 -12 -1 -} {0 6 34 16923 -12 } +} {0d0 0d6 0d34 0d16923 -0d12 } test format-2.1 {string formatting} { format "%s %s %c %s" abcd {This is a very long test string.} 120 x } {abcd This is a very long test string. x x} Index: tests/link.test ================================================================== --- tests/link.test +++ tests/link.test @@ -171,10 +171,31 @@ set ulong 0 set float -60.00e+ set uwide 0 concat [testlink get] | $int $real $bool $string $wide $char $uchar $short $ushort $uint $long $ulong $float $uwide } -result {0 5000.0 0 0 0 0 0 0 0 0 0 0 -60.0 0 | 0 5000e 0 0 0 0 0 0 0 0 0 0 -60.00e+ 0} +test link-2.10 {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 "0x" + set real "0b" + set bool 0 + set string "0" + set wide "0D" + set char "0X" + set uchar "0B" + set short "0D" + set ushort "0x" + set uint "0b" + set long "0d" + set ulong "0X" + set float "0B" + set uwide "0D" + concat [testlink get] | $int $real $bool $string $wide $char $uchar $short $ushort $uint $long $ulong $float $uwide +} -result {0 0.0 0 0 0 0 0 0 0 0 0 0 0.0 0 | 0x 0b 0 0 0D 0X 0B 0D 0x 0b 0d 0X 0B 0D} test link-3.1 {read-only variables} -constraints {testlink} -setup { testlink delete } -body { testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234 Index: tests/util.test ================================================================== --- tests/util.test +++ tests/util.test @@ -550,10 +550,16 @@ string index abcd 01 } b test util-9.0.7 {TclGetIntForIndex} { string index abcd { 01 } } b +test util-9.0.8 {TclGetIntForIndex} { + string index abcd { 0d0 } +} a +test util-9.0.9 {TclGetIntForIndex} { + string index abcd { -0d0 } +} a test util-9.1.0 {TclGetIntForIndex} { string index abcd 3 } d test util-9.1.1 {TclGetIntForIndex} { string index abcd { 3 } @@ -561,10 +567,16 @@ test util-9.1.2 {TclGetIntForIndex} { string index abcdefghijk 0xa } k test util-9.1.3 {TclGetIntForIndex} { string index abcdefghijk { 0xa } +} k +test util-9.1.4 {TclGetIntForIndex} { + string index abcdefghijk 0d10 +} k +test util-9.1.5 {TclGetIntForIndex} { + string index abcdefghijk { 0d10 } } k test util-9.2.0 {TclGetIntForIndex} { string index abcd end } d test util-9.2.1 {TclGetIntForIndex} -body { @@ -668,16 +680,22 @@ test util-9.30 {TclGetIntForIndex} -body { string index a {0+ } } -returnCodes error -match glob -result * test util-9.31 {TclGetIntForIndex} -body { string index a 0x +} -returnCodes error -match glob -result * +test util-9.31.1 {TclGetIntForIndex} -body { + string index a 0d } -returnCodes error -match glob -result * test util-9.32 {TclGetIntForIndex} -body { string index a 0x1FFFFFFFF+0 } -returnCodes error -match glob -result * test util-9.33 {TclGetIntForIndex} -body { string index a 100000000000+0 +} -returnCodes error -match glob -result * +test util-9.33.1 {TclGetIntForIndex} -body { + string index a 0d100000000000+0 } -returnCodes error -match glob -result * test util-9.34 {TclGetIntForIndex} -body { string index a 1.0 } -returnCodes error -match glob -result * test util-9.35 {TclGetIntForIndex} -body {