v.util: make util.smart_quote use its output string builder directly
parent
81fe702b77
commit
45c6b6493b
|
@ -45,7 +45,7 @@ pub fn (b &Builder) byte_at(n int) byte {
|
||||||
// write appends the string `s` to the buffer
|
// write appends the string `s` to the buffer
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (mut b Builder) write_string(s string) {
|
pub fn (mut b Builder) write_string(s string) {
|
||||||
if s == '' {
|
if s.len == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
unsafe { b.push_many(s.str, s.len) }
|
unsafe { b.push_many(s.str, s.len) }
|
||||||
|
|
|
@ -2,93 +2,119 @@ module util
|
||||||
|
|
||||||
import strings
|
import strings
|
||||||
|
|
||||||
const (
|
const invalid_escapes = r'({$`.'.bytes()
|
||||||
invalid_escapes = ['(', '{', '$', '`', '.']
|
|
||||||
)
|
|
||||||
|
|
||||||
[direct_array_access]
|
const backslash = 92
|
||||||
|
|
||||||
|
const backslash_r = 13
|
||||||
|
|
||||||
|
const backslash_n = 10
|
||||||
|
|
||||||
|
const double_quote = 34
|
||||||
|
|
||||||
|
const double_escape = '\\\\'
|
||||||
|
|
||||||
|
//[direct_array_access]
|
||||||
pub fn smart_quote(str string, raw bool) string {
|
pub fn smart_quote(str string, raw bool) string {
|
||||||
len := str.len
|
len := str.len
|
||||||
if len == 0 {
|
if len == 0 {
|
||||||
return str
|
return ''
|
||||||
}
|
}
|
||||||
mut result := strings.new_builder(len)
|
mut result := strings.new_builder(len)
|
||||||
mut pos := -1
|
mut pos := -1
|
||||||
mut last := ''
|
mut last := byte(0)
|
||||||
// TODO: This should be a single char?
|
mut current := byte(0)
|
||||||
mut next := ''
|
mut next := byte(0)
|
||||||
mut skip_next := false
|
mut skip_next := false
|
||||||
for {
|
for {
|
||||||
pos = pos + 1
|
pos++
|
||||||
if skip_next {
|
if skip_next {
|
||||||
skip_next = false
|
skip_next = false
|
||||||
pos = pos + 1
|
pos++
|
||||||
}
|
}
|
||||||
if pos >= len {
|
if pos >= len {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if pos + 1 < len {
|
if pos + 1 < len {
|
||||||
next = str[pos + 1].ascii_str()
|
next = str[pos + 1]
|
||||||
}
|
|
||||||
mut current := str
|
|
||||||
mut toadd := str
|
|
||||||
if len > 1 {
|
|
||||||
current = str[pos].ascii_str()
|
|
||||||
toadd = current
|
|
||||||
}
|
}
|
||||||
|
current = str[pos]
|
||||||
// double quote
|
// double quote
|
||||||
if current == '"' {
|
if current == util.double_quote {
|
||||||
toadd = '\\"'
|
current = 0
|
||||||
current = ''
|
last = current
|
||||||
|
result.write_b(util.backslash)
|
||||||
|
result.write_b(util.double_quote)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
if current == '\\' {
|
if current == util.backslash {
|
||||||
if raw {
|
if raw {
|
||||||
toadd = '\\\\'
|
last = current
|
||||||
|
result.write_string(util.double_escape)
|
||||||
|
continue
|
||||||
} else {
|
} else {
|
||||||
// escaped backslash - keep as is
|
// escaped backslash - keep as is
|
||||||
if next == '\\' {
|
if next == util.backslash {
|
||||||
toadd = '\\\\'
|
|
||||||
skip_next = true
|
skip_next = true
|
||||||
} else if next != '' {
|
last = current
|
||||||
|
result.write_string(util.double_escape)
|
||||||
|
continue
|
||||||
|
} else if next != 0 {
|
||||||
if raw {
|
if raw {
|
||||||
toadd = '\\\\' + next
|
|
||||||
skip_next = true
|
skip_next = true
|
||||||
}
|
last = current
|
||||||
// keep all valid escape sequences
|
result.write_string(util.double_escape)
|
||||||
else if next !in util.invalid_escapes {
|
continue
|
||||||
toadd = '\\' + next
|
} else if next in util.invalid_escapes {
|
||||||
skip_next = true
|
skip_next = true
|
||||||
|
last = current
|
||||||
|
result.write_b(next)
|
||||||
|
continue
|
||||||
} else {
|
} else {
|
||||||
toadd = next
|
// keep all valid escape sequences
|
||||||
skip_next = true
|
skip_next = true
|
||||||
|
last = current
|
||||||
|
result.write_b(current)
|
||||||
|
result.write_b(next)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// keep newlines in string
|
// keep newlines in string
|
||||||
if current == '\n' {
|
if current == util.backslash_n {
|
||||||
toadd = '\\n'
|
current = 0
|
||||||
current = ''
|
last = current
|
||||||
} else if current == '\r' && next == '\n' {
|
result.write_b(util.backslash)
|
||||||
toadd = '\r\n'
|
result.write_b(`n`)
|
||||||
current = ''
|
continue
|
||||||
|
} else if current == util.backslash_r && next == util.backslash_n {
|
||||||
|
result.write_b(current)
|
||||||
|
result.write_b(next)
|
||||||
|
current = 0
|
||||||
skip_next = true
|
skip_next = true
|
||||||
|
last = current
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
// Dolar sign
|
// Dolar sign
|
||||||
if !raw && current == '$' {
|
if !raw && current == `$` {
|
||||||
if last == '\\' {
|
if last == util.backslash {
|
||||||
toadd = r'\$'
|
result.write_b(last)
|
||||||
|
result.write_b(current)
|
||||||
|
last = current
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Windows style new line \r\n
|
// Windows style new line \r\n
|
||||||
if !raw && current == '\r' {
|
if !raw && current == util.backslash_r && next == util.backslash_n {
|
||||||
if next == '\n' {
|
skip_next = true
|
||||||
skip_next = true
|
result.write_b(util.backslash)
|
||||||
toadd = '\\n'
|
result.write_b(`n`)
|
||||||
}
|
last = current
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
result.write_string(toadd)
|
|
||||||
last = current
|
last = current
|
||||||
|
result.write_b(current)
|
||||||
}
|
}
|
||||||
return result.str()
|
return result.str()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue