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)

This commit is contained in:
Delyan Angelov 2025-06-18 16:37:57 +03:00 committed by GitHub
parent c6feed9849
commit 2cd1c9e26b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 92 additions and 23 deletions

View file

@ -455,6 +455,9 @@ pub fn (s string) replace_each(vals []string) string {
// of the new string to do just one allocation. // of the new string to do just one allocation.
mut new_len := s.len mut new_len := s.len
mut idxs := []RepIndex{cap: 6} mut idxs := []RepIndex{cap: 6}
defer {
unsafe { idxs.free() }
}
mut idx := 0 mut idx := 0
s_ := s.clone() s_ := s.clone()
for rep_i := 0; rep_i < vals.len; rep_i += 2 { 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] @[direct_array_access]
pub fn (s string) split_any(delim string) []string { pub fn (s string) split_any(delim string) []string {
mut res := []string{} mut res := []string{}
unsafe { res.flags.set(.noslices) }
defer { unsafe { res.flags.clear(.noslices) } }
mut i := 0 mut i := 0
// check empty source string // check empty source string
if s.len > 0 { if s.len > 0 {
@ -874,6 +879,8 @@ pub fn (s string) split_any(delim string) []string {
@[direct_array_access] @[direct_array_access]
pub fn (s string) rsplit_any(delim string) []string { pub fn (s string) rsplit_any(delim string) []string {
mut res := []string{} mut res := []string{}
unsafe { res.flags.set(.noslices) }
defer { unsafe { res.flags.clear(.noslices) } }
mut i := s.len - 1 mut i := s.len - 1
if s.len > 0 { if s.len > 0 {
if delim.len <= 0 { if delim.len <= 0 {
@ -964,6 +971,8 @@ pub fn (s string) split_n(delim string, n int) []string {
@[direct_array_access] @[direct_array_access]
pub fn (s string) split_nth(delim string, nth int) []string { pub fn (s string) split_nth(delim string, nth int) []string {
mut res := []string{} mut res := []string{}
unsafe { res.flags.set(.noslices) } // allow freeing of old data during <<
defer { unsafe { res.flags.clear(.noslices) } }
match delim.len { match delim.len {
0 { 0 {
@ -1023,6 +1032,8 @@ pub fn (s string) split_nth(delim string, nth int) []string {
@[direct_array_access] @[direct_array_access]
pub fn (s string) rsplit_nth(delim string, nth int) []string { pub fn (s string) rsplit_nth(delim string, nth int) []string {
mut res := []string{} mut res := []string{}
unsafe { res.flags.set(.noslices) } // allow freeing of old data during <<
defer { unsafe { res.flags.clear(.noslices) } }
match delim.len { match delim.len {
0 { 0 {
@ -1082,6 +1093,8 @@ pub fn (s string) split_into_lines() []string {
if s.len == 0 { if s.len == 0 {
return res return res
} }
unsafe { res.flags.set(.noslices) } // allow freeing of old data during <<
defer { unsafe { res.flags.clear(.noslices) } }
cr := `\r` cr := `\r`
lf := `\n` lf := `\n`
mut line_start := 0 mut line_start := 0
@ -1110,6 +1123,8 @@ pub fn (s string) split_into_lines() []string {
// Repeated, trailing or leading whitespaces will be omitted. // Repeated, trailing or leading whitespaces will be omitted.
pub fn (s string) split_by_space() []string { pub fn (s string) split_by_space() []string {
mut res := []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') { for word in s.split_any(' \n\t\v\f\r') {
if word != '' { if word != '' {
res << word res << word
@ -2466,6 +2481,8 @@ pub fn (s string) repeat(count int) string {
// Example: assert ' sss ssss'.fields() == ['sss', 'ssss'] // Example: assert ' sss ssss'.fields() == ['sss', 'ssss']
pub fn (s string) fields() []string { pub fn (s string) fields() []string {
mut res := []string{} mut res := []string{}
unsafe { res.flags.set(.noslices) }
defer { unsafe { res.flags.clear(.noslices) } }
mut word_start := 0 mut word_start := 0
mut word_len := 0 mut word_len := 0
mut is_in_word := false mut is_in_word := false

View file

@ -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. // 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 // On Android, it will return just the relative_path segment, allowing you to later use os.read_apk_asset
// to read from it. // to read from it.
@[manualfree]
pub fn get_path(base_folder string, relative_path string) string { pub fn get_path(base_folder string, relative_path string) string {
$if android { $if android {
return relative_path return relative_path.clone()
} $else { } $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 // 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 // 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. // locate the file, in a way, that is relative to the executable.
@[manualfree]
pub fn read_bytes(base_folder string, relative_path string) ![]u8 { 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 { $if android {
return os.read_apk_asset(get_path(base_folder, relative_path)) f_read = os.read_apk_asset
} $else {
return os.read_bytes(get_path(base_folder, relative_path))
} }
res := f_read(fpath)!
return res
} }
// read_text will return the full content of the given asset as a string. // read_text will return the full content of the given asset as a string.
// See also read_bytes. // See also read_bytes.
@[manualfree]
pub fn read_text(base_folder string, relative_path string) !string { pub fn read_text(base_folder string, relative_path string) !string {
res := read_bytes(base_folder, relative_path)! bytes := read_bytes(base_folder, relative_path)!
return res.bytestr() defer { unsafe { bytes.free() } }
res := bytes.bytestr()
return res
} }

View file

@ -22,11 +22,13 @@ fn debug_font_println(s string) {
// If the env variable `VUI_FONT` is set this is used instead. // 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 // NOTE that, in some cases, the function calls out to external OS programs
// so running this in a hot loop is not advised. // so running this in a hot loop is not advised.
@[manualfree]
pub fn default() string { pub fn default() string {
env_font := os.getenv('VUI_FONT') env_font := os.getenv('VUI_FONT')
if env_font != '' && os.exists(env_font) { if env_font != '' && os.exists(env_font) {
return env_font return env_font
} }
unsafe { env_font.free() }
$if windows { $if windows {
if os.exists('C:\\Windows\\Fonts\\segoeui.ttf') { if os.exists('C:\\Windows\\Fonts\\segoeui.ttf') {
debug_font_println('Using font "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 return font
} }
} }
unsafe { fonts.free() }
} }
$if android { $if android {
xml_files := ['/system/etc/system_fonts.xml', '/system/etc/fonts.xml', 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) { if os.is_file(xml_file) && os.is_readable(xml_file) {
xml := os.read_file(xml_file) or { continue } xml := os.read_file(xml_file) or { continue }
lines := xml.split('\n') lines := xml.split('\n')
unsafe { xml.free() }
mut candidate_font := '' mut candidate_font := ''
for line in lines { for line in lines {
if line.contains('<font') { if line.contains('<font') {
@ -65,12 +69,16 @@ pub fn default() string {
debug_font_println('Using font "${candidate_path}"') debug_font_println('Using font "${candidate_path}"')
return candidate_path return candidate_path
} }
unsafe { candidate_path.free() }
} }
} }
} }
} }
unsafe { candidate_font.free() }
} }
} }
unsafe { font_locations.free() }
unsafe { xml_files.free() }
} }
mut fm := os.execute("fc-match --format='%{file}\n' -s") mut fm := os.execute("fc-match --format='%{file}\n' -s")
if fm.exit_code == 0 { if fm.exit_code == 0 {
@ -81,59 +89,93 @@ pub fn default() string {
return l return l
} }
} }
unsafe { lines.free() }
} else { } else {
panic('fc-match failed to fetch system font') panic('fc-match failed to fetch system font')
} }
unsafe { fm.free() }
panic('failed to init the font') panic('failed to init the font')
} }
// get_path_variant returns the `font_path` file name replaced with the // get_path_variant returns the `font_path` file name replaced with the
// file name of the font's `variant` version if it exists. // file name of the font's `variant` version if it exists.
@[manualfree]
pub fn get_path_variant(font_path string, variant Variant) string { pub fn get_path_variant(font_path string, variant Variant) string {
// TODO: find some way to make this shorter and more eye-pleasant // TODO: find some way to make this shorter and more eye-pleasant
// NotoSans, LiberationSans, DejaVuSans, Arial and SFNS should work // NotoSans, LiberationSans, DejaVuSans, Arial and SFNS should work
mut file := os.file_name(font_path) mut file := os.file_name(font_path)
defer { unsafe { file.free() } }
mut fpath := font_path.replace(file, '') mut fpath := font_path.replace(file, '')
file = file.replace('.ttf', '') defer { unsafe { fpath.free() } }
mut_replace(file, '.ttf', '')
flower := file.to_lower()
defer { unsafe { flower.free() } }
match variant { match variant {
.normal {} .normal {}
.bold { .bold {
if fpath.ends_with('-Regular') { if fpath.ends_with('-Regular') {
file = file.replace('-Regular', '-Bold') mut_replace(file, '-Regular', '-Bold')
} else if file.starts_with('DejaVuSans') { } else if file.starts_with('DejaVuSans') {
file += '-Bold' mut_plus(file, '-Bold')
} else if file.to_lower().starts_with('arial') { } else if flower.starts_with('arial') {
file += 'bd' mut_plus(file, 'bd')
} else { } else {
file += '-bold' mut_plus(file, '-bold')
} }
$if macos { $if macos {
if os.exists('SFNS-bold') { if os.exists('SFNS-bold') {
file = 'SFNS-bold' mut_assign(file, 'SFNS-bold')
} }
} }
} }
.italic { .italic {
if file.ends_with('-Regular') { if file.ends_with('-Regular') {
file = file.replace('-Regular', '-Italic') mut_replace(file, '-Regular', '-Italic')
} else if file.starts_with('DejaVuSans') { } else if file.starts_with('DejaVuSans') {
file += '-Oblique' mut_plus(file, '-Oblique')
} else if file.to_lower().starts_with('arial') { } else if flower.starts_with('arial') {
file += 'i' mut_plus(file, 'i')
} else { } else {
file += 'Italic' mut_plus(file, 'Italic')
} }
} }
.mono { .mono {
if !file.ends_with('Mono-Regular') && file.ends_with('-Regular') { if !file.ends_with('Mono-Regular') && file.ends_with('-Regular') {
file = file.replace('-Regular', 'Mono-Regular') mut_replace(file, '-Regular', 'Mono-Regular')
} else if file.to_lower().starts_with('arial') { } else if flower.starts_with('arial') {
// Arial has no mono variant // Arial has no mono variant
} else { } else {
file += 'Mono' mut_plus(file, 'Mono')
} }
} }
} }
return '${fpath}${file}.ttf' res := '${fpath}${file}.ttf'
return res
}
fn mut_replace(s &string, find string, replacement string) {
new := (*s).replace(find, replacement)
unsafe { s.free() }
unsafe {
*s = new
}
}
fn mut_plus(s &string, tail string) {
new := (*s) + tail
unsafe { s.free() }
unsafe {
*s = new
}
}
fn mut_assign(s &string, value string) {
unsafe { s.free() }
unsafe {
*s = value.clone()
}
} }