* 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:
parent
ac7a365137
commit
742862b847
4 changed files with 55 additions and 8 deletions
|
|
@ -21,6 +21,9 @@
|
||||||
- `encodings.getCurrentEncoding` now distinguishes between the console's
|
- `encodings.getCurrentEncoding` now distinguishes between the console's
|
||||||
encoding and the OS's encoding. This distinction is only meaningful on
|
encoding and the OS's encoding. This distinction is only meaningful on
|
||||||
Windows.
|
Windows.
|
||||||
|
- Added `system.getOsFileHandle` which is usually more useful
|
||||||
|
than `system.getFileHandle`. This distinction is only meaningful on
|
||||||
|
Windows.
|
||||||
|
|
||||||
## Library changes
|
## Library changes
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4496,12 +4496,6 @@ proc substr*(s: string, first = 0): string =
|
||||||
when defined(nimconfig):
|
when defined(nimconfig):
|
||||||
include "system/nimscript"
|
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):
|
when not defined(js):
|
||||||
proc toOpenArray*[T](x: ptr UncheckedArray[T]; first, last: int): openArray[T] {.
|
proc toOpenArray*[T](x: ptr UncheckedArray[T]; first, last: int): openArray[T] {.
|
||||||
magic: "Slice".}
|
magic: "Slice".}
|
||||||
|
|
|
||||||
|
|
@ -202,7 +202,7 @@ when defined(windows):
|
||||||
# But we cannot call printf directly as the string might contain \0.
|
# 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.
|
# So we have to loop over all the sections separated by potential \0s.
|
||||||
var i = c_fprintf(f, "%s", s)
|
var i = c_fprintf(f, "%s", s)
|
||||||
while i < s.len and false:
|
while i < s.len:
|
||||||
if s[i] == '\0':
|
if s[i] == '\0':
|
||||||
inc i
|
inc i
|
||||||
else:
|
else:
|
||||||
|
|
@ -257,9 +257,22 @@ proc flushFile*(f: File) {.tags: [WriteIOEffect].} =
|
||||||
discard c_fflush(f)
|
discard c_fflush(f)
|
||||||
|
|
||||||
proc getFileHandle*(f: File): FileHandle =
|
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
|
## returns the OS file handle of the file ``f``. This is only useful for
|
||||||
## platform specific programming.
|
## 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],
|
proc readLine*(f: File, line: var TaintedString): bool {.tags: [ReadIOEffect],
|
||||||
benign.} =
|
benign.} =
|
||||||
|
|
@ -607,6 +620,16 @@ when defined(windows) and not defined(nimscript):
|
||||||
c_setmode(c_fileno(stdout), O_BINARY)
|
c_setmode(c_fileno(stdout), O_BINARY)
|
||||||
c_setmode(c_fileno(stderr), 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.} =
|
proc readFile*(filename: string): TaintedString {.tags: [ReadIOEffect], benign.} =
|
||||||
## Opens a file named `filename` for reading, calls `readAll
|
## Opens a file named `filename` for reading, calls `readAll
|
||||||
|
|
|
||||||
27
tests/system/techo_unicode.nim
Normal file
27
tests/system/techo_unicode.nim
Normal 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()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue