Skip to content

Commit fd102f3

Browse files
skilchenVarriount
authored andcommitted
Fix strformat precision handling for strings (#7941)
* fix strformat precision handling for strings * add some limited unicode awareness to the precision handling for strings * improvement suggested by Varriount: use setLen and runeOffset instead of runeSubstr
1 parent a3e5242 commit fd102f3

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

lib/pure/strformat.nim

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,12 +558,16 @@ proc format*(value: string; specifier: string; res: var string) =
558558
## sense to call this directly, but it is required to exist
559559
## by the ``&`` macro.
560560
let spec = parseStandardFormatSpecifier(specifier)
561+
var value = value
561562
case spec.typ
562563
of 's', '\0': discard
563564
else:
564565
raise newException(ValueError,
565566
"invalid type in format string for string, expected 's', but got " &
566567
spec.typ)
568+
if spec.precision != -1:
569+
if spec.precision < runelen(value):
570+
setLen(value, runeOffset(value, spec.precision))
567571
res.add alignString(value, spec.minimumWidth, spec.align, spec.fill)
568572

569573
when isMainModule:

tests/stdlib/tstrformat.nim

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,32 @@ var o: Obj
1212
doAssert fmt"{o}" == "foobar"
1313
doAssert fmt"{o:10}" == "foobar "
1414

15+
# see issue #7933
16+
var str = "abc"
17+
doAssert fmt">7.1 :: {str:>7.1}" == ">7.1 :: a"
18+
doAssert fmt">7.2 :: {str:>7.2}" == ">7.2 :: ab"
19+
doAssert fmt">7.3 :: {str:>7.3}" == ">7.3 :: abc"
20+
doAssert fmt">7.9 :: {str:>7.9}" == ">7.9 :: abc"
21+
doAssert fmt">7.0 :: {str:>7.0}" == ">7.0 :: "
22+
doAssert fmt" 7.1 :: {str:7.1}" == " 7.1 :: a "
23+
doAssert fmt" 7.2 :: {str:7.2}" == " 7.2 :: ab "
24+
doAssert fmt" 7.3 :: {str:7.3}" == " 7.3 :: abc "
25+
doAssert fmt" 7.9 :: {str:7.9}" == " 7.9 :: abc "
26+
doAssert fmt" 7.0 :: {str:7.0}" == " 7.0 :: "
27+
doAssert fmt"^7.1 :: {str:^7.1}" == "^7.1 :: a "
28+
doAssert fmt"^7.2 :: {str:^7.2}" == "^7.2 :: ab "
29+
doAssert fmt"^7.3 :: {str:^7.3}" == "^7.3 :: abc "
30+
doAssert fmt"^7.9 :: {str:^7.9}" == "^7.9 :: abc "
31+
doAssert fmt"^7.0 :: {str:^7.0}" == "^7.0 :: "
32+
str = "äöüe\u0309\u0319o\u0307\u0359"
33+
doAssert fmt"^7.1 :: {str:^7.1}" == "^7.1 :: ä "
34+
doAssert fmt"^7.2 :: {str:^7.2}" == "^7.2 :: äö "
35+
doAssert fmt"^7.3 :: {str:^7.3}" == "^7.3 :: äöü "
36+
doAssert fmt"^7.0 :: {str:^7.0}" == "^7.0 :: "
37+
# this is actually wrong, but the unicode module has no support for graphemes
38+
doAssert fmt"^7.4 :: {str:^7.4}" == "^7.4 :: äöüe "
39+
doAssert fmt"^7.9 :: {str:^7.9}" == "^7.9 :: äöüe\u0309\u0319o\u0307\u0359"
40+
1541
# see issue #7932
1642
doAssert fmt"{15:08}" == "00000015" # int, works
1743
doAssert fmt"{1.5:08}" == "000001.5" # float, works

0 commit comments

Comments
 (0)