1# Commands covered:  format
2#
3# This file contains a collection of tests for one or more of the Tcl
4# built-in commands.  Sourcing this file into Tcl runs the tests and
5# generates output for errors.  No output means no errors were found.
6#
7# Copyright © 1991-1994 The Regents of the University of California.
8# Copyright © 1994-1998 Sun Microsystems, Inc.
9#
10# See the file "license.terms" for information on usage and redistribution
11# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12
13if {"::tcltest" ni [namespace children]} {
14    package require tcltest 2.5
15    namespace import -force ::tcltest::*
16}
17
18# %u output depends on word length, so this test is not portable.
19testConstraint longIs32bit [expr {$tcl_platform(wordSize) == 4}]
20testConstraint longIs64bit [expr {$tcl_platform(wordSize) == 8}]
21testConstraint wideIs64bit [expr {wide(0x8000000000000000) < 0}]
22testConstraint pointerIs64bit [expr {$tcl_platform(pointerSize) >= 8}]
23# MSVC uses a broken libc that gets sprintf("%g") wrong. This is a pain
24# particularly in Continuous Integration, and there isn't anything much we can
25# do about it.
26testConstraint knownMsvcBug [expr {![info exists ::env(CI_BUILD_WITH_MSVC)]}]
27
28test format-1.1 {integer formatting} {
29    format "%*d %d %d %d" 6 34 16923 -12 -1
30} {    34 16923 -12 -1}
31test format-1.2 {integer formatting} {
32    format "%4d %4d %4d %4d %d %#x %#X" 6 34 16923 -12 -1 14 12
33} {   6   34 16923  -12 -1 0xe 0xC}
34test format-1.3 {integer formatting} longIs32bit {
35    format "%4u %4u %4u %4u %d %#o" 6 34 16923 -12 -1 0
36} {   6   34 16923 4294967284 -1 0}
37test format-1.3.1 {integer formatting} longIs64bit {
38    format "%4u %4u %4u %4u %d %#o" 6 34 16923 -12 -1 0
39} {   6   34 16923 18446744073709551604 -1 0}
40test format-1.4 {integer formatting} {
41    format "%-4d %-4i %-4d %-4ld" 6 34 16923 -12 -1
42} {6    34   16923 -12 }
43test format-1.5 {integer formatting} {
44    format "%04d %04d %04d %04i" 6 34 16923 -12 -1
45} {0006 0034 16923 -012}
46test format-1.6 {integer formatting} {
47    format "%00*d" 6 34
48} {000034}
49# Printing negative numbers in hex or octal format depends on word
50# length, so these tests are not portable.
51test format-1.7 {integer formatting} longIs32bit {
52    format "%4x %4x %4x %4x" 6 34 16923 -12 -1
53} {   6   22 421b fffffff4}
54test format-1.7.1 {integer formatting} longIs64bit {
55    format "%4x %4x %4x %4x" 6 34 16923 -12 -1
56} {   6   22 421b fffffffffffffff4}
57test format-1.8 {integer formatting} longIs32bit {
58    format "%#x %#x %#X %#X %#x" 0 6 34 16923 -12 -1
59} {0 0x6 0x22 0x421B 0xfffffff4}
60test format-1.8.1 {integer formatting} longIs64bit {
61    format "%#x %#x %#X %#X %#x" 0 6 34 16923 -12 -1
62} {0 0x6 0x22 0x421B 0xfffffffffffffff4}
63test format-1.9 {integer formatting} longIs32bit {
64    format "%#5x %#20x %#20x %#20x %#20x" 0 6 34 16923 -12 -1
65} {    0                  0x6                 0x22               0x421b           0xfffffff4}
66test format-1.9.1 {integer formatting} longIs64bit {
67    format "%#5x %#20x %#20x %#20x %#20x" 0 6 34 16923 -12 -1
68} {    0                  0x6                 0x22               0x421b   0xfffffffffffffff4}
69test format-1.10 {integer formatting} longIs32bit {
70    format "%-#5x %-#20x %-#20x %-#20x %-#20x" 0 6 34 16923 -12 -1
71} {0     0x6                  0x22                 0x421b               0xfffffff4          }
72test format-1.10.1 {integer formatting} longIs64bit {
73    format "%-#5x %-#20x %-#20x %-#20x %-#20x" 0 6 34 16923 -12 -1
74} {0     0x6                  0x22                 0x421b               0xfffffffffffffff4  }
75test format-1.11 {integer formatting} longIs32bit {
76    format "%-#5o %-#20o %#-20o %#-20o %#-20o" 0 6 34 16923 -12 -1
77} {0     0o6                  0o42                 0o41033              0o37777777764       }
78test format-1.11.1 {integer formatting} longIs64bit {
79    format "%-#5o %-#20o %#-20o %#-20o %#-20o" 0 6 34 16923 -12 -1
80} {0     0o6                  0o42                 0o41033              0o1777777777777777777764}
81test format-1.12 {integer formatting} {
82    format "%b %#b %#b %llb" 5 0 5 [expr {2**100}]
83} {101 0 0b101 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000}
84test format-1.13 {integer formatting} {
85    format "%#0d %#0d %#0d %#0d %#0d" 0 6 34 16923 -12 -1
86} {0 0d6 0d34 0d16923 -0d12}
87test format-1.14 {integer formatting} {
88    format "%#05d %#020d %#020d %#020d %#020d" 0 6 34 16923 -12 -1
89} {00000 0d000000000000000006 0d000000000000000034 0d000000000000016923 -0d00000000000000012}
90test format-1.15 {integer formatting} {
91    format "%-#05d %-#020d %-#020d %-#020d %-#020d" 0 6 34 16923 -12 -1
92} {00000 0d000000000000000006 0d000000000000000034 0d000000000000016923 -0d00000000000000012}
93
94
95test format-2.1 {string formatting} {
96    format "%s %s %c %s" abcd {This is a very long test string.} 120 x
97} {abcd This is a very long test string. x x}
98test format-2.2 {string formatting} {
99    format "%20s %20s %20c %20s" abcd {This is a very long test string.} 120 x
100} {                abcd This is a very long test string.                    x                    x}
101test format-2.3 {string formatting} {
102    format "%.10s %.10s %c %.10s" abcd {This is a very long test string.} 120 x
103} {abcd This is a  x x}
104test format-2.4 {string formatting} {
105    format "%s %s %% %c %s" abcd {This is a very long test string.} 120 x
106} {abcd This is a very long test string. % x x}
107test format-2.5 {string formatting, embedded nulls} {
108    format "%10s" abc\x00def
109} "   abc\x00def"
110test format-2.6 {string formatting, international chars} {
111    format "%10s" abc\uFEFFdef
112} "   abc\uFEFFdef"
113test format-2.7 {string formatting, international chars} {
114    format "%.5s" abc\uFEFFdef
115} "abc\uFEFFd"
116test format-2.8 {string formatting, international chars} {
117    format "foo\uFEFFbar%s" baz
118} "foo\uFEFFbarbaz"
119test format-2.9 {string formatting, width} {
120    format "a%5sa" f
121} "a    fa"
122test format-2.10 {string formatting, width} {
123    format "a%-5sa" f
124} "af    a"
125test format-2.11 {string formatting, width} {
126    format "a%2sa" foo
127} "afooa"
128test format-2.12 {string formatting, width} {
129    format "a%0sa" foo
130} "afooa"
131test format-2.13 {string formatting, precision} {
132    format "a%.2sa" foobarbaz
133} "afoa"
134test format-2.14 {string formatting, precision} {
135    format "a%.sa" foobarbaz
136} "aa"
137test format-2.15 {string formatting, precision} {
138    list [catch {format "a%.-2sa" foobarbaz} msg] $msg
139} {1 {bad field specifier "-"}}
140test format-2.16 {string formatting, width and precision} {
141    format "a%5.2sa" foobarbaz
142} "a   foa"
143test format-2.17 {string formatting, width and precision} {
144    format "a%5.7sa" foobarbaz
145} "afoobarba"
146test format-2.18 {string formatting, surrogates} {
147    format "\uD83D%s" \uDE02
148} \uD83D\uDE02
149test format-2.19 {string formatting, surrogates} {
150    format "%s\uDE02" \uD83D
151} \uD83D\uDE02
152
153test format-3.1 {Tcl_FormatObjCmd: character formatting} {
154    format "|%c|%0c|%-1c|%1c|%-6c|%6c|%*c|%*c|" 65 65 65 65 65 65 3 65 -4 65
155} "|A|A|A|A|A     |     A|  A|A   |"
156test format-3.2 {Tcl_FormatObjCmd: international character formatting} {
157    format "|%c|%0c|%-1c|%1c|%-6c|%6c|%*c|%*c|" 0xA2 0x4E4E 0x25A 0xC3 0xFF08 0 3 0x6575 -4 0x4E4F
158} "|¢|乎|ɚ|Ã|(     |     \x00|  敵|乏   |"
159
160test format-4.1 {e and f formats} {eformat} {
161    format "%e %e %e %e" 34.2e12 68.514 -.125 -16000. .000053
162} {3.420000e+13 6.851400e+01 -1.250000e-01 -1.600000e+04}
163test format-4.2 {e and f formats} {eformat} {
164    format "%20e %20e %20e %20e" 34.2e12 68.514 -.125 -16000. .000053
165} {        3.420000e+13         6.851400e+01        -1.250000e-01        -1.600000e+04}
166test format-4.3 {e and f formats} {eformat} {
167    format "%.1e %.1e %.1e %.1e" 34.2e12 68.514 -.126 -16000. .000053
168} {3.4e+13 6.9e+01 -1.3e-01 -1.6e+04}
169test format-4.4 {e and f formats} {eformat} {
170    format "%020e %020e %020e %020e" 34.2e12 68.514 -.126 -16000. .000053
171} {000000003.420000e+13 000000006.851400e+01 -00000001.260000e-01 -00000001.600000e+04}
172test format-4.5 {e and f formats} {eformat} {
173    format "%7.1e %7.1e %7.1e %7.1e" 34.2e12 68.514 -.126 -16000. .000053
174} {3.4e+13 6.9e+01 -1.3e-01 -1.6e+04}
175test format-4.6 {e and f formats} {
176    format "%f %f %f %f" 34.2e12 68.514 -.125 -16000. .000053
177} {34200000000000.000000 68.514000 -0.125000 -16000.000000}
178test format-4.7 {e and f formats} {
179    format "%.4f %.4f %.4f %.4f %.4f" 34.2e12 68.514 -.125 -16000. .000053
180} {34200000000000.0000 68.5140 -0.1250 -16000.0000 0.0001}
181test format-4.8 {e and f formats} {eformat} {
182    format "%.4e %.5e %.6e" -9.99996 -9.99996 9.99996
183} {-1.0000e+01 -9.99996e+00 9.999960e+00}
184test format-4.9 {e and f formats} {
185    format "%.4f %.5f %.6f" -9.99996 -9.99996 9.99996
186} {-10.0000 -9.99996 9.999960}
187test format-4.10 {e and f formats} {
188    format "%20f %-20f %020f" -9.99996 -9.99996 9.99996
189} {           -9.999960 -9.999960            0000000000009.999960}
190test format-4.11 {e and f formats} {
191    format "%-020f %020f" -9.99996 -9.99996 9.99996
192} {-9.999960            -000000000009.999960}
193test format-4.12 {e and f formats} {eformat} {
194    format "%.0e %#.0e" -9.99996 -9.99996 9.99996
195} {-1e+01 -1.e+01}
196test format-4.13 {e and f formats} {
197    format "%.0f %#.0f" -9.99996 -9.99996 9.99996
198} {-10 -10.}
199test format-4.14 {e and f formats} {
200    format "%.4f %.5f %.6f" -9.99996 -9.99996 9.99996
201} {-10.0000 -9.99996 9.999960}
202test format-4.15 {e and f formats} {
203    format "%3.0f %3.0f %3.0f %3.0f" 1.0 1.1 1.01 1.001
204} {  1   1   1   1}
205test format-4.16 {e and f formats} {
206    format "%3.1f %3.1f %3.1f %3.1f" 0.0 0.1 0.01 0.001
207} {0.0 0.1 0.0 0.0}
208
209test format-5.1 {g-format} {eformat} {
210    format "%.3g" 12341.0
211} {1.23e+04}
212test format-5.2 {g-format} {eformat} {
213    format "%.3G" 1234.12345
214} {1.23E+03}
215test format-5.3 {g-format} {
216    format "%.3g" 123.412345
217} {123}
218test format-5.4 {g-format} {
219    format "%.3g" 12.3412345
220} {12.3}
221test format-5.5 {g-format} {
222    format "%.3g" 1.23412345
223} {1.23}
224test format-5.6 {g-format} {
225    format "%.3g" 1.23412345
226} {1.23}
227test format-5.7 {g-format} {
228    format "%.3g" .123412345
229} {0.123}
230test format-5.8 {g-format} {
231    format "%.3g" .012341
232} {0.0123}
233test format-5.9 {g-format} {
234    format "%.3g" .0012341
235} {0.00123}
236test format-5.10 {g-format} {
237    format "%.3g" .00012341
238} {0.000123}
239test format-5.11 {g-format} {eformat} {
240    format "%.3g" .00001234
241} {1.23e-05}
242test format-5.12 {g-format} {eformat} {
243    format "%.4g" 9999.6
244} {1e+04}
245test format-5.13 {g-format} {
246    format "%.4g" 999.96
247} {1000}
248test format-5.14 {g-format} {
249    format "%.3g" 1.0
250} {1}
251test format-5.15 {g-format} {
252    format "%.3g" .1
253} {0.1}
254test format-5.16 {g-format} {
255    format "%.3g" .01
256} {0.01}
257test format-5.17 {g-format} {
258    format "%.3g" .001
259} {0.001}
260test format-5.18 {g-format} {eformat} {
261    format "%.3g" .00001
262} {1e-05}
263test format-5.19 {g-format} {eformat} {
264    format "%#.3g" 1234.0
265} {1.23e+03}
266test format-5.20 {g-format} {eformat} {
267    format "%#.3G" 9999.5
268} {1.00E+04}
269
270test format-6.1 {floating-point zeroes} {eformat} {
271    format "%e %f %g" 0.0 0.0 0.0 0.0
272} {0.000000e+00 0.000000 0}
273test format-6.2 {floating-point zeroes} {eformat} {
274    format "%.4e %.4f %.4g" 0.0 0.0 0.0 0.0
275} {0.0000e+00 0.0000 0}
276test format-6.3 {floating-point zeroes} {eformat knownMsvcBug} {
277    format "%#.4e %#.4f %#.4g" 0.0 0.0 0.0 0.0
278} {0.0000e+00 0.0000 0.000}
279test format-6.4 {floating-point zeroes} {eformat} {
280    format "%.0e %.0f %.0g" 0.0 0.0 0.0 0.0
281} {0e+00 0 0}
282test format-6.5 {floating-point zeroes} {eformat knownMsvcBug} {
283    format "%#.0e %#.0f %#.0g" 0.0 0.0 0.0 0.0
284} {0.e+00 0. 0.}
285test format-6.6 {floating-point zeroes} {
286    format "%3.0f %3.0f %3.0f %3.0f" 0.0 0.0 0.0 0.0
287} {  0   0   0   0}
288test format-6.7 {floating-point zeroes} {
289    format "%3.0f %3.0f %3.0f %3.0f" 1.0 1.1 1.01 1.001
290} {  1   1   1   1}
291test format-6.8 {floating-point zeroes} {
292    format "%3.1f %3.1f %3.1f %3.1f" 0.0 0.1 0.01 0.001
293} {0.0 0.1 0.0 0.0}
294
295test format-7.1 {various syntax features} {
296    format "%*.*f" 12 3 12.345678901
297} {      12.346}
298test format-7.2 {various syntax features} {
299    format "%0*.*f" 12 3 12.345678901
300} {00000012.346}
301test format-7.3 {various syntax features} {
302    format "\*\t\\n"
303} {*	\n}
304
305test format-8.1 {error conditions} {
306    catch format
307} 1
308test format-8.2 {error conditions} {
309    catch format msg
310    set msg
311} {wrong # args: should be "format formatString ?arg ...?"}
312test format-8.3 {error conditions} {
313    catch {format %*d}
314} 1
315test format-8.4 {error conditions} {
316    catch {format %*d} msg
317    set msg
318} {not enough arguments for all format specifiers}
319test format-8.5 {error conditions} {
320    catch {format %*.*f 12}
321} 1
322test format-8.6 {error conditions} {
323    catch {format %*.*f 12} msg
324    set msg
325} {not enough arguments for all format specifiers}
326test format-8.7 {error conditions} {
327    catch {format %*.*f 12 3}
328} 1
329test format-8.8 {error conditions} {
330    catch {format %*.*f 12 3} msg
331    set msg
332} {not enough arguments for all format specifiers}
333test format-8.9 {error conditions} {
334    list [catch {format %*d x 3} msg] $msg
335} {1 {expected integer but got "x"}}
336test format-8.10 {error conditions} {
337    list [catch {format %*.*f 2 xyz 3} msg] $msg
338} {1 {expected integer but got "xyz"}}
339test format-8.11 {error conditions} {
340    catch {format %d 2a}
341} 1
342test format-8.12 {error conditions} {
343    catch {format %d 2a} msg
344    set msg
345} {expected integer but got "2a"}
346test format-8.13 {error conditions} {
347    catch {format %c 2x}
348} 1
349test format-8.14 {error conditions} {
350    catch {format %c 2x} msg
351    set msg
352} {expected integer but got "2x"}
353test format-8.15 {error conditions} {
354    catch {format %f 2.1z}
355} 1
356test format-8.16 {error conditions} {
357    catch {format %f 2.1z} msg
358    set msg
359} {expected floating-point number but got "2.1z"}
360test format-8.17 {error conditions} {
361    catch {format ab%}
362} 1
363test format-8.18 {error conditions} {
364    catch {format ab% 12} msg
365    set msg
366} {format string ended in middle of field specifier}
367test format-8.19 {error conditions} {
368    catch {format %q x}
369} 1
370test format-8.20 {error conditions} {
371    catch {format %r x} msg
372    set msg
373} {bad field specifier "r"}
374test format-8.21 {error conditions} {
375    catch {format %d}
376} 1
377test format-8.22 {error conditions} {
378    catch {format %d} msg
379    set msg
380} {not enough arguments for all format specifiers}
381test format-8.23 {error conditions} {
382    catch {format "%d %d" 24 xyz} msg
383    set msg
384} {expected integer but got "xyz"}
385# Since "%zd" and "%td" are equivalent to "%lld" in 64-bit platforms and
386# equivalent to "%d" in 32-bit platforms, they are really not useful in
387# scripts, therefore they are not documented. It's intended use is through
388# the function Tcl_AppendPrintfToObj (et al).
389test format-8.24 {Undocumented formats} -body {
390    format "%zd %td %d" [expr {2**30}] [expr {2**30}] [expr {2**30}]
391} -result {1073741824 1073741824 1073741824}
392test format-8.25 {Undocumented formats} -constraints pointerIs64bit -body {
393    format "%zd %td %lld" [expr {2**33}] [expr {2**33}] [expr {2**33}]
394} -result {8589934592 8589934592 8589934592}
395# Since "%p" is equivalent to "%#llx" in 64-bit platforms and equivalent
396# to "%#x" in 32-bit platforms, it are really not useful in scripts,
397# therefore they are not documented. It's intended use is through the
398# function Tcl_AppendPrintfToObj (et al).
399test format-8.26 {Undocumented formats} -body {
400    format "%p %#x" [expr {2**31}] [expr {2**31}]
401} -result {0x80000000 0x80000000}
402test format-8.27 {Undocumented formats} -constraints pointerIs64bit -body {
403    format "%p %#llx" [expr {2**33}] [expr {2**33}]
404} -result {0x200000000 0x200000000}
405
406test format-9.1 {long result} {
407    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}
408    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
409} {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}
410
411test format-10.1 {"h" format specifier} {
412    format %hd 0xffff
413} -1
414test format-10.2 {"h" format specifier} {
415    format %hx 0x10fff
416} fff
417test format-10.3 {"h" format specifier} {
418    format %hd 0x10000
419} 0
420test format-10.4 {"h" format specifier} {
421    # Bug 1154163: This is minimal behaviour for %hx specifier!
422    format %hx 1
423} 1
424test format-10.5 {"h" format specifier} {
425    # Bug 1284178: Highly out-of-range values shouldn't cause errors
426    format %hu 0x100000000
427} 0
428
429test format-11.1 {XPG3 %$n specifiers} {
430    format {%2$d %1$d} 4 5
431} {5 4}
432test format-11.2 {XPG3 %$n specifiers} {
433    format {%2$d %1$d %1$d %3$d} 4 5 6
434} {5 4 4 6}
435test format-11.3 {XPG3 %$n specifiers} {
436    list [catch {format {%2$d %3$d} 4 5} msg] $msg
437} {1 {"%n$" argument index out of range}}
438test format-11.4 {XPG3 %$n specifiers} {
439    list [catch {format {%2$d %0$d} 4 5 6} msg] $msg
440} {1 {"%n$" argument index out of range}}
441test format-11.5 {XPG3 %$n specifiers} {
442    list [catch {format {%d %1$d} 4 5 6} msg] $msg
443} {1 {cannot mix "%" and "%n$" conversion specifiers}}
444test format-11.6 {XPG3 %$n specifiers} {
445    list [catch {format {%2$d %d} 4 5 6} msg] $msg
446} {1 {cannot mix "%" and "%n$" conversion specifiers}}
447test format-11.7 {XPG3 %$n specifiers} {
448    list [catch {format {%2$d %3d} 4 5 6} msg] $msg
449} {1 {cannot mix "%" and "%n$" conversion specifiers}}
450test format-11.8 {XPG3 %$n specifiers} {
451    format {%2$*d %3$d} 1 10 4
452} {         4 4}
453test format-11.9 {XPG3 %$n specifiers} {
454    format {%2$.*s %4$d} 1 5 abcdefghijklmnop 44
455} {abcde 44}
456test format-11.10 {XPG3 %$n specifiers} {
457    list [catch {format {%2$*d} 4} msg] $msg
458} {1 {"%n$" argument index out of range}}
459test format-11.11 {XPG3 %$n specifiers} {
460    list [catch {format {%2$*d} 4 5} msg] $msg
461} {1 {"%n$" argument index out of range}}
462test format-11.12 {XPG3 %$n specifiers} {
463    list [catch {format {%2$*d} 4 5 6} msg] $msg
464} {0 {    6}}
465
466test format-12.1 {negative width specifiers} {
467    format "%*d" -47 25
468} {25                                             }
469
470test format-13.1 {tcl_precision fuzzy comparison} {
471    catch {unset a}
472    catch {unset b}
473    catch {unset c}
474    catch {unset d}
475    set a 0.0000000000001
476    set b 0.00000000000001
477    set c 0.00000000000000001
478    set d [expr {$a + $b + $c}]
479    format {%0.10f %0.12f %0.15f %0.17f} $d $d $d $d
480} {0.0000000000 0.000000000000 0.000000000000110 0.00000000000011001}
481test format-13.2 {tcl_precision fuzzy comparison} {
482    catch {unset a}
483    catch {unset b}
484    catch {unset c}
485    catch {unset d}
486    set a 0.000000000001
487    set b 0.000000000000005
488    set c 0.0000000000000008
489    set d [expr {$a + $b + $c}]
490    format {%0.10f %0.12f %0.15f %0.17f} $d $d $d $d
491} {0.0000000000 0.000000000001 0.000000000001006 0.00000000000100580}
492test format-13.3 {tcl_precision fuzzy comparison} {
493    catch {unset a}
494    catch {unset b}
495    catch {unset c}
496    set a 0.00000000000099
497    set b 0.000000000000011
498    set c [expr {$a + $b}]
499    format {%0.10f %0.12f %0.15f %0.17f} $c $c $c $c
500} {0.0000000000 0.000000000001 0.000000000001001 0.00000000000100100}
501test format-13.4 {tcl_precision fuzzy comparison} {
502    catch {unset a}
503    catch {unset b}
504    catch {unset c}
505    set a 0.444444444444
506    set b 0.33333333333333
507    set c [expr {$a + $b}]
508    format {%0.10f %0.12f %0.15f %0.16f} $c $c $c $c
509} {0.7777777778 0.777777777777 0.777777777777330 0.7777777777773300}
510test format-13.5 {tcl_precision fuzzy comparison} {
511    catch {unset a}
512    catch {unset b}
513    catch {unset c}
514    set a 0.444444444444
515    set b 0.99999999999999
516    set c [expr {$a + $b}]
517    format {%0.10f %0.12f %0.15f} $c $c $c
518} {1.4444444444 1.444444444444 1.444444444443990}
519
520test format-14.1 {testing MAX_FLOAT_SIZE for 0 and 1} {
521    format {%s} ""
522} {}
523test format-14.2 {testing MAX_FLOAT_SIZE for 0 and 1} {
524    format {%s} "a"
525} {a}
526
527test format-15.1 {testing %0..s 0 padding for chars/strings} {
528    format %05s a
529} {0000a}
530test format-15.2 {testing %0..s 0 padding for chars/strings} {
531    format "% 5s" a
532} {    a}
533test format-15.3 {testing %0..s 0 padding for chars/strings} {
534    format %5s a
535} {    a}
536test format-15.4 {testing %0..s 0 padding for chars/strings} {
537    format %05c 61
538} {0000=}
539test format-15.5 {testing %d space padding for integers} {
540    format "(% 1d) (% 1d)" 10 -10
541} {( 10) (-10)}
542test format-15.6 {testing %d plus padding for integers} {
543    format "(%+1d) (%+1d)" 10 -10
544} {(+10) (-10)}
545
546set a "0123456789"
547set b ""
548for {set i 0} {$i < 290} {incr i} {
549    append b $a
550}
551for {set i 290} {$i < 400} {incr i} {
552    test format-16.[expr {$i -289}] {testing MAX_FLOAT_SIZE} {
553        format {%s} $b
554    } $b
555    append b "x"
556}
557
558test format-17.1 {testing %d with wide} {longIs32bit wideIs64bit} {
559    format %d 7810179016327718216
560} 1819043144
561test format-17.2 {testing %ld with wide} {wideIs64bit} {
562    format %ld 7810179016327718216
563} 7810179016327718216
564test format-17.3 {testing %ld with non-wide} {wideIs64bit} {
565    format %ld 42
566} 42
567test format-17.4 {testing %l with non-integer} {
568    format %lf 1
569} 1.000000
570test format-17.5 {testing %llu with positive bignum} -body {
571    format %llu 0xabcdef0123456789abcdef
572} -result 207698809136909011942886895
573test format-17.6 {testing %llu with negative number} -body {
574    format %llu -1
575} -returnCodes 1 -result {unsigned bignum format is invalid}
576
577test format-18.1 {do not demote existing numeric values} {
578    set a 0xaaaaaaaa
579    # Ensure $a and $b are separate objects
580    set b 0xaaaa
581    append b aaaa
582    set result [expr {$a == $b}]
583    format %08lx $b
584    lappend result [expr {$a == $b}]
585    set b 0xaaaa
586    append b aaaa
587    lappend result [expr {$a == $b}]
588    format %08x $b
589    lappend result [expr {$a == $b}]
590} {1 1 1 1}
591test format-18.2 {do not demote existing numeric values} {longIs32bit wideIs64bit} {
592    set a [expr {0xaaaaaaaaaa + 1}]
593    set b 0xaaaaaaaaab
594    list [format %08x $a] [expr {$a == $b}]
595} {aaaaaaab 1}
596
597test format-19.1 {regression test - tcl-core message by Brian Griffin on 26 0ctober 2004} -body {
598    set x 0x8fedc654
599    list [expr { ~ $x }] [format %08x [expr { ~$x }]]
600} -match regexp -result {-2414724693 f*701239ab}
601test format-19.2 {Bug 1867855} {
602    format %llx 0
603} 0
604test format-19.3 {Bug 2830354} {
605    string length [format %340f 0]
606} 340
607
608test format-19.4.1 {Bug d498578df4: width overflow should cause limit exceeded} \
609-constraints {longIs32bit} -body {
610    # in case of overflow into negative, it produces width -2 (and limit exceeded),
611    # in case of width will be unsigned, it will be outside limit (2GB for 32bit)...
612    # and it don't throw an error in case the bug is not fixed (and probably no segfault).
613    format %[expr {0xffffffff - 1}]g 0
614} -returnCodes error -result "max size for a Tcl value exceeded"
615
616test format-19.4.2 {Bug d498578df4: width overflow should cause limit exceeded} -body {
617    # limit should exceeds in any case,
618    # and it don't throw an error in case the bug is not fixed (and probably no segfault).
619    format %[expr {0xffffffffffffffff - 1}]g 0
620} -returnCodes error -result "max size for a Tcl value exceeded"
621
622# Note that this test may fail in future versions
623test format-20.1 {Bug 2932421: plain %s caused intrep change of args} -body {
624    set x [dict create a b c d]
625    format %s $x
626    # After this, obj in $x should be a dict
627    # We are testing to make sure it has not been shimmered to a
628    # different intrep when that is not necessary.
629    # Whether or not there is a string rep - we should not care!
630    tcl::unsupported::representation $x
631} -match glob -result {value is a dict *}
632
633# cleanup
634catch {unset a}
635catch {unset b}
636catch {unset c}
637catch {unset d}
638::tcltest::cleanupTests
639return
640
641# Local Variables:
642# mode: tcl
643# End:
644