diff options
Diffstat (limited to 'lib')
-rwxr-xr-x | lib/pure/osproc.nim | 12 | ||||
-rw-r--r-- | lib/pure/romans.nim | 59 | ||||
-rwxr-xr-x | lib/pure/streams.nim | 34 |
3 files changed, 86 insertions, 19 deletions
diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index d74cf1fdc..de5317717 100755 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -232,10 +232,11 @@ when defined(Windows) and not defined(useNimRtl): handle: THandle atTheEnd: bool - proc hsClose(s: PFileHandleStream) = nil # nothing to do here - proc hsAtEnd(s: PFileHandleStream): bool = return s.atTheEnd + proc hsClose(s: PStream) = nil # nothing to do here + proc hsAtEnd(s: PStream): bool = return PFileHandleStream(s).atTheEnd - proc hsReadData(s: PFileHandleStream, buffer: pointer, bufLen: int): int = + proc hsReadData(s: PStream, buffer: pointer, bufLen: int): int = + var s = PFileHandleStream(s) if s.atTheEnd: return 0 var br: int32 var a = winlean.ReadFile(s.handle, buffer, bufLen, br, nil) @@ -246,7 +247,8 @@ when defined(Windows) and not defined(useNimRtl): s.atTheEnd = br < bufLen result = br - proc hsWriteData(s: PFileHandleStream, buffer: pointer, bufLen: int) = + proc hsWriteData(s: PStream, buffer: pointer, bufLen: int) = + var s = PFileHandleStream(s) var bytesWritten: int32 var a = winlean.writeFile(s.handle, buffer, bufLen, bytesWritten, nil) if a == 0: OSError() @@ -507,7 +509,7 @@ elif not defined(useNimRtl): quit("execve call failed: " & $strerror(errno)) # Parent process. Copy process information. if poEchoCmd in options: - echo(command & " " & join(args, " ")) + echo(command, " ", join(args, " ")) result.id = pid result.inputHandle = p_stdin[writeIdx] diff --git a/lib/pure/romans.nim b/lib/pure/romans.nim new file mode 100644 index 000000000..dee3226d8 --- /dev/null +++ b/lib/pure/romans.nim @@ -0,0 +1,59 @@ +# +# +# Nimrod's Runtime Library +# (c) Copyright 2011 Philippe Lhoste +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## Module for converting an integer to a Roman numeral. +## See http://en.wikipedia.org/wiki/Roman_numerals for reference. + +const + RomanNumeralDigits* = {'I', 'i', 'V', 'v', 'X', 'x', 'L', 'l', 'C', 'c', + 'D', 'd', 'M', 'm'} ## set of all characters a Roman numeral may consist of + +proc romanToDecimal*(romanVal: string): int = + ## Converts a Roman numeral to its int representation. + result = 0 + var prevVal = 0 + for i in countdown(romanVal.len - 1, 0): + var val = 0 + case romanVal[i] + of 'I', 'i': val = 1 + of 'V', 'v': val = 5 + of 'X', 'x': val = 10 + of 'L', 'l': val = 50 + of 'C', 'c': val = 100 + of 'D', 'd': val = 500 + of 'M', 'm': val = 1000 + else: + raise newException(EInvalidValue, "invalid roman numeral: " & $romanVal) + if val >= prevVal: + inc(result, val) + else: + dec(result, val) + prevVal = val + +proc decimalToRoman*(number: range[1..3_999]): string = + ## Converts a number to a Roman numeral. + const romanComposites = [ + ("M", 1000), ("CM", 900), + ("D", 500), ("CD", 400), ("C", 100), + ("XC", 90), ("L", 50), ("XL", 40), ("X", 10), ("IX", 9), + ("V", 5), ("IV", 4), ("I", 1)] + result = "" + var decVal = number + for key, val in items(romanComposites): + while decVal >= val: + dec(decVal, val) + result.add(key) + +when isMainModule: + import math + randomize() + for i in 1 .. 100: + var rnd = 1 + random(3990) + assert rnd == rnd.decimalToRoman.romanToDecimal + diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim index f4d2911fc..d0e6ecec7 100755 --- a/lib/pure/streams.nim +++ b/lib/pure/streams.nim @@ -104,28 +104,34 @@ type data*: string pos: int -proc ssAtEnd(s: PStringStream): bool = +proc ssAtEnd(s: PStream): bool = + var s = PStringStream(s) return s.pos >= s.data.len -proc ssSetPosition(s: PStringStream, pos: int) = +proc ssSetPosition(s: PStream, pos: int) = + var s = PStringStream(s) s.pos = min(pos, s.data.len-1) -proc ssGetPosition(s: PStringStream): int = +proc ssGetPosition(s: PStream): int = + var s = PStringStream(s) return s.pos -proc ssReadData(s: PStringStream, buffer: pointer, bufLen: int): int = +proc ssReadData(s: PStream, buffer: pointer, bufLen: int): int = + var s = PStringStream(s) result = min(bufLen, s.data.len - s.pos) if result > 0: copyMem(buffer, addr(s.data[s.pos]), result) inc(s.pos, result) -proc ssWriteData(s: PStringStream, buffer: pointer, bufLen: int) = +proc ssWriteData(s: PStream, buffer: pointer, bufLen: int) = + var s = PStringStream(s) if bufLen > 0: setLen(s.data, s.data.len + bufLen) copyMem(addr(s.data[s.pos]), buffer, bufLen) inc(s.pos, bufLen) -proc ssClose(s: PStringStream) = +proc ssClose(s: PStream) = + var s = PStringStream(s) s.data = nil proc newStringStream*(s: string = ""): PStringStream = @@ -145,16 +151,16 @@ type TFileStream* = object of TStream f: TFile -proc fsClose(s: PFileStream) = close(s.f) -proc fsAtEnd(s: PFileStream): bool = return EndOfFile(s.f) -proc fsSetPosition(s: PFileStream, pos: int) = setFilePos(s.f, pos) -proc fsGetPosition(s: PFileStream): int = return int(getFilePos(s.f)) +proc fsClose(s: PStream) = close(PFileStream(s).f) +proc fsAtEnd(s: PStream): bool = return EndOfFile(PFileStream(s).f) +proc fsSetPosition(s: PStream, pos: int) = setFilePos(PFileStream(s).f, pos) +proc fsGetPosition(s: PStream): int = return int(getFilePos(PFileStream(s).f)) -proc fsReadData(s: PFileStream, buffer: pointer, bufLen: int): int = - result = readBuffer(s.f, buffer, bufLen) +proc fsReadData(s: PStream, buffer: pointer, bufLen: int): int = + result = readBuffer(PFileStream(s).f, buffer, bufLen) -proc fsWriteData(s: PFileStream, buffer: pointer, bufLen: int) = - if writeBuffer(s.f, buffer, bufLen) != bufLen: +proc fsWriteData(s: PStream, buffer: pointer, bufLen: int) = + if writeBuffer(PFileStream(s).f, buffer, bufLen) != bufLen: raise newEIO("cannot write to stream") proc newFileStream*(f: TFile): PFileStream = |