From 5aac27662665e33e21c3cf60764cb676fdfe5d19 Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 19 Feb 2002 10:26:24 +0000 Subject: Fixed behaviour of [format] on 64-bit platforms by defining it to work with machine words by default. This seems to be what the test suite expected anyway, and it is a fairly sensible choice. The other alternative was to make %d always 32-bit and %ld always 64-bit, but that'd be more complex to do. --- ChangeLog | 8 ++++++++ doc/format.n | 20 +++++++++++++------- generic/tclCmdAH.c | 29 ++++++++++++++++------------- 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 + + * 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 * 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; -- cgit v0.12