diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2024-05-30 21:52:02 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2024-05-30 21:52:02 (GMT) |
commit | a61d95045e2a65e0c2d418576016e24d29906994 (patch) | |
tree | 3e442b0535cda92d5e44030d1eaff97976af5b43 | |
parent | c6cbb0ff4a7bb42711f2b21953de289903ffa8b4 (diff) | |
parent | 9ce6a4582944552a01b327cb06eb7b420e914f08 (diff) | |
download | tcl-a61d95045e2a65e0c2d418576016e24d29906994.zip tcl-a61d95045e2a65e0c2d418576016e24d29906994.tar.gz tcl-a61d95045e2a65e0c2d418576016e24d29906994.tar.bz2 |
Fix [9c258a841a]: document %t/%z/%j/%q size field specifiers. Fix %j/%z/%t matching the C printf
-rw-r--r-- | doc/format.n | 17 | ||||
-rw-r--r-- | generic/tclStringObj.c | 19 | ||||
-rw-r--r-- | tests/format.test | 6 |
3 files changed, 28 insertions, 14 deletions
diff --git a/doc/format.n b/doc/format.n index eb64491..b0a0107 100644 --- a/doc/format.n +++ b/doc/format.n @@ -133,21 +133,22 @@ it must be a numeric string. .SS "OPTIONAL SIZE MODIFIER" .PP The fifth part of a conversion specifier is a size modifier, -which must be \fBll\fR, \fBh\fR, \fBl\fR, or \fBL\fR. +which must be \fBll\fR, \fBh\fR, \fBl\fR, \fBz\fR, \fBt\fR, or \fBL\fR. If it is \fBll\fR it specifies that an integer value is taken without truncation for conversion to a formatted substring. If it is \fBh\fR it specifies that an integer value is truncated to a 16-bit range before converting. This option is rarely useful. -If it is \fBl\fR it specifies that the integer value is -truncated to the same range as that produced by the \fBwide()\fR +If it is \fBl\fR (or \fBj\fR or \fBq\fR) it specifies that the integer value +is truncated to the same range as that produced by the \fBwide()\fR function of the \fBexpr\fR command (at least a 64-bit range). +If it is \fBz\fR or \fBt\fR it specifies that the integer value is +truncated to the range determined by the value of the \fBpointerSize\fR +element of the \fBtcl_platform\fR array. If it is \fBL\fR it specifies that an integer or double value is taken without truncation for conversion to a formatted substring. -If neither \fBh\fR nor \fBl\fR nor \fBL\fR are present, the integer value is -truncated to the same range as that produced by the \fBint()\fR -function of the \fBexpr\fR command (at least a 32-bit range, but -determined by the value of the \fBwordSize\fR element of the -\fBtcl_platform\fR array). +If neither of those are present, the integer value is +truncated to the range determined by the value of the +\fBwordSize\fR element of the \fBtcl_platform\fR array). .SS "MANDATORY CONVERSION TYPE" .PP The last thing in a conversion specifier is an alphabetic character diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 980bf22..b4da1a9 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -2457,8 +2457,21 @@ Tcl_AppendFormatToObj( format += step; step = TclUtfToUniChar(format, &ch); } - } else if ((ch == 't') || (ch == 'z') || (ch == 'q') || (ch == 'j') - || (ch == 'L')) { + } else if ((ch == 'q') || (ch == 'j')) { + format += step; + step = TclUtfToUniChar(format, &ch); +#ifndef TCL_WIDE_INT_IS_LONG + useWide = 1; +#endif + } else if ((ch == 't') || (ch == 'z')) { + format += step; + step = TclUtfToUniChar(format, &ch); +#ifndef TCL_WIDE_INT_IS_LONG + if (sizeof(void *) > sizeof(int)) { + useWide = 1; + } +#endif + } else if (ch == 'L') { format += step; step = TclUtfToUniChar(format, &ch); useBig = 1; @@ -2534,7 +2547,7 @@ Tcl_AppendFormatToObj( Tcl_Size toAppend; #ifndef TCL_WIDE_INT_IS_LONG - if (ch == 'p') { + if ((ch == 'p') && (sizeof(void *) > sizeof(int))) { useWide = 1; } #endif diff --git a/tests/format.test b/tests/format.test index 4accb33..9f69fc0 100644 --- a/tests/format.test +++ b/tests/format.test @@ -389,17 +389,17 @@ test format-8.23 {error conditions} { test format-8.24 {Undocumented formats} -body { format "%zd %td %d" [expr {2**30}] [expr {2**30}] [expr {2**30}] } -result {1073741824 1073741824 1073741824} -test format-8.25 {Undocumented formats} -constraints pointerIs64bit -body { +test format-8.25 {Other formats} -constraints pointerIs64bit -body { format "%zd %td %lld" [expr {2**33}] [expr {2**33}] [expr {2**33}] } -result {8589934592 8589934592 8589934592} # Since "%p" is equivalent to "%#llx" in 64-bit platforms and equivalent # to "%#x" in 32-bit platforms, it are really not useful in scripts, # therefore they are not documented. It's intended use is through the # function Tcl_AppendPrintfToObj (et al). -test format-8.26 {Undocumented formats} -body { +test format-8.26 {Other formats} -body { format "%p %#x" [expr {2**31}] [expr {2**31}] } -result {0x80000000 0x80000000} -test format-8.27 {Undocumented formats} -constraints pointerIs64bit -body { +test format-8.27 {Other formats} -constraints pointerIs64bit -body { format "%p %#llx" [expr {2**33}] [expr {2**33}] } -result {0x200000000 0x200000000} test format-8.28 {Internal use of TCL_COMBINE flag should not be visible at script level} { |