summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2024-05-30 21:52:02 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2024-05-30 21:52:02 (GMT)
commita61d95045e2a65e0c2d418576016e24d29906994 (patch)
tree3e442b0535cda92d5e44030d1eaff97976af5b43
parentc6cbb0ff4a7bb42711f2b21953de289903ffa8b4 (diff)
parent9ce6a4582944552a01b327cb06eb7b420e914f08 (diff)
downloadtcl-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.n17
-rw-r--r--generic/tclStringObj.c19
-rw-r--r--tests/format.test6
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} {