compiler uses new 'readLine'

This commit is contained in:
Araq 2011-11-27 19:01:55 +01:00
commit a489161b16
8 changed files with 86 additions and 73 deletions

View file

@ -380,8 +380,8 @@ proc externalFileChanged(filename: string): bool =
var currentCrc = int(footprint(filename)) var currentCrc = int(footprint(filename))
var f: TFile var f: TFile
if open(f, crcFile, fmRead): if open(f, crcFile, fmRead):
var line = f.readLine() var line = newStringOfCap(40)
if isNil(line) or line.len == 0: line = "0" if not f.readLine(line): line = "0"
close(f) close(f)
var oldCrc = parseInt(line) var oldCrc = parseInt(line)
result = oldCrc != currentCrc result = oldCrc != currentCrc

View file

@ -206,8 +206,8 @@ proc filterTmpl(stdin: PLLStream, filename: string, call: PNode): PLLStream =
p.emit = strArg(call, "emit", 3, "result.add") p.emit = strArg(call, "emit", 3, "result.add")
p.conc = strArg(call, "conc", 4, " & ") p.conc = strArg(call, "conc", 4, " & ")
p.toStr = strArg(call, "tostring", 5, "$") p.toStr = strArg(call, "tostring", 5, "$")
while not LLStreamAtEnd(p.inp): p.x = newStringOfCap(120)
p.x = LLStreamReadLine(p.inp) while LLStreamReadLine(p.inp, p.x):
p.info.line = p.info.line + int16(1) p.info.line = p.info.line + int16(1)
parseLine(p) parseLine(p)
newLine(p) newLine(p)

View file

@ -59,8 +59,8 @@ proc filterStrip(stdin: PLLStream, filename: string, call: PNode): PLLStream =
var leading = boolArg(call, "leading", 2, true) var leading = boolArg(call, "leading", 2, true)
var trailing = boolArg(call, "trailing", 3, true) var trailing = boolArg(call, "trailing", 3, true)
result = LLStreamOpen("") result = LLStreamOpen("")
while not LLStreamAtEnd(stdin): var line = newStringOfCap(80)
var line = LLStreamReadLine(stdin) while LLStreamReadLine(stdin, line):
var stripped = strip(line, leading, trailing) var stripped = strip(line, leading, trailing)
if (len(pattern) == 0) or startsWith(stripped, pattern): if (len(pattern) == 0) or startsWith(stripped, pattern):
LLStreamWriteln(result, stripped) LLStreamWriteln(result, stripped)
@ -73,7 +73,7 @@ proc filterReplace(stdin: PLLStream, filename: string, call: PNode): PLLStream =
if len(sub) == 0: invalidPragma(call) if len(sub) == 0: invalidPragma(call)
var by = strArg(call, "by", 2, "") var by = strArg(call, "by", 2, "")
result = LLStreamOpen("") result = LLStreamOpen("")
while not LLStreamAtEnd(stdin): var line = newStringOfCap(80)
var line = LLStreamReadLine(stdin) while LLStreamReadLine(stdin, line):
LLStreamWriteln(result, replace(line, sub, by)) LLStreamWriteln(result, replace(line, sub, by))
LLStreamClose(stdin) LLStreamClose(stdin)

View file

@ -23,7 +23,7 @@ when debugIds:
proc registerID*(id: PIdObj) = proc registerID*(id: PIdObj) =
when debugIDs: when debugIDs:
if (id.id == - 1) or ContainsOrIncl(usedIds, id.id): if id.id == -1 or ContainsOrIncl(usedIds, id.id):
InternalError("ID already used: " & $id.id) InternalError("ID already used: " & $id.id)
proc getID*(): int {.inline.} = proc getID*(): int {.inline.} =
@ -55,9 +55,12 @@ proc saveMaxIds*(project: string) =
proc loadMaxIds*(project: string) = proc loadMaxIds*(project: string) =
var f: TFile var f: TFile
if open(f, project.toGid, fmRead): if open(f, project.toGid, fmRead):
var frontEndId = parseInt(f.readLine) var line = newStringOfCap(20)
var backEndId = parseInt(f.readLine) if f.readLine(line):
gFrontEndId = max(gFrontEndId, frontEndId) var frontEndId = parseInt(line)
gBackEndId = max(gBackEndId, backEndId) if f.readLine(line):
var backEndId = parseInt(line)
gFrontEndId = max(gFrontEndId, frontEndId)
gBackEndId = max(gBackEndId, backEndId)
f.close() f.close()

View file

@ -16,11 +16,11 @@ when not defined(windows) and defined(useGnuReadline):
import rdstdin import rdstdin
type type
TLLStreamKind* = enum # stream encapsulates stdin TLLStreamKind* = enum # enum of different stream implementations
llsNone, # null stream: reading and writing has no effect llsNone, # null stream: reading and writing has no effect
llsString, # stream encapsulates a string llsString, # stream encapsulates a string
llsFile, # stream encapsulates a file llsFile, # stream encapsulates a file
llsStdIn llsStdIn # stream encapsulates stdin
TLLStream* = object of TObject TLLStream* = object of TObject
kind*: TLLStreamKind # accessible for low-level access (lexbase uses this) kind*: TLLStreamKind # accessible for low-level access (lexbase uses this)
f*: tfile f*: tfile
@ -37,13 +37,12 @@ proc LLStreamOpen*(): PLLStream
proc LLStreamOpenStdIn*(): PLLStream proc LLStreamOpenStdIn*(): PLLStream
proc LLStreamClose*(s: PLLStream) proc LLStreamClose*(s: PLLStream)
proc LLStreamRead*(s: PLLStream, buf: pointer, bufLen: int): int proc LLStreamRead*(s: PLLStream, buf: pointer, bufLen: int): int
proc LLStreamReadLine*(s: PLLStream): string proc LLStreamReadLine*(s: PLLStream, line: var string): bool
proc LLStreamReadAll*(s: PLLStream): string proc LLStreamReadAll*(s: PLLStream): string
proc LLStreamWrite*(s: PLLStream, data: string) proc LLStreamWrite*(s: PLLStream, data: string)
proc LLStreamWrite*(s: PLLStream, data: Char) proc LLStreamWrite*(s: PLLStream, data: Char)
proc LLStreamWrite*(s: PLLStream, buf: pointer, buflen: int) proc LLStreamWrite*(s: PLLStream, buf: pointer, buflen: int)
proc LLStreamWriteln*(s: PLLStream, data: string) proc LLStreamWriteln*(s: PLLStream, data: string)
proc LLStreamAtEnd*(s: PLLStream): bool
# implementation # implementation
proc LLStreamOpen(data: string): PLLStream = proc LLStreamOpen(data: string): PLLStream =
@ -80,9 +79,9 @@ proc LLStreamClose(s: PLLStream) =
when not defined(ReadLineFromStdin): when not defined(ReadLineFromStdin):
# fallback implementation: # fallback implementation:
proc ReadLineFromStdin(prompt: string): string = proc ReadLineFromStdin(prompt: string, line: var string): bool =
stdout.write(prompt) stdout.write(prompt)
result = readLine(stdin) result = readLine(stdin, line)
proc endsWith*(x: string, s: set[char]): bool = proc endsWith*(x: string, s: set[char]): bool =
var i = x.len-1 var i = x.len-1
@ -95,8 +94,8 @@ const
'|', '%', '&', '$', '@', '~', ','} '|', '%', '&', '$', '@', '~', ','}
AdditionalLineContinuationOprs = {'#', ':', '='} AdditionalLineContinuationOprs = {'#', ':', '='}
proc endsWithOpr*(x: string): bool = proc endsWithOpr*(x: string): bool =
# also used be the standard template filter: # also used by the standard template filter:
result = x.endsWith(LineContinuationOprs) result = x.endsWith(LineContinuationOprs)
proc continueLine(line: string, inTripleString: bool): bool {.inline.} = proc continueLine(line: string, inTripleString: bool): bool {.inline.} =
@ -105,15 +104,11 @@ proc continueLine(line: string, inTripleString: bool): bool {.inline.} =
line.endsWith(LineContinuationOprs+AdditionalLineContinuationOprs) line.endsWith(LineContinuationOprs+AdditionalLineContinuationOprs)
proc LLreadFromStdin(s: PLLStream, buf: pointer, bufLen: int): int = proc LLreadFromStdin(s: PLLStream, buf: pointer, bufLen: int): int =
var var inTripleString = false
line: string
L: int
inTripleString = false
s.s = "" s.s = ""
s.rd = 0 s.rd = 0
while true: var line = newStringOfCap(120)
line = ReadLineFromStdin(if s.s.len == 0: ">>> " else: "... ") while ReadLineFromStdin(if s.s.len == 0: ">>> " else: "... ", line):
L = len(line)
add(s.s, line) add(s.s, line)
add(s.s, "\n") add(s.s, "\n")
if line.contains("\"\"\""): if line.contains("\"\"\""):
@ -139,36 +134,30 @@ proc LLStreamRead(s: PLLStream, buf: pointer, bufLen: int): int =
of llsStdIn: of llsStdIn:
result = LLreadFromStdin(s, buf, bufLen) result = LLreadFromStdin(s, buf, bufLen)
proc LLStreamReadLine(s: PLLStream): string = proc LLStreamReadLine(s: PLLStream, line: var string): bool =
setLen(line, 0)
case s.kind case s.kind
of llsNone: of llsNone:
result = "" result = true
of llsString: of llsString:
result = "" while s.rd < len(s.s):
while s.rd < len(s.s): case s.s[s.rd]
case s.s[s.rd + 0] of '\x0D':
of '\x0D':
inc(s.rd) inc(s.rd)
if s.s[s.rd + 0] == '\x0A': inc(s.rd) if s.s[s.rd] == '\x0A': inc(s.rd)
break break
of '\x0A': of '\x0A':
inc(s.rd) inc(s.rd)
break break
else: else:
add(result, s.s[s.rd + 0]) add(line, s.s[s.rd])
inc(s.rd) inc(s.rd)
of llsFile: result = line.len > 0 or s.rd < len(s.s)
result = readLine(s.f) of llsFile:
of llsStdIn: result = readLine(s.f, line)
result = readLine(stdin) of llsStdIn:
result = readLine(stdin, line)
proc LLStreamAtEnd(s: PLLStream): bool =
case s.kind
of llsNone: result = true
of llsString: result = s.rd >= len(s.s)
of llsFile: result = endOfFile(s.f)
of llsStdIn: result = false
proc LLStreamWrite(s: PLLStream, data: string) = proc LLStreamWrite(s: PLLStream, data: string) =
case s.kind case s.kind
of llsNone, llsStdIn: of llsNone, llsStdIn:

View file

@ -89,12 +89,13 @@ proc parsePipe(filename: string, inputStream: PLLStream): PNode =
result = ast.emptyNode result = ast.emptyNode
var s = LLStreamOpen(filename, fmRead) var s = LLStreamOpen(filename, fmRead)
if s != nil: if s != nil:
var line = LLStreamReadLine(s) var line = newStringOfCap(80)
discard LLStreamReadLine(s, line)
var i = UTF8_Bom(line) var i = UTF8_Bom(line)
if containsShebang(line, i): if containsShebang(line, i):
line = LLStreamReadLine(s) discard LLStreamReadLine(s, line)
i = 0 i = 0
if (line[i] == '#') and (line[i + 1] == '!'): if line[i] == '#' and line[i+1] == '!':
inc(i, 2) inc(i, 2)
while line[i] in WhiteSpace: inc(i) while line[i] in WhiteSpace: inc(i)
var q: TParser var q: TParser

View file

@ -14,15 +14,25 @@
## wanted functionality. ## wanted functionality.
when defined(Windows): when defined(Windows):
proc ReadLineFromStdin*(prompt: string): TaintedString = proc ReadLineFromStdin*(prompt: string): TaintedString {.deprecated.} =
## Reads a line from stdin. ## Reads a line from stdin.
stdout.write(prompt) stdout.write(prompt)
result = readLine(stdin) result = readLine(stdin)
proc ReadLineFromStdin*(prompt: string, line: var TaintedString): bool =
## Reads a `line` from stdin. `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.
stdout.write(prompt)
result = readLine(stdin, line)
else: else:
import readline, history import readline, history
proc ReadLineFromStdin*(prompt: string): TaintedString = proc ReadLineFromStdin*(prompt: string): TaintedString {.deprecated.} =
var buffer = readline.readLine(prompt) var buffer = readline.readLine(prompt)
if isNil(buffer): quit(0) if isNil(buffer): quit(0)
result = TaintedString($buffer) result = TaintedString($buffer)
@ -30,6 +40,16 @@ else:
add_history(buffer) add_history(buffer)
readline.free(buffer) readline.free(buffer)
proc ReadLineFromStdin*(prompt: string, line: var TaintedString): bool =
var buffer = readline.readLine(prompt)
if isNil(buffer): quit(0)
line = TaintedString($buffer)
if line.string.len > 0:
add_history(buffer)
readline.free(buffer)
# XXX how to determine CTRL+D?
result = true
# initialization: # initialization:
# disable auto-complete: # disable auto-complete:
proc doNothing(a, b: cint): cint {.cdecl, procvar.} = nil proc doNothing(a, b: cint): cint {.cdecl, procvar.} = nil

View file

@ -150,19 +150,6 @@ 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 {.deprecated.} =
## Reads a line from a stream `s`. Note: This is not very efficient. Raises
## `EIO` if an error occured.
## **Deprecated since version 0.8.14**: Because Posix supports it poorly.
result = TaintedString""
while not atEnd(s):
var c = readChar(s)
if c == '\c':
c = readChar(s)
break
elif c == '\L' or c == '\0': break
result.string.add(c)
proc readLine*(s: PStream, line: var TaintedString): bool = proc readLine*(s: PStream, line: var TaintedString): bool =
## reads a line of text from the stream `s` into `line`. `line` must not be ## reads a line of text from the stream `s` into `line`. `line` must not be
## ``nil``! May throw an IO exception. ## ``nil``! May throw an IO exception.
@ -183,6 +170,19 @@ proc readLine*(s: PStream, line: var TaintedString): bool =
line.string.add(c) line.string.add(c)
result = true result = true
proc readLine*(s: PStream): TaintedString {.deprecated.} =
## Reads a line from a stream `s`. Note: This is not very efficient. Raises
## `EIO` if an error occured.
## **Deprecated since version 0.8.14**: Because Posix supports it poorly.
result = TaintedString""
while true:
var c = readChar(s)
if c == '\c':
c = readChar(s)
break
elif c == '\L' or c == '\0': break
result.string.add(c)
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