From 3e04dfc79f613352f39362a28d41a8bad50547d5 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Tue, 5 Jan 2021 18:59:51 +0100 Subject: [PATCH] builtin: fix byte.str() (part 1) --- vlib/builtin/int.v | 15 +++++++- vlib/builtin/string.v | 64 +++++++++++++++++------------------ vlib/flag/flag.v | 2 +- vlib/strconv/number_to_base.v | 4 +-- vlib/v/checker/checker.v | 5 +++ vlib/v/scanner/scanner.v | 2 +- vlib/v/util/errors.v | 2 +- vlib/v/util/quote.v | 4 +-- vlib/v/vmod/parser.v | 18 +++++----- 9 files changed, 67 insertions(+), 49 deletions(-) diff --git a/vlib/builtin/int.v b/vlib/builtin/int.v index 0e7106ede7..46ecf6226e 100644 --- a/vlib/builtin/int.v +++ b/vlib/builtin/int.v @@ -452,6 +452,19 @@ pub fn (b byte) str() string { return str } +pub fn (b byte) ascii_str() string { + mut str := string{ + str: malloc(2) + len: 1 + } + unsafe { + str.str[0] = b + str.str[1] = `\0` + } + // println(str) + return str +} + // str_escaped returns the contents of `byte` as an escaped `string`. // Example: assert byte(0).str_escaped() == r'`\0`' pub fn (b byte) str_escaped() string { @@ -464,7 +477,7 @@ pub fn (b byte) str_escaped() string { 11 { r'`\v`' } 12 { r'`\f`' } 13 { r'`\r`' } - 32...126 { b.str() } + 32...126 { b.ascii_str() } else { '0x' + b.hex() } } return str diff --git a/vlib/builtin/string.v b/vlib/builtin/string.v index 8cd02dd860..aff9f39087 100644 --- a/vlib/builtin/string.v +++ b/vlib/builtin/string.v @@ -44,7 +44,7 @@ NB: A V string should be/is immutable from the point of view of pub struct string { pub: str byteptr // points to a C style 0 terminated string of bytes. - len int // the length of the .str field, excluding the ending 0 byte. It is always equal to strlen(.str). + len int // the length of the .str field, excluding the ending 0 byte. It is always equal to strlen(.str). mut: is_lit int } @@ -68,7 +68,7 @@ pub mut: // vstrlen returns the V length of the C string `s` (0 terminator is not counted). [unsafe] pub fn vstrlen(s byteptr) int { - return unsafe {C.strlen(charptr(s))} + return unsafe { C.strlen(charptr(s)) } } // tos converts a C string to a V string. @@ -109,7 +109,7 @@ pub fn tos3(s charptr) string { } return string{ str: byteptr(s) - len: unsafe {C.strlen(s)} + len: unsafe { C.strlen(s) } } } @@ -134,7 +134,7 @@ pub fn tos_lit(s charptr) string { eprintln('warning: `tos_lit` has been deprecated, use `_SLIT` instead') return string{ str: byteptr(s) - len: unsafe {C.strlen(s)} + len: unsafe { C.strlen(s) } is_lit: 1 } } @@ -144,7 +144,7 @@ pub fn tos_lit(s charptr) string { pub fn (bp byteptr) vstring() string { return string{ str: bp - len: unsafe {C.strlen(charptr(bp))} + len: unsafe { C.strlen(charptr(bp)) } } } @@ -162,7 +162,7 @@ pub fn (bp byteptr) vstring_with_len(len int) string { pub fn (cp charptr) vstring() string { return string{ str: byteptr(cp) - len: unsafe {C.strlen(cp)} + len: unsafe { C.strlen(cp) } } } @@ -188,7 +188,7 @@ pub fn (a string) clone() string { return '' } mut b := string{ - str: unsafe {malloc(a.len + 1)} + str: unsafe { malloc(a.len + 1) } len: a.len } unsafe { @@ -225,7 +225,7 @@ pub fn (s string) replace(rep string, with string) string { // Get locations of all reps within this string mut idxs := []int{} defer { - unsafe {idxs.free()} + unsafe { idxs.free() } } mut idx := 0 for { @@ -529,7 +529,7 @@ pub fn (s string) split_nth(delim string, nth int) []string { res << s.right(i) break } - res << ch.str() + res << ch.ascii_str() i++ } return res @@ -567,8 +567,8 @@ pub fn (s string) split_into_lines() []string { } mut start := 0 for i := 0; i < s.len; i++ { - is_lf := unsafe {s.str[i]} == `\n` - is_crlf := i != s.len - 1 && unsafe {s.str[i] == `\r` && s.str[i + 1] == `\n`} + is_lf := unsafe { s.str[i] } == `\n` + is_crlf := i != s.len - 1 && unsafe { s.str[i] == `\r` && s.str[i + 1] == `\n` } is_eol := is_lf || is_crlf is_last := if is_crlf { i == s.len - 2 } else { i == s.len - 1 } if is_eol || is_last { @@ -651,7 +651,7 @@ pub fn (s string) index_old(p string) int { mut i := 0 for i < s.len { mut j := 0 - for j < p.len && unsafe {s.str[i + j] == p.str[j]} { + for j < p.len && unsafe { s.str[i + j] == p.str[j] } { j++ } if j == p.len { @@ -671,7 +671,7 @@ pub fn (s string) index(p string) ?int { mut i := 0 for i < s.len { mut j := 0 - for j < p.len && unsafe {s.str[i + j] == p.str[j]} { + for j < p.len && unsafe { s.str[i + j] == p.str[j] } { j++ } if j == p.len { @@ -690,20 +690,20 @@ fn (s string) index_kmp(p string) int { mut prefix := []int{len: p.len} mut j := 0 for i := 1; i < p.len; i++ { - for unsafe {p.str[j] != p.str[i]} && j > 0 { + for unsafe { p.str[j] != p.str[i] } && j > 0 { j = prefix[j - 1] } - if unsafe {p.str[j] == p.str[i]} { + if unsafe { p.str[j] == p.str[i] } { j++ } prefix[i] = j } j = 0 for i in 0 .. s.len { - for unsafe {p.str[j] != s.str[i]} && j > 0 { + for unsafe { p.str[j] != s.str[i] } && j > 0 { j = prefix[j - 1] } - if unsafe {p.str[j] == s.str[i]} { + if unsafe { p.str[j] == s.str[i] } { j++ } if j == p.len { @@ -716,7 +716,7 @@ fn (s string) index_kmp(p string) int { // index_any returns the position of any of the characters in the input string - if found. pub fn (s string) index_any(chars string) int { for c in chars { - index := s.index(c.str()) or { continue } + index := s.index(c.ascii_str()) or { continue } return index } return -1 @@ -730,7 +730,7 @@ pub fn (s string) last_index(p string) ?int { mut i := s.len - p.len for i >= 0 { mut j := 0 - for j < p.len && unsafe {s.str[i + j] == p.str[j]} { + for j < p.len && unsafe { s.str[i + j] == p.str[j] } { j++ } if j == p.len { @@ -757,7 +757,7 @@ pub fn (s string) index_after(p string, start int) int { for i < s.len { mut j := 0 mut ii := i - for j < p.len && unsafe {s.str[ii] == p.str[j]} { + for j < p.len && unsafe { s.str[ii] == p.str[j] } { j++ ii++ } @@ -773,7 +773,7 @@ pub fn (s string) index_after(p string, start int) int { // index_byte returns -1 if the byte can not be found. pub fn (s string) index_byte(c byte) int { for i in 0 .. s.len { - if unsafe {s.str[i]} == c { + if unsafe { s.str[i] } == c { return i } } @@ -784,7 +784,7 @@ pub fn (s string) index_byte(c byte) int { // last_index_byte returns -1 if the byte is not found. pub fn (s string) last_index_byte(c byte) int { for i := s.len - 1; i >= 0; i-- { - if unsafe {s.str[i] == c} { + if unsafe { s.str[i] == c } { return i } } @@ -825,7 +825,7 @@ pub fn (s string) contains(substr string) bool { // contains_any returns `true` if the string contains any chars in `chars`. pub fn (s string) contains_any(chars string) bool { for c in chars { - if c.str() in s { + if c.ascii_str() in s { return true } } @@ -851,7 +851,7 @@ pub fn (s string) starts_with(p string) bool { return false } for i in 0 .. p.len { - if unsafe {s.str[i] != p.str[i]} { + if unsafe { s.str[i] != p.str[i] } { return false } } @@ -923,7 +923,7 @@ pub fn (s string) capitalize() string { if s.len == 0 { return '' } - return s[0].str().to_upper() + s[1..] + return s[0].ascii_str().to_upper() + s[1..] // sl := s.to_lower() // cap := sl[0].str().to_upper() + sl.right(1) // return cap @@ -1152,7 +1152,7 @@ pub fn (s string) ustring() ustring { runes: __new_array(0, s.len, int(sizeof(int))) } for i := 0; i < s.len; i++ { - char_len := utf8_char_len(unsafe {s.str[i]}) + char_len := utf8_char_len(unsafe { s.str[i] }) res.runes << i i += char_len - 1 res.len++ @@ -1176,7 +1176,7 @@ pub fn (s string) ustring_tmp() ustring { res.runes.len = s.len mut j := 0 for i := 0; i < s.len; i++ { - char_len := utf8_char_len(unsafe {s.str[i]}) + char_len := utf8_char_len(unsafe { s.str[i] }) res.runes[j] = i j++ i += char_len - 1 @@ -1226,14 +1226,14 @@ pub fn (u ustring) add(a ustring) ustring { } mut j := 0 for i := 0; i < u.s.len; i++ { - char_len := utf8_char_len(unsafe {u.s.str[i]}) + char_len := utf8_char_len(unsafe { u.s.str[i] }) res.runes << j i += char_len - 1 j += char_len res.len++ } for i := 0; i < a.s.len; i++ { - char_len := utf8_char_len(unsafe {a.s.str[i]}) + char_len := utf8_char_len(unsafe { a.s.str[i] }) res.runes << j i += char_len - 1 j += char_len @@ -1555,7 +1555,7 @@ pub fn (s string) bytes() []byte { return [] } mut buf := []byte{len: s.len} - unsafe {C.memcpy(buf.data, s.str, s.len)} + unsafe { C.memcpy(buf.data, s.str, s.len) } return buf } @@ -1669,7 +1669,7 @@ pub fn (s string) split_by_whitespace() []string { } if is_space && is_in_word { word_end = i - res << s[word_start .. word_end] + res << s[word_start..word_end] is_in_word = false word_end = 0 word_start = 0 @@ -1678,7 +1678,7 @@ pub fn (s string) split_by_whitespace() []string { } if is_in_word && word_start > 0 { // collect the remainder word at the end - res << s[word_start .. s.len] + res << s[word_start..s.len] } return res } diff --git a/vlib/flag/flag.v b/vlib/flag/flag.v index bde4be88b6..738f72eec5 100644 --- a/vlib/flag/flag.v +++ b/vlib/flag/flag.v @@ -383,7 +383,7 @@ pub fn (fs FlagParser) usage() string { for f in fs.flags { mut onames := []string{} if f.abbr != 0 { - onames << '-$f.abbr.str()' + onames << '-$f.abbr.ascii_str()' } if f.name != '' { if !f.val_desc.contains('') { diff --git a/vlib/strconv/number_to_base.v b/vlib/strconv/number_to_base.v index 73cd185461..3284df0f70 100644 --- a/vlib/strconv/number_to_base.v +++ b/vlib/strconv/number_to_base.v @@ -19,7 +19,7 @@ pub fn format_int(n i64, radix int) string { } mut res := '' for n_copy != 0 { - res = base_digits[n_copy % radix].str() + res + res = base_digits[n_copy % radix].ascii_str() + res n_copy /= radix } return '$sign$res' @@ -38,7 +38,7 @@ pub fn format_uint(n u64, radix int) string { mut res := '' uradix := u64(radix) for n_copy != 0 { - res = base_digits[n_copy % uradix].str() + res + res = base_digits[n_copy % uradix].ascii_str() + res n_copy /= uradix } return res diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index fd92feab78..c131cc9123 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1222,6 +1222,11 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { } // call_expr.generic_type = c.unwrap_generic(call_expr.generic_type) } + /* + if left_type == table.byte_type && method_name == 'str' { + c.warn('byte str', call_expr.pos) + } + */ // TODO: remove this for actual methods, use only for compiler magic // FIXME: Argument count != 1 will break these if left_type_sym.kind == .array && method_name in array_builtin_methods { diff --git a/vlib/v/scanner/scanner.v b/vlib/v/scanner/scanner.v index 6824d1889e..1e01d9bcbd 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -973,7 +973,7 @@ fn (mut s Scanner) text_scan() token.Token { return s.end_of_file() } } - s.error('invalid character `$c.str()`') + s.error('invalid character `$c.ascii_str()`') break } return s.end_of_file() diff --git a/vlib/v/util/errors.v b/vlib/v/util/errors.v index d762c66771..c80d20354e 100644 --- a/vlib/v/util/errors.v +++ b/vlib/v/util/errors.v @@ -131,7 +131,7 @@ pub fn source_context(kind string, source string, column int, pos token.Position mut pointerline := '' for bchar in sline[..start_column] { x := if bchar.is_space() { bchar } else { ` ` } - pointerline += x.str() + pointerline += x.ascii_str() } underline := if pos.len > 1 { '~'.repeat(end_column - start_column) } else { '^' } pointerline += bold(color(kind, underline)) diff --git a/vlib/v/util/quote.v b/vlib/v/util/quote.v index 03439a1159..ec69bc9e56 100644 --- a/vlib/v/util/quote.v +++ b/vlib/v/util/quote.v @@ -28,14 +28,14 @@ pub fn smart_quote(str string, raw bool) string { } if pos + 1 < len { unsafe { - next = str.str[pos + 1].str() + next = str.str[pos + 1].ascii_str() } } mut current := str mut toadd := str if len > 1 { unsafe { - current = str.str[pos].str() + current = str.str[pos].ascii_str() } toadd = current } diff --git a/vlib/v/vmod/parser.v b/vlib/v/vmod/parser.v index 88ca3bde72..3df5315226 100644 --- a/vlib/v/vmod/parser.v +++ b/vlib/v/vmod/parser.v @@ -87,7 +87,7 @@ fn (mut s Scanner) create_string(q byte) string { str += s.text[s.pos..s.pos + 1] s.pos += 2 } else { - str += s.text[s.pos].str() + str += s.text[s.pos].ascii_str() s.pos++ } } @@ -97,7 +97,7 @@ fn (mut s Scanner) create_string(q byte) string { fn (mut s Scanner) create_ident() string { mut text := '' for is_name_alpha(s.text[s.pos]) { - text += s.text[s.pos].str() + text += s.text[s.pos].ascii_str() s.pos++ } return text @@ -138,13 +138,13 @@ fn (mut s Scanner) scan_all() { continue } match c { - `{` { s.tokenize(.lcbr, c.str()) } - `}` { s.tokenize(.rcbr, c.str()) } - `[` { s.tokenize(.labr, c.str()) } - `]` { s.tokenize(.rabr, c.str()) } - `:` { s.tokenize(.colon, c.str()) } - `,` { s.tokenize(.comma, c.str()) } - else { s.tokenize(.unknown, c.str()) } + `{` { s.tokenize(.lcbr, c.ascii_str()) } + `}` { s.tokenize(.rcbr, c.ascii_str()) } + `[` { s.tokenize(.labr, c.ascii_str()) } + `]` { s.tokenize(.rabr, c.ascii_str()) } + `:` { s.tokenize(.colon, c.ascii_str()) } + `,` { s.tokenize(.comma, c.ascii_str()) } + else { s.tokenize(.unknown, c.ascii_str()) } } s.pos++ }