more enhancements for #11618 (#11976)

* finish the Windows IO layer changes; refs #11618
* added system.getOsFileHandle which is less error-prone on Windows
* make tests green again
This commit is contained in:
Andreas Rumpf
2019-08-18 22:57:56 +02:00
committed by GitHub
parent ac7a365137
commit 742862b847
4 changed files with 55 additions and 8 deletions

View File

@@ -21,6 +21,9 @@
- `encodings.getCurrentEncoding` now distinguishes between the console's
encoding and the OS's encoding. This distinction is only meaningful on
Windows.
- Added `system.getOsFileHandle` which is usually more useful
than `system.getFileHandle`. This distinction is only meaningful on
Windows.
## Library changes

View File

@@ -4496,12 +4496,6 @@ proc substr*(s: string, first = 0): string =
when defined(nimconfig):
include "system/nimscript"
when defined(windows) and appType == "console" and
not defined(nimDontSetUtf8CodePage) and not defined(nimscript):
proc setConsoleOutputCP(codepage: cint): cint {.stdcall, dynlib: "kernel32",
importc: "SetConsoleOutputCP".}
discard setConsoleOutputCP(65001) # 65001 - utf-8 codepage
when not defined(js):
proc toOpenArray*[T](x: ptr UncheckedArray[T]; first, last: int): openArray[T] {.
magic: "Slice".}

View File

@@ -202,7 +202,7 @@ when defined(windows):
# But we cannot call printf directly as the string might contain \0.
# So we have to loop over all the sections separated by potential \0s.
var i = c_fprintf(f, "%s", s)
while i < s.len and false:
while i < s.len:
if s[i] == '\0':
inc i
else:
@@ -257,9 +257,22 @@ proc flushFile*(f: File) {.tags: [WriteIOEffect].} =
discard c_fflush(f)
proc getFileHandle*(f: File): FileHandle =
## returns the file handle of the file ``f``. This is only useful for
## platform specific programming.
## Note that on Windows this doesn't return the Windows-specific handle,
## but the C library's notion of a handle, whatever that means.
## Use `getOsFileHandle` instead.
c_fileno(f)
proc getOsFileHandle*(f: File): FileHandle =
## returns the OS file handle of the file ``f``. This is only useful for
## platform specific programming.
c_fileno(f)
when defined(windows):
proc getOsfhandle(fd: cint): FileHandle {.
importc: "_get_osfhandle", header: "<io.h>".}
result = getOsfhandle(getFileHandle(f))
else:
result = c_fileno(f)
proc readLine*(f: File, line: var TaintedString): bool {.tags: [ReadIOEffect],
benign.} =
@@ -607,6 +620,16 @@ when defined(windows) and not defined(nimscript):
c_setmode(c_fileno(stdout), O_BINARY)
c_setmode(c_fileno(stderr), O_BINARY)
when defined(windows) and appType == "console" and
not defined(nimDontSetUtf8CodePage) and not defined(nimscript):
proc setConsoleOutputCP(codepage: cuint): int32 {.stdcall, dynlib: "kernel32",
importc: "SetConsoleOutputCP".}
proc setConsoleCP(wCodePageID: cuint): int32 {.stdcall, dynlib: "kernel32",
importc: "SetConsoleCP".}
const Utf8codepage = 65001
discard setConsoleOutputCP(Utf8codepage)
discard setConsoleCP(Utf8codepage)
proc readFile*(filename: string): TaintedString {.tags: [ReadIOEffect], benign.} =
## Opens a file named `filename` for reading, calls `readAll

View File

@@ -0,0 +1,27 @@
discard """
output: '''ÄhmÖÜ
abasdfdsmÄhmaИ
Иnastystring
A你好
ИnastystringA你好
ÖÜhmabasdfdsmÄhmaИ'''
disabled: "posix"
joinable: "false"
"""
import winlean
echo "ÄhmÖÜ"
echo "abasdfdsmÄhmaИ"
echo "И\0nasty\0\0\0\0string\0"
echo "A你好"
write stdout, "И\0nasty\0\0\0\0string\0"
writeLine stdout, "A你好"
stdout.flushFile()
let handle = getOsFileHandle(stdout)
var a = "ÖÜhmabasdfdsmÄhmaИ"
var ac = 0'i32
discard writeFile(handle, addr a[0], int32(len(a)), addr ac, nil)
stdout.flushFile()