mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
strings: run v fmt (#7438)
This commit is contained in:
parent
fade162471
commit
6c341a77f5
@ -58,6 +58,8 @@ const (
|
||||
'vlib/v/vmod/',
|
||||
'vlib/gg/gg.v',
|
||||
'vlib/os/',
|
||||
'vlib/semver/',
|
||||
'vlib/strings/',
|
||||
'vlib/time/',
|
||||
'vlib/builtin/array_test.v',
|
||||
]
|
||||
|
@ -1,19 +1,18 @@
|
||||
// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved.
|
||||
// Use of this source code is governed by an MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
module strings
|
||||
|
||||
pub struct Builder {
|
||||
mut:
|
||||
buf []byte
|
||||
buf []byte
|
||||
pub mut:
|
||||
len int
|
||||
len int
|
||||
initial_size int = 1
|
||||
}
|
||||
|
||||
pub fn new_builder(initial_size int) Builder {
|
||||
return Builder {
|
||||
return Builder{
|
||||
buf: make(0, initial_size, sizeof(byte))
|
||||
initial_size: initial_size
|
||||
}
|
||||
@ -26,19 +25,19 @@ pub fn (mut b Builder) write_b(data byte) {
|
||||
|
||||
pub fn (mut b Builder) write(s string) {
|
||||
b.buf.push_many(s.str, s.len)
|
||||
//b.buf << []byte(s) // TODO
|
||||
// b.buf << []byte(s) // TODO
|
||||
b.len += s.len
|
||||
}
|
||||
|
||||
pub fn (mut b Builder) writeln(s string) {
|
||||
b.buf.push_many(s.str, s.len)
|
||||
//b.buf << []byte(s) // TODO
|
||||
// b.buf << []byte(s) // TODO
|
||||
b.buf << `\n`
|
||||
b.len += s.len + 1
|
||||
}
|
||||
|
||||
pub fn (b Builder) str() string {
|
||||
return unsafe { byteptr(b.buf.data).vstring_with_len(b.len) }
|
||||
return unsafe {byteptr(b.buf.data).vstring_with_len(b.len)}
|
||||
}
|
||||
|
||||
pub fn (mut b Builder) cut(n int) {
|
||||
|
@ -3,8 +3,11 @@
|
||||
// that can be found in the LICENSE file.
|
||||
module strings
|
||||
|
||||
// strings.Builder is used to efficiently append many strings to a large
|
||||
// dynamically growing buffer, then use the resulting large string. Using
|
||||
// a string builder is much better for performance/memory usage than doing
|
||||
// constantly string concatenation.
|
||||
pub struct Builder {
|
||||
// TODO
|
||||
pub mut:
|
||||
buf []byte
|
||||
str_calls int
|
||||
@ -12,9 +15,10 @@ pub mut:
|
||||
initial_size int = 1
|
||||
}
|
||||
|
||||
// new_builder returns a new string builder, with an initial capacity of `initial_size`
|
||||
pub fn new_builder(initial_size int) Builder {
|
||||
return Builder{
|
||||
//buf: make(0, initial_size)
|
||||
// buf: make(0, initial_size)
|
||||
buf: []byte{cap: initial_size}
|
||||
str_calls: 0
|
||||
len: 0
|
||||
@ -22,16 +26,19 @@ pub fn new_builder(initial_size int) Builder {
|
||||
}
|
||||
}
|
||||
|
||||
// write_bytes appends `bytes` to the accumulated buffer
|
||||
pub fn (mut b Builder) write_bytes(bytes byteptr, howmany int) {
|
||||
b.buf.push_many(bytes, howmany)
|
||||
b.len += howmany
|
||||
}
|
||||
|
||||
// write_b appends a single `data` byte to the accumulated buffer
|
||||
pub fn (mut b Builder) write_b(data byte) {
|
||||
b.buf << data
|
||||
b.len++
|
||||
}
|
||||
|
||||
// write appends the string `s` to the buffer
|
||||
[inline]
|
||||
pub fn (mut b Builder) write(s string) {
|
||||
if s == '' {
|
||||
@ -45,21 +52,23 @@ pub fn (mut b Builder) write(s string) {
|
||||
b.len += s.len
|
||||
}
|
||||
|
||||
// go_back discards the last `n` bytes from the buffer
|
||||
pub fn (mut b Builder) go_back(n int) {
|
||||
b.buf.trim(b.buf.len-n)
|
||||
b.buf.trim(b.buf.len - n)
|
||||
b.len -= n
|
||||
}
|
||||
|
||||
fn bytes2string(b []byte) string {
|
||||
mut copy := b.clone()
|
||||
copy << byte(`\0`)
|
||||
res := tos(copy.data, copy.len-1)
|
||||
res := tos(copy.data, copy.len - 1)
|
||||
return res
|
||||
}
|
||||
|
||||
// cut_last cuts the last `n` bytes from the buffer and returns them
|
||||
pub fn (mut b Builder) cut_last(n int) string {
|
||||
res := bytes2string( b.buf[b.len-n..] )
|
||||
b.buf.trim(b.buf.len-n)
|
||||
res := bytes2string(b.buf[b.len - n..])
|
||||
b.buf.trim(b.buf.len - n)
|
||||
b.len -= n
|
||||
return res
|
||||
}
|
||||
@ -72,12 +81,14 @@ pub fn (mut b Builder) cut_to(pos int) string {
|
||||
return res
|
||||
}
|
||||
*/
|
||||
|
||||
// go_back_to resets the buffer to the given position `pos`
|
||||
// NB: pos should be < than the existing buffer length.
|
||||
pub fn (mut b Builder) go_back_to(pos int) {
|
||||
b.buf.trim(pos)
|
||||
b.len = pos
|
||||
}
|
||||
|
||||
// writeln appends the string `s`, and then a newline character.
|
||||
[inline]
|
||||
pub fn (mut b Builder) writeln(s string) {
|
||||
// for c in s {
|
||||
@ -95,7 +106,7 @@ pub fn (b &Builder) last_n(n int) string {
|
||||
if n > b.len {
|
||||
return ''
|
||||
}
|
||||
return bytes2string( b.buf[b.len-n..] )
|
||||
return bytes2string(b.buf[b.len - n..])
|
||||
}
|
||||
|
||||
// buf == 'hello world'
|
||||
@ -104,31 +115,30 @@ pub fn (b &Builder) after(n int) string {
|
||||
if n >= b.len {
|
||||
return ''
|
||||
}
|
||||
return bytes2string( b.buf[n..] )
|
||||
return bytes2string(b.buf[n..])
|
||||
}
|
||||
|
||||
// str returns all of the accumulated content of the buffer.
|
||||
// NB: in order to avoid memleaks and additional memory copies, after a call to b.str(),
|
||||
// the builder b will be empty. The returned string *owns* the accumulated data so far.
|
||||
pub fn (mut b Builder) str() string {
|
||||
b.str_calls++
|
||||
if b.str_calls > 1 {
|
||||
panic('builder.str() should be called just once.\n' +
|
||||
'If you want to reuse a builder, call b.free() first.')
|
||||
panic('builder.str() should be called just once.\nIf you want to reuse a builder, call b.free() first.')
|
||||
}
|
||||
b.buf << `\0`
|
||||
s := tos(b.buf.data, b.len)
|
||||
bis := b.initial_size
|
||||
//free(b.buf.data)
|
||||
// free(b.buf.data)
|
||||
b.buf = []byte{cap: bis}
|
||||
b.len = 0
|
||||
return s
|
||||
}
|
||||
|
||||
// manually free the contents of the buffer
|
||||
pub fn (mut b Builder) free() {
|
||||
unsafe{
|
||||
free(b.buf.data)
|
||||
}
|
||||
//b.buf = []byte{cap: b.initial_size}
|
||||
unsafe {free(b.buf.data)}
|
||||
// b.buf = []byte{cap: b.initial_size}
|
||||
b.len = 0
|
||||
b.str_calls = 0
|
||||
}
|
||||
|
@ -23,14 +23,13 @@ fn test_sb() {
|
||||
y := MyInt(20)
|
||||
sb.writeln('x = $x y = $y')
|
||||
res := sb.str()
|
||||
assert res[res.len-1] == `\n`
|
||||
assert res[res.len - 1] == `\n`
|
||||
println('"$res"')
|
||||
assert res.trim_space() == 'x = 10 y = 20'
|
||||
//
|
||||
sb = strings.new_builder(10)
|
||||
sb.write('x = $x y = $y')
|
||||
assert sb.str() == 'x = 10 y = 20'
|
||||
|
||||
$if !windows {
|
||||
// TODO msvc bug
|
||||
sb = strings.new_builder(10)
|
||||
@ -49,7 +48,7 @@ const (
|
||||
fn test_big_sb() {
|
||||
mut sb := strings.new_builder(100)
|
||||
mut sb2 := strings.new_builder(10000)
|
||||
for i in 0..maxn {
|
||||
for i in 0 .. maxn {
|
||||
sb.writeln(i.str())
|
||||
sb2.write('+')
|
||||
}
|
||||
@ -62,12 +61,11 @@ fn test_big_sb() {
|
||||
assert lines[98765] == '98765'
|
||||
println(sb2.len)
|
||||
assert sb2.len == maxn
|
||||
|
||||
}
|
||||
|
||||
fn test_byte_write() {
|
||||
mut sb := strings.new_builder(100)
|
||||
temp_str := "byte testing"
|
||||
temp_str := 'byte testing'
|
||||
mut count := 0
|
||||
for word in temp_str {
|
||||
sb.write_b(word)
|
||||
|
@ -1,10 +1,11 @@
|
||||
module strings
|
||||
|
||||
// #-js
|
||||
// use levenshtein distance algorithm to calculate
|
||||
// the distance between between two strings (lower is closer)
|
||||
pub fn levenshtein_distance(a string, b string) int {
|
||||
mut f := [0].repeat(b.len + 1)
|
||||
for j in 0..f.len {
|
||||
for j in 0 .. f.len {
|
||||
f[j] = j
|
||||
}
|
||||
for ca in a {
|
||||
@ -15,8 +16,7 @@ pub fn levenshtein_distance(a string, b string) int {
|
||||
mut mn := if f[j] + 1 <= f[j - 1] + 1 { f[j] + 1 } else { f[j - 1] + 1 }
|
||||
if cb != ca {
|
||||
mn = if mn <= fj1 + 1 { mn } else { fj1 + 1 }
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
mn = if mn <= fj1 { mn } else { fj1 }
|
||||
}
|
||||
fj1 = f[j]
|
||||
@ -50,14 +50,14 @@ pub fn dice_coefficient(s1 string, s2 string) f32 {
|
||||
}
|
||||
a := if s1.len > s2.len { s1 } else { s2 }
|
||||
b := if a == s1 { s2 } else { s1 }
|
||||
mut first_bigrams := map[string]int
|
||||
for i in 0..a.len - 1 {
|
||||
mut first_bigrams := map[string]int{}
|
||||
for i in 0 .. a.len - 1 {
|
||||
bigram := a[i..i + 2]
|
||||
q := if bigram in first_bigrams { first_bigrams[bigram] + 1 } else { 1 }
|
||||
first_bigrams[bigram] = q
|
||||
}
|
||||
mut intersection_size := 0
|
||||
for i in 0..b.len - 1 {
|
||||
for i in 0 .. b.len - 1 {
|
||||
bigram := b[i..i + 2]
|
||||
count := if bigram in first_bigrams { first_bigrams[bigram] } else { 0 }
|
||||
if count > 0 {
|
||||
@ -67,4 +67,3 @@ pub fn dice_coefficient(s1 string, s2 string) f32 {
|
||||
}
|
||||
return (2.0 * f32(intersection_size)) / (f32(a.len) + f32(b.len) - 2)
|
||||
}
|
||||
|
||||
|
@ -7,10 +7,10 @@ pub fn repeat(c byte, n int) string {
|
||||
}
|
||||
mut bytes := unsafe {malloc(n + 1)}
|
||||
unsafe {
|
||||
C.memset( bytes, c, n )
|
||||
C.memset(bytes, c, n)
|
||||
bytes[n] = `0`
|
||||
}
|
||||
return unsafe { bytes.vstring_with_len(n) }
|
||||
return unsafe {bytes.vstring_with_len(n)}
|
||||
}
|
||||
|
||||
// strings.repeat_string - gives you `n` repetitions of the substring `s`
|
||||
@ -21,18 +21,18 @@ pub fn repeat_string(s string, n int) string {
|
||||
return ''
|
||||
}
|
||||
slen := s.len
|
||||
blen := slen*n
|
||||
blen := slen * n
|
||||
mut bytes := unsafe {malloc(blen + 1)}
|
||||
for bi in 0..n {
|
||||
bislen := bi*slen
|
||||
for si in 0..slen {
|
||||
for bi in 0 .. n {
|
||||
bislen := bi * slen
|
||||
for si in 0 .. slen {
|
||||
unsafe {
|
||||
bytes[bislen+si] = s[si]
|
||||
bytes[bislen + si] = s[si]
|
||||
}
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
bytes[blen] = `0`
|
||||
}
|
||||
return unsafe { bytes.vstring_with_len(blen) }
|
||||
return unsafe {bytes.vstring_with_len(blen)}
|
||||
}
|
||||
|
@ -9,9 +9,9 @@ pub fn repeat(c byte, n int) string {
|
||||
}
|
||||
|
||||
pub fn repeat_string(s string, n int) string {
|
||||
/*
|
||||
// TODO: uncomment this. It is commented for now, so that `v doc strings` works
|
||||
/*
|
||||
// TODO: uncomment this. It is commented for now, so that `v doc strings` works
|
||||
res := # s.repeat(n)
|
||||
return res
|
||||
*/
|
||||
*/
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
module strings
|
||||
|
||||
//import rand
|
||||
|
||||
// import rand
|
||||
// random returns a random string with `n` characters
|
||||
/*
|
||||
pub fn random(n int) string {
|
||||
@ -12,4 +11,3 @@ pub fn random(n int) string {
|
||||
return tos(buf)
|
||||
}
|
||||
*/
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user