From 2cd1c9e26bcdc0a87ef800cbe98aee6c52804bfc Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Wed, 18 Jun 2025 16:37:57 +0300 Subject: [PATCH] builtin,os: enable no warnings for gg programs like `v -gc boehm_leak -cg -keepc run examples/gg/minimal.v` (part 1 - before the `gg` loop) (#24749) --- vlib/builtin/string.v | 17 ++++++++++ vlib/os/asset/asset.v | 24 ++++++++++---- vlib/os/font/font.v | 74 +++++++++++++++++++++++++++++++++---------- 3 files changed, 92 insertions(+), 23 deletions(-) diff --git a/vlib/builtin/string.v b/vlib/builtin/string.v index ce5e15ac3..32a20e418 100644 --- a/vlib/builtin/string.v +++ b/vlib/builtin/string.v @@ -455,6 +455,9 @@ pub fn (s string) replace_each(vals []string) string { // of the new string to do just one allocation. mut new_len := s.len mut idxs := []RepIndex{cap: 6} + defer { + unsafe { idxs.free() } + } mut idx := 0 s_ := s.clone() for rep_i := 0; rep_i < vals.len; rep_i += 2 { @@ -845,6 +848,8 @@ fn (s string) plus_two(a string, b string) string { @[direct_array_access] pub fn (s string) split_any(delim string) []string { mut res := []string{} + unsafe { res.flags.set(.noslices) } + defer { unsafe { res.flags.clear(.noslices) } } mut i := 0 // check empty source string if s.len > 0 { @@ -874,6 +879,8 @@ pub fn (s string) split_any(delim string) []string { @[direct_array_access] pub fn (s string) rsplit_any(delim string) []string { mut res := []string{} + unsafe { res.flags.set(.noslices) } + defer { unsafe { res.flags.clear(.noslices) } } mut i := s.len - 1 if s.len > 0 { if delim.len <= 0 { @@ -964,6 +971,8 @@ pub fn (s string) split_n(delim string, n int) []string { @[direct_array_access] pub fn (s string) split_nth(delim string, nth int) []string { mut res := []string{} + unsafe { res.flags.set(.noslices) } // allow freeing of old data during << + defer { unsafe { res.flags.clear(.noslices) } } match delim.len { 0 { @@ -1023,6 +1032,8 @@ pub fn (s string) split_nth(delim string, nth int) []string { @[direct_array_access] pub fn (s string) rsplit_nth(delim string, nth int) []string { mut res := []string{} + unsafe { res.flags.set(.noslices) } // allow freeing of old data during << + defer { unsafe { res.flags.clear(.noslices) } } match delim.len { 0 { @@ -1082,6 +1093,8 @@ pub fn (s string) split_into_lines() []string { if s.len == 0 { return res } + unsafe { res.flags.set(.noslices) } // allow freeing of old data during << + defer { unsafe { res.flags.clear(.noslices) } } cr := `\r` lf := `\n` mut line_start := 0 @@ -1110,6 +1123,8 @@ pub fn (s string) split_into_lines() []string { // Repeated, trailing or leading whitespaces will be omitted. pub fn (s string) split_by_space() []string { mut res := []string{} + unsafe { res.flags.set(.noslices) } + defer { unsafe { res.flags.clear(.noslices) } } for word in s.split_any(' \n\t\v\f\r') { if word != '' { res << word @@ -2466,6 +2481,8 @@ pub fn (s string) repeat(count int) string { // Example: assert ' sss ssss'.fields() == ['sss', 'ssss'] pub fn (s string) fields() []string { mut res := []string{} + unsafe { res.flags.set(.noslices) } + defer { unsafe { res.flags.clear(.noslices) } } mut word_start := 0 mut word_len := 0 mut is_in_word := false diff --git a/vlib/os/asset/asset.v b/vlib/os/asset/asset.v index 8703e0d00..86c232c4f 100644 --- a/vlib/os/asset/asset.v +++ b/vlib/os/asset/asset.v @@ -6,11 +6,14 @@ import os // of a resource in it. On desktop systems, it returns a path relative to the location of the executable. // On Android, it will return just the relative_path segment, allowing you to later use os.read_apk_asset // to read from it. +@[manualfree] pub fn get_path(base_folder string, relative_path string) string { $if android { - return relative_path + return relative_path.clone() } $else { - return os.resource_abs_path(os.join_path(base_folder, relative_path)) + fpath := os.join_path_single(base_folder, relative_path) + defer { unsafe { fpath.free() } } + return os.resource_abs_path(fpath) } } @@ -18,17 +21,24 @@ pub fn get_path(base_folder string, relative_path string) string { // On Android, it will use os.read_apk_asset, relying that the asset base folder has been prepared, and // prepackaged inside your APK. On desktop systems, it will use the base_folder and relative_path, to // locate the file, in a way, that is relative to the executable. +@[manualfree] pub fn read_bytes(base_folder string, relative_path string) ![]u8 { + fpath := get_path(base_folder, relative_path) + defer { unsafe { fpath.free() } } + mut f_read := os.read_bytes $if android { - return os.read_apk_asset(get_path(base_folder, relative_path)) - } $else { - return os.read_bytes(get_path(base_folder, relative_path)) + f_read = os.read_apk_asset } + res := f_read(fpath)! + return res } // read_text will return the full content of the given asset as a string. // See also read_bytes. +@[manualfree] pub fn read_text(base_folder string, relative_path string) !string { - res := read_bytes(base_folder, relative_path)! - return res.bytestr() + bytes := read_bytes(base_folder, relative_path)! + defer { unsafe { bytes.free() } } + res := bytes.bytestr() + return res } diff --git a/vlib/os/font/font.v b/vlib/os/font/font.v index e6f113e05..4597fc841 100644 --- a/vlib/os/font/font.v +++ b/vlib/os/font/font.v @@ -22,11 +22,13 @@ fn debug_font_println(s string) { // If the env variable `VUI_FONT` is set this is used instead. // NOTE that, in some cases, the function calls out to external OS programs // so running this in a hot loop is not advised. +@[manualfree] pub fn default() string { env_font := os.getenv('VUI_FONT') if env_font != '' && os.exists(env_font) { return env_font } + unsafe { env_font.free() } $if windows { if os.exists('C:\\Windows\\Fonts\\segoeui.ttf') { debug_font_println('Using font "C:\\Windows\\Fonts\\segoeui.ttf"') @@ -44,6 +46,7 @@ pub fn default() string { return font } } + unsafe { fonts.free() } } $if android { xml_files := ['/system/etc/system_fonts.xml', '/system/etc/fonts.xml', @@ -54,6 +57,7 @@ pub fn default() string { if os.is_file(xml_file) && os.is_readable(xml_file) { xml := os.read_file(xml_file) or { continue } lines := xml.split('\n') + unsafe { xml.free() } mut candidate_font := '' for line in lines { if line.contains('