strings: run v fmt (#7438)

pull/7460/head
zakuro 2020-12-22 05:00:32 +09:00 committed by GitHub
parent fade162471
commit 6c341a77f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 55 additions and 49 deletions

View File

@ -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',
]

View File

@ -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) {

View File

@ -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
}

View File

@ -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)

View File

@ -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)
}

View File

@ -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)}
}

View File

@ -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
*/
*/
}

View File

@ -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)
}
*/