1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00
v/vlib/v/util/quote.v

98 lines
1.6 KiB
V

module util
import strings
const (
invalid_escapes = ['(', '{', '$', '`', '.']
)
pub fn smart_quote(str string, raw bool) string {
len := str.len
if len == 0 {
return str
}
mut result := strings.new_builder(0)
mut pos := -1
mut last := ''
// TODO: This should be a single char?
mut next := ''
mut skip_next := false
for {
pos = pos + 1
if skip_next {
skip_next = false
pos = pos + 1
}
if pos >= len {
break
}
if pos + 1 < len {
unsafe {
next = str.str[pos + 1].str()
}
}
mut current := str
mut toadd := str
if len > 1 {
unsafe {
current = str.str[pos].str()
}
toadd = current
}
// double quote
if current == '"' {
toadd = '\\"'
current = ''
}
if current == '\\' {
if raw {
toadd = '\\\\'
} else {
// escaped backslash - keep as is
if next == '\\' {
toadd = '\\\\'
skip_next = true
} else if next != '' {
if raw {
toadd = '\\\\' + next
skip_next = true
}
// keep all valid escape sequences
else if next !in invalid_escapes {
toadd = '\\' + next
skip_next = true
} else {
toadd = next
skip_next = true
}
}
}
}
// keep newlines in string
if current == '\n' {
toadd = '\\n'
current = ''
} else if current == '\r' && next == '\n' {
toadd = '\r\n'
current = ''
skip_next = true
}
// Dolar sign
if !raw && current == '$' {
if last == '\\' {
toadd = r'\$'
}
}
// Windows style new line \r\n
if !raw && current == '\r' {
if next == '\n' {
skip_next = true
toadd = '\\n'
}
}
result.write(toadd)
last = current
}
return result.str()
}