summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--doc/format.n20
-rw-r--r--generic/tclCmdAH.c29
3 files changed, 37 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog
index 417fbbd..f98541d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2002-02-19 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/format.n: Updated docs to list the specification.
+ * generic/tclCmdAH.c (Tcl_FormatObjCmd): Made behaviour on 64-bit
+ platforms correctly meet the specification, that %d works with the
+ native word-sized integer, instead of trying to guess (wrongly)
+ from the value being passed.
+
2002-02-19 Don Porter <dgp@users.sourceforge.net>
* changes: First draft of updated changes for 8.4a4 release.
diff --git a/doc/format.n b/doc/format.n
index db72688..b69a8f6 100644
--- a/doc/format.n
+++ b/doc/format.n
@@ -5,7 +5,7 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-'\" RCS: @(#) $Id: format.n,v 1.6 2002/02/15 14:28:47 dkf Exp $
+'\" RCS: @(#) $Id: format.n,v 1.7 2002/02/19 10:26:24 dkf Exp $
'\"
.so man.macros
.TH format n 8.1 Tcl "Tcl Built-In Commands"
@@ -133,7 +133,9 @@ truncated to a 16-bit value before converting.
This option is rarely useful.
.VS 8.4
If it is \fBl\fR it specifies that the numeric value should be (at
-least) a 64-bit value.
+least) a 64-bit value. If neither \fBh\fR or \fBl\fR are present,
+numeric values are interpreted as being values of the width of the
+native machine word, as described by \fBtcl_platform(wordSize)\fR.
.VE
.PP
The last thing in a conversion specifier is an alphabetic character
@@ -206,12 +208,16 @@ differences:
For \fB%c\fR conversions the argument must be a decimal string,
which will then be converted to the corresponding character value.
.IP [3]
-The \fBl\fR modifier is ignored; integer values are always converted
-as if there were no modifier present and real values are always
-converted as if the \fBl\fR modifier were present (i.e. type
-\fBdouble\fR is used for the internal representation).
+The \fBl\fR modifier
+.VS 8.4
+is ignored for real values and on 64-bit platforms, which are always
+converted as if the \fBl\fR modifier were present (i.e. the types
+\fBdouble\fR and \fBlong\fR are used for the internal representation
+of real and integer values, respectively).
+.VE 8.4
If the \fBh\fR modifier is specified then integer values are truncated
-to \fBshort\fR before conversion.
+to \fBshort\fR before conversion. Both \fBh\fR and \fBl\fR modifiers
+are ignored on all other conversions.
.SH "SEE ALSO"
sprintf(3), string(n)
diff --git a/generic/tclCmdAH.c b/generic/tclCmdAH.c
index d6c3ba7..d3928e2 100644
--- a/generic/tclCmdAH.c
+++ b/generic/tclCmdAH.c
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclCmdAH.c,v 1.21 2002/02/15 14:28:48 dkf Exp $
+ * RCS: @(#) $Id: tclCmdAH.c,v 1.22 2002/02/19 10:26:24 dkf Exp $
*/
#include "tclInt.h"
@@ -1898,7 +1898,8 @@ Tcl_FormatObjCmd(dummy, interp, objc, objv)
* whatever's generated. This is hard to estimate.
* 3. there's no way to move the arguments from objv to the call
* to sprintf in a reasonable way. This is particularly nasty
- * because some of the arguments may be two-word values (doubles).
+ * because some of the arguments may be two-word values (doubles
+ * and wide-ints).
* So, what happens here is to scan the format string one % group
* at a time, making many individual calls to sprintf.
*/
@@ -2000,7 +2001,7 @@ Tcl_FormatObjCmd(dummy, interp, objc, objv)
newPtr++;
format++;
}
- if (isdigit(UCHAR(*format))) { /* INTL: Tcl source. */
+ if (isdigit(UCHAR(*format))) { /* INTL: Tcl source. */
width = strtoul(format, &end, 10); /* INTL: Tcl source. */
format = end;
} else if (*format == '*') {
@@ -2043,7 +2044,7 @@ Tcl_FormatObjCmd(dummy, interp, objc, objv)
format++;
gotPrecision = 1;
}
- if (isdigit(UCHAR(*format))) { /* INTL: Tcl source. */
+ if (isdigit(UCHAR(*format))) { /* INTL: Tcl source. */
precision = strtoul(format, &end, 10); /* INTL: "C" locale. */
format = end;
} else if (*format == '*') {
@@ -2105,15 +2106,17 @@ Tcl_FormatObjCmd(dummy, interp, objc, objv)
objv[objIndex], &intValue) != TCL_OK) {
goto fmtError;
}
- if ((unsigned long) intValue > UINT_MAX) {
- /*
- * Add the 'l' for long format type.
- */
- newPtr++;
- *newPtr = 0;
- newPtr[-1] = newPtr[-2];
- newPtr[-2] = 'l';
- }
+#if (LONG_MAX > INT_MAX)
+ /*
+ * Add the 'l' for long format type because we are on
+ * an LP64 archtecture and we are really going to pass
+ * a long argument to sprintf.
+ */
+ newPtr++;
+ *newPtr = 0;
+ newPtr[-1] = newPtr[-2];
+ newPtr[-2] = 'l';
+#endif /* LONG_MAX > INT_MAX */
whichValue = INT_VALUE;
size = 40 + precision;
break;