deprecated endOfFile and readLine

This commit is contained in:
Araq 2011-11-25 18:17:14 +01:00
commit 4b39ac5cbe
6 changed files with 59 additions and 29 deletions

View file

@ -43,9 +43,10 @@ proc close*(s, unused: PStream) {.deprecated.} =
## closes the stream `s`. ## closes the stream `s`.
s.closeImpl(s) s.closeImpl(s)
proc atEnd*(s: PStream): bool = proc atEnd*(s: PStream): bool {.deprecated.} =
## checks if more data can be read from `f`. Returns true if all data has ## checks if more data can be read from `f`. Returns true if all data has
## been read. ## been read.
## **Deprecated since version 0.8.14**: Because Posix supports it poorly.
result = s.atEndImpl(s) result = s.atEndImpl(s)
proc atEnd*(s, unused: PStream): bool {.deprecated.} = proc atEnd*(s, unused: PStream): bool {.deprecated.} =
@ -149,9 +150,10 @@ proc readStr*(s: PStream, length: int): TaintedString =
var L = readData(s, addr(string(result)[0]), length) var L = readData(s, addr(string(result)[0]), length)
if L != length: setLen(result.string, L) if L != length: setLen(result.string, L)
proc readLine*(s: PStream): TaintedString = proc readLine*(s: PStream): TaintedString {.deprecated.} =
## Reads a line from a stream `s`. Note: This is not very efficient. Raises ## Reads a line from a stream `s`. Note: This is not very efficient. Raises
## `EIO` if an error occured. ## `EIO` if an error occured.
## **Deprecated since version 0.8.14**: Because Posix supports it poorly.
result = TaintedString"" result = TaintedString""
while not atEnd(s): while not atEnd(s):
var c = readChar(s) var c = readChar(s)
@ -161,6 +163,26 @@ proc readLine*(s: PStream): TaintedString =
elif c == '\L' or c == '\0': break elif c == '\L' or c == '\0': break
result.string.add(c) result.string.add(c)
proc readLine*(s: PStream, line: var TaintedString): bool =
## reads a line of text from the stream `s` into `line`. `line` must not be
## ``nil``! May throw an IO exception.
## A line of text may be delimited by ``CR``, ``LF`` or
## ``CRLF``. The newline character(s) are not part of the returned string.
## Returns ``false`` if the end of the file has been reached, ``true``
## otherwise. If ``false`` is returned `line` contains no new data.
line.setLen(0)
while true:
var c = readChar(s)
if c == '\c':
c = readChar(s)
break
elif c == '\L': break
elif c == '\0':
if line.len > 0: break
else: return false
line.string.add(c)
result = true
type type
PStringStream* = ref TStringStream ## a stream that encapsulates a string PStringStream* = ref TStringStream ## a stream that encapsulates a string
TStringStream* = object of TStream TStringStream* = object of TStream

View file

@ -1670,8 +1670,10 @@ when not defined(EcmaScript) and not defined(NimrodVM):
proc Close*(f: TFile) {.importc: "fclose", nodecl.} proc Close*(f: TFile) {.importc: "fclose", nodecl.}
## Closes the file. ## Closes the file.
proc EndOfFile*(f: TFile): Bool proc EndOfFile*(f: TFile): Bool {.deprecated.}
## Returns true iff `f` is at the end. ## Returns true iff `f` is at the end.
## **Deprecated since version 0.8.14**: Because Posix supports it poorly.
proc readChar*(f: TFile): char {.importc: "fgetc", nodecl.} proc readChar*(f: TFile): char {.importc: "fgetc", nodecl.}
## Reads a single character from the stream `f`. If the stream ## Reads a single character from the stream `f`. If the stream
## has no more characters, `EEndOfFile` is raised. ## has no more characters, `EEndOfFile` is raised.
@ -1700,10 +1702,21 @@ when not defined(EcmaScript) and not defined(NimrodVM):
proc write*(f: TFile, a: openArray[string]) proc write*(f: TFile, a: openArray[string])
## Writes a value to the file `f`. May throw an IO exception. ## Writes a value to the file `f`. May throw an IO exception.
proc readLine*(f: TFile): TaintedString proc readLine*(f: TFile): TaintedString {.deprecated.}
## reads a line of text from the file `f`. May throw an IO exception. ## reads a line of text from the file `f`. May throw an IO exception.
## A line of text may be delimited by ``CR``, ``LF`` or ## A line of text may be delimited by ``CR``, ``LF`` or
## ``CRLF``. The newline character(s) are not part of the returned string. ## ``CRLF``. The newline character(s) are not part of the returned string.
##
## **Deprecated since 0.8.14**: Use the `readLine` that takes a ``var``
## parameter instead.
proc readLine*(f: TFile, line: var TaintedString): bool
## reads a line of text from the file `f` into `line`. `line` must not be
## ``nil``! May throw an IO exception.
## A line of text may be delimited by ``CR``, ``LF`` or
## ``CRLF``. The newline character(s) are not part of the returned string.
## Returns ``false`` if the end of the file has been reached, ``true``
## otherwise. If ``false`` is returned `line` contains no new data.
proc writeln*[Ty](f: TFile, x: Ty) {.inline.} proc writeln*[Ty](f: TFile, x: Ty) {.inline.}
## writes a value `x` to `f` and then writes "\n". ## writes a value `x` to `f` and then writes "\n".
@ -1843,18 +1856,14 @@ when not defined(EcmaScript) and not defined(NimrodVM):
## Iterate over any line in the file named `filename`. ## Iterate over any line in the file named `filename`.
## If the file does not exist `EIO` is raised. ## If the file does not exist `EIO` is raised.
var f = open(filename) var f = open(filename)
var res = "" var res = TaintedString(newStringOfCap(80))
while not endOfFile(f): while f.readLine(res): yield res
rawReadLine(f, res) close(f)
yield TaintedString(res)
Close(f)
iterator lines*(f: TFile): TaintedString = iterator lines*(f: TFile): TaintedString =
## Iterate over any line in the file `f`. ## Iterate over any line in the file `f`.
var res = "" var res = TaintedString(newStringOfCap(80))
while not endOfFile(f): while f.readLine(res): yield TaintedString(res)
rawReadLine(f, res)
yield TaintedString(res)
include "system/assign" include "system/assign"
include "system/repr" include "system/repr"

View file

@ -39,29 +39,26 @@ var
proc raiseEIO(msg: string) {.noinline, noreturn.} = proc raiseEIO(msg: string) {.noinline, noreturn.} =
raise newException(EIO, msg) raise newException(EIO, msg)
proc rawReadLine(f: TFile, result: var string) = proc readLine(f: TFile, line: var TaintedString): bool =
# of course this could be optimized a bit; but IO is slow anyway... # of course this could be optimized a bit; but IO is slow anyway...
# and it was difficult to get this CORRECT with Ansi C's methods # and it was difficult to get this CORRECT with Ansi C's methods
setLen(result, 0) # reuse the buffer! setLen(line, 0) # reuse the buffer!
while True: while True:
var c = fgetc(f) var c = fgetc(f)
if c < 0'i32: if c < 0'i32:
if result.len > 0: break if line.len > 0: break
else: raiseEIO("EOF reached") else: return false
if c == 10'i32: break # LF if c == 10'i32: break # LF
if c == 13'i32: # CR if c == 13'i32: # CR
c = fgetc(f) # is the next char LF? c = fgetc(f) # is the next char LF?
if c != 10'i32: ungetc(c, f) # no, put the character back if c != 10'i32: ungetc(c, f) # no, put the character back
break break
add result, chr(int(c)) add line.string, chr(int(c))
result = true
proc readLine(f: TFile): TaintedString = proc readLine(f: TFile): TaintedString =
when taintMode: result = TaintedString(newStringOfCap(80))
result = TaintedString"" if not readLine(f, result): raiseEIO("EOF reached")
rawReadLine(f, result.string)
else:
result = ""
rawReadLine(f, result)
proc write(f: TFile, i: int) = proc write(f: TFile, i: int) =
when sizeof(int) == 8: when sizeof(int) == 8:

View file

@ -25,9 +25,9 @@ proc consume() {.thread.} =
proc produce() {.thread.} = proc produce() {.thread.} =
var m: TMsg var m: TMsg
var input = open("readme.txt") var input = open("readme.txt")
while not endOfFile(input): var line = ""
if chan.ready: while input.readLine(line):
m.data = input.readLine() m.data = line
chan.send(m) chan.send(m)
close(input) close(input)
m.k = mEof m.k = mEof

View file

@ -1,7 +1,7 @@
version 0.8.14 version 0.8.14
============== ==============
- deprecate endOfFile and readline - stdlib and compiler should not use deprecated endOfFile and readline
version 0.9.0 version 0.9.0
============= =============

View file

@ -52,6 +52,8 @@ Changes affecting backwards compatibility
because they should not be used directly anymore. because they should not be used directly anymore.
Wrapper procs have been created that should be used instead. Wrapper procs have been created that should be used instead.
- ``export`` is now a keyword. - ``export`` is now a keyword.
- ``system.endOfFile``, ``system.readLine`` and their stream equivalents
are deprecated because Posix supports it poorly.
Language Additions Language Additions