When reading files, check if the eof flag is set before throwing.
This commit is contained in:
parent
dd2a0ec431
commit
dc6c0559e9
2 changed files with 23 additions and 5 deletions
|
|
@ -2594,7 +2594,10 @@ when not defined(JS): #and not defined(nimscript):
|
||||||
## Closes the file.
|
## Closes the file.
|
||||||
|
|
||||||
proc endOfFile*(f: File): bool {.tags: [], benign.}
|
proc endOfFile*(f: File): bool {.tags: [], benign.}
|
||||||
## Returns true iff `f` is at the end.
|
## Returns true if `f` is at the end.
|
||||||
|
|
||||||
|
proc fileError*(f: File): bool {.tags: [], benign.}
|
||||||
|
## Returns true if the error indicator of `f` is set.
|
||||||
|
|
||||||
proc readChar*(f: File): char {.
|
proc readChar*(f: File): char {.
|
||||||
importc: "fgetc", header: "<stdio.h>", tags: [ReadIOEffect].}
|
importc: "fgetc", header: "<stdio.h>", tags: [ReadIOEffect].}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ proc fread(buf: pointer, size, n: int, f: File): int {.
|
||||||
proc fseek(f: File, offset: clong, whence: int): int {.
|
proc fseek(f: File, offset: clong, whence: int): int {.
|
||||||
importc: "fseek", header: "<stdio.h>", tags: [].}
|
importc: "fseek", header: "<stdio.h>", tags: [].}
|
||||||
proc ftell(f: File): int {.importc: "ftell", header: "<stdio.h>", tags: [].}
|
proc ftell(f: File): int {.importc: "ftell", header: "<stdio.h>", tags: [].}
|
||||||
|
proc ferror(f: File): int {.importc: "ferror", header: "<stdio.h>", tags: [].}
|
||||||
|
proc feof(f: File): int {.importc: "feof", header: "<stdio.h>", tags: [].}
|
||||||
proc setvbuf(stream: File, buf: pointer, typ, size: cint): cint {.
|
proc setvbuf(stream: File, buf: pointer, typ, size: cint): cint {.
|
||||||
importc, header: "<stdio.h>", tags: [].}
|
importc, header: "<stdio.h>", tags: [].}
|
||||||
proc memchr(s: pointer, c: cint, n: csize): pointer {.
|
proc memchr(s: pointer, c: cint, n: csize): pointer {.
|
||||||
|
|
@ -147,9 +149,17 @@ proc rawFileSize(file: File): int =
|
||||||
proc readAllFile(file: File, len: int): string =
|
proc readAllFile(file: File, len: int): string =
|
||||||
# We acquire the filesize beforehand and hope it doesn't change.
|
# We acquire the filesize beforehand and hope it doesn't change.
|
||||||
# Speeds things up.
|
# Speeds things up.
|
||||||
result = newString(int(len))
|
result = newString(len)
|
||||||
if readBuffer(file, addr(result[0]), int(len)) != len:
|
let bytes = readBuffer(file, addr(result[0]), len)
|
||||||
|
if endOfFile(file):
|
||||||
|
if bytes < len:
|
||||||
|
result = substr(result, 0 , bytes - 1)
|
||||||
|
elif fileError(file):
|
||||||
raiseEIO("error while reading from file")
|
raiseEIO("error while reading from file")
|
||||||
|
else:
|
||||||
|
# We red all the bytes but did not reach the EOF
|
||||||
|
# Try to read it as a buffer
|
||||||
|
result = readAllBuffer(file)
|
||||||
|
|
||||||
proc readAllFile(file: File): string =
|
proc readAllFile(file: File): string =
|
||||||
var len = rawFileSize(file)
|
var len = rawFileSize(file)
|
||||||
|
|
@ -187,12 +197,17 @@ proc endOfFile(f: File): bool =
|
||||||
ungetc(c, f)
|
ungetc(c, f)
|
||||||
return c < 0'i32
|
return c < 0'i32
|
||||||
|
|
||||||
|
proc fileError(f: File): bool =
|
||||||
|
result = (ferror(f) != 0)
|
||||||
|
|
||||||
proc writeLn[Ty](f: File, x: varargs[Ty, `$`]) =
|
proc writeLn[Ty](f: File, x: varargs[Ty, `$`]) =
|
||||||
for i in items(x): write(f, i)
|
for i in items(x):
|
||||||
|
write(f, i)
|
||||||
write(f, "\n")
|
write(f, "\n")
|
||||||
|
|
||||||
proc writeLine[Ty](f: File, x: varargs[Ty, `$`]) =
|
proc writeLine[Ty](f: File, x: varargs[Ty, `$`]) =
|
||||||
for i in items(x): write(f, i)
|
for i in items(x):
|
||||||
|
write(f, i)
|
||||||
write(f, "\n")
|
write(f, "\n")
|
||||||
|
|
||||||
when declared(stdout):
|
when declared(stdout):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue