builtin: use C.write for print/eprint . Call C.SetConsoleOutputCP(C.CP_UTF8) on windows

pull/6352/head
Delyan Angelov 2020-09-11 13:06:11 +03:00
parent d46c1f0f20
commit 40ed2e1b3d
2 changed files with 27 additions and 33 deletions

View File

@ -6,6 +6,9 @@ module builtin
__global g_m2_buf byteptr
__global g_m2_ptr byteptr
type FnExitCb fn()
fn C.atexit(f FnExitCb) int
pub fn exit(code int) {
C.exit(code)
}
@ -66,48 +69,25 @@ pub fn eprintln(s string) {
if s.str == 0 {
eprintln('eprintln(NIL)')
}
$if !windows {
C.fflush(C.stdout)
C.fflush(C.stderr)
C.fprintf(C.stderr, '%.*s\n', s.len, s.str)
C.fflush(C.stderr)
return
}
// TODO issues with stderr and cross compiling for Linux
println(s)
C.fflush(C.stdout)
C.fflush(C.stderr)
C.write(2, s.str, s.len)
C.write(2, c'\n', 1)
C.fflush(C.stderr)
}
pub fn eprint(s string) {
if s.str == 0 {
eprintln('eprint(NIL)')
}
$if !windows {
C.fflush(C.stdout)
C.fflush(C.stderr)
C.fprintf(C.stderr, '%.*s', s.len, s.str)
C.fflush(C.stderr)
return
}
print(s)
C.fflush(C.stdout)
C.fflush(C.stderr)
C.write(2, s.str, s.len)
C.fflush(C.stderr)
}
pub fn print(s string) {
$if windows {
output_handle := C.GetStdHandle(C.STD_OUTPUT_HANDLE)
mut bytes_written := 0
if is_atty(1) > 0 {
wide_str := s.to_wide()
wide_len := C.wcslen(wide_str)
C.WriteConsole(output_handle, wide_str, wide_len, &bytes_written, 0)
unsafe {
free(wide_str)
}
} else {
C.WriteFile(output_handle, s.str, s.len, &bytes_written, 0)
}
} $else {
C.printf('%.*s', s.len, s.str)
}
C.write(1, s.str, s.len)
}
const (

View File

@ -59,11 +59,25 @@ const (
symopt_debug = 0x80000000
)
// g_original_codepage - used to restore the original windows console code page when exiting
__global g_original_codepage u32=0
// utf8 to stdout needs C.SetConsoleOutputCP(C.CP_UTF8)
fn C.GetConsoleOutputCP() u32
fn C.SetConsoleOutputCP(wCodePageID u32) bool
fn restore_codepage() {
C.SetConsoleOutputCP( g_original_codepage )
}
fn builtin_init() {
g_original_codepage = C.GetConsoleOutputCP()
C.SetConsoleOutputCP(C.CP_UTF8)
C.atexit(restore_codepage)
if is_atty(1) > 0 {
C.SetConsoleMode(C.GetStdHandle(C.STD_OUTPUT_HANDLE), C.ENABLE_PROCESSED_OUTPUT | 0x0004) // enable_virtual_terminal_processing
C.SetConsoleMode(C.GetStdHandle(C.STD_ERROR_HANDLE), C.ENABLE_PROCESSED_OUTPUT | 0x0004) // enable_virtual_terminal_processing
unsafe {
C.setbuf(C.stdout, 0)
C.setbuf(C.stderr, 0)
}
}
add_unhandled_exception_handler()