Skip to content

Commit c3ff1e9

Browse files
authored
Merge pull request #2298 from MarenFayre/left-pad
Fix left padding format specifier and float formatting
2 parents dd3fac7 + 13029d0 commit c3ff1e9

2 files changed

Lines changed: 27 additions & 76 deletions

File tree

core/fmt/fmt.odin

Lines changed: 27 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ _fmt_int :: proc(fi: ^Info, u: u64, base: int, is_signed: bool, bit_size: int, d
678678
}
679679
} else if fi.zero && fi.width_set {
680680
prec = fi.width
681-
if neg || fi.plus || fi.space {
681+
if neg || fi.plus {
682682
// There needs to be space for the "sign"
683683
prec -= 1
684684
}
@@ -697,7 +697,6 @@ _fmt_int :: proc(fi: ^Info, u: u64, base: int, is_signed: bool, bit_size: int, d
697697
flags: strconv.Int_Flags
698698
if fi.hash && !fi.zero { flags |= {.Prefix} }
699699
if fi.plus { flags |= {.Plus} }
700-
if fi.space { flags |= {.Space} }
701700
s := strconv.append_bits(buf[start:], u, base, is_signed, bit_size, digits, flags)
702701

703702
if fi.hash && fi.zero && fi.indent == 0 {
@@ -744,7 +743,7 @@ _fmt_int_128 :: proc(fi: ^Info, u: u128, base: int, is_signed: bool, bit_size: i
744743
}
745744
} else if fi.zero && fi.width_set {
746745
prec = fi.width
747-
if neg || fi.plus || fi.space {
746+
if neg || fi.plus {
748747
// There needs to be space for the "sign"
749748
prec -= 1
750749
}
@@ -763,7 +762,6 @@ _fmt_int_128 :: proc(fi: ^Info, u: u128, base: int, is_signed: bool, bit_size: i
763762
flags: strconv.Int_Flags
764763
if fi.hash && !fi.zero { flags |= {.Prefix} }
765764
if fi.plus { flags |= {.Plus} }
766-
if fi.space { flags |= {.Space} }
767765
s := strconv.append_bits_128(buf[start:], u, base, is_signed, bit_size, digits, flags)
768766

769767
if fi.hash && fi.zero && fi.indent == 0 {
@@ -867,79 +865,37 @@ _pad :: proc(fi: ^Info, s: string) {
867865
}
868866
}
869867

870-
fmt_float :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune) {
871-
switch verb {
872-
case 'f', 'F', 'g', 'G', 'v':
873-
prec: int = 3
874-
if fi.prec_set {
875-
prec = fi.prec
876-
}
877-
buf: [386]byte
878-
879-
str := strconv.append_float(buf[1:], v, 'f', prec, bit_size)
880-
b := buf[:len(str)+1]
881-
if b[1] == '+' || b[1] == '-' {
882-
b = b[1:]
883-
} else {
884-
b[0] = '+'
885-
}
868+
_fmt_float_as :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune, float_fmt: byte) {
869+
prec: int = 3
870+
if fi.prec_set {
871+
prec = fi.prec
872+
}
873+
buf: [386]byte
886874

887-
if fi.space && !fi.plus && b[0] == '+' {
888-
b[0] = ' '
889-
}
875+
// Can return "NaN", "+Inf", "-Inf", "+<value>", "-<value>".
876+
str := strconv.append_float(buf[:], v, float_fmt, prec, bit_size)
877+
assert(len(str) >= 2)
890878

891-
if len(b) > 1 && (b[1] == 'N' || b[1] == 'I') {
892-
io.write_string(fi.writer, string(b), &fi.n)
893-
return
879+
if !fi.plus { // '+' modifier means preserve all signs.
880+
switch {
881+
case str[0] == 'N': // Not a "NaN"
882+
case str[1] == 'I': // Not a "±Inf"
883+
case str[0] == '+': // Found "+<value>"
884+
// Strip + sign
885+
str = str[1:]
894886
}
887+
}
895888

896-
if fi.plus || b[0] != '+' {
897-
if fi.zero && fi.width_set && fi.width > len(b) {
898-
io.write_byte(fi.writer, b[0], &fi.n)
899-
fmt_write_padding(fi, fi.width - len(b))
900-
io.write_string(fi.writer, string(b[1:]), &fi.n)
901-
} else {
902-
_pad(fi, string(b))
903-
}
904-
} else {
905-
_pad(fi, string(b[1:]))
906-
}
889+
_pad(fi, str)
890+
}
907891

892+
fmt_float :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune) {
893+
switch verb {
894+
case 'f', 'F', 'g', 'G', 'v':
895+
_fmt_float_as(fi, v, bit_size, verb, 'f')
908896
case 'e', 'E':
909-
prec: int = 3
910-
if fi.prec_set {
911-
prec = fi.prec
912-
}
913-
buf: [386]byte
914-
915-
str := strconv.append_float(buf[1:], v, 'e', prec, bit_size)
916-
b := buf[:len(str)+1]
917-
if b[1] == '+' || b[1] == '-' {
918-
b = b[1:]
919-
} else {
920-
b[0] = '+'
921-
}
922-
923-
if fi.space && !fi.plus && b[0] == '+' {
924-
b[0] = ' '
925-
}
926-
927-
if len(b) > 1 && (b[1] == 'N' || b[1] == 'I') {
928-
io.write_string(fi.writer, string(b), &fi.n)
929-
return
930-
}
931-
932-
if fi.plus || str[0] != '+' {
933-
if fi.zero && fi.width_set && fi.width > len(b) {
934-
io.write_byte(fi.writer, b[0], &fi.n)
935-
fmt_write_padding(fi, fi.width - len(b))
936-
io.write_string(fi.writer, string(b[1:]), &fi.n)
937-
} else {
938-
_pad(fi, string(b))
939-
}
940-
} else {
941-
_pad(fi, string(b[1:]))
942-
}
897+
// BUG(): "%.3e" returns "3.000e+00"
898+
_fmt_float_as(fi, v, bit_size, verb, 'e')
943899

944900
case 'h', 'H':
945901
prev_fi := fi^

core/strconv/integers.odin

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package strconv
33
Int_Flag :: enum {
44
Prefix,
55
Plus,
6-
Space,
76
}
87
Int_Flags :: bit_set[Int_Flag]
98

@@ -73,8 +72,6 @@ append_bits :: proc(buf: []byte, x: u64, base: int, is_signed: bool, bit_size: i
7372
i-=1; a[i] = '-'
7473
case .Plus in flags:
7574
i-=1; a[i] = '+'
76-
case .Space in flags:
77-
i-=1; a[i] = ' '
7875
}
7976

8077
out := a[i:]
@@ -157,8 +154,6 @@ append_bits_128 :: proc(buf: []byte, x: u128, base: int, is_signed: bool, bit_si
157154
i-=1; a[i] = '-'
158155
case .Plus in flags:
159156
i-=1; a[i] = '+'
160-
case .Space in flags:
161-
i-=1; a[i] = ' '
162157
}
163158

164159
out := a[i:]

0 commit comments

Comments
 (0)