diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2019-08-18 22:57:56 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-08-18 22:57:56 +0200 |
commit | 742862b847646dff4562992cd502d3077b2c9474 (patch) | |
tree | 8ffdf07aa85b7d593a2450c20425bf91c210ef93 | |
parent | ac7a3651379f0601f9bbf5b1d613c8d6eb89cf4c (diff) | |
download | Nim-742862b847646dff4562992cd502d3077b2c9474.tar.gz |
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
-rw-r--r-- | changelog.md | 3 | ||||
-rw-r--r-- | lib/system.nim | 6 | ||||
-rw-r--r-- | lib/system/io.nim | 27 | ||||
-rw-r--r-- | tests/system/techo_unicode.nim | 27 |
4 files changed, 55 insertions, 8 deletions
diff --git a/changelog.md b/changelog.md index 3780c270b..41d371b60 100644 --- a/changelog.md +++ b/changelog.md @@ -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 diff --git a/lib/system.nim b/lib/system.nim index d582411d8..7e23b5188 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -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".} diff --git a/lib/system/io.nim b/lib/system/io.nim index 7f7df74ba..977e8539a 100644 --- a/lib/system/io.nim +++ b/lib/system/io.nim @@ -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,10 +257,23 @@ proc flushFile*(f: File) {.tags: [WriteIOEffect].} = discard c_fflush(f) proc getFileHandle*(f: File): FileHandle = - ## returns the OS file handle of the file ``f``. This is only useful for + ## 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. + 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.} = ## reads a line of text from the file `f` into `line`. May throw an IO @@ -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 diff --git a/tests/system/techo_unicode.nim b/tests/system/techo_unicode.nim new file mode 100644 index 000000000..d0395224b --- /dev/null +++ b/tests/system/techo_unicode.nim @@ -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() |