diff --git a/cmd/tools/fast/fast.v b/cmd/tools/fast/fast.v index d771111334..aa6bc07a9a 100644 --- a/cmd/tools/fast/fast.v +++ b/cmd/tools/fast/fast.v @@ -188,8 +188,8 @@ fn measure_steps(vdir string) (int, int, int, int, int) { } else { // Fetch number of V lines if line[0].contains('V') && line[0].contains('source') && line[0].contains('size') { - start := line[0].index(':') or { 0 } - end := line[0].index('lines,') or { 0 } + start := line[0].index_opt(':') or { 0 } + end := line[0].index_opt('lines,') or { 0 } s := line[0][start + 1..end] vlines = s.trim_space().int() } diff --git a/cmd/tools/vcheck-md.v b/cmd/tools/vcheck-md.v index 1f65a310b8..67fcb116aa 100644 --- a/cmd/tools/vcheck-md.v +++ b/cmd/tools/vcheck-md.v @@ -291,7 +291,7 @@ fn (mut ad AnchorData) add_links(line_number int, line string) { fn (mut ad AnchorData) add_link_targets(line_number int, line string) { if line.trim_space().starts_with('#') { - if headline_start_pos := line.index(' ') { + if headline_start_pos := line.index_opt(' ') { headline := line.substr(headline_start_pos + 1, line.len) link := create_ref_link(headline) ad.anchors[link] << Headline{ diff --git a/cmd/tools/vpm.v b/cmd/tools/vpm.v index bdc4645519..a3fe50e9d3 100644 --- a/cmd/tools/vpm.v +++ b/cmd/tools/vpm.v @@ -247,7 +247,7 @@ fn vpm_install_from_vcs(module_names []string, vcs_key string) { for n in module_names { url := n.trim_space() - first_cut_pos := url.last_index('/') or { + first_cut_pos := url.last_index_opt('/') or { errors++ println('Errors while retrieving name for module "$url" :') println(err) @@ -256,7 +256,7 @@ fn vpm_install_from_vcs(module_names []string, vcs_key string) { mod_name := url.substr(first_cut_pos + 1, url.len) - second_cut_pos := url.substr(0, first_cut_pos).last_index('/') or { + second_cut_pos := url.substr(0, first_cut_pos).last_index_opt('/') or { errors++ println('Errors while retrieving name for module "$url" :') println(err) diff --git a/cmd/tools/vrepl.v b/cmd/tools/vrepl.v index f6c25b12f9..f3a5571138 100644 --- a/cmd/tools/vrepl.v +++ b/cmd/tools/vrepl.v @@ -445,7 +445,7 @@ fn convert_output(os_result os.Result) string { if line.contains('.vrepl_temp.v:') { // Hide the temporary file name sline := line.all_after('.vrepl_temp.v:') - idx := sline.index(' ') or { + idx := sline.index_opt(' ') or { content += endline_if_missed(sline) return content } @@ -453,7 +453,7 @@ fn convert_output(os_result os.Result) string { } else if line.contains('.vrepl.v:') { // Ensure that .vrepl.v: is at the start, ignore the path // This is needed to have stable .repl tests. - idx := line.index('.vrepl.v:') or { panic(err) } + idx := line.index_opt('.vrepl.v:') or { panic(err) } content += endline_if_missed(line[idx..]) } else { content += endline_if_missed(line) diff --git a/cmd/tools/vvet/vvet.v b/cmd/tools/vvet/vvet.v index 42bc430d07..9f8fa0a49a 100644 --- a/cmd/tools/vvet/vvet.v +++ b/cmd/tools/vvet/vvet.v @@ -122,14 +122,14 @@ fn (mut vt Vet) vet_line(lines []string, line string, lnumber int) { return cleaned.split(',') } ident_fn_name := fn (line string) string { - mut fn_idx := line.index(' fn ') or { return '' } + mut fn_idx := line.index_opt(' fn ') or { return '' } if line.len < fn_idx + 5 { return '' } mut tokens := line[fn_idx + 4..].split(' ') // Skip struct identifier if tokens.first().starts_with('(') { - fn_idx = line.index(')') or { return '' } + fn_idx = line.index_opt(')') or { return '' } tokens = line[fn_idx..].split(' ') if tokens.len > 1 { tokens = [tokens[1]] diff --git a/vlib/builtin/js/string.js.v b/vlib/builtin/js/string.js.v index 09b740cffa..557b3f78f6 100644 --- a/vlib/builtin/js/string.js.v +++ b/vlib/builtin/js/string.js.v @@ -719,7 +719,7 @@ pub fn (s string) replace_each(vals []string) string { } // last_index returns the position of the last occurence of the input string. -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 } @@ -737,9 +737,9 @@ fn (s string) last_index_(p string) int { 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) +// lsat_index_opt is a wrapper around `last_index` that returns `none` if the input string can't be found. +pub fn (s string) last_index_opt(p string) ?int { + idx := s.last_index(p) if idx == -1 { return none } @@ -783,6 +783,15 @@ pub fn (s string) index_after(p string, start int) int { return -1 } +// index_after_opt is a wrapper around `index_after` that returns `none` if the input string can't be found. +pub fn (s string) index_after_opt(p string, start int) ?int { + idx := s.index_after(p, start) + if idx == -1 { + return none + } + return idx +} + pub fn (s string) split_into_lines() []string { mut res := []string{} if s.len == 0 { @@ -827,6 +836,15 @@ pub fn (s string) index_any(chars string) int { return -1 } +// index_any_opt is a wrapper around `index_any` that returns `none` if the input string can't be found. +pub fn (s string) index_any_opt(chars string) ?int { + idx := s.index_any(chars) + if idx == -1 { + return none + } + return idx +} + // limit returns a portion of the string, starting at `0` and extending for a given number of characters afterward. // 'hello'.limit(2) => 'he' // 'hi'.limit(10) => 'hi' @@ -948,14 +966,21 @@ pub fn (s []string) join(sep string) string { // There's no better way to find length of JS String in bytes. #Object.defineProperty(string.prototype,"len", { get: function() {return new int(new TextEncoder().encode(this.str).length);}, set: function(l) {/* ignore */ } }); // 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(search string) ?int { +// It will return `-1` if the input string can't be found. +pub fn (s string) index(search string) int { res := 0 #res.val = s.str.indexOf(search) - if res == -1 { + + return res +} + +// index_opt is a wrapper around `index` that returns `none` if the input string can't be found. +pub fn (s string) index_opt(search string) ?int { + idx := s.index(search) + if idx == -1 { return none } - return res + return idx } pub fn (_rune string) utf32_code() int { diff --git a/vlib/builtin/string.v b/vlib/builtin/string.v index 293b48bcca..04b65f93af 100644 --- a/vlib/builtin/string.v +++ b/vlib/builtin/string.v @@ -319,7 +319,7 @@ 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) + idx := s.index(rep) if idx == -1 { return s.clone() } @@ -901,7 +901,7 @@ 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. [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 } @@ -922,10 +922,9 @@ fn (s string) index_(p string) int { 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) +// index_opt is a wrapper around `index` that returns `none` if the input string can't be found. +pub fn (s string) index_opt(p string) ?int { + idx := s.index(p) if idx == -1 { return none } @@ -967,6 +966,15 @@ fn (s string) index_kmp(p string) int { return -1 } +// index_kmp_opt is a wrapper around `index_kmp` that returns `none` if the input string can't be found. +pub fn (s string) index_kmp_opt(p string) ?int { + idx := s.index_kmp(p) + if idx == -1 { + return none + } + return idx +} + // 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 i, ss in s { @@ -979,9 +987,18 @@ pub fn (s string) index_any(chars string) int { return -1 } +// index_any_opt is a wrapper around `index_any` that returns `none` if the input string can't be found. +pub fn (s string) index_any_opt(chars string) ?int { + idx := s.index_any(chars) + if idx == -1 { + return none + } + return idx +} + // 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 } @@ -999,9 +1016,9 @@ fn (s string) last_index_(p string) int { 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) +// last_index_opt is a wrapper around `last_index` that returns `none` if the input string can't be found. +pub fn (s string) last_index_opt(p string) ?int { + idx := s.last_index(p) if idx == -1 { return none } @@ -1037,6 +1054,15 @@ pub fn (s string) index_after(p string, start int) int { return -1 } +// index_after_opt is a wrapper around `index_after` that returns `none` if the input string can't be found. +pub fn (s string) index_after_opt(p string, start int) ?int { + idx := s.index_after(p, start) + if idx == -1 { + return none + } + return idx +} + // index_byte returns the index of byte `c` if found in the string. // index_byte returns -1 if the byte can not be found. [direct_array_access] @@ -1049,6 +1075,15 @@ pub fn (s string) index_byte(c byte) int { return -1 } +// index_byte_opt is a wrapper around `index_byte` that returns `none` if the input string can't be found. +pub fn (s string) index_byte_opt(c byte) ?int { + idx := s.index_byte(c) + if idx == -1 { + return none + } + return idx +} + // 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. [direct_array_access] @@ -1061,8 +1096,16 @@ pub fn (s string) last_index_byte(c byte) int { return -1 } +// last_index_byte_opt is a wrapper around `last_index_byte` that returns `none` if the input string can't be found. +pub fn (s string) last_index_byte_opt(c byte) ?int { + idx := s.last_index_byte(c) + if idx == -1 { + return none + } + return idx +} + // count returns the number of occurrences of `substr` in the string. -// count returns -1 if no `substr` could be found. [direct_array_access] pub fn (s string) count(substr string) int { if s.len == 0 || substr.len == 0 { @@ -1103,7 +1146,7 @@ pub fn (s string) contains(substr string) bool { if substr.len == 0 { return true } - if s.index_(substr) == -1 { + if s.index(substr) == -1 { return false } return true @@ -1294,13 +1337,13 @@ 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) + start_pos := s.index(start) if start_pos == -1 { return '' } // First get everything to the right of 'start' val := s[start_pos + start.len..] - end_pos := val.index_(end) + end_pos := val.index(end) if end_pos == -1 { return val } @@ -1582,7 +1625,7 @@ 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) + pos := s.index(sub) if pos == -1 { return s.clone() } @@ -1595,7 +1638,7 @@ 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) + pos := s.index(sub) if pos == -1 { return s.clone() } @@ -1607,7 +1650,7 @@ 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) + pos := s.last_index(sub) if pos == -1 { return s.clone() } @@ -1619,7 +1662,7 @@ 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) + pos := s.index(sub) if pos == -1 { return s.clone() } @@ -1631,7 +1674,7 @@ 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) + pos := s.last_index(sub) if pos == -1 { return s.clone() } diff --git a/vlib/builtin/string_interpolation.v b/vlib/builtin/string_interpolation.v index ccba92f25d..b71e380c2f 100644 --- a/vlib/builtin/string_interpolation.v +++ b/vlib/builtin/string_interpolation.v @@ -708,7 +708,7 @@ pub fn str_intp_g64(in_str string) string { // replace %% with the in_str [manualfree] pub fn str_intp_sub(base_str string, in_str string) string { - index := base_str.index('%%') or { + index := base_str.index_opt('%%') or { eprintln('No strin interpolation %% parameteres') exit(1) } diff --git a/vlib/encoding/csv/reader.v b/vlib/encoding/csv/reader.v index 55bf5b8d8e..0c292c23c0 100644 --- a/vlib/encoding/csv/reader.v +++ b/vlib/encoding/csv/reader.v @@ -147,7 +147,7 @@ fn (mut r Reader) read_record() ?[]string { keep_raw = false } if line.len == 0 || line[0] != `"` { // not quoted - j := line.index(r.delimiter.ascii_str()) or { + j := line.index_opt(r.delimiter.ascii_str()) or { // last fields << line[..line.len] break diff --git a/vlib/io/util/util.v b/vlib/io/util/util.v index 895a1c06bf..1fa45c528c 100644 --- a/vlib/io/util/util.v +++ b/vlib/io/util/util.v @@ -84,7 +84,7 @@ fn prefix_and_suffix(pattern string) ?(string, string) { if pat.contains(os.path_separator) { return error('pattern cannot contain path separators ($os.path_separator).') } - pos := pat.last_index('*') or { -1 } + pos := pat.last_index('*') mut prefix := '' mut suffix := '' if pos != -1 { diff --git a/vlib/net/http/response.v b/vlib/net/http/response.v index e1fbfd76c3..a7987307ab 100644 --- a/vlib/net/http/response.v +++ b/vlib/net/http/response.v @@ -136,7 +136,7 @@ pub fn new_response(conf ResponseConfig) Response { // helper function expects the first line in `data` to be the HTTP status line // (HTTP/1.1 200 OK). fn find_headers_range(data string) ?(int, int) { - start_idx := data.index('\n') or { return error('no start index found') } + 1 + start_idx := data.index_opt('\n') or { return error('no start index found') } + 1 mut count := 0 for i := start_idx; i < data.len; i++ { if data[i] == `\n` { diff --git a/vlib/net/urllib/urllib.v b/vlib/net/urllib/urllib.v index dc632f254f..23b14624d9 100644 --- a/vlib/net/urllib/urllib.v +++ b/vlib/net/urllib/urllib.v @@ -505,8 +505,8 @@ fn parse_url(rawurl string, via_request bool) ?URL { // RFC 3986, ยง3.3: // In addition, a URI reference (Section 4.1) may be a relative-path reference, // in which case the first path segment cannot contain a colon (':') character. - colon := rest.index(':') or { return error('there should be a : in the URL') } - slash := rest.index('/') or { return error('there should be a / in the URL') } + colon := rest.index_opt(':') or { return error('there should be a : in the URL') } + slash := rest.index_opt('/') or { return error('there should be a / in the URL') } if colon >= 0 && (slash < 0 || colon < slash) { // First path segment has colon. Not allowed in relative URL. return error(error_msg('parse_url: first path segment in URL cannot contain colon', @@ -534,7 +534,7 @@ struct ParseAuthorityRes { } fn parse_authority(authority string) ?ParseAuthorityRes { - i := authority.last_index('@') or { -1 } + i := authority.last_index('@') mut host := '' mut zuser := user('') if i < 0 { @@ -578,7 +578,7 @@ fn parse_host(host string) ?string { if host.starts_with('[') { // parse an IP-Literal in RFC 3986 and RFC 6874. // E.g., '[fe80::1]', '[fe80::1%25en0]', '[fe80::1]:80'. - mut i := host.last_index(']') or { + mut i := host.last_index_opt(']') or { return error(error_msg("parse_host: missing ']' in host", '')) } mut colon_port := host[i + 1..] @@ -592,13 +592,13 @@ fn parse_host(host string) ?string { // can only %-encode non-ASCII bytes. // We do impose some restrictions on the zone, to avoid stupidity // like newlines. - if zone := host[..i].index('%25') { + if zone := host[..i].index_opt('%25') { host1 := unescape(host[..zone], .encode_host) or { return err.msg() } host2 := unescape(host[zone..i], .encode_zone) or { return err.msg() } host3 := unescape(host[i..], .encode_host) or { return err.msg() } return host1 + host2 + host3 } - if idx := host.last_index(':') { + if idx := host.last_index_opt(':') { colon_port = host[idx..] if !valid_optional_port(colon_port) { return error(error_msg('parse_host: invalid port $colon_port after host ', @@ -811,7 +811,7 @@ fn parse_query_values(mut m Values, query string) ?bool { continue } mut value := '' - if idx := key.index('=') { + if idx := key.index_opt('=') { i = idx value = key[i + 1..] key = key[..i] @@ -872,7 +872,7 @@ fn resolve_path(base string, ref string) string { if ref == '' { full = base } else if ref[0] != `/` { - i := base.last_index('/') or { -1 } + i := base.last_index('/') full = base[..i + 1] + ref } else { full = ref diff --git a/vlib/os/os.v b/vlib/os/os.v index a0a8397249..eba12a51b1 100644 --- a/vlib/os/os.v +++ b/vlib/os/os.v @@ -173,7 +173,7 @@ pub fn is_dir_empty(path string) bool { // file_ext will return the part after the last occurence of `.` in `path`. // The `.` is included. pub fn file_ext(path string) string { - pos := path.last_index('.') or { return '' } + pos := path.last_index_opt('.') or { return '' } return path[pos..] } @@ -187,7 +187,7 @@ pub fn dir(opath string) string { return '.' } path := opath.replace_each(['/', path_separator, r'\', path_separator]) - pos := path.last_index(path_separator) or { return '.' } + pos := path.last_index_opt(path_separator) or { return '.' } if pos == 0 && path_separator == '/' { return '/' } @@ -208,10 +208,10 @@ pub fn base(opath string) string { } if path.ends_with(path_separator) { path2 := path[..path.len - 1] - pos := path2.last_index(path_separator) or { return path2.clone() } + pos := path2.last_index_opt(path_separator) or { return path2.clone() } return path2[pos + 1..] } - pos := path.last_index(path_separator) or { return path.clone() } + pos := path.last_index_opt(path_separator) or { return path.clone() } return path[pos + 1..] } diff --git a/vlib/rand/random_numbers_test.v b/vlib/rand/random_numbers_test.v index 0f32adc7c2..f5f1d61697 100644 --- a/vlib/rand/random_numbers_test.v +++ b/vlib/rand/random_numbers_test.v @@ -208,7 +208,7 @@ fn test_rand_string_from_set() { str := rand.string_from_set(charset, len) assert str.len == len for character in str { - position := charset.index(character.ascii_str()) or { -1 } + position := charset.index(character.ascii_str()) assert position > -1 } } diff --git a/vlib/semver/parse.v b/vlib/semver/parse.v index 3443f59993..b2ed89aefa 100644 --- a/vlib/semver/parse.v +++ b/vlib/semver/parse.v @@ -21,12 +21,12 @@ fn parse(input string) RawVersion { mut raw_version := input mut prerelease := '' mut metadata := '' - plus_idx := raw_version.last_index('+') or { -1 } + plus_idx := raw_version.last_index('+') if plus_idx > 0 { metadata = raw_version[(plus_idx + 1)..] raw_version = raw_version[0..plus_idx] } - hyphen_idx := raw_version.index('-') or { -1 } + hyphen_idx := raw_version.index('-') if hyphen_idx > 0 { prerelease = raw_version[(hyphen_idx + 1)..] raw_version = raw_version[0..hyphen_idx] diff --git a/vlib/time/parse.c.v b/vlib/time/parse.c.v index 2554a22617..bbbf9f3502 100644 --- a/vlib/time/parse.c.v +++ b/vlib/time/parse.c.v @@ -18,7 +18,7 @@ pub fn parse_rfc3339(s string) ?Time { return t } - t_i := sn.index('T') or { -1 } + t_i := sn.index('T') parts := if t_i != -1 { [sn[..t_i], sn[t_i + 1..]] } else { sn.split(' ') } // Check if sn is date only @@ -62,7 +62,7 @@ pub fn parse(s string) ?Time { if s == '' { return error_invalid_time(0) } - pos := s.index(' ') or { return error_invalid_time(1) } + pos := s.index_opt(' ') or { return error_invalid_time(1) } symd := s[..pos] ymd := symd.split('-') if ymd.len != 3 { @@ -119,7 +119,7 @@ pub fn parse_iso8601(s string) ?Time { if s == '' { return error_invalid_time(0) } - t_i := s.index('T') or { -1 } + t_i := s.index('T') parts := if t_i != -1 { [s[..t_i], s[t_i + 1..]] } else { s.split(' ') } if !(parts.len == 1 || parts.len == 2) { return error_invalid_time(12) @@ -160,7 +160,7 @@ pub fn parse_rfc2822(s string) ?Time { if fields.len < 5 { return error_invalid_time(1) } - pos := months_string.index(fields[2]) or { return error_invalid_time(2) } + pos := months_string.index_opt(fields[2]) or { return error_invalid_time(2) } mm := pos / 3 + 1 unsafe { tmstr := malloc_noscan(s.len * 2) diff --git a/vlib/toml/checker/checker.v b/vlib/toml/checker/checker.v index 1bdf5ca1a1..7c25c12ec7 100644 --- a/vlib/toml/checker/checker.v +++ b/vlib/toml/checker/checker.v @@ -103,7 +103,7 @@ fn (c Checker) check_number(num ast.Number) ? { mut is_bin, mut is_oct, mut is_hex := false, false, false is_float := lit_lower_case.all_before('e').contains('.') has_exponent_notation := lit_lower_case.contains('e') - float_decimal_index := lit.index('.') or { -1 } + float_decimal_index := lit.index('.') // mut is_first_digit := byte(lit[0]).is_digit() mut ascii := byte(lit[0]).ascii_str() is_sign_prefixed := lit[0] in [`+`, `-`] diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 3963072860..b0a97f7b6a 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -2083,7 +2083,7 @@ pub fn all_registers(mut t Table, arch pref.Arch) map[string]ScopeObject { for bit_size, array in ast.x86_with_number_register_list { for name, max_num in array { for i in 0 .. max_num { - hash_index := name.index('#') or { + hash_index := name.index_opt('#') or { panic('all_registers: no hashtag found') } assembled_name := '${name[..hash_index]}$i${name[hash_index + 1..]}' @@ -2144,7 +2144,7 @@ fn gen_all_registers(mut t Table, without_numbers []string, with_numbers map[str } for name, max_num in with_numbers { for i in 0 .. max_num { - hash_index := name.index('#') or { panic('all_registers: no hashtag found') } + hash_index := name.index_opt('#') or { panic('all_registers: no hashtag found') } assembled_name := '${name[..hash_index]}$i${name[hash_index + 1..]}' res[assembled_name] = AsmRegister{ name: assembled_name diff --git a/vlib/v/ast/cflags.v b/vlib/v/ast/cflags.v index 12fedd9815..555952782d 100644 --- a/vlib/v/ast/cflags.v +++ b/vlib/v/ast/cflags.v @@ -31,7 +31,7 @@ pub fn (mut t Table) parse_cflag(cflg string, mod string, ctimedefines []string) if !flag.starts_with(os_override) { continue } - pos := flag.index(' ') or { return none } + pos := flag.index_opt(' ') or { return none } fos = flag[..pos].trim_space() flag = flag[pos..].trim_space() } @@ -48,7 +48,7 @@ pub fn (mut t Table) parse_cflag(cflg string, mod string, ctimedefines []string) } } } - mut index := flag.index(' -') or { -1 } + mut index := flag.index(' -') for index > -1 { mut has_next := false for f in allowed_flags { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index ccbb01337f..1d0d4fcded 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -413,7 +413,7 @@ fn (mut c Checker) check_valid_snake_case(name string, identifier string, pos to } fn stripped_name(name string) string { - idx := name.last_index('.') or { -1 } + idx := name.last_index('.') return name[(idx + 1)..] } diff --git a/vlib/v/checker/struct.v b/vlib/v/checker/struct.v index 70eb53434c..acd2f69c36 100644 --- a/vlib/v/checker/struct.v +++ b/vlib/v/checker/struct.v @@ -189,7 +189,7 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type { // but `x := T{}` is ok. if !c.is_builtin_mod && !c.inside_unsafe && type_sym.language == .v && c.table.cur_concrete_types.len == 0 { - pos := type_sym.name.last_index('.') or { -1 } + pos := type_sym.name.last_index('.') first_letter := type_sym.name[pos + 1] if !first_letter.is_capital() { c.error('cannot initialize builtin type `$type_sym.name`', node.pos) diff --git a/vlib/v/checker/tests/type_cast_optional_err.out b/vlib/v/checker/tests/type_cast_optional_err.out index bb52bad666..3eef0160a2 100644 --- a/vlib/v/checker/tests/type_cast_optional_err.out +++ b/vlib/v/checker/tests/type_cast_optional_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/type_cast_optional_err.vv:2:13: error: cannot type cast an optional 1 | fn main() { - 2 | println(int('hi'.last_index('i'))) - | ~~~~~~~~~~~~~~~~~~~~~~~~~ + 2 | println(int('hi'.last_index_opt('i'))) + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 3 | } diff --git a/vlib/v/checker/tests/type_cast_optional_err.vv b/vlib/v/checker/tests/type_cast_optional_err.vv index 982559cbda..237b7d92ae 100644 --- a/vlib/v/checker/tests/type_cast_optional_err.vv +++ b/vlib/v/checker/tests/type_cast_optional_err.vv @@ -1,3 +1,3 @@ fn main() { - println(int('hi'.last_index('i'))) + println(int('hi'.last_index_opt('i'))) } diff --git a/vlib/v/gen/js/js.v b/vlib/v/gen/js/js.v index 33dc2d3e6b..ffa6cf97f0 100644 --- a/vlib/v/gen/js/js.v +++ b/vlib/v/gen/js/js.v @@ -308,7 +308,7 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string { // calculate final generated location in output based on position current_segment := g.out.substr(int(sm_pos), int(sourcemap_ns_entry.ns_pos)) current_line += u32(current_segment.count('\n')) - current_column := if last_nl_pos := current_segment.last_index('\n') { + current_column := if last_nl_pos := current_segment.last_index_opt('\n') { u32(current_segment.len - last_nl_pos - 1) } else { u32(0) @@ -547,7 +547,7 @@ pub fn (mut g JsGen) new_tmp_var() string { // 'fn' => '' [inline] fn get_ns(s string) string { - idx := s.last_index('.') or { return '' } + idx := s.last_index_opt('.') or { return '' } return s.substr(0, idx) } @@ -3394,7 +3394,7 @@ fn (mut g JsGen) gen_struct_init(it ast.StructInit) { type_sym := g.table.sym(it.typ) mut name := type_sym.name if name.contains('<') { - name = name[0..name.index('<') or { name.len }] + name = name[0..name.index_opt('<') or { name.len }] } if it.fields.len == 0 && type_sym.kind != .interface_ { if type_sym.kind == .struct_ && type_sym.language == .js { diff --git a/vlib/v/parser/tmpl.v b/vlib/v/parser/tmpl.v index e0aa85eebd..5d91e79026 100644 --- a/vlib/v/parser/tmpl.v +++ b/vlib/v/parser/tmpl.v @@ -129,7 +129,7 @@ fn vweb_tmpl_${fn_name}() string { eprintln('>>> tfile: $template_file, spos: ${start_of_line_pos:6}, epos:${end_of_line_pos:6}, fi: ${tline_number:5}, i: ${i:5}, state: ${state:10}, line: $line') } if line.contains('@header') { - position := line.index('@header') or { 0 } + position := line.index_opt('@header') or { 0 } p.error_with_error(errors.Error{ message: "Please use @include 'header' instead of @header (deprecated)" file_path: template_file @@ -144,7 +144,7 @@ fn vweb_tmpl_${fn_name}() string { continue } if line.contains('@footer') { - position := line.index('@footer') or { 0 } + position := line.index_opt('@footer') or { 0 } p.error_with_error(errors.Error{ message: "Please use @include 'footer' instead of @footer (deprecated)" file_path: template_file @@ -177,7 +177,7 @@ fn vweb_tmpl_${fn_name}() string { eprintln('>>> basepath: "$basepath" , template_file: "$template_file" , fn_name: "$fn_name" , @include line: "$line" , file_name: "$file_name" , file_ext: "$file_ext" , templates_folder: "$templates_folder" , file_path: "$file_path"') } file_content := os.read_file(file_path) or { - position := line.index('@include ') or { 0 } + '@include '.len + position := line.index_opt('@include ') or { 0 } + '@include '.len p.error_with_error(errors.Error{ message: 'Reading file $file_name from path: $file_path failed' details: "Failed to @include '$file_name'" @@ -202,7 +202,7 @@ fn vweb_tmpl_${fn_name}() string { } if line.contains('@if ') { source.writeln(parser.tmpl_str_end) - pos := line.index('@if') or { continue } + pos := line.index_opt('@if') or { continue } source.writeln('if ' + line[pos + 4..] + '{') source.writeln(tmpl_str_start) continue @@ -225,7 +225,7 @@ fn vweb_tmpl_${fn_name}() string { } if line.contains('@for') { source.writeln(parser.tmpl_str_end) - pos := line.index('@for') or { continue } + pos := line.index_opt('@for') or { continue } source.writeln('for ' + line[pos + 4..] + '{') source.writeln(tmpl_str_start) continue @@ -239,14 +239,14 @@ fn vweb_tmpl_${fn_name}() string { if state != .simple { if line.contains('@js ') { - pos := line.index('@js') or { continue } + pos := line.index_opt('@js') or { continue } source.write_string('') continue } if line.contains('@css ') { - pos := line.index('@css') or { continue } + pos := line.index_opt('@css') or { continue } source.write_string('') diff --git a/vlib/v/pkgconfig/pkgconfig.v b/vlib/v/pkgconfig/pkgconfig.v index 3eec069825..04a023b64d 100644 --- a/vlib/v/pkgconfig/pkgconfig.v +++ b/vlib/v/pkgconfig/pkgconfig.v @@ -72,8 +72,8 @@ fn (mut pc PkgConfig) parse_list(s string) []string { fn (mut pc PkgConfig) parse_line(s string) string { mut r := s.trim_space() for r.contains('\${') { - tok0 := r.index('\${') or { break } - mut tok1 := r[tok0..].index('}') or { break } + tok0 := r.index_opt('\${') or { break } + mut tok1 := r[tok0..].index_opt('}') or { break } tok1 += tok0 v := r[tok0 + 2..tok1] r = r.replace('\${$v}', pc.vars[v]) diff --git a/vlib/v/tests/option_default_values_test.v b/vlib/v/tests/option_default_values_test.v index 2abd546fa9..4da886df3b 100644 --- a/vlib/v/tests/option_default_values_test.v +++ b/vlib/v/tests/option_default_values_test.v @@ -127,7 +127,7 @@ fn test_nested_optional_with_opt_fn_call_as_last_value() { fn remove_suffix1(s string) string { n := s.len - i := s.last_index('.') or { n } + i := s.last_index_opt('.') or { n } return s[0..i] } diff --git a/vlib/v/util/util.v b/vlib/v/util/util.v index 3e077928d6..b3affaf60d 100644 --- a/vlib/v/util/util.v +++ b/vlib/v/util/util.v @@ -69,7 +69,7 @@ pub fn resolve_vmodroot(str string, dir string) ?string { // in `str` with the value of the env variable `$ENV_VAR_NAME`. pub fn resolve_env_value(str string, check_for_presence bool) ?string { env_ident := "\$env('" - at := str.index(env_ident) or { + at := str.index_opt(env_ident) or { return error('no "$env_ident' + '...\')" could be found in "$str".') } mut ch := byte(`.`)