Support for the printf optimisation for windows and wide strings

pull/1385/head
F1ssi0N 2019-07-27 16:28:22 +01:00 committed by Alexander Medvednikov
parent 3794129c91
commit acd28fa495
4 changed files with 27 additions and 7 deletions

View File

@ -400,7 +400,9 @@ fn (p mut Parser) fn_decl() {
p.genln('pthread_mutex_lock(&live_fn_mutex);')
}
if f.name == 'main' || f.name == 'WinMain' {
p.genln('')
p.genln('init_consts();')
p.genln('#ifdef _WIN32\n fflush(stdout); _setmode(_fileno(stdout), _O_U8TEXT); \n#endif\n')
if p.table.imports.contains('os') {
if f.name == 'main' {
p.genln('os__args = os__init_os_args(argc, argv);')
@ -810,7 +812,13 @@ fn (p mut Parser) fn_call_args(f mut Fn) *Fn {
T := p.table.find_type(typ)
fmt := p.typ_to_fmt(typ, 0)
if fmt != '' {
p.cgen.resetln(p.cgen.cur_line.replace('println (', '/*opt*/printf ("' + fmt + '\\n", '))
// Fix for win32 unicode support
if p.os == .windows || p.os == .msvc {
//p.cgen.resetln(p.cgen.cur_line.replace('println (', '/*opt*/printf ("' + fmt + '\\n", '))
p.cgen.resetln(p.cgen.cur_line.replace('println (', '/*opt*/wprintf (L"' + fmt.replace('%.*s', '%.*S') + '\\n", '))
} else {
p.cgen.resetln(p.cgen.cur_line.replace('println (', '/*opt*/printf ("' + fmt + '\\n", '))
}
continue
}
if typ.ends_with('*') {

View File

@ -404,7 +404,7 @@ string _STR_TMP(const char *fmt, ...) {
// It can be skipped in single file programs
if v.pref.is_script {
//println('Generating main()...')
cgen.genln('int main() { \n#ifdef _WIN32\n _setmode(_fileno(stdout), _O_U8TEXT); \n#endif\n init_consts(); $cgen.fn_main; return 0; }')
cgen.genln('int main() { \n#ifdef _WIN32\n fflush(stdout); _setmode(_fileno(stdout), _O_U8TEXT); \n#endif\n init_consts(); $cgen.fn_main; return 0; }')
}
else {
println('panic: function `main` is undeclared in the main module')
@ -413,7 +413,7 @@ string _STR_TMP(const char *fmt, ...) {
}
// Generate `main` which calls every single test function
else if v.pref.is_test {
cgen.genln('int main() { \n#ifdef _WIN32\n _setmode(_fileno(stdout), _O_U8TEXT); \n#endif\n init_consts();')
cgen.genln('int main() { \n#ifdef _WIN32\n fflush(stdout); _setmode(_fileno(stdout), _O_U8TEXT); \n#endif\n init_consts();')
for key, f in v.table.fns {
if f.name.starts_with('test_') {
cgen.genln('$f.name();')

View File

@ -2398,9 +2398,19 @@ fn (p mut Parser) string_expr() {
cur_line := p.cgen.cur_line.trim_space()
if cur_line.contains('println (') && p.tok != .plus &&
!cur_line.contains('string_add') && !cur_line.contains('eprintln') {
p.cgen.resetln(cur_line.replace('println (', 'printf('))
p.gen('$format\\n$args')
return
if p.os == .windows || p.os == .msvc {
p.cgen.resetln(cur_line.replace('println (', 'wprintf( TEXT('))// .replace('%.*s', '%.*S'))
// Emily: HACKY HACK
real_format := format.replace('%.*s', '%.*S')
real_args := args.right(1)
p.gen('$real_format\\n")$real_args')
} else {
p.cgen.resetln(cur_line.replace('println (', 'printf('))
p.gen('$format\\n$args')
}
return
}
// '$age'! means the user wants this to be a tmp string (uses global buffer, no allocation,
// won't be used again)

View File

@ -51,7 +51,9 @@ pub fn println(s string) {
panic('println(NIL)')
}
$if windows {
C._putws(s.to_wide())
// HACKY HACK
// use capital s for printing regular ascii strings
C.wprintf(C.TEXT('%.*S\n'), s.len, s)
} $else {
C.printf('%.*s\n', s.len, s.str)
}