mirror of
https://github.com/vlang/v.git
synced 2025-08-03 17:57:59 -04:00
v.builder, builtin: use ANSI encoding for the .rsp file under Windows; add builtin string_to_ansi_not_null_terminated + tests (#22409)
This commit is contained in:
parent
5a8ba962a8
commit
dc6a9583d7
@ -2,6 +2,7 @@ module builtin
|
||||
|
||||
import strings
|
||||
|
||||
const cp_acp = 0
|
||||
const cp_utf8 = 65001
|
||||
|
||||
// to_wide returns a pointer to an UTF-16 version of the string receiver.
|
||||
@ -92,3 +93,27 @@ pub fn string_from_wide2(_wstr &u16, len int) string {
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
// wide_to_ansi create an ANSI string, given a windows
|
||||
// style string, encoded in UTF-16.
|
||||
// It use CP_ACP, which is ANSI code page identifier, as dest encoding.
|
||||
// NOTE: It return a vstring(encoded in UTF-8) []u8 under Linux.
|
||||
pub fn wide_to_ansi(_wstr &u16) []u8 {
|
||||
$if windows {
|
||||
num_bytes := C.WideCharToMultiByte(cp_acp, 0, _wstr, -1, 0, 0, 0, 0)
|
||||
if num_bytes != 0 {
|
||||
mut str_to := []u8{len: num_bytes}
|
||||
C.WideCharToMultiByte(cp_acp, 0, _wstr, -1, &char(str_to.data), str_to.len,
|
||||
0, 0)
|
||||
return str_to
|
||||
} else {
|
||||
return []u8{}
|
||||
}
|
||||
} $else {
|
||||
s := unsafe { string_from_wide(_wstr) }
|
||||
mut str_to := []u8{len: s.len + 1}
|
||||
unsafe { vmemcpy(str_to.data, s.str, s.len) }
|
||||
return str_to
|
||||
}
|
||||
return []u8{} // TODO: remove this, bug?
|
||||
}
|
||||
|
@ -184,3 +184,13 @@ pub fn utf8_str_visible_length(s string) int {
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
// string_to_ansi_not_null_terminated returns an ANSI version of the string `_str`.
|
||||
// NOTE: This is most useful for converting a vstring to an ANSI string under Windows.
|
||||
// NOTE: The ANSI string return is not null-terminated, then you can use `os.write_file_array` write an ANSI file.
|
||||
pub fn string_to_ansi_not_null_terminated(_str string) []u8 {
|
||||
wstr := _str.to_wide()
|
||||
mut ansi := wide_to_ansi(wstr)
|
||||
ansi.pop() // remove tailing zero
|
||||
return ansi
|
||||
}
|
||||
|
@ -76,3 +76,12 @@ fn test_reverse_cyrillic_with_string_from_wide() {
|
||||
z := unsafe { string_from_wide(ws) }
|
||||
assert z == s
|
||||
}
|
||||
|
||||
fn test_wide_to_ansi() {
|
||||
ws := 'abc'.to_wide()
|
||||
assert wide_to_ansi(ws) == [u8(97), 98, 99, 0]
|
||||
}
|
||||
|
||||
fn test_string_to_ansi_not_null_terminated() {
|
||||
assert string_to_ansi_not_null_terminated('abc') == [u8(97), 98, 99]
|
||||
}
|
||||
|
@ -666,8 +666,14 @@ pub fn (mut v Builder) cc() {
|
||||
response_file_content = str_args.replace('\\', '\\\\')
|
||||
rspexpr := '@${response_file}'
|
||||
cmd = '${v.quote_compiler_name(ccompiler)} ${os.quoted_path(rspexpr)}'
|
||||
os.write_file(response_file, response_file_content) or {
|
||||
verror('Unable to write to C response file "${response_file}"')
|
||||
$if windows {
|
||||
os.write_file_array(response_file, string_to_ansi_not_null_terminated(response_file_content)) or {
|
||||
verror('Unable to write to C response file "${response_file}"')
|
||||
}
|
||||
} $else {
|
||||
os.write_file(response_file, response_file_content) or {
|
||||
verror('Unable to write to C response file "${response_file}"')
|
||||
}
|
||||
}
|
||||
}
|
||||
if !v.ccoptions.debug_mode {
|
||||
|
@ -355,9 +355,9 @@ pub fn (mut v Builder) cc_msvc() {
|
||||
a << env_ldflags
|
||||
}
|
||||
v.dump_c_options(a)
|
||||
args := '\xEF\xBB\xBF' + a.join(' ')
|
||||
args := a.join(' ')
|
||||
// write args to a file so that we dont smash createprocess
|
||||
os.write_file(out_name_cmd_line, args) or {
|
||||
os.write_file_array(out_name_cmd_line, string_to_ansi_not_null_terminated(args)) or {
|
||||
verror('Unable to write response file to "${out_name_cmd_line}"')
|
||||
}
|
||||
cmd := '"${r.full_cl_exe_path}" "@${out_name_cmd_line}"'
|
||||
|
Loading…
x
Reference in New Issue
Block a user