From b5b93b092b8c72e76ff578650e01950fcc7c2314 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 22 Apr 2026 03:01:28 +0300 Subject: [PATCH] all: super_batch7 fixes --- vlib/builtin/array_notd_gcboehm_opt.v | 9 ++++++++ vlib/builtin/builtin_nix.c.v | 7 +++++++ vlib/encoding/README.md | 2 +- vlib/encoding/iconv/iconv.v | 12 ----------- vlib/encoding/iconv/iconv_test.v | 10 --------- vlib/os/os_nix.c.v | 7 +++++++ vlib/v/ast/ast.v | 13 ++++-------- vlib/v/builder/cc.v | 14 ++++++++++++- vlib/v/builder/cflags.v | 3 ++- vlib/v/checker/struct.v | 4 ++-- vlib/v/fmt/fmt.v | 2 ++ vlib/v/gen/c/cgen.v | 4 ++-- vlib/v/parser/expr.v | 21 ++++++++++--------- vlib/v/tests/builtin_arrays/array_init_test.v | 2 +- 14 files changed, 61 insertions(+), 49 deletions(-) diff --git a/vlib/builtin/array_notd_gcboehm_opt.v b/vlib/builtin/array_notd_gcboehm_opt.v index eab2a561b..f2313b2ec 100644 --- a/vlib/builtin/array_notd_gcboehm_opt.v +++ b/vlib/builtin/array_notd_gcboehm_opt.v @@ -4,6 +4,15 @@ module builtin +// these are needed for calls inside `$if gcboehm_opt ? { ... }` in array.v +fn alloc_array_data_noscan(total_size u64) voidptr { + return alloc_array_data(total_size) +} + +fn alloc_array_data_noscan_uninit(total_size u64) voidptr { + return alloc_array_data_uninit(total_size) +} + // this is needed in `string.v` fn __new_array_noscan(mylen int, cap int, elm_size int) array { return __new_array(mylen, cap, elm_size) diff --git a/vlib/builtin/builtin_nix.c.v b/vlib/builtin/builtin_nix.c.v index 40cc8c9ef..17d40dca3 100644 --- a/vlib/builtin/builtin_nix.c.v +++ b/vlib/builtin/builtin_nix.c.v @@ -25,3 +25,10 @@ pub fn panic_lasterr(base string) { // TODO: use strerror_r and errno panic(base + ' unknown') } + +// write_buf_to_console is a Windows-only helper; on non-Windows platforms +// it is a no-op stub so that callers guarded by `$if windows { ... }` still +// type-check on other targets. +fn write_buf_to_console(fd int, buf &u8, buf_len int) bool { + return false +} diff --git a/vlib/encoding/README.md b/vlib/encoding/README.md index 07958cb45..16252a1db 100644 --- a/vlib/encoding/README.md +++ b/vlib/encoding/README.md @@ -1,4 +1,4 @@ ## Description `encoding` is a namespace for different formats/protocols encoding/decoding, -like `csv`, `utf8`, `base64`, and legacy text encodings such as `windows1252`. +like `csv`, `utf8`, `base64` etc. diff --git a/vlib/encoding/iconv/iconv.v b/vlib/encoding/iconv/iconv.v index 115080f68..518616e67 100644 --- a/vlib/encoding/iconv/iconv.v +++ b/vlib/encoding/iconv/iconv.v @@ -1,7 +1,6 @@ module iconv // Module iconv provides functions to convert between vstring(UTF8) and other encodings. -import encoding.windows1252 import os @[inline] @@ -28,9 +27,6 @@ pub fn vstring_to_encoding(str string, tocode string) ![]u8 { encoding_name = 'UTF-8' } } - if is_windows_1252_encoding(encoding_name) { - return windows1252.encode(str) - } return conv(encoding_name, 'UTF-8', str.str, str.len) } @@ -48,19 +44,11 @@ pub fn encoding_to_vstring(bytes []u8, fromcode string) !string { encoding_name = 'UTF-8' } } - if is_windows_1252_encoding(encoding_name) { - return windows1252.decode(bytes) - } mut dst := conv('UTF-8', encoding_name, bytes.data, bytes.len)! dst << 0 // add a tail zero, to build a vstring return unsafe { cstring_to_vstring(dst.data) } } -@[inline] -fn is_windows_1252_encoding(encoding_name string) bool { - return encoding_name in ['CP1252', 'MS-ANSI', 'WINDOWS-1252', 'WINDOWS1252']! -} - // create_utf_string_with_bom will create a utf8/utf16/utf32 string with BOM header // for utf8, it will prepend 0xEFBBBF to the `src` // for utf16le, it will prepend 0xFFFE to the `src` diff --git a/vlib/encoding/iconv/iconv_test.v b/vlib/encoding/iconv/iconv_test.v index 9ebaa10f4..ce6d91701 100644 --- a/vlib/encoding/iconv/iconv_test.v +++ b/vlib/encoding/iconv/iconv_test.v @@ -78,16 +78,6 @@ fn test_encoding_to_vstring() { } } -fn test_windows_1252_encoding_support() ! { - pound := iconv.encoding_to_vstring([u8(0xa3)], 'WINDOWS-1252')! - assert pound == 'Ā£' - assert pound.runes() == [rune(0x00a3)] - - smart_quotes := iconv.encoding_to_vstring([u8(0x93), 0x56, 0x94], 'CP1252')! - assert smart_quotes == 'ā€œVā€' - assert iconv.vstring_to_encoding(smart_quotes, 'WINDOWS-1252')! == [u8(0x93), 0x56, 0x94] -} - fn test_create_utf_string_with_bom() { // bug ? vfmt create strange format here // vfmt off diff --git a/vlib/os/os_nix.c.v b/vlib/os/os_nix.c.v index 5d8c5d015..3ab1e46fc 100644 --- a/vlib/os/os_nix.c.v +++ b/vlib/os/os_nix.c.v @@ -9,6 +9,13 @@ module os #include #insert "@VEXEROOT/vlib/os/execute_capture_nix.h" +// short_path is a Windows-only helper that returns the DOS 8.3 short path. +// On non-Windows platforms it simply returns the given path unchanged, +// so that callers guarded by `$if windows { ... }` type-check on other targets. +pub fn short_path(path string) string { + return path +} + // path_separator is the platform specific separator string, used between the folders and filenames in a path. It is '/' on POSIX, and '\\' on Windows. pub const path_separator = '/' diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 2d3e07aaf..06a3ba1d8 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -940,6 +940,7 @@ pub mut: // is_expand_simple_interpolation bool // true, when the function/method is marked as @[expand_simple_interpolation] is_unwrapped_fn_selector bool // true, when the call is from an unwrapped selector (e.g. if t.foo != none { t.foo() }) + is_paren_wrapped_call bool // true, when the callee was wrapped in parentheses: `(f)(x)` — used by vfmt to preserve the parens // Calls to it with an interpolation argument like `b.f('x ${y}')`, will be converted to `b.f('x ')` followed by `b.f(y)`. // The same type, has to support also a .write_decimal(n i64) method. } @@ -3247,16 +3248,10 @@ pub fn (expr Expr) is_reference() bool { } // remove_par removes all parenthesis and gets the innermost Expr -pub fn (mut expr Expr) remove_par() Expr { +pub fn (expr Expr) remove_par() Expr { mut e := expr - for { - mut next_expr := Expr(EmptyExpr{}) - if mut e is ParExpr { - next_expr = e.expr - } else { - break - } - e = next_expr + for e is ParExpr { + e = (e as ParExpr).expr } return e } diff --git a/vlib/v/builder/cc.v b/vlib/v/builder/cc.v index 380f516e5..6e99870af 100644 --- a/vlib/v/builder/cc.v +++ b/vlib/v/builder/cc.v @@ -1075,7 +1075,15 @@ fn (mut v Builder) setup_output_name() { } pub fn (mut v Builder) tcc_quoted_path(p string) string { - return os.quoted_path(v.tcc_windows_path(p)) + wp := v.tcc_windows_path(p) + if v.ccoptions.cc == .tcc && !v.pref.no_rsp { + // tcc has a bug that prevents it from parsing names quoted with `'` in .rsp files, + // so force double-quoted, backslash-escaped paths for tcc rsp mode. + mut escaped := wp.replace('\\', '\\\\') + escaped = escaped.replace('"', '\\"') + return '"${escaped}"' + } + return os.quoted_path(wp) } fn looks_like_windows_path(value string) bool { @@ -1496,6 +1504,10 @@ pub fn (mut v Builder) cc() { if v.pref.ccompiler != '' && v.pref.ccompiler != ccompiler { if v.pref.is_verbose { eprintln('Compilation with tcc failed. Retrying with ${v.pref.ccompiler} ...') + } else { + $if macos { + eprintln(term.red('warning: tcc compilation failed, falling back to ${v.pref.ccompiler} (this is much slower)')) + } } continue } diff --git a/vlib/v/builder/cflags.v b/vlib/v/builder/cflags.v index 3f2d80395..4990a8225 100644 --- a/vlib/v/builder/cflags.v +++ b/vlib/v/builder/cflags.v @@ -12,7 +12,8 @@ fn (mut v Builder) get_os_cflags() []cflag.CFlag { ctimedefines << v.pref.compile_defines } for mut flag in v.table.cflags { - if ext := os.file_ext(flag.value); ext in ['.o', '.obj'] { + ext := os.file_ext(flag.value) + if ext in ['.o', '.obj'] { flag.cached = v.pref.cache_manager.mod_postfix_with_key2cpath(flag.mod, ext, os.real_path(flag.value)) } diff --git a/vlib/v/checker/struct.v b/vlib/v/checker/struct.v index c49a229ae..e6a49850c 100644 --- a/vlib/v/checker/struct.v +++ b/vlib/v/checker/struct.v @@ -143,8 +143,8 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) { c.error('field ${err_desc} reference but default value ${val_desc} reference', default_pos) } else if field.default_expr is ast.StructInit - || (field.typ.is_ptr() - && (field.default_expr is ast.Ident || field.default_expr is ast.SelectorExpr)) { + || (field.typ.is_ptr() && (field.default_expr is ast.Ident + || field.default_expr is ast.SelectorExpr)) { c.error('reference field must be initialized with reference', default_pos) } } diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index 3ccf79612..3faf00e9e 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -2213,6 +2213,8 @@ pub fn (mut f Fmt) call_expr(node ast.CallExpr) { name := f.short_module(node.name) if node.is_static_method { f.write_static_method(node.name, name) + } else if node.is_paren_wrapped_call { + f.write('(${name})') } else { f.write(name) } diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 27ed48c99..cbd509b40 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -8612,8 +8612,8 @@ fn (mut g Gen) cast_expr(node ast.CastExpr) { return } use_dynamic_ptr_payload := node_typ.is_ptr() && expr_type.is_ptr() - && final_expr_sym.kind == .sum_type - && final_sym.kind !in [.sum_type, .interface] && final_sym.language == .c + && final_expr_sym.kind == .sum_type && final_sym.kind !in [.sum_type, .interface] + && final_sym.language == .c if (g.pref.translated || g.file.is_translated) && sym.kind == .function { // TODO: handle the type in fn casts, not just exprs /* diff --git a/vlib/v/parser/expr.v b/vlib/v/parser/expr.v index 33c1802b6..85214bce8 100644 --- a/vlib/v/parser/expr.v +++ b/vlib/v/parser/expr.v @@ -882,16 +882,17 @@ fn (mut p Parser) call_expr_with_left(left ast.Expr) ast.CallExpr { kind = p.call_kind(fn_name) } return ast.CallExpr{ - name: name - name_pos: name_pos - mod: mod - kind: kind - left: unwrapped_left - args: args - pos: pos - scope: p.scope - or_block: or_block - is_return_used: p.expecting_value + name: name + name_pos: name_pos + mod: mod + kind: kind + left: unwrapped_left + args: args + pos: pos + scope: p.scope + or_block: or_block + is_return_used: p.expecting_value + is_paren_wrapped_call: left is ast.ParExpr } } diff --git a/vlib/v/tests/builtin_arrays/array_init_test.v b/vlib/v/tests/builtin_arrays/array_init_test.v index f32be277a..5fe1c7816 100644 --- a/vlib/v/tests/builtin_arrays/array_init_test.v +++ b/vlib/v/tests/builtin_arrays/array_init_test.v @@ -290,7 +290,7 @@ fn empty_array_from_generic_typ[T]() []T { fn test_array_init_from_typeof_idx() { fixed := [1, 2, 3]! - dyn := []typeof(fixed[0]).idx{} + dyn := []typeof(fixed[0]).idx{}{} assert typeof(dyn).name == '[]int' assert dyn.len == 0 } -- 2.39.5