diff --git a/cmd/tools/vpm.v b/cmd/tools/vpm.v index bdc4645519..d15fdacca7 100644 --- a/cmd/tools/vpm.v +++ b/cmd/tools/vpm.v @@ -570,16 +570,16 @@ fn get_all_modules() []string { mut start_token := '' - start_index = s.index_after(start_token, start_index) + start_token.len + start_index = s.index_after(start_token, start_index) or { -1 } + start_token.len // get the index of the end of module entry - end_index := s.index_after(end_token, start_index) + end_index := s.index_after(end_token, start_index) or { -1 } if end_index == -1 { break } diff --git a/examples/links_scraper.v b/examples/links_scraper.v index 2a0b775886..38c6e45399 100644 --- a/examples/links_scraper.v +++ b/examples/links_scraper.v @@ -4,11 +4,11 @@ fn main() { html := http.get_text('https://news.ycombinator.com') mut pos := 0 for { - pos = html.index_after('https://', pos + 1) + pos = html.index_after('https://', pos + 1) or { -1 } if pos == -1 { break } - end := html.index_after('"', pos) + end := html.index_after('"', pos) or { html.len } println(html[pos..end]) } } diff --git a/vlib/builtin/string.v b/vlib/builtin/string.v index 293b48bcca..3ab18896d8 100644 --- a/vlib/builtin/string.v +++ b/vlib/builtin/string.v @@ -319,11 +319,11 @@ pub fn (a string) clone() string { // replace_once replaces the first occurence of `rep` with the string passed in `with`. pub fn (s string) replace_once(rep string, with string) string { - idx := s.index_(rep) - if idx == -1 { + if idx := s.index(rep) { + return s.substr(0, idx) + with + s.substr(idx + rep.len, s.len) + } else { return s.clone() } - return s.substr(0, idx) + with + s.substr(idx + rep.len, s.len) } // replace replaces all occurences of `rep` with the string passed in `with`. @@ -343,10 +343,7 @@ pub fn (s string) replace(rep string, with string) string { } mut idx := 0 for { - idx = s.index_after(rep, idx) - if idx == -1 { - break - } + idx = s.index_after(rep, idx) or { break } idxs << idx idx += rep.len } @@ -419,7 +416,7 @@ pub fn (s string) replace_each(vals []string) string { with := vals[rep_i + 1] for { - idx = s_.index_after(rep, idx) + idx = s_.index_after(rep, idx) or { -1 } if idx == -1 { break } @@ -899,11 +896,11 @@ pub fn (s string) substr_ni(_start int, _end int) string { } // index returns the position of the first character of the input string. -// It will return `-1` if the input string can't be found. +// It will return `none` if the input string can't be found. [direct_array_access] -fn (s string) index_(p string) int { +pub fn (s string) index(p string) ?int { if p.len > s.len || p.len == 0 { - return -1 + return none } if p.len > 2 { return s.index_kmp(p) @@ -919,24 +916,14 @@ fn (s string) index_(p string) int { } i++ } - return -1 -} - -// index returns the position of the first character of the input string. -// It will return `none` if the input string can't be found. -pub fn (s string) index(p string) ?int { - idx := s.index_(p) - if idx == -1 { - return none - } - return idx + return none } // index_kmp does KMP search. [direct_array_access; manualfree] -fn (s string) index_kmp(p string) int { +fn (s string) index_kmp(p string) ?int { if p.len > s.len { - return -1 + return none } mut prefix := []int{len: p.len} defer { @@ -964,11 +951,11 @@ fn (s string) index_kmp(p string) int { return i - p.len + 1 } } - return -1 + return none } // 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 { +pub fn (s string) index_any(chars string) ?int { for i, ss in s { for c in chars { if c == ss { @@ -976,14 +963,14 @@ pub fn (s string) index_any(chars string) int { } } } - return -1 + return none } // last_index returns the position of the last occurence of the input string. [direct_array_access] -fn (s string) last_index_(p string) int { +pub fn (s string) last_index(p string) ?int { if p.len > s.len || p.len == 0 { - return -1 + return none } mut i := s.len - p.len for i >= 0 { @@ -996,30 +983,21 @@ fn (s string) last_index_(p string) int { } i-- } - return -1 -} - -// last_index returns the position of the last occurence of the input string. -pub fn (s string) last_index(p string) ?int { - idx := s.last_index_(p) - if idx == -1 { - return none - } - return idx + return none } // index_after returns the position of the input string, starting search from `start` position. [direct_array_access] -pub fn (s string) index_after(p string, start int) int { +pub fn (s string) index_after(p string, start int) ?int { if p.len > s.len { - return -1 + return none } mut strt := start if start < 0 { strt = 0 } if start >= s.len { - return -1 + return none } mut i := strt for i < s.len { @@ -1034,35 +1012,35 @@ pub fn (s string) index_after(p string, start int) int { } i++ } - return -1 + return none } // index_byte returns the index of byte `c` if found in the string. -// index_byte returns -1 if the byte can not be found. +// index_byte returns `none` if the byte can not be found. [direct_array_access] -pub fn (s string) index_byte(c byte) int { +pub fn (s string) index_byte(c byte) ?int { for i in 0 .. s.len { if unsafe { s.str[i] } == c { return i } } - return -1 + return none } // last_index_byte returns the index of the last occurence of byte `c` if found in the string. -// last_index_byte returns -1 if the byte is not found. +// last_index_byte returns `none` if the byte is not found. [direct_array_access] -pub fn (s string) last_index_byte(c byte) int { +pub fn (s string) last_index_byte(c byte) ?int { for i := s.len - 1; i >= 0; i-- { if unsafe { s.str[i] == c } { return i } } - return -1 + return none } // count returns the number of occurrences of `substr` in the string. -// count returns -1 if no `substr` could be found. +// count returns 0 if no `substr` could be found. [direct_array_access] pub fn (s string) count(substr string) int { if s.len == 0 || substr.len == 0 { @@ -1088,10 +1066,7 @@ pub fn (s string) count(substr string) int { mut i := 0 for { - i = s.index_after(substr, i) - if i == -1 { - return n - } + i = s.index_after(substr, i) or { return n } i += substr.len n++ } @@ -1103,10 +1078,11 @@ pub fn (s string) contains(substr string) bool { if substr.len == 0 { return true } - if s.index_(substr) == -1 { + if _ := s.index(substr) { + return true + } else { return false } - return true } // contains_any returns `true` if the string contains any chars in `chars`. @@ -1294,16 +1270,10 @@ pub fn (s string) is_title() bool { // find_between returns the string found between `start` string and `end` string. // Example: assert 'hey [man] how you doin'.find_between('[', ']') == 'man' pub fn (s string) find_between(start string, end string) string { - start_pos := s.index_(start) - if start_pos == -1 { - return '' - } + start_pos := s.index(start) or { return '' } // First get everything to the right of 'start' val := s[start_pos + start.len..] - end_pos := val.index_(end) - if end_pos == -1 { - return val - } + end_pos := val.index(end) or { return val } return val[..end_pos] } @@ -1582,11 +1552,11 @@ pub fn (s &string) free() { // Example: assert 'abcd'.before('.') == 'abcd' // TODO: deprecate and remove either .before or .all_before pub fn (s string) before(sub string) string { - pos := s.index_(sub) - if pos == -1 { + if pos := s.index(sub) { + return s[..pos] + } else { return s.clone() } - return s[..pos] } // all_before returns the contents before `sub` in the string. @@ -1595,11 +1565,11 @@ pub fn (s string) before(sub string) string { // Example: assert 'abcd'.all_before('.') == 'abcd' pub fn (s string) all_before(sub string) string { // TODO remove dup method - pos := s.index_(sub) - if pos == -1 { + if pos := s.index(sub) { + return s[..pos] + } else { return s.clone() } - return s[..pos] } // all_before_last returns the contents before the last occurence of `sub` in the string. @@ -1607,11 +1577,11 @@ pub fn (s string) all_before(sub string) string { // Example: assert '23:34:45.234'.all_before_last(':') == '23:34' // Example: assert 'abcd'.all_before_last('.') == 'abcd' pub fn (s string) all_before_last(sub string) string { - pos := s.last_index_(sub) - if pos == -1 { + if pos := s.last_index(sub) { + return s[..pos] + } else { return s.clone() } - return s[..pos] } // all_after returns the contents after `sub` in the string. @@ -1619,11 +1589,11 @@ pub fn (s string) all_before_last(sub string) string { // Example: assert '23:34:45.234'.all_after('.') == '234' // Example: assert 'abcd'.all_after('z') == 'abcd' pub fn (s string) all_after(sub string) string { - pos := s.index_(sub) - if pos == -1 { + if pos := s.index(sub) { + return s[pos + sub.len..] + } else { return s.clone() } - return s[pos + sub.len..] } // all_after_last returns the contents after the last occurence of `sub` in the string. @@ -1631,11 +1601,11 @@ pub fn (s string) all_after(sub string) string { // Example: assert '23:34:45.234'.all_after_last(':') == '45.234' // Example: assert 'abcd'.all_after_last('z') == 'abcd' pub fn (s string) all_after_last(sub string) string { - pos := s.last_index_(sub) - if pos == -1 { + if pos := s.last_index(sub) { + return s[pos + sub.len..] + } else { return s.clone() } - return s[pos + sub.len..] } // after returns the contents after the last occurence of `sub` in the string. diff --git a/vlib/builtin/string_test.v b/vlib/builtin/string_test.v index 5ae69866e5..91e7112b55 100644 --- a/vlib/builtin/string_test.v +++ b/vlib/builtin/string_test.v @@ -961,8 +961,12 @@ fn test_string_to_rune() { fn test_index_any() { x := 'abcdefghij' - assert x.index_any('ef') == 4 - assert x.index_any('fe') == 4 + if idx := x.index_any('ef') { + assert idx == 4 + } + if idx := x.index_any('fe') { + assert idx == 4 + } } fn test_string_f64() { diff --git a/vlib/encoding/base58/base58.v b/vlib/encoding/base58/base58.v index fb2ff72027..3c6d9f254d 100644 --- a/vlib/encoding/base58/base58.v +++ b/vlib/encoding/base58/base58.v @@ -94,8 +94,7 @@ pub fn decode_int_walpha(input string, alphabet Alphabet) ?int { mut total := 0 // to hold the results b58 := input.reverse() for i, ch in b58 { - ch_i := alphabet.encode.bytestr().index_byte(ch) - if ch_i == -1 { + ch_i := alphabet.encode.bytestr().index_byte(ch) or { return error(@MOD + '.' + @FN + ': input string contains values not found in the provided alphabet') } diff --git a/vlib/encoding/csv/reader.v b/vlib/encoding/csv/reader.v index 55bf5b8d8e..017623d2b0 100644 --- a/vlib/encoding/csv/reader.v +++ b/vlib/encoding/csv/reader.v @@ -87,11 +87,11 @@ fn (mut r Reader) read_line() ?string { return IError(&EndOfFileError{}) } le := if r.is_mac_pre_osx_le { '\r' } else { '\n' } - mut i := r.data.index_after(le, r.row_pos) + mut i := r.data.index_after(le, r.row_pos) or { -1 } if i == -1 { if r.row_pos == 0 { // check for pre osx mac line endings - i = r.data.index_after('\r', r.row_pos) + i = r.data.index_after('\r', r.row_pos) or { -1 } if i != -1 { r.is_mac_pre_osx_le = true } else { diff --git a/vlib/encoding/csv/writer.v b/vlib/encoding/csv/writer.v index 07bd26c59d..3201f2a030 100644 --- a/vlib/encoding/csv/writer.v +++ b/vlib/encoding/csv/writer.v @@ -37,10 +37,7 @@ pub fn (mut w Writer) write(record []string) ?bool { } w.sb.write_string('"') for field.len > 0 { - mut i := field.index_any('"\r\n') - if i < 0 { - i = field.len - } + mut i := field.index_any('"\r\n') or { field.len } w.sb.write_string(field[..i]) field = field[i..] if field.len > 0 { @@ -69,7 +66,10 @@ fn (w &Writer) field_needs_quotes(field string) bool { if field == '' { return false } - if field.contains(w.delimiter.ascii_str()) || (field.index_any('"\r\n') != -1) { + if field.contains(w.delimiter.ascii_str()) { + return true + } + if _ := field.index_any('"\r\n') { return true } return false diff --git a/vlib/flag/flag.v b/vlib/flag/flag.v index 9ef26b5a6a..b59af4ba91 100644 --- a/vlib/flag/flag.v +++ b/vlib/flag/flag.v @@ -305,7 +305,8 @@ fn (mut fs FlagParser) parse_bool_value(longhand string, shorthand byte) ?string fs.args.delete(i) return val } - if arg.len > 1 && arg[0] == `-` && arg[1] != `-` && arg.index_byte(shorthand) != -1 { + if arg.len > 1 && arg[0] == `-` && arg[1] != `-` + && arg.index_byte(shorthand) or { -1 } != -1 { // -abc is equivalent to -a -b -c return 'true' } diff --git a/vlib/net/http/cookie.v b/vlib/net/http/cookie.v index d647b3daf6..abe1db69bd 100644 --- a/vlib/net/http/cookie.v +++ b/vlib/net/http/cookie.v @@ -68,7 +68,7 @@ pub fn read_cookies(h map[string][]string, filter string) []&Cookie { mut line := line_.trim_space() mut part := '' for line.len > 0 { - if line.index_any(';') > 0 { + if _ := line.index_any(';') { line_parts := line.split(';') part = line_parts[0] line = line_parts[1] diff --git a/vlib/net/urllib/urllib.v b/vlib/net/urllib/urllib.v index 5217703720..834e32d38d 100644 --- a/vlib/net/urllib/urllib.v +++ b/vlib/net/urllib/urllib.v @@ -418,10 +418,7 @@ fn get_scheme(rawurl string) ?string { // sep. If cutc is true then sep is included with the second substring. // If sep does not occur in s then s and the empty string is returned. fn split(s string, sep byte, cutc bool) (string, string) { - i := s.index_byte(sep) - if i < 0 { - return s, '' - } + i := s.index_byte(sep) or { return s, '' } if cutc { return s[..i], s[i + 1..] } @@ -746,11 +743,10 @@ pub fn (u URL) str() string { // it would be mistaken for a scheme name. Such a segment must be // preceded by a dot-segment (e.g., './this:that') to make a relative- // path reference. - i := path.index_byte(`:`) - if i > -1 { + if i := path.index_byte(`:`) { // TODO remove this when autofree handles tmp // expressions like this - if i > -1 && path[..i].index_byte(`/`) == -1 { + if i > -1 && path[..i].index_byte(`/`) or { -1 } == -1 { buf.write_string('./') } } @@ -800,7 +796,7 @@ fn parse_query_values(mut m Values, query string) ?bool { mut q := query for q != '' { mut key := q - mut i := key.index_any('&;') + mut i := key.index_any('&;') or { -1 } if i >= 0 { q = key[i + 1..] key = key[..i] @@ -1006,8 +1002,7 @@ pub fn (u &URL) port() string { fn split_host_port(hostport string) (string, string) { mut host := hostport mut port := '' - colon := host.last_index_byte(`:`) - if colon != -1 { + if colon := host.last_index_byte(`:`) { if valid_optional_port(host[colon..]) { port = host[colon + 1..] host = host[..colon] diff --git a/vlib/os/environment.c.v b/vlib/os/environment.c.v index ed74681145..bf317e554b 100644 --- a/vlib/os/environment.c.v +++ b/vlib/os/environment.c.v @@ -109,8 +109,7 @@ pub fn environ() map[string]string { break } eline := unsafe { cstring_to_vstring(x) } - eq_index := eline.index_byte(`=`) - if eq_index > 0 { + if eq_index := eline.index_byte(`=`) { res[eline[0..eq_index]] = eline[eq_index + 1..] } i++ diff --git a/vlib/semver/range.v b/vlib/semver/range.v index 2f77bb7327..a9488b3809 100644 --- a/vlib/semver/range.v +++ b/vlib/semver/range.v @@ -130,9 +130,7 @@ fn parse_comparator(input string) ?Comparator { fn parse_xrange(input string) ?Version { mut raw_ver := parse(input).complete() for typ in versions { - if raw_ver.raw_ints[typ].index_any(semver.x_range_symbols) == -1 { - continue - } + raw_ver.raw_ints[typ].index_any(semver.x_range_symbols) or { continue } match typ { ver_major { raw_ver.raw_ints[ver_major] = '0' @@ -156,8 +154,9 @@ fn parse_xrange(input string) ?Version { } fn can_expand(input string) bool { - return input[0] == `~` || input[0] == `^` || input.contains(semver.hyphen_range_sep) - || input.index_any(semver.x_range_symbols) > -1 + return input[0] == `~` || input[0] == `^` || input.contains(semver.hyphen_range_sep) || input.index_any(semver.x_range_symbols) or { + -1 + } > -1 } fn expand_comparator_set(input string) ?ComparatorSet { diff --git a/vlib/v/ast/cflags.v b/vlib/v/ast/cflags.v index 12fedd9815..163230a47d 100644 --- a/vlib/v/ast/cflags.v +++ b/vlib/v/ast/cflags.v @@ -63,7 +63,7 @@ pub fn (mut t Table) parse_cflag(cflg string, mod string, ctimedefines []string) if has_next { break } - index = flag.index_after(' -', index + 1) + index = flag.index_after(' -', index + 1) or { -1 } } if index == -1 { value = flag.trim_space() diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 268c7188ec..aee350ab33 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -2975,7 +2975,7 @@ fn (mut p Parser) parse_number_literal() ast.Expr { lit := p.tok.lit full_lit := if is_neg { '-' + lit } else { lit } mut node := ast.empty_expr() - if lit.index_any('.eE') >= 0 && lit[..2] !in ['0x', '0X', '0o', '0O', '0b', '0B'] { + if lit.index_any('.eE') or { -1 } >= 0 && lit[..2] !in ['0x', '0X', '0o', '0O', '0b', '0B'] { node = ast.FloatLiteral{ val: full_lit pos: pos diff --git a/vlib/v/scanner/scanner.v b/vlib/v/scanner/scanner.v index 0ebaa11121..03a1ceba52 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -1334,13 +1334,9 @@ fn trim_slash_line_break(s string) string { mut start := 0 mut ret_str := s for { - idx := ret_str.index_after('\\\n', start) - if idx != -1 { - ret_str = ret_str[..idx] + ret_str[idx + 2..].trim_left(' \n\t\v\f\r') - start = idx - } else { - break - } + idx := ret_str.index_after('\\\n', start) or { break } + ret_str = ret_str[..idx] + ret_str[idx + 2..].trim_left(' \n\t\v\f\r') + start = idx } return ret_str }