mirror of
https://github.com/vlang/v.git
synced 2025-08-04 02:07:28 -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
|
import strings
|
||||||
|
|
||||||
|
const cp_acp = 0
|
||||||
const cp_utf8 = 65001
|
const cp_utf8 = 65001
|
||||||
|
|
||||||
// to_wide returns a pointer to an UTF-16 version of the string receiver.
|
// 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
|
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
|
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) }
|
z := unsafe { string_from_wide(ws) }
|
||||||
assert z == s
|
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('\\', '\\\\')
|
response_file_content = str_args.replace('\\', '\\\\')
|
||||||
rspexpr := '@${response_file}'
|
rspexpr := '@${response_file}'
|
||||||
cmd = '${v.quote_compiler_name(ccompiler)} ${os.quoted_path(rspexpr)}'
|
cmd = '${v.quote_compiler_name(ccompiler)} ${os.quoted_path(rspexpr)}'
|
||||||
os.write_file(response_file, response_file_content) or {
|
$if windows {
|
||||||
verror('Unable to write to C response file "${response_file}"')
|
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 {
|
if !v.ccoptions.debug_mode {
|
||||||
|
@ -355,9 +355,9 @@ pub fn (mut v Builder) cc_msvc() {
|
|||||||
a << env_ldflags
|
a << env_ldflags
|
||||||
}
|
}
|
||||||
v.dump_c_options(a)
|
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
|
// 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}"')
|
verror('Unable to write response file to "${out_name_cmd_line}"')
|
||||||
}
|
}
|
||||||
cmd := '"${r.full_cl_exe_path}" "@${out_name_cmd_line}"'
|
cmd := '"${r.full_cl_exe_path}" "@${out_name_cmd_line}"'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user