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.
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

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.
// 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
}

View file

@ -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('<font') {
@ -65,12 +69,16 @@ pub fn default() string {
debug_font_println('Using font "${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")
if fm.exit_code == 0 {
@ -81,59 +89,93 @@ pub fn default() string {
return l
}
}
unsafe { lines.free() }
} else {
panic('fc-match failed to fetch system font')
}
unsafe { fm.free() }
panic('failed to init the font')
}
// get_path_variant returns the `font_path` file name replaced with the
// file name of the font's `variant` version if it exists.
@[manualfree]
pub fn get_path_variant(font_path string, variant Variant) string {
// TODO: find some way to make this shorter and more eye-pleasant
// NotoSans, LiberationSans, DejaVuSans, Arial and SFNS should work
mut file := os.file_name(font_path)
defer { unsafe { file.free() } }
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 {
.normal {}
.bold {
if fpath.ends_with('-Regular') {
file = file.replace('-Regular', '-Bold')
mut_replace(file, '-Regular', '-Bold')
} else if file.starts_with('DejaVuSans') {
file += '-Bold'
} else if file.to_lower().starts_with('arial') {
file += 'bd'
mut_plus(file, '-Bold')
} else if flower.starts_with('arial') {
mut_plus(file, 'bd')
} else {
file += '-bold'
mut_plus(file, '-bold')
}
$if macos {
if os.exists('SFNS-bold') {
file = 'SFNS-bold'
mut_assign(file, 'SFNS-bold')
}
}
}
.italic {
if file.ends_with('-Regular') {
file = file.replace('-Regular', '-Italic')
mut_replace(file, '-Regular', '-Italic')
} else if file.starts_with('DejaVuSans') {
file += '-Oblique'
} else if file.to_lower().starts_with('arial') {
file += 'i'
mut_plus(file, '-Oblique')
} else if flower.starts_with('arial') {
mut_plus(file, 'i')
} else {
file += 'Italic'
mut_plus(file, 'Italic')
}
}
.mono {
if !file.ends_with('Mono-Regular') && file.ends_with('-Regular') {
file = file.replace('-Regular', 'Mono-Regular')
} else if file.to_lower().starts_with('arial') {
mut_replace(file, '-Regular', 'Mono-Regular')
} else if flower.starts_with('arial') {
// Arial has no mono variant
} 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()
}
}