readLine: Fix issues with --gc:arc

**--gc:arc** defines **nimv2**. This changes the definition of **WideCStringObj**.
Also an empty string should be returned in case of EOF.
This commit is contained in:
ktamp 2020-06-26 00:31:06 +03:00 • committed by GitHub
commit 41c97e4b70
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -354,8 +354,8 @@ proc readLine*(f: File, line: var TaintedString): bool {.tags: [ReadIOEffect],
when defined(windows) and not defined(useWinAnsi): when defined(windows) and not defined(useWinAnsi):
proc readConsole(hConsoleInput: FileHandle, lpBuffer: pointer, proc readConsole(hConsoleInput: FileHandle, lpBuffer: pointer,
nNumberOfCharsToRead: uint32, nNumberOfCharsToRead: int32,
lpNumberOfCharsRead: ptr uint32, lpNumberOfCharsRead: ptr int32,
pInputControl: pointer): int32 {. pInputControl: pointer): int32 {.
importc: "ReadConsoleW", stdcall, dynlib: "kernel32".} importc: "ReadConsoleW", stdcall, dynlib: "kernel32".}
@ -383,7 +383,7 @@ proc readLine*(f: File, line: var TaintedString): bool {.tags: [ReadIOEffect],
# this implies the file is open # this implies the file is open
if f.isatty: if f.isatty:
const numberOfCharsToRead = 2048 const numberOfCharsToRead = 2048
var numberOfCharsRead = 0'u32 var numberOfCharsRead = 0'i32
var buffer = newWideCString("", numberOfCharsToRead) var buffer = newWideCString("", numberOfCharsToRead)
if readConsole(getOsFileHandle(f), addr(buffer[0]), if readConsole(getOsFileHandle(f), addr(buffer[0]),
numberOfCharsToRead, addr(numberOfCharsRead), nil) == 0: numberOfCharsToRead, addr(numberOfCharsRead), nil) == 0:
@ -393,19 +393,24 @@ proc readLine*(f: File, line: var TaintedString): bool {.tags: [ReadIOEffect],
if formatMessageW(0x00000100 or 0x00001000 or 0x00000200, if formatMessageW(0x00000100 or 0x00001000 or 0x00000200,
nil, error, 0, addr(msgbuf), 0, nil) != 0'i32: nil, error, 0, addr(msgbuf), 0, nil) != 0'i32:
errorMsg = $msgbuf errorMsg = $msgbuf
if msgbuf != nil: localFree(cast[pointer](msgbuf)) if msgbuf != nil:
localFree(cast[pointer](msgbuf))
raiseEIO("error: " & $error & " `" & errorMsg & "`") raiseEIO("error: " & $error & " `" & errorMsg & "`")
# input always ends with "\r\n" # input always ends with "\r\n"
numberOfCharsRead -= 2 numberOfCharsRead -= 2
# handle Ctrl+Z as EOF # handle Ctrl+Z as EOF
for i in 0'u32..<numberOfCharsRead: for i in 0..<numberOfCharsRead:
if buffer[i].uint16 == 26: #Ctrl+Z if buffer[i].uint16 == 26: #Ctrl+Z
close(f) #has the same effect as setting EOF close(f) #has the same effect as setting EOF
if i == 0: if i == 0:
line = TaintedString("")
return false return false
numberOfCharsRead = i numberOfCharsRead = i
break break
buffer[numberOfCharsRead] = 0.Utf16Char buffer[numberOfCharsRead] = 0.Utf16Char
when defined(nimv2):
line = TaintedString($toWideCString(buffer))
else:
line = TaintedString($buffer) line = TaintedString($buffer)
return(true) return(true)