From 5cd2aa6814f15d240cbcd4deebee03a772d2d5a3 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sun, 5 Jan 2025 17:18:41 +0200 Subject: [PATCH] support `s[x..y]` used in the gcc/clang backtrace expansion in builtin --- vlib/builtin/backtraces_nix.c.v | 9 +++------ vlib/builtin/sorted_map.v | 1 + vlib/builtin/string.v | 3 ++- vlib/builtin/utf8.v | 9 +++++---- vlib/v/markused/markused.v | 4 ++++ vlib/v/markused/walker.v | 4 ++++ 6 files changed, 19 insertions(+), 11 deletions(-) diff --git a/vlib/builtin/backtraces_nix.c.v b/vlib/builtin/backtraces_nix.c.v index 57deb4a296beeb..cd66ff71431370 100644 --- a/vlib/builtin/backtraces_nix.c.v +++ b/vlib/builtin/backtraces_nix.c.v @@ -67,13 +67,10 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool { return false } nr_actual_frames := nr_ptrs - skipframes - mut sframes := []string{} //////csymbols := backtrace_symbols(*voidptr(&buffer[skipframes]), nr_actual_frames) csymbols := C.backtrace_symbols(voidptr(&buffer[skipframes]), nr_actual_frames) for i in 0 .. nr_actual_frames { - sframes << unsafe { tos2(&u8(csymbols[i])) } - } - for sframe in sframes { + sframe := unsafe { tos2(&u8(csymbols[i])) } executable := sframe.all_before('(') addr := sframe.all_after('[').all_before(']') beforeaddr := sframe.all_before('[') @@ -92,7 +89,7 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool { output += tos(bp, vstrlen(bp)) } } - output = output.trim_space() + ':' + output = output.trim_chars(' \t\n', .trim_both) + ':' if C.pclose(f) != 0 { eprintln(sframe) continue @@ -111,7 +108,7 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool { eprint(' | ') eprintln(beforeaddr) } - if sframes.len > 0 { + if nr_actual_frames > 0 { unsafe { C.free(csymbols) } } } diff --git a/vlib/builtin/sorted_map.v b/vlib/builtin/sorted_map.v index 8c0b0247fcf8b3..7be2dca4a964cc 100644 --- a/vlib/builtin/sorted_map.v +++ b/vlib/builtin/sorted_map.v @@ -158,6 +158,7 @@ fn (mut n mapnode) split_child(child_index int, mut y mapnode) { n.len++ } +@[direct_array_access] fn (m SortedMap) get(key string, out voidptr) bool { mut node := m.root for { diff --git a/vlib/builtin/string.v b/vlib/builtin/string.v index d4686d92a11759..2056f7c9e42e42 100644 --- a/vlib/builtin/string.v +++ b/vlib/builtin/string.v @@ -1154,7 +1154,8 @@ pub fn (s string) substr_unsafe(start int, _end int) string { pub fn (s string) substr_with_check(start int, _end int) !string { end := if _end == max_int { s.len } else { _end } // max_int if start > end || start > s.len || end > s.len || start < 0 || end < 0 { - return error('substr(${start}, ${end}) out of bounds (len=${s.len})') + return error('substr(' + start.str() + ', ' + end.str() + ') out of bounds (len=' + + s.len.str() + ')') } len := end - start if len == s.len { diff --git a/vlib/builtin/utf8.v b/vlib/builtin/utf8.v index 5755cdda25b40f..2d0afdf6400562 100644 --- a/vlib/builtin/utf8.v +++ b/vlib/builtin/utf8.v @@ -78,14 +78,15 @@ pub fn utf32_decode_to_buffer(code u32, mut buf &u8) int { // it is used in vlib/builtin/string.v, // and also in vlib/v/gen/c/cgen.v pub fn (_rune string) utf32_code() int { - return int(_rune.bytes().utf8_to_utf32() or { - // error('more than one utf-8 rune found in this string') - rune(0) - }) + if res := _rune.bytes().utf8_to_utf32() { + return int(res) + } + return 0 } // convert array of utf8 bytes to single utf32 value // will error if more than 4 bytes are submitted +@[direct_array_access] pub fn (_bytes []u8) utf8_to_utf32() !rune { if _bytes.len == 0 { return 0 diff --git a/vlib/v/markused/markused.v b/vlib/v/markused/markused.v index 3000f485914b8b..7b51efdb855e17 100644 --- a/vlib/v/markused/markused.v +++ b/vlib/v/markused/markused.v @@ -520,6 +520,10 @@ pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&a } } + if table.used_features.range_index { + walker.fn_by_name(string_idx_str + '.substr') + } + table.used_features.used_fns = walker.used_fns.move() table.used_features.used_consts = walker.used_consts.move() table.used_features.used_globals = walker.used_globals.move() diff --git a/vlib/v/markused/walker.v b/vlib/v/markused/walker.v index d48f1404414688..3cbe99bb552128 100644 --- a/vlib/v/markused/walker.v +++ b/vlib/v/markused/walker.v @@ -367,6 +367,10 @@ fn (mut w Walker) expr(node_ ast.Expr) { w.features.used_maps++ } else if sym.kind == .array { w.features.used_arrays++ + } else if sym.kind == .string { + if node.index is ast.RangeExpr { + w.features.range_index = true + } } } ast.InfixExpr {