aboutsummaryrefslogtreecommitdiff
path: root/v_windows/v/vlib/strconv/format_mem.v
diff options
context:
space:
mode:
Diffstat (limited to 'v_windows/v/vlib/strconv/format_mem.v')
-rw-r--r--v_windows/v/vlib/strconv/format_mem.v498
1 files changed, 498 insertions, 0 deletions
diff --git a/v_windows/v/vlib/strconv/format_mem.v b/v_windows/v/vlib/strconv/format_mem.v
new file mode 100644
index 0000000..f3a11cb
--- /dev/null
+++ b/v_windows/v/vlib/strconv/format_mem.v
@@ -0,0 +1,498 @@
+/*=============================================================================
+Copyright (c) 2019-2021 Dario Deledda. All rights reserved.
+Use of this source code is governed by an MIT license
+that can be found in the LICENSE file.
+
+This file contains string interpolation V functions
+=============================================================================*/
+module strconv
+
+import strings
+
+// strings.Builder version of format_str
+pub fn format_str_sb(s string, p BF_param, mut sb strings.Builder) {
+ if p.len0 <= 0 {
+ sb.write_string(s)
+ return
+ }
+ dif := p.len0 - utf8_str_visible_length(s)
+ if dif <= 0 {
+ sb.write_string(s)
+ return
+ }
+
+ if p.allign == .right {
+ for i1 := 0; i1 < dif; i1++ {
+ sb.write_b(p.pad_ch)
+ }
+ }
+ sb.write_string(s)
+ if p.allign == .left {
+ for i1 := 0; i1 < dif; i1++ {
+ sb.write_b(p.pad_ch)
+ }
+ }
+}
+
+const (
+ // digit pairs in reverse order
+ digit_pairs = '00102030405060708090011121314151617181910212223242526272829203132333435363738393041424344454647484940515253545556575859506162636465666768696071727374757677787970818283848586878889809192939495969798999'
+)
+
+// format_dec_sb format a u64
+[direct_array_access]
+pub fn format_dec_sb(d u64, p BF_param, mut res strings.Builder) {
+ mut n_char := dec_digits(d)
+ sign_len := if !p.positive || p.sign_flag { 1 } else { 0 }
+ number_len := sign_len + n_char
+ dif := p.len0 - number_len
+ mut sign_written := false
+
+ if p.allign == .right {
+ if p.pad_ch == `0` {
+ if p.positive {
+ if p.sign_flag {
+ res.write_b(`+`)
+ sign_written = true
+ }
+ } else {
+ res.write_b(`-`)
+ sign_written = true
+ }
+ }
+ // write the pad chars
+ for i1 := 0; i1 < dif; i1++ {
+ res.write_b(p.pad_ch)
+ }
+ }
+
+ if !sign_written {
+ // no pad char, write the sign before the number
+ if p.positive {
+ if p.sign_flag {
+ res.write_b(`+`)
+ }
+ } else {
+ res.write_b(`-`)
+ }
+ }
+
+ /*
+ // Legacy version
+ // max u64 18446744073709551615 => 20 byte
+ mut buf := [32]byte{}
+ mut i := 20
+ mut d1 := d
+ for i >= (21 - n_char) {
+ buf[i] = byte(d1 % 10) + `0`
+ d1 = d1 / 10
+ i--
+ }
+ i++
+ */
+
+ //===========================================
+ // Speed version
+ // max u64 18446744073709551615 => 20 byte
+ mut buf := [32]byte{}
+ mut i := 20
+ mut n := d
+ mut d_i := u64(0)
+ if n > 0 {
+ for n > 0 {
+ n1 := n / 100
+ // calculate the digit_pairs start index
+ d_i = (n - (n1 * 100)) << 1
+ n = n1
+ unsafe {
+ buf[i] = strconv.digit_pairs.str[d_i]
+ }
+ i--
+ d_i++
+ unsafe {
+ buf[i] = strconv.digit_pairs.str[d_i]
+ }
+ i--
+ }
+ i++
+ // remove head zero
+ if d_i < 20 {
+ i++
+ }
+ unsafe { res.write_ptr(&buf[i], n_char) }
+ } else {
+ // we have a zero no need of more code!
+ res.write_b(`0`)
+ }
+ //===========================================
+
+ if p.allign == .left {
+ for i1 := 0; i1 < dif; i1++ {
+ res.write_b(p.pad_ch)
+ }
+ }
+ return
+}
+
+[direct_array_access; manualfree]
+pub fn f64_to_str_lnd1(f f64, dec_digit int) string {
+ unsafe {
+ // we add the rounding value
+ s := f64_to_str(f + dec_round[dec_digit], 18)
+ // check for +inf -inf Nan
+ if s.len > 2 && (s[0] == `n` || s[1] == `i`) {
+ return s
+ }
+
+ m_sgn_flag := false
+ mut sgn := 1
+ mut b := [26]byte{}
+ mut d_pos := 1
+ mut i := 0
+ mut i1 := 0
+ mut exp := 0
+ mut exp_sgn := 1
+
+ mut dot_res_sp := -1
+
+ // get sign and deciaml parts
+ for c in s {
+ if c == `-` {
+ sgn = -1
+ i++
+ } else if c == `+` {
+ sgn = 1
+ i++
+ } else if c >= `0` && c <= `9` {
+ b[i1] = c
+ i1++
+ i++
+ } else if c == `.` {
+ if sgn > 0 {
+ d_pos = i
+ } else {
+ d_pos = i - 1
+ }
+ i++
+ } else if c == `e` {
+ i++
+ break
+ } else {
+ s.free()
+ return '[Float conversion error!!]'
+ }
+ }
+ b[i1] = 0
+
+ // get exponent
+ if s[i] == `-` {
+ exp_sgn = -1
+ i++
+ } else if s[i] == `+` {
+ exp_sgn = 1
+ i++
+ }
+
+ mut c := i
+ for c < s.len {
+ exp = exp * 10 + int(s[c] - `0`)
+ c++
+ }
+
+ // allocate exp+32 chars for the return string
+ // mut res := []byte{len:exp+32,init:`0`}
+ mut res := []byte{len: exp + 32, init: 0}
+ mut r_i := 0 // result string buffer index
+
+ // println("s:${sgn} b:${b[0]} es:${exp_sgn} exp:${exp}")
+
+ // s no more needed
+ s.free()
+
+ if sgn == 1 {
+ if m_sgn_flag {
+ res[r_i] = `+`
+ r_i++
+ }
+ } else {
+ res[r_i] = `-`
+ r_i++
+ }
+
+ i = 0
+ if exp_sgn >= 0 {
+ for b[i] != 0 {
+ res[r_i] = b[i]
+ r_i++
+ i++
+ if i >= d_pos && exp >= 0 {
+ if exp == 0 {
+ dot_res_sp = r_i
+ res[r_i] = `.`
+ r_i++
+ }
+ exp--
+ }
+ }
+ for exp >= 0 {
+ res[r_i] = `0`
+ r_i++
+ exp--
+ }
+ // println("exp: $exp $r_i $dot_res_sp")
+ } else {
+ mut dot_p := true
+ for exp > 0 {
+ res[r_i] = `0`
+ r_i++
+ exp--
+ if dot_p {
+ dot_res_sp = r_i
+ res[r_i] = `.`
+ r_i++
+ dot_p = false
+ }
+ }
+ for b[i] != 0 {
+ res[r_i] = b[i]
+ r_i++
+ i++
+ }
+ }
+
+ // no more digits needed, stop here
+ if dec_digit <= 0 {
+ tmp_res := tos(res.data, dot_res_sp).clone()
+ res.free()
+ return tmp_res
+ }
+
+ // println("r_i-d_pos: ${r_i - d_pos}")
+ if dot_res_sp >= 0 {
+ if (r_i - dot_res_sp) > dec_digit {
+ r_i = dot_res_sp + dec_digit + 1
+ }
+ res[r_i] = 0
+ // println("result: [${tos(&res[0],r_i)}]")
+ tmp_res := tos(res.data, r_i).clone()
+ res.free()
+ return tmp_res
+ } else {
+ if dec_digit > 0 {
+ mut c1 := 0
+ res[r_i] = `.`
+ r_i++
+ for c1 < dec_digit {
+ res[r_i] = `0`
+ r_i++
+ c1++
+ }
+ res[r_i] = 0
+ }
+ tmp_res := tos(res.data, r_i).clone()
+ res.free()
+ return tmp_res
+ }
+ }
+}
+
+// strings.Builder version of format_fl
+[manualfree]
+pub fn format_fl(f f64, p BF_param) string {
+ unsafe {
+ mut s := ''
+ // mut fs := "1.2343"
+ mut fs := f64_to_str_lnd1(if f >= 0.0 { f } else { -f }, p.len1)
+ // println("Dario")
+ // println(fs)
+
+ // error!!
+ if fs[0] == `[` {
+ s.free()
+ return fs
+ }
+
+ if p.rm_tail_zero {
+ tmp := fs
+ fs = remove_tail_zeros(fs)
+ tmp.free()
+ }
+ mut res := strings.new_builder(if p.len0 > fs.len { p.len0 } else { fs.len })
+
+ mut sign_len_diff := 0
+ if p.pad_ch == `0` {
+ if p.positive {
+ if p.sign_flag {
+ res.write_b(`+`)
+ sign_len_diff = -1
+ }
+ } else {
+ res.write_b(`-`)
+ sign_len_diff = -1
+ }
+ tmp := s
+ s = fs.clone()
+ tmp.free()
+ } else {
+ if p.positive {
+ if p.sign_flag {
+ tmp := s
+ s = '+' + fs
+ tmp.free()
+ } else {
+ tmp := s
+ s = fs.clone()
+ tmp.free()
+ }
+ } else {
+ tmp := s
+ s = '-' + fs
+ tmp.free()
+ }
+ }
+
+ dif := p.len0 - s.len + sign_len_diff
+
+ if p.allign == .right {
+ for i1 := 0; i1 < dif; i1++ {
+ res.write_b(p.pad_ch)
+ }
+ }
+ res.write_string(s)
+ if p.allign == .left {
+ for i1 := 0; i1 < dif; i1++ {
+ res.write_b(p.pad_ch)
+ }
+ }
+
+ s.free()
+ fs.free()
+ tmp_res := res.str()
+ res.free()
+ return tmp_res
+ }
+}
+
+[manualfree]
+pub fn format_es(f f64, p BF_param) string {
+ unsafe {
+ mut s := ''
+ mut fs := f64_to_str_pad(if f > 0 { f } else { -f }, p.len1)
+ if p.rm_tail_zero {
+ fs = remove_tail_zeros(fs)
+ }
+ mut res := strings.new_builder(if p.len0 > fs.len { p.len0 } else { fs.len })
+
+ mut sign_len_diff := 0
+ if p.pad_ch == `0` {
+ if p.positive {
+ if p.sign_flag {
+ res.write_b(`+`)
+ sign_len_diff = -1
+ }
+ } else {
+ res.write_b(`-`)
+ sign_len_diff = -1
+ }
+ tmp := s
+ s = fs.clone()
+ tmp.free()
+ } else {
+ if p.positive {
+ if p.sign_flag {
+ tmp := s
+ s = '+' + fs
+ tmp.free()
+ } else {
+ tmp := s
+ s = fs.clone()
+ tmp.free()
+ }
+ } else {
+ tmp := s
+ s = '-' + fs
+ tmp.free()
+ }
+ }
+
+ dif := p.len0 - s.len + sign_len_diff
+ if p.allign == .right {
+ for i1 := 0; i1 < dif; i1++ {
+ res.write_b(p.pad_ch)
+ }
+ }
+ res.write_string(s)
+ if p.allign == .left {
+ for i1 := 0; i1 < dif; i1++ {
+ res.write_b(p.pad_ch)
+ }
+ }
+ s.free()
+ fs.free()
+ tmp_res := res.str()
+ res.free()
+ return tmp_res
+ }
+}
+
+[direct_array_access]
+pub fn remove_tail_zeros(s string) string {
+ unsafe {
+ mut buf := malloc_noscan(s.len + 1)
+ mut i_d := 0
+ mut i_s := 0
+
+ // skip spaces
+ for i_s < s.len && s[i_s] !in [`-`, `+`] && (s[i_s] > `9` || s[i_s] < `0`) {
+ buf[i_d] = s[i_s]
+ i_s++
+ i_d++
+ }
+ // sign
+ if i_s < s.len && s[i_s] in [`-`, `+`] {
+ buf[i_d] = s[i_s]
+ i_s++
+ i_d++
+ }
+
+ // integer part
+ for i_s < s.len && s[i_s] >= `0` && s[i_s] <= `9` {
+ buf[i_d] = s[i_s]
+ i_s++
+ i_d++
+ }
+
+ // check decimals
+ if i_s < s.len && s[i_s] == `.` {
+ mut i_s1 := i_s + 1
+ mut sum := 0
+ for i_s1 < s.len && s[i_s1] >= `0` && s[i_s1] <= `9` {
+ sum += s[i_s1] - byte(`0`)
+ i_s1++
+ }
+ // decimal part must be copied
+ if sum > 0 {
+ for c_i in i_s .. i_s1 {
+ buf[i_d] = s[c_i]
+ i_d++
+ }
+ }
+ i_s = i_s1
+ }
+
+ if i_s < s.len && s[i_s] != `.` {
+ // check exponent
+ for {
+ buf[i_d] = s[i_s]
+ i_s++
+ i_d++
+ if i_s >= s.len {
+ break
+ }
+ }
+ }
+
+ buf[i_d] = 0
+ return tos(buf, i_d)
+ }
+}