Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Minimum backport [4b12ccb336] to Tcl 8.6. If we do %lld/%llu we should do the %I32/%I64 (microsoft-)variants as well, otherwise TCL_LL_MODIFIER only is usable on non-Windows platforms |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | rfe-4b12ccb336 |
Files: | files | file ages | folders |
SHA3-256: |
96aa2c6b01776329f9285d43e9b9a32a |
User & Date: | jan.nijtmans 2024-05-02 12:46:47 |
Context
2024-05-02
| ||
13:05 | A little bit more minimum check-in: 6f3cfbaafa user: jan.nijtmans tags: rfe-4b12ccb336 | |
12:46 | Minimum backport [4b12ccb336] to Tcl 8.6. If we do %lld/%llu we should do the %I32/%I64 (microsoft-)... check-in: 96aa2c6b01 user: jan.nijtmans tags: rfe-4b12ccb336 | |
11:12 | Remove COMPAT==0 part, no longer makes sense. More code-cleanup, backported from 8.7 check-in: f5665fcac2 user: jan.nijtmans tags: core-8-6-branch | |
Changes
Changes to generic/tclStringObj.c.
︙ | ︙ | |||
2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 | format += step; step = TclUtfToUniChar(format, &ch); #ifndef TCL_WIDE_INT_IS_LONG } else { useWide = 1; #endif } } format += step; span = format; /* * Step 6. The actual conversion character. | > > > > > > > > > > > > > > | 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 | format += step; step = TclUtfToUniChar(format, &ch); #ifndef TCL_WIDE_INT_IS_LONG } else { useWide = 1; #endif } } else if (ch == 'I') { if ((format[1] == '6') && (format[2] == '4')) { format += (step + 2); step = TclUtfToUniChar(format, &ch); #ifndef TCL_WIDE_INT_IS_LONG useWide = 1; #endif } else if ((format[1] == '3') && (format[2] == '2')) { format += (step + 2); step = TclUtfToUniChar(format, &ch); } else { format += step; step = TclUtfToUniChar(format, &ch); } } format += step; span = format; /* * Step 6. The actual conversion character. |
︙ | ︙ | |||
2138 2139 2140 2141 2142 2143 2144 | segment = Tcl_NewStringObj(buf, length); Tcl_IncrRefCount(segment); allocSegment = 1; break; } case 'u': | < < < < < < > | > | > > > > > > > > > > > > | 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 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 | segment = Tcl_NewStringObj(buf, length); Tcl_IncrRefCount(segment); allocSegment = 1; break; } case 'u': case 'd': case 'o': case 'x': case 'X': case 'b': { short s = 0; /* Silence compiler warning; only defined and * used when useShort is true. */ long l; Tcl_WideInt w; mp_int big; int isNegative = 0; int toAppend; if (useBig) { int cmpResult; if (Tcl_GetBignumFromObj(interp, segment, &big) != TCL_OK) { goto error; } cmpResult = mp_cmp_d(&big, 0); isNegative = (cmpResult == MP_LT); if (cmpResult == MP_EQ) gotHash = 0; if (ch == 'u') { if (isNegative) { mp_clear(&big); msg = "unsigned bignum format is invalid"; errCode = "BADUNSIGNED"; goto errorMsg; } else { ch = 'd'; } } #ifndef TCL_WIDE_INT_IS_LONG } else if (useWide) { if (Tcl_GetWideIntFromObj(NULL, segment, &w) != TCL_OK) { Tcl_Obj *objPtr; if (Tcl_GetBignumFromObj(interp,segment,&big) != TCL_OK) { goto error; |
︙ | ︙ | |||
2636 2637 2638 2639 2640 2641 2642 | { if ((value < 0) && strchr("puoxX", c)) { #ifdef TCL_WIDE_INT_IS_LONG mp_int bignumValue; mp_init_u64(&bignumValue, (unsigned long)value); return Tcl_NewBignumObj(&bignumValue); #else | | > > > > > > > > > > > > > | 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 | { if ((value < 0) && strchr("puoxX", c)) { #ifdef TCL_WIDE_INT_IS_LONG mp_int bignumValue; mp_init_u64(&bignumValue, (unsigned long)value); return Tcl_NewBignumObj(&bignumValue); #else return Tcl_NewWideIntObj((unsigned long)value); #endif } return Tcl_NewLongObj(value); } static Tcl_Obj * NewWideIntObj( char c, Tcl_WideInt value) { if ((value < 0) && strchr("puoxX", c)) { mp_int bignumValue; mp_init_u64(&bignumValue, (Tcl_WideUInt)value); return Tcl_NewBignumObj(&bignumValue); } return Tcl_NewWideIntObj(value); } static void AppendPrintfToObjVA( Tcl_Obj *objPtr, const char *format, va_list argList) { |
︙ | ︙ | |||
2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 | Tcl_ListObjAppendElement(NULL, list, Tcl_NewIntObj( va_arg(argList, int))); break; case 1: Tcl_ListObjAppendElement(NULL, list, NewLongObj(*p, va_arg(argList, long))); break; } break; case 'e': case 'E': case 'f': case 'g': case 'G': | > > > > | 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 | Tcl_ListObjAppendElement(NULL, list, Tcl_NewIntObj( va_arg(argList, int))); break; case 1: Tcl_ListObjAppendElement(NULL, list, NewLongObj(*p, va_arg(argList, long))); break; case 2: Tcl_ListObjAppendElement(NULL, list, NewWideIntObj(*p, va_arg(argList, Tcl_WideInt))); break; } break; case 'e': case 'E': case 'f': case 'g': case 'G': |
︙ | ︙ | |||
2755 2756 2757 2758 2759 2760 2761 | p = end; break; } case '.': gotPrecision = 1; p++; break; | < > > > > > > | > > > > > | 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 | p = end; break; } case '.': gotPrecision = 1; p++; break; case 'l': ++size; p++; break; case 'I': if (p[1]=='6' && p[2]=='4') { p += 2; size = 2; } else if (p[1]=='3' && p[2]=='2') { p += 2; } else if (sizeof(size_t) == sizeof(Tcl_WideInt)) { size = 2; } p++; break; case 'h': size = -1; /* FALLTHRU */ default: p++; |
︙ | ︙ |
Changes to tests/format.test.
︙ | ︙ | |||
17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # %u output depends on word length, so this test is not portable. testConstraint longIs32bit [expr {int(0x80000000) < 0}] testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}] testConstraint wideIs64bit [expr { (wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}] testConstraint wideBiggerThanInt [expr {wide(0x80000000) != int(0x80000000)}] # MSVC uses a broken libc that gets sprintf("%g") wrong. This is a pain # particularly in Continuous Integration, and there isn't anything much we can # do about it. testConstraint notWinCI [expr { ($::tcl_platform(platform) ne "windows") || ![info exists ::env(CI)]}] test format-1.1 {integer formatting} { | > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | # %u output depends on word length, so this test is not portable. testConstraint longIs32bit [expr {int(0x80000000) < 0}] testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}] testConstraint wideIs64bit [expr { (wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}] testConstraint wideBiggerThanInt [expr {wide(0x80000000) != int(0x80000000)}] testConstraint pointerIs64bit [expr {$tcl_platform(pointerSize) >= 8}] # MSVC uses a broken libc that gets sprintf("%g") wrong. This is a pain # particularly in Continuous Integration, and there isn't anything much we can # do about it. testConstraint notWinCI [expr { ($::tcl_platform(platform) ne "windows") || ![info exists ::env(CI)]}] test format-1.1 {integer formatting} { |
︙ | ︙ | |||
374 375 376 377 378 379 380 381 382 383 384 385 386 387 | catch {format %d} msg set msg } {not enough arguments for all format specifiers} test format-8.23 {error conditions} { catch {format "%d %d" 24 xyz} msg set msg } {expected integer but got "xyz"} test format-9.1 {long result} { set a {1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z} format {1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG %s %s} $a $a } {1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z} test format-10.1 {"h" format specifier} { | > > > | 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 | catch {format %d} msg set msg } {not enough arguments for all format specifiers} test format-8.23 {error conditions} { catch {format "%d %d" 24 xyz} msg set msg } {expected integer but got "xyz"} test format-8.25 {%lld / %llu} -constraints pointerIs64bit -body { format "%lld %llu" [expr {2**33}] [expr {2**33}] } -result {8589934592 8589934592} test format-9.1 {long result} { set a {1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z} format {1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG %s %s} $a $a } {1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z} test format-10.1 {"h" format specifier} { |
︙ | ︙ | |||
541 542 543 544 545 546 547 | format %ld 42 } 42 test format-17.4 {testing %l with non-integer} { format %lf 1 } 1.000000 test format-17.5 {testing %llu with positive bignum} -body { format %llu 0xabcdef0123456789abcdef | | | 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 | format %ld 42 } 42 test format-17.4 {testing %l with non-integer} { format %lf 1 } 1.000000 test format-17.5 {testing %llu with positive bignum} -body { format %llu 0xabcdef0123456789abcdef } -result 207698809136909011942886895 test format-17.6 {testing %llu with negative number} -body { format %llu -1 } -returnCodes 1 -result {unsigned bignum format is invalid} test format-18.1 {do not demote existing numeric values} { set a 0xaaaaaaaa # Ensure $a and $b are separate objects |
︙ | ︙ |