diff options
Diffstat (limited to 'lib')
71 files changed, 1270 insertions, 2311 deletions
diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 8c70d2b47..fc5b5bfb7 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -129,13 +129,6 @@ const nnkCallKinds* = {nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand, nnkCallStrLit} -proc `[]`*(n: NimNode, i: int): NimNode {.magic: "NChild", noSideEffect.} - ## get `n`'s `i`'th child. - -proc `[]=`*(n: NimNode, i: int, child: NimNode) {.magic: "NSetChild", - noSideEffect.} - ## set `n`'s `i`'th child to `child`. - proc `!`*(s: string): NimIdent {.magic: "StrToIdent", noSideEffect.} ## constructs an identifier from the string `s` @@ -162,6 +155,20 @@ proc sameType*(a, b: NimNode): bool {.magic: "SameNodeType", noSideEffect.} = proc len*(n: NimNode): int {.magic: "NLen", noSideEffect.} ## returns the number of children of `n`. +proc `[]`*(n: NimNode, i: int): NimNode {.magic: "NChild", noSideEffect.} + ## get `n`'s `i`'th child. + +proc `[]`*(n: NimNode, i: BackwardsIndex): NimNode = n[n.len - i.int] + ## get `n`'s `i`'th child. + +proc `[]=`*(n: NimNode, i: int, child: NimNode) {.magic: "NSetChild", + noSideEffect.} + ## set `n`'s `i`'th child to `child`. + +proc `[]=`*(n: NimNode, i: BackwardsIndex, child: NimNode) = + ## set `n`'s `i`'th child to `child`. + n[n.len - i.int] = child + proc add*(father, child: NimNode): NimNode {.magic: "NAdd", discardable, noSideEffect, locks: 0.} ## Adds the `child` to the `father` node. Returns the @@ -839,7 +846,7 @@ proc newNilLit*(): NimNode {.compileTime.} = ## New nil literal shortcut result = newNimNode(nnkNilLit) -proc last*(node: NimNode): NimNode {.compileTime.} = node[<node.len] +proc last*(node: NimNode): NimNode {.compileTime.} = node[node.len-1] ## Return the last item in nodes children. Same as `node[^1]` @@ -887,7 +894,7 @@ proc newIfStmt*(branches: varargs[tuple[cond, body: NimNode]]): proc copyChildrenTo*(src, dest: NimNode) {.compileTime.}= ## Copy all children from `src` to `dest` - for i in 0 .. < src.len: + for i in 0 ..< src.len: dest.add src[i].copyNimTree template expectRoutine(node: NimNode) = @@ -986,6 +993,11 @@ iterator items*(n: NimNode): NimNode {.inline.} = for i in 0 ..< n.len: yield n[i] +iterator pairs*(n: NimNode): (int, NimNode) {.inline.} = + ## Iterates over the children of the NimNode ``n`` and its indices. + for i in 0 ..< n.len: + yield (i, n[i]) + iterator children*(n: NimNode): NimNode {.inline.} = ## Iterates over the children of the NimNode ``n``. for i in 0 ..< n.len: @@ -1099,10 +1111,10 @@ proc eqIdent*(node: NimNode; s: string): bool {.compileTime.} = else: result = false -proc hasArgOfName* (params: NimNode; name: string): bool {.compiletime.}= +proc hasArgOfName*(params: NimNode; name: string): bool {.compiletime.}= ## Search nnkFormalParams for an argument. assert params.kind == nnkFormalParams - for i in 1 .. <params.len: + for i in 1 ..< params.len: template node: untyped = params[i] if name.eqIdent( $ node[0]): return true diff --git a/lib/deprecated/pure/actors.nim b/lib/deprecated/pure/actors.nim index 36bd41e9e..17321cc0e 100644 --- a/lib/deprecated/pure/actors.nim +++ b/lib/deprecated/pure/actors.nim @@ -18,7 +18,7 @@ ## var ## a: ActorPool[int, void] ## createActorPool(a) -## for i in 0 .. < 300: +## for i in 0 ..< 300: ## a.spawn(i, proc (x: int) {.thread.} = echo x) ## a.join() ## @@ -133,7 +133,7 @@ proc createActorPool*[In, Out](a: var ActorPool[In, Out], poolSize = 4) = newSeq(a.actors, poolSize) when Out isnot void: open(a.outputs) - for i in 0 .. < a.actors.len: + for i in 0 ..< a.actors.len: a.actors[i] = spawn(poolWorker[In, Out]) proc sync*[In, Out](a: var ActorPool[In, Out], polling=50) = @@ -164,8 +164,8 @@ proc terminate*[In, Out](a: var ActorPool[In, Out]) = ## resources attached to `a`. var t: Task[In, Out] t.shutdown = true - for i in 0.. <a.actors.len: send(a.actors[i].i, t) - for i in 0.. <a.actors.len: join(a.actors[i]) + for i in 0..<a.actors.len: send(a.actors[i].i, t) + for i in 0..<a.actors.len: join(a.actors[i]) when Out isnot void: close(a.outputs) a.actors = nil @@ -227,7 +227,7 @@ when not defined(testing) and isMainModule: var a: ActorPool[int, void] createActorPool(a) - for i in 0 .. < 300: + for i in 0 ..< 300: a.spawn(i, proc (x: int) {.thread.} = echo x) when false: diff --git a/lib/impure/db_postgres.nim b/lib/impure/db_postgres.nim index a42950557..b0d3170f8 100644 --- a/lib/impure/db_postgres.nim +++ b/lib/impure/db_postgres.nim @@ -98,15 +98,18 @@ proc dbFormat(formatstr: SqlQuery, args: varargs[string]): string = var a = 0 if args.len > 0 and not string(formatstr).contains("?"): dbError("""parameter substitution expects "?" """) - for c in items(string(formatstr)): - if c == '?': - if args[a] == nil: - add(result, "NULL") + if args.len == 0: + return string(formatstr) + else: + for c in items(string(formatstr)): + if c == '?': + if args[a] == nil: + add(result, "NULL") + else: + add(result, dbQuote(args[a])) + inc(a) else: - add(result, dbQuote(args[a])) - inc(a) - else: - add(result, c) + add(result, c) proc tryExec*(db: DbConn, query: SqlQuery, args: varargs[string, `$`]): bool {.tags: [ReadDbEffect, WriteDbEffect].} = diff --git a/lib/impure/nre.nim b/lib/impure/nre.nim index 4013182af..3d4afc0ae 100644 --- a/lib/impure/nre.nim +++ b/lib/impure/nre.nim @@ -155,7 +155,7 @@ type ## - ``"abc".match(re"(?<letter>\w)").captures["letter"] == "a"`` ## - ``"abc".match(re"(\w)\w").captures[-1] == "ab"`` ## - ## ``captureBounds[]: Option[Slice[int]]`` + ## ``captureBounds[]: Option[HSlice[int, int]]`` ## gets the bounds of the given capture according to the same rules as ## the above. If the capture is not filled, then ``None`` is returned. ## The bounds are both inclusive. @@ -167,7 +167,7 @@ type ## ``match: string`` ## the full text of the match. ## - ## ``matchBounds: Slice[int]`` + ## ``matchBounds: HSlice[int, int]`` ## the bounds of the match, as in ``captureBounds[]`` ## ## ``(captureBounds|captures).toTable`` @@ -182,9 +182,9 @@ type ## Not nil. str*: string ## The string that was matched against. ## Not nil. - pcreMatchBounds: seq[Slice[cint]] ## First item is the bounds of the match - ## Other items are the captures - ## `a` is inclusive start, `b` is exclusive end + pcreMatchBounds: seq[HSlice[cint, cint]] ## First item is the bounds of the match + ## Other items are the captures + ## `a` is inclusive start, `b` is exclusive end Captures* = distinct RegexMatch CaptureBounds* = distinct RegexMatch @@ -251,13 +251,13 @@ proc captureBounds*(pattern: RegexMatch): CaptureBounds = return CaptureBounds(p proc captures*(pattern: RegexMatch): Captures = return Captures(pattern) -proc `[]`*(pattern: CaptureBounds, i: int): Option[Slice[int]] = +proc `[]`*(pattern: CaptureBounds, i: int): Option[HSlice[int, int]] = let pattern = RegexMatch(pattern) if pattern.pcreMatchBounds[i + 1].a != -1: let bounds = pattern.pcreMatchBounds[i + 1] return some(int(bounds.a) .. int(bounds.b-1)) else: - return none(Slice[int]) + return none(HSlice[int, int]) proc `[]`*(pattern: Captures, i: int): string = let pattern = RegexMatch(pattern) @@ -272,10 +272,10 @@ proc `[]`*(pattern: Captures, i: int): string = proc match*(pattern: RegexMatch): string = return pattern.captures[-1] -proc matchBounds*(pattern: RegexMatch): Slice[int] = +proc matchBounds*(pattern: RegexMatch): HSlice[int, int] = return pattern.captureBounds[-1].get -proc `[]`*(pattern: CaptureBounds, name: string): Option[Slice[int]] = +proc `[]`*(pattern: CaptureBounds, name: string): Option[HSlice[int, int]] = let pattern = RegexMatch(pattern) return pattern.captureBounds[pattern.pattern.captureNameToId.fget(name)] @@ -295,13 +295,13 @@ proc toTable*(pattern: Captures, default: string = nil): Table[string, string] = result = initTable[string, string]() toTableImpl(nextVal == nil) -proc toTable*(pattern: CaptureBounds, default = none(Slice[int])): - Table[string, Option[Slice[int]]] = - result = initTable[string, Option[Slice[int]]]() +proc toTable*(pattern: CaptureBounds, default = none(HSlice[int, int])): + Table[string, Option[HSlice[int, int]]] = + result = initTable[string, Option[HSlice[int, int]]]() toTableImpl(nextVal.isNone) template itemsImpl(cond: untyped) {.dirty.} = - for i in 0 .. <RegexMatch(pattern).pattern.captureCount: + for i in 0 ..< RegexMatch(pattern).pattern.captureCount: let nextVal = pattern[i] # done in this roundabout way to avoid multiple yields (potential code # bloat) @@ -309,13 +309,13 @@ template itemsImpl(cond: untyped) {.dirty.} = yield nextYieldVal -iterator items*(pattern: CaptureBounds, default = none(Slice[int])): Option[Slice[int]] = +iterator items*(pattern: CaptureBounds, default = none(HSlice[int, int])): Option[HSlice[int, int]] = itemsImpl(nextVal.isNone) iterator items*(pattern: Captures, default: string = nil): string = itemsImpl(nextVal == nil) -proc toSeq*(pattern: CaptureBounds, default = none(Slice[int])): seq[Option[Slice[int]]] = +proc toSeq*(pattern: CaptureBounds, default = none(HSlice[int, int])): seq[Option[HSlice[int, int]]] = accumulateResult(pattern.items(default)) proc toSeq*(pattern: Captures, default: string = nil): seq[string] = @@ -396,8 +396,6 @@ proc extractOptions(pattern: string): tuple[pattern: string, flags: int, study: # }}} -type UncheckedArray {.unchecked.}[T] = array[0 .. 0, T] - proc destroyRegex(pattern: Regex) = pcre.free_substring(cast[cstring](pattern.pcreObj)) pattern.pcreObj = nil @@ -412,7 +410,7 @@ proc getNameToNumberTable(pattern: Regex): Table[string, int] = result = initTable[string, int]() - for i in 0 .. <entryCount: + for i in 0 ..< entryCount: let pos = i * entrySize let num = (int(table[pos]) shl 8) or int(table[pos + 1]) - 1 var name = "" @@ -464,7 +462,7 @@ proc matchImpl(str: string, pattern: Regex, start, endpos: int, flags: int): Opt # 1x capture count as slack space for PCRE let vecsize = (pattern.captureCount() + 1) * 3 # div 2 because each element is 2 cints long - myResult.pcreMatchBounds = newSeq[Slice[cint]](ceil(vecsize / 2).int) + myResult.pcreMatchBounds = newSeq[HSlice[cint, cint]](ceil(vecsize / 2).int) myResult.pcreMatchBounds.setLen(vecsize div 3) let strlen = if endpos == int.high: str.len else: endpos+1 diff --git a/lib/impure/re.nim b/lib/impure/re.nim index e00f91de1..24fc83366 100644 --- a/lib/impure/re.nim +++ b/lib/impure/re.nim @@ -13,10 +13,6 @@ ## We had to de-deprecate this module since too much code relies on it ## and many people prefer its API over ``nre``'s. ## -## **Note:** The 're' proc defaults to the **extended regular expression -## syntax** which lets you use whitespace freely to make your regexes readable. -## However, this means matching whitespace requires ``\s`` or something similar. -## ## This module is implemented by providing a wrapper around the ## `PRCE (Perl-Compatible Regular Expressions) <http://www.pcre.org>`_ ## C library. This means that your application will depend on the PRCE @@ -78,7 +74,7 @@ proc finalizeRegEx(x: Regex) = if not isNil(x.e): pcre.free_substring(cast[cstring](x.e)) -proc re*(s: string, flags = {reExtended, reStudy}): Regex = +proc re*(s: string, flags = {reStudy}): Regex = ## Constructor of regular expressions. ## ## Note that Nim's @@ -96,6 +92,13 @@ proc re*(s: string, flags = {reExtended, reStudy}): Regex = result.e = pcre.study(result.h, options, addr msg) if not isNil(msg): raiseInvalidRegex($msg) +proc rex*(s: string, flags = {reStudy, reExtended}): Regex = + ## Constructor for extended regular expressions. + ## + ## The extended means that comments starting with `#` and + ## whitespace are ignored. + result = re(s, flags) + proc bufSubstr(b: cstring, sPos, ePos: int): string {.inline.} = ## Return a Nim string built from a slice of a cstring buffer. ## Don't assume cstring is '\0' terminated diff --git a/lib/impure/ssl.nim b/lib/impure/ssl.nim index e3312d792..5b0e899f6 100644 --- a/lib/impure/ssl.nim +++ b/lib/impure/ssl.nim @@ -63,16 +63,16 @@ proc recvLine*(sock: SecureSocket, line: var TaintedString): bool = setLen(line.string, 0) while true: var c: array[0..0, char] - var n = BIO_read(sock.bio, c, c.len.cint) + var n = BIO_read(sock.bio, addr c, c.len.cint) if n <= 0: return false if c[0] == '\r': - n = BIO_read(sock.bio, c, c.len.cint) + n = BIO_read(sock.bio, addr c, c.len.cint) if n > 0 and c[0] == '\L': return true elif n <= 0: return false elif c[0] == '\L': return true - add(line.string, c) + add(line.string, c[0]) proc send*(sock: SecureSocket, data: string) = diff --git a/lib/nimbase.h b/lib/nimbase.h index 34a2e43e7..76192713b 100644 --- a/lib/nimbase.h +++ b/lib/nimbase.h @@ -396,15 +396,13 @@ typedef struct TStringDesc* string; #define GenericSeqSize sizeof(TGenericSeq) #define paramCount() cmdCount -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__i386__) -# ifndef NAN -static unsigned long nimNaN[2]={0xffffffff, 0x7fffffff}; -# define NAN (*(double*) nimNaN) -# endif -#endif - +// NAN definition copied from math.h included in the Windows SDK version 10.0.14393.0 #ifndef NAN -# define NAN (0.0 / 0.0) +#ifndef _HUGE_ENUF +#define _HUGE_ENUF 1e+300 // _HUGE_ENUF*_HUGE_ENUF must overflow +#endif +#define NAN_INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF)) +#define NAN ((float)(NAN_INFINITY * 0.0F)) #endif #ifndef INF diff --git a/lib/posix/linux.nim b/lib/posix/linux.nim index 01d5e57de..8786ab535 100644 --- a/lib/posix/linux.nim +++ b/lib/posix/linux.nim @@ -26,3 +26,5 @@ const proc clone*(fn: pointer; child_stack: pointer; flags: cint; arg: pointer; ptid: ptr Pid; tls: pointer; ctid: ptr Pid): cint {.importc, header: "<sched.h>".} + +proc pipe2*(a: array[0..1, cint], flags: cint): cint {.importc, header: "<unistd.h>".} \ No newline at end of file diff --git a/lib/posix/posix_other.nim b/lib/posix/posix_other.nim index 69f6acfb8..7321889a8 100644 --- a/lib/posix/posix_other.nim +++ b/lib/posix/posix_other.nim @@ -146,7 +146,7 @@ type Mode* {.importc: "mode_t", header: "<sys/types.h>".} = cint Nlink* {.importc: "nlink_t", header: "<sys/types.h>".} = int Off* {.importc: "off_t", header: "<sys/types.h>".} = int64 - Pid* {.importc: "pid_t", header: "<sys/types.h>".} = int + Pid* {.importc: "pid_t", header: "<sys/types.h>".} = int32 Pthread_attr* {.importc: "pthread_attr_t", header: "<sys/types.h>".} = int Pthread_barrier* {.importc: "pthread_barrier_t", header: "<sys/types.h>".} = int diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim index 9eee04404..fdf2d7cbb 100644 --- a/lib/pure/algorithm.nim +++ b/lib/pure/algorithm.nim @@ -371,3 +371,126 @@ when isMainModule: for i in 0 .. high(arr1): assert arr1.reversed(0, i) == arr1.reversed()[high(arr1) - i .. high(arr1)] assert arr1.reversed(i, high(arr1)) == arr1.reversed()[0 .. high(arr1) - i] + + +proc rotateInternal[T](arg: var openarray[T]; first, middle, last: int): int = + ## A port of std::rotate from c++. Ported from `this reference <http://www.cplusplus.com/reference/algorithm/rotate/>`_. + result = first + last - middle + + if first == middle or middle == last: + return + + assert first < middle + assert middle < last + + # m prefix for mutable + var + mFirst = first + mMiddle = middle + next = middle + + swap(arg[mFirst], arg[next]) + mFirst += 1 + next += 1 + if mFirst == mMiddle: + mMiddle = next + + while next != last: + swap(arg[mFirst], arg[next]) + mFirst += 1 + next += 1 + if mFirst == mMiddle: + mMiddle = next + + next = mMiddle + while next != last: + swap(arg[mFirst], arg[next]) + mFirst += 1 + next += 1 + if mFirst == mMiddle: + mMiddle = next + elif next == last: + next = mMiddle + +proc rotatedInternal[T](arg: openarray[T]; first, middle, last: int): seq[T] = + result = newSeq[T](arg.len) + for i in 0 ..< first: + result[i] = arg[i] + let N = last - middle + let M = middle - first + for i in 0 ..< N: + result[first+i] = arg[middle+i] + for i in 0 ..< M: + result[first+N+i] = arg[first+i] + for i in last ..< arg.len: + result[i] = arg[i] + +proc rotateLeft*[T](arg: var openarray[T]; slice: HSlice[int, int]; dist: int): int = + ## Performs a left rotation on a range of elements. If you want to rotate right, use a negative ``dist``. + ## Specifically, ``rotateLeft`` rotates the elements at ``slice`` by ``dist`` positions. + ## The element at index ``slice.a + dist`` will be at index ``slice.a``. + ## The element at index ``slice.b`` will be at ``slice.a + dist -1``. + ## The element at index ``slice.a`` will be at ``slice.b + 1 - dist``. + ## The element at index ``slice.a + dist - 1`` will be at ``slice.b``. + # + ## Elements outsize of ``slice`` will be left unchanged. + ## The time complexity is linear to ``slice.b - slice.a + 1``. + ## + ## ``slice`` + ## the indices of the element range that should be rotated. + ## + ## ``dist`` + ## the distance in amount of elements that the data should be rotated. Can be negative, can be any number. + ## + ## .. code-block:: nim + ## var list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + ## list.rotateLeft(1 .. 8, 3) + ## doAssert list == [0, 4, 5, 6, 7, 8, 1, 2, 3, 9, 10] + let sliceLen = slice.b + 1 - slice.a + let distLeft = ((dist mod sliceLen) + sliceLen) mod sliceLen + arg.rotateInternal(slice.a, slice.a+distLeft, slice.b + 1) + +proc rotateLeft*[T](arg: var openarray[T]; dist: int): int = + ## default arguments for slice, so that this procedure operates on the entire + ## ``arg``, and not just on a part of it. + let arglen = arg.len + let distLeft = ((dist mod arglen) + arglen) mod arglen + arg.rotateInternal(0, distLeft, arglen) + +proc rotatedLeft*[T](arg: openarray[T]; slice: HSlice[int, int], dist: int): seq[T] = + ## same as ``rotateLeft``, just with the difference that it does + ## not modify the argument. It creates a new ``seq`` instead + let sliceLen = slice.b + 1 - slice.a + let distLeft = ((dist mod sliceLen) + sliceLen) mod sliceLen + arg.rotatedInternal(slice.a, slice.a+distLeft, slice.b+1) + +proc rotatedLeft*[T](arg: openarray[T]; dist: int): seq[T] = + ## same as ``rotateLeft``, just with the difference that it does + ## not modify the argument. It creates a new ``seq`` instead + let arglen = arg.len + let distLeft = ((dist mod arglen) + arglen) mod arglen + arg.rotatedInternal(0, distLeft, arg.len) + +when isMainModule: + var list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + let list2 = list.rotatedLeft(1 ..< 9, 3) + let expected = [0, 4, 5, 6, 7, 8, 1, 2, 3, 9, 10] + + doAssert list.rotateLeft(1 ..< 9, 3) == 6 + doAssert list == expected + doAssert list2 == @expected + + var s0,s1,s2,s3,s4,s5 = "xxxabcdefgxxx" + + doAssert s0.rotateLeft(3 ..< 10, 3) == 7 + doAssert s0 == "xxxdefgabcxxx" + doAssert s1.rotateLeft(3 ..< 10, 2) == 8 + doAssert s1 == "xxxcdefgabxxx" + doAssert s2.rotateLeft(3 ..< 10, 4) == 6 + doAssert s2 == "xxxefgabcdxxx" + doAssert s3.rotateLeft(3 ..< 10, -3) == 6 + doAssert s3 == "xxxefgabcdxxx" + doAssert s4.rotateLeft(3 ..< 10, -10) == 6 + doAssert s4 == "xxxefgabcdxxx" + doAssert s5.rotateLeft(3 ..< 10, 11) == 6 + doAssert s5 == "xxxefgabcdxxx" diff --git a/lib/pure/asyncmacro.nim b/lib/pure/asyncmacro.nim index 6e7d7993f..981190211 100644 --- a/lib/pure/asyncmacro.nim +++ b/lib/pure/asyncmacro.nim @@ -61,14 +61,14 @@ proc generateExceptionCheck(futSym, else: var exceptionChecks: seq[tuple[cond, body: NimNode]] = @[] let errorNode = newDotExpr(futSym, newIdentNode("error")) - for i in 1 .. <tryStmt.len: + for i in 1 ..< tryStmt.len: let exceptBranch = tryStmt[i] if exceptBranch[0].kind == nnkStmtList: exceptionChecks.add((newIdentNode("true"), exceptBranch[0])) else: var exceptIdentCount = 0 var ifCond: NimNode - for i in 0 .. <exceptBranch.len: + for i in 0 ..< exceptBranch.len: let child = exceptBranch[i] if child.kind == nnkIdent: let cond = infix(errorNode, "of", child) @@ -270,7 +270,7 @@ proc processBody(node, retFutureSym: NimNode, return else: discard - for i in 0 .. <result.len: + for i in 0 ..< result.len: result[i] = processBody(result[i], retFutureSym, subTypeIsVoid, futureVarIdents, nil) @@ -287,7 +287,7 @@ proc getName(node: NimNode): string {.compileTime.} = proc getFutureVarIdents(params: NimNode): seq[NimNode] {.compileTime.} = result = @[] - for i in 1 .. <len(params): + for i in 1 ..< len(params): expectKind(params[i], nnkIdentDefs) if params[i][1].kind == nnkBracketExpr and ($params[i][1][0].ident).normalize == "futurevar": @@ -466,7 +466,7 @@ proc stripAwait(node: NimNode): NimNode = node[0][0] = emptyNoopSym else: discard - for i in 0 .. <result.len: + for i in 0 ..< result.len: result[i] = stripAwait(result[i]) proc splitParamType(paramType: NimNode, async: bool): NimNode = @@ -512,7 +512,7 @@ proc splitProc(prc: NimNode): (NimNode, NimNode) = # Retrieve the `T` inside `Future[T]`. let returnType = stripReturnType(result[0][3][0]) result[0][3][0] = splitParamType(returnType, async=false) - for i in 1 .. <result[0][3].len: + for i in 1 ..< result[0][3].len: # Sync proc (0) -> FormalParams (3) -> IdentDefs, the parameter (i) -> # parameter type (1). result[0][3][i][1] = splitParamType(result[0][3][i][1], async=false) @@ -521,7 +521,7 @@ proc splitProc(prc: NimNode): (NimNode, NimNode) = result[1] = prc.copyNimTree() if result[1][3][0].kind == nnkBracketExpr: result[1][3][0][1] = splitParamType(result[1][3][0][1], async=true) - for i in 1 .. <result[1][3].len: + for i in 1 ..< result[1][3].len: # Async proc (1) -> FormalParams (3) -> IdentDefs, the parameter (i) -> # parameter type (1). result[1][3][i][1] = splitParamType(result[1][3][i][1], async=true) diff --git a/lib/pure/collections/critbits.nim b/lib/pure/collections/critbits.nim index f70a12843..19f1f2e58 100644 --- a/lib/pure/collections/critbits.nim +++ b/lib/pure/collections/critbits.nim @@ -257,7 +257,7 @@ proc allprefixedAux[T](c: CritBitTree[T], key: string; longestMatch: bool): Node p = p.child[dir] if q.byte < key.len: top = p if not longestMatch: - for i in 0 .. <key.len: + for i in 0 ..< key.len: if p.key[i] != key[i]: return result = top diff --git a/lib/pure/collections/deques.nim b/lib/pure/collections/deques.nim index 1bbe9f1ad..1e0cb82d2 100644 --- a/lib/pure/collections/deques.nim +++ b/lib/pure/collections/deques.nim @@ -207,9 +207,9 @@ when isMainModule: assert($deq == "[4, 56, 6, 789]") assert deq[0] == deq.peekFirst and deq.peekFirst == 4 - assert deq[^1] == deq.peekLast and deq.peekLast == 789 + #assert deq[^1] == deq.peekLast and deq.peekLast == 789 deq[0] = 42 - deq[^1] = 7 + deq[deq.len - 1] = 7 assert 6 in deq and 789 notin deq assert deq.find(6) >= 0 diff --git a/lib/pure/collections/lists.nim b/lib/pure/collections/lists.nim index f847ddd58..560273dfa 100644 --- a/lib/pure/collections/lists.nim +++ b/lib/pure/collections/lists.nim @@ -37,6 +37,14 @@ type DoublyLinkedRing*[T] = object ## a doubly linked ring head*: DoublyLinkedNode[T] + SomeLinkedList*[T] = SinglyLinkedList[T] | DoublyLinkedList[T] + + SomeLinkedRing*[T] = SinglyLinkedRing[T] | DoublyLinkedRing[T] + + SomeLinkedCollection*[T] = SomeLinkedList[T] | SomeLinkedRing[T] + + SomeLinkedNode*[T] = SinglyLinkedNode[T] | DoublyLinkedNode[T] + {.deprecated: [TDoublyLinkedNode: DoublyLinkedNodeObj, PDoublyLinkedNode: DoublyLinkedNode, TSinglyLinkedNode: SinglyLinkedNodeObj, @@ -86,137 +94,57 @@ template itemsRingImpl() {.dirty.} = it = it.next if it == L.head: break -template nodesListImpl() {.dirty.} = - var it = L.head - while it != nil: - var nxt = it.next - yield it - it = nxt - -template nodesRingImpl() {.dirty.} = - var it = L.head - if it != nil: - while true: - var nxt = it.next - yield it - it = nxt - if it == L.head: break - -template findImpl() {.dirty.} = - for x in nodes(L): - if x.value == value: return x - -iterator items*[T](L: DoublyLinkedList[T]): T = +iterator items*[T](L: SomeLinkedList[T]): T = ## yields every value of `L`. itemsListImpl() -iterator items*[T](L: SinglyLinkedList[T]): T = - ## yields every value of `L`. - itemsListImpl() - -iterator items*[T](L: SinglyLinkedRing[T]): T = - ## yields every value of `L`. - itemsRingImpl() - -iterator items*[T](L: DoublyLinkedRing[T]): T = +iterator items*[T](L: SomeLinkedRing[T]): T = ## yields every value of `L`. itemsRingImpl() -iterator mitems*[T](L: var DoublyLinkedList[T]): var T = +iterator mitems*[T](L: var SomeLinkedList[T]): var T = ## yields every value of `L` so that you can modify it. itemsListImpl() -iterator mitems*[T](L: var SinglyLinkedList[T]): var T = - ## yields every value of `L` so that you can modify it. - itemsListImpl() - -iterator mitems*[T](L: var SinglyLinkedRing[T]): var T = +iterator mitems*[T](L: var SomeLinkedRing[T]): var T = ## yields every value of `L` so that you can modify it. itemsRingImpl() -iterator mitems*[T](L: var DoublyLinkedRing[T]): var T = - ## yields every value of `L` so that you can modify it. - itemsRingImpl() - -iterator nodes*[T](L: SinglyLinkedList[T]): SinglyLinkedNode[T] = - ## iterates over every node of `x`. Removing the current node from the - ## list during traversal is supported. - nodesListImpl() - -iterator nodes*[T](L: DoublyLinkedList[T]): DoublyLinkedNode[T] = - ## iterates over every node of `x`. Removing the current node from the - ## list during traversal is supported. - nodesListImpl() - -iterator nodes*[T](L: SinglyLinkedRing[T]): SinglyLinkedNode[T] = +iterator nodes*[T](L: SomeLinkedList[T]): SomeLinkedNode[T] = ## iterates over every node of `x`. Removing the current node from the ## list during traversal is supported. - nodesRingImpl() + var it = L.head + while it != nil: + var nxt = it.next + yield it + it = nxt -iterator nodes*[T](L: DoublyLinkedRing[T]): DoublyLinkedNode[T] = +iterator nodes*[T](L: SomeLinkedRing[T]): SomeLinkedNode[T] = ## iterates over every node of `x`. Removing the current node from the ## list during traversal is supported. - nodesRingImpl() + var it = L.head + if it != nil: + while true: + var nxt = it.next + yield it + it = nxt + if it == L.head: break -template dollarImpl() {.dirty.} = +proc `$`*[T](L: SomeLinkedCollection[T]): string = + ## turns a list into its string representation. result = "[" for x in nodes(L): if result.len > 1: result.add(", ") result.add($x.value) result.add("]") -proc `$`*[T](L: SinglyLinkedList[T]): string = - ## turns a list into its string representation. - dollarImpl() - -proc `$`*[T](L: DoublyLinkedList[T]): string = - ## turns a list into its string representation. - dollarImpl() - -proc `$`*[T](L: SinglyLinkedRing[T]): string = - ## turns a list into its string representation. - dollarImpl() - -proc `$`*[T](L: DoublyLinkedRing[T]): string = - ## turns a list into its string representation. - dollarImpl() - -proc find*[T](L: SinglyLinkedList[T], value: T): SinglyLinkedNode[T] = - ## searches in the list for a value. Returns nil if the value does not - ## exist. - findImpl() - -proc find*[T](L: DoublyLinkedList[T], value: T): DoublyLinkedNode[T] = +proc find*[T](L: SomeLinkedCollection[T], value: T): SomeLinkedNode[T] = ## searches in the list for a value. Returns nil if the value does not ## exist. - findImpl() - -proc find*[T](L: SinglyLinkedRing[T], value: T): SinglyLinkedNode[T] = - ## searches in the list for a value. Returns nil if the value does not - ## exist. - findImpl() - -proc find*[T](L: DoublyLinkedRing[T], value: T): DoublyLinkedNode[T] = - ## searches in the list for a value. Returns nil if the value does not - ## exist. - findImpl() - -proc contains*[T](L: SinglyLinkedList[T], value: T): bool {.inline.} = - ## searches in the list for a value. Returns false if the value does not - ## exist, true otherwise. - result = find(L, value) != nil - -proc contains*[T](L: DoublyLinkedList[T], value: T): bool {.inline.} = - ## searches in the list for a value. Returns false if the value does not - ## exist, true otherwise. - result = find(L, value) != nil - -proc contains*[T](L: SinglyLinkedRing[T], value: T): bool {.inline.} = - ## searches in the list for a value. Returns false if the value does not - ## exist, true otherwise. - result = find(L, value) != nil + for x in nodes(L): + if x.value == value: return x -proc contains*[T](L: DoublyLinkedRing[T], value: T): bool {.inline.} = +proc contains*[T](L: SomeLinkedCollection[T], value: T): bool {.inline.} = ## searches in the list for a value. Returns false if the value does not ## exist, true otherwise. result = find(L, value) != nil @@ -266,7 +194,6 @@ proc remove*[T](L: var DoublyLinkedList[T], n: DoublyLinkedNode[T]) = if n.next != nil: n.next.prev = n.prev if n.prev != nil: n.prev.next = n.next - proc append*[T](L: var SinglyLinkedRing[T], n: SinglyLinkedNode[T]) = ## appends a node `n` to `L`. Efficiency: O(1). if L.head != nil: diff --git a/lib/pure/collections/queues.nim b/lib/pure/collections/queues.nim index 401422162..ce792d6da 100644 --- a/lib/pure/collections/queues.nim +++ b/lib/pure/collections/queues.nim @@ -198,9 +198,8 @@ when isMainModule: assert($q == "[4, 56, 6, 789]") assert q[0] == q.front and q.front == 4 - assert q[^1] == q.back and q.back == 789 q[0] = 42 - q[^1] = 7 + q[q.len - 1] = 7 assert 6 in q and 789 notin q assert q.find(6) >= 0 diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim index e8e725aa3..0eb8e6704 100644 --- a/lib/pure/collections/sequtils.nim +++ b/lib/pure/collections/sequtils.nim @@ -13,8 +13,9 @@ ## were inspired by functional programming languages. ## ## For functional style programming you may want to pass `anonymous procs -## <manual.html#anonymous-procs>`_ to procs like ``filter`` to reduce typing. -## Anonymous procs can use `the special do notation <manual.html#do-notation>`_ +## <manual.html#procedures-anonymous-procs>`_ to procs like ``filter`` to +## reduce typing. Anonymous procs can use `the special do notation +## <manual.html#procedures-do-notation>`_ ## which is more convenient in certain situations. include "system/inclrtl" @@ -43,8 +44,23 @@ proc concat*[T](seqs: varargs[seq[T]]): seq[T] = result[i] = itm inc(i) -proc cycle*[T](s: seq[T], n: Natural): seq[T] = - ## Returns a new sequence with the items of `s` repeated `n` times. +proc count*[T](s: openArray[T], x: T): int = + ## Returns the number of occurrences of the item `x` in the container `s`. + ## + ## Example: + ## + ## .. code-block:: + ## let + ## s = @[1, 2, 2, 3, 2, 4, 2] + ## c = count(s, 2) + ## assert c == 4 + for itm in items(s): + if itm == x: + inc result + +proc cycle*[T](s: openArray[T], n: Natural): seq[T] = + ## Returns a new sequence with the items of the container `s` repeated + ## `n` times. ## ## Example: ## @@ -56,7 +72,7 @@ proc cycle*[T](s: seq[T], n: Natural): seq[T] = ## assert total == @[1, 2, 3, 1, 2, 3, 1, 2, 3] result = newSeq[T](n * s.len) var o = 0 - for x in 0..<n: + for x in 0 ..< n: for e in s: result[o] = e inc o @@ -72,12 +88,14 @@ proc repeat*[T](x: T, n: Natural): seq[T] = ## total = repeat(5, 3) ## assert total == @[5, 5, 5] result = newSeq[T](n) - for i in 0..<n: + for i in 0 ..< n: result[i] = x -proc deduplicate*[T](seq1: seq[T]): seq[T] = +proc deduplicate*[T](s: openArray[T]): seq[T] = ## Returns a new sequence without duplicates. ## + ## Example: + ## ## .. code-block:: ## let ## dup1 = @[1, 1, 3, 4, 2, 2, 8, 1, 4] @@ -87,17 +105,19 @@ proc deduplicate*[T](seq1: seq[T]): seq[T] = ## assert unique1 == @[1, 3, 4, 2, 8] ## assert unique2 == @["a", "c", "d"] result = @[] - for itm in items(seq1): + for itm in items(s): if not result.contains(itm): result.add(itm) {.deprecated: [distnct: deduplicate].} -proc zip*[S, T](seq1: seq[S], seq2: seq[T]): seq[tuple[a: S, b: T]] = - ## Returns a new sequence with a combination of the two input sequences. +proc zip*[S, T](s1: openArray[S], s2: openArray[T]): seq[tuple[a: S, b: T]] = + ## Returns a new sequence with a combination of the two input containers. ## ## For convenience you can access the returned tuples through the named - ## fields `a` and `b`. If one sequence is shorter, the remaining items in the - ## longer sequence are discarded. Example: + ## fields `a` and `b`. If one container is shorter, the remaining items in + ## the longer container are discarded. + ## + ## Example: ## ## .. code-block:: ## let @@ -110,15 +130,16 @@ proc zip*[S, T](seq1: seq[S], seq2: seq[T]): seq[tuple[a: S, b: T]] = ## assert zip2 == @[(1, "one"), (2, "two"), (3, "three")] ## assert zip1[2].b == 4 ## assert zip2[2].b == "three" - var m = min(seq1.len, seq2.len) + var m = min(s1.len, s2.len) newSeq(result, m) - for i in 0 .. m-1: result[i] = (seq1[i], seq2[i]) + for i in 0 ..< m: + result[i] = (s1[i], s2[i]) proc distribute*[T](s: seq[T], num: Positive, spread = true): seq[seq[T]] = ## Splits and distributes a sequence `s` into `num` sub sequences. ## ## Returns a sequence of `num` sequences. For some input values this is the - ## inverse of the `concat <#concat>`_ proc. The proc will assert in debug + ## inverse of the `concat <#concat>`_ proc. The proc will assert in debug ## builds if `s` is nil or `num` is less than one, and will likely crash on ## release builds. The input sequence `s` can be empty, which will produce ## `num` empty sequences. @@ -159,48 +180,52 @@ proc distribute*[T](s: seq[T], num: Positive, spread = true): seq[seq[T]] = # Use an algorithm which overcounts the stride and minimizes reading limits. if extra > 0: inc(stride) - for i in 0 .. <num: + for i in 0 ..< num: result[i] = newSeq[T]() - for g in first .. <min(s.len, first + stride): + for g in first ..< min(s.len, first + stride): result[i].add(s[g]) first += stride else: # Use an undercounting algorithm which *adds* the remainder each iteration. - for i in 0 .. <num: + for i in 0 ..< num: last = first + stride if extra > 0: extra -= 1 inc(last) result[i] = newSeq[T]() - for g in first .. <last: + for g in first ..< last: result[i].add(s[g]) first = last - -proc map*[T, S](data: openArray[T], op: proc (x: T): S {.closure.}): +proc map*[T, S](s: openArray[T], op: proc (x: T): S {.closure.}): seq[S]{.inline.} = ## Returns a new sequence with the results of `op` applied to every item in - ## `data`. + ## the container `s`. ## ## Since the input is not modified you can use this version of ``map`` to - ## transform the type of the elements in the input sequence. Example: + ## transform the type of the elements in the input container. + ## + ## Example: ## ## .. code-block:: nim ## let ## a = @[1, 2, 3, 4] ## b = map(a, proc(x: int): string = $x) ## assert b == @["1", "2", "3", "4"] - newSeq(result, data.len) - for i in 0..data.len-1: result[i] = op(data[i]) + newSeq(result, s.len) + for i in 0 ..< s.len: + result[i] = op(s[i]) -proc map*[T](data: var openArray[T], op: proc (x: var T) {.closure.}) +proc map*[T](s: var openArray[T], op: proc (x: var T) {.closure.}) {.deprecated.} = - ## Applies `op` to every item in `data` modifying it directly. + ## Applies `op` to every item in `s` modifying it directly. ## ## Note that this version of ``map`` requires your input and output types to - ## be the same, since they are modified in-place. Example: + ## be the same, since they are modified in-place. + ## + ## Example: ## ## .. code-block:: nim ## var a = @["1", "2", "3", "4"] @@ -210,15 +235,16 @@ proc map*[T](data: var openArray[T], op: proc (x: var T) {.closure.}) ## echo repr(a) ## # --> ["142", "242", "342", "442"] ## **Deprecated since version 0.12.0:** Use the ``apply`` proc instead. - for i in 0..data.len-1: op(data[i]) + for i in 0 ..< s.len: op(s[i]) -proc apply*[T](data: var seq[T], op: proc (x: var T) {.closure.}) +proc apply*[T](s: var openArray[T], op: proc (x: var T) {.closure.}) {.inline.} = - ## Applies `op` to every item in `data` modifying it directly. + ## Applies `op` to every item in `s` modifying it directly. ## ## Note that this requires your input and output types to ## be the same, since they are modified in-place. ## The parameter function takes a ``var T`` type parameter. + ## ## Example: ## ## .. code-block:: nim @@ -229,15 +255,16 @@ proc apply*[T](data: var seq[T], op: proc (x: var T) {.closure.}) ## echo repr(a) ## # --> ["142", "242", "342", "442"] ## - for i in 0..data.len-1: op(data[i]) + for i in 0 ..< s.len: op(s[i]) -proc apply*[T](data: var seq[T], op: proc (x: T): T {.closure.}) +proc apply*[T](s: var openArray[T], op: proc (x: T): T {.closure.}) {.inline.} = - ## Applies `op` to every item in `data` modifying it directly. + ## Applies `op` to every item in `s` modifying it directly. ## ## Note that this requires your input and output types to ## be the same, since they are modified in-place. ## The parameter function takes and returns a ``T`` type variable. + ## ## Example: ## ## .. code-block:: nim @@ -248,11 +275,10 @@ proc apply*[T](data: var seq[T], op: proc (x: T): T {.closure.}) ## echo repr(a) ## # --> ["142", "242", "342", "442"] ## - for i in 0..data.len-1: data[i] = op(data[i]) + for i in 0 ..< s.len: s[i] = op(s[i]) - -iterator filter*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): T = - ## Iterates through a sequence and yields every item that fulfills the +iterator filter*[T](s: openArray[T], pred: proc(x: T): bool {.closure.}): T = + ## Iterates through a container and yields every item that fulfills the ## predicate. ## ## Example: @@ -262,11 +288,11 @@ iterator filter*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): T = ## for n in filter(numbers, proc (x: int): bool = x mod 2 == 0): ## echo($n) ## # echoes 4, 8, 4 in separate lines - for i in 0..<seq1.len: - if pred(seq1[i]): - yield seq1[i] + for i in 0 ..< s.len: + if pred(s[i]): + yield s[i] -proc filter*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): seq[T] +proc filter*[T](s: openArray[T], pred: proc(x: T): bool {.closure.}): seq[T] {.inline.} = ## Returns a new sequence with all the items that fulfilled the predicate. ## @@ -280,11 +306,11 @@ proc filter*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): seq[T] ## assert f1 == @["red", "black"] ## assert f2 == @["yellow"] result = newSeq[T]() - for i in 0..<seq1.len: - if pred(seq1[i]): - result.add(seq1[i]) + for i in 0 ..< s.len: + if pred(s[i]): + result.add(s[i]) -proc keepIf*[T](seq1: var seq[T], pred: proc(item: T): bool {.closure.}) +proc keepIf*[T](s: var seq[T], pred: proc(x: T): bool {.closure.}) {.inline.} = ## Keeps the items in the passed sequence if they fulfilled the predicate. ## Same as the ``filter`` proc, but modifies the sequence directly. @@ -296,12 +322,12 @@ proc keepIf*[T](seq1: var seq[T], pred: proc(item: T): bool {.closure.}) ## keepIf(floats, proc(x: float): bool = x > 10) ## assert floats == @[13.0, 12.5, 10.1] var pos = 0 - for i in 0 .. <len(seq1): - if pred(seq1[i]): + for i in 0 ..< len(s): + if pred(s[i]): if pos != i: - shallowCopy(seq1[pos], seq1[i]) + shallowCopy(s[pos], s[i]) inc(pos) - setLen(seq1, pos) + setLen(s, pos) proc delete*[T](s: var seq[T]; first, last: Natural) = ## Deletes in `s` the items at position `first` .. `last`. This modifies @@ -354,11 +380,12 @@ proc insert*[T](dest: var seq[T], src: openArray[T], pos=0) = inc(j) -template filterIt*(seq1, pred: untyped): untyped = +template filterIt*(s, pred: untyped): untyped = ## Returns a new sequence with all the items that fulfilled the predicate. ## ## Unlike the `proc` version, the predicate needs to be an expression using ## the ``it`` variable for testing, like: ``filterIt("abcxyz", it == 'x')``. + ## ## Example: ## ## .. code-block:: @@ -368,8 +395,8 @@ template filterIt*(seq1, pred: untyped): untyped = ## notAcceptable = filterIt(temperatures, it > 50 or it < -10) ## assert acceptable == @[-2.0, 24.5, 44.31] ## assert notAcceptable == @[-272.15, 99.9, -113.44] - var result = newSeq[type(seq1[0])]() - for it {.inject.} in items(seq1): + var result = newSeq[type(s[0])]() + for it {.inject.} in items(s): if pred: result.add(it) result @@ -378,6 +405,7 @@ template keepItIf*(varSeq: seq, pred: untyped) = ## ## Unlike the `proc` version, the predicate needs to be an expression using ## the ``it`` variable for testing, like: ``keepItIf("abcxyz", it == 'x')``. + ## ## Example: ## ## .. code-block:: @@ -385,7 +413,7 @@ template keepItIf*(varSeq: seq, pred: untyped) = ## keepItIf(candidates, it.len == 3 and it[0] == 'b') ## assert candidates == @["bar", "baz"] var pos = 0 - for i in 0 .. <len(varSeq): + for i in 0 ..< len(varSeq): let it {.inject.} = varSeq[i] if pred: if pos != i: @@ -393,8 +421,8 @@ template keepItIf*(varSeq: seq, pred: untyped) = inc(pos) setLen(varSeq, pos) -proc all*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): bool = - ## Iterates through a sequence and checks if every item fulfills the +proc all*[T](s: openArray[T], pred: proc(x: T): bool {.closure.}): bool = + ## Iterates through a container and checks if every item fulfills the ## predicate. ## ## Example: @@ -403,12 +431,12 @@ proc all*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): bool = ## let numbers = @[1, 4, 5, 8, 9, 7, 4] ## assert all(numbers, proc (x: int): bool = return x < 10) == true ## assert all(numbers, proc (x: int): bool = return x < 9) == false - for i in seq1: + for i in s: if not pred(i): return false return true -template allIt*(seq1, pred: untyped): bool = +template allIt*(s, pred: untyped): bool = ## Checks if every item fulfills the predicate. ## ## Example: @@ -418,14 +446,14 @@ template allIt*(seq1, pred: untyped): bool = ## assert allIt(numbers, it < 10) == true ## assert allIt(numbers, it < 9) == false var result = true - for it {.inject.} in items(seq1): + for it {.inject.} in items(s): if not pred: result = false break result -proc any*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): bool = - ## Iterates through a sequence and checks if some item fulfills the +proc any*[T](s: openArray[T], pred: proc(x: T): bool {.closure.}): bool = + ## Iterates through a container and checks if some item fulfills the ## predicate. ## ## Example: @@ -434,12 +462,12 @@ proc any*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): bool = ## let numbers = @[1, 4, 5, 8, 9, 7, 4] ## assert any(numbers, proc (x: int): bool = return x > 8) == true ## assert any(numbers, proc (x: int): bool = return x > 9) == false - for i in seq1: + for i in s: if pred(i): return true return false -template anyIt*(seq1, pred: untyped): bool = +template anyIt*(s, pred: untyped): bool = ## Checks if some item fulfills the predicate. ## ## Example: @@ -449,7 +477,7 @@ template anyIt*(seq1, pred: untyped): bool = ## assert anyIt(numbers, it > 8) == true ## assert anyIt(numbers, it > 9) == false var result = false - for it {.inject.} in items(seq1): + for it {.inject.} in items(s): if pred: result = true break @@ -493,7 +521,9 @@ template foldl*(sequence, operation: untyped): untyped = ## variables ``a`` and ``b`` for each step of the fold. Since this is a left ## fold, for non associative binary operations like subtraction think that ## the sequence of numbers 1, 2 and 3 will be parenthesized as (((1) - 2) - - ## 3). Example: + ## 3). + ## + ## Example: ## ## .. code-block:: ## let @@ -527,6 +557,7 @@ template foldl*(sequence, operation, first): untyped = ## The ``operation`` parameter should be an expression which uses the variables ## ``a`` and ``b`` for each step of the fold. The ``first`` parameter is the ## start value (the first ``a``) and therefor defines the type of the result. + ## ## Example: ## ## .. code-block:: @@ -555,7 +586,9 @@ template foldr*(sequence, operation: untyped): untyped = ## variables ``a`` and ``b`` for each step of the fold. Since this is a right ## fold, for non associative binary operations like subtraction think that ## the sequence of numbers 1, 2 and 3 will be parenthesized as (1 - (2 - - ## (3))). Example: + ## (3))). + ## + ## Example: ## ## .. code-block:: ## let @@ -580,13 +613,15 @@ template foldr*(sequence, operation: untyped): untyped = result = operation result -template mapIt*(seq1, typ, op: untyped): untyped = +template mapIt*(s, typ, op: untyped): untyped = ## Convenience template around the ``map`` proc to reduce typing. ## ## The template injects the ``it`` variable which you can use directly in an ## expression. You also need to pass as `typ` the type of the expression, ## since the new returned sequence can have a different type than the - ## original. Example: + ## original. + ## + ## Example: ## ## .. code-block:: ## let @@ -596,16 +631,18 @@ template mapIt*(seq1, typ, op: untyped): untyped = ## **Deprecated since version 0.12.0:** Use the ``mapIt(seq1, op)`` ## template instead. var result: seq[typ] = @[] - for it {.inject.} in items(seq1): + for it {.inject.} in items(s): result.add(op) result -template mapIt*(seq1, op: untyped): untyped = +template mapIt*(s, op: untyped): untyped = ## Convenience template around the ``map`` proc to reduce typing. ## ## The template injects the ``it`` variable which you can use directly in an - ## expression. Example: + ## expression. + ## + ## Example: ## ## .. code-block:: ## let @@ -614,19 +651,19 @@ template mapIt*(seq1, op: untyped): untyped = ## assert strings == @["4", "8", "12", "16"] type outType = type(( block: - var it{.inject.}: type(items(seq1)); + var it{.inject.}: type(items(s)); op)) var result: seq[outType] - when compiles(seq1.len): - let s = seq1 + when compiles(s.len): + let t = s var i = 0 result = newSeq[outType](s.len) - for it {.inject.} in s: + for it {.inject.} in t: result[i] = op i += 1 else: result = @[] - for it {.inject.} in seq1: + for it {.inject.} in s: result.add(op) result @@ -635,20 +672,23 @@ template applyIt*(varSeq, op: untyped) = ## ## The template injects the ``it`` variable which you can use directly in an ## expression. The expression has to return the same type as the sequence you - ## are mutating. Example: + ## are mutating. + ## + ## Example: ## ## .. code-block:: ## var nums = @[1, 2, 3, 4] ## nums.applyIt(it * 3) ## assert nums[0] + nums[3] == 15 - for i in 0 .. <varSeq.len: + for i in 0 ..< varSeq.len: let it {.inject.} = varSeq[i] varSeq[i] = op - template newSeqWith*(len: int, init: untyped): untyped = - ## creates a new sequence, calling `init` to initialize each value. Example: + ## creates a new sequence, calling `init` to initialize each value. + ## + ## Example: ## ## .. code-block:: ## var seq2D = newSeqWith(20, newSeq[bool](10)) @@ -660,7 +700,7 @@ template newSeqWith*(len: int, init: untyped): untyped = ## var seqRand = newSeqWith(20, random(10)) ## echo seqRand var result = newSeq[type(init)](len) - for i in 0 .. <len: + for i in 0 ..< len: result[i] = init result @@ -674,45 +714,178 @@ when isMainModule: total = concat(s1, s2, s3) assert total == @[1, 2, 3, 4, 5, 6, 7] - block: # duplicates test + block: # count test + let + s1 = @[1, 2, 3, 2] + s2 = @['a', 'b', 'x', 'a'] + a1 = [1, 2, 3, 2] + a2 = ['a', 'b', 'x', 'a'] + r0 = count(s1, 0) + r1 = count(s1, 1) + r2 = count(s1, 2) + r3 = count(s2, 'y') + r4 = count(s2, 'x') + r5 = count(s2, 'a') + ar0 = count(a1, 0) + ar1 = count(a1, 1) + ar2 = count(a1, 2) + ar3 = count(a2, 'y') + ar4 = count(a2, 'x') + ar5 = count(a2, 'a') + assert r0 == 0 + assert r1 == 1 + assert r2 == 2 + assert r3 == 0 + assert r4 == 1 + assert r5 == 2 + assert ar0 == 0 + assert ar1 == 1 + assert ar2 == 2 + assert ar3 == 0 + assert ar4 == 1 + assert ar5 == 2 + + block: # cycle tests + let + a = @[1, 2, 3] + b: seq[int] = @[] + c = [1, 2, 3] + + doAssert a.cycle(3) == @[1, 2, 3, 1, 2, 3, 1, 2, 3] + doAssert a.cycle(0) == @[] + #doAssert a.cycle(-1) == @[] # will not compile! + doAssert b.cycle(3) == @[] + doAssert c.cycle(3) == @[1, 2, 3, 1, 2, 3, 1, 2, 3] + doAssert c.cycle(0) == @[] + + block: # repeat tests + assert repeat(10, 5) == @[10, 10, 10, 10, 10] + assert repeat(@[1,2,3], 2) == @[@[1,2,3], @[1,2,3]] + assert repeat([1,2,3], 2) == @[[1,2,3], [1,2,3]] + + block: # deduplicates test let dup1 = @[1, 1, 3, 4, 2, 2, 8, 1, 4] dup2 = @["a", "a", "c", "d", "d"] + dup3 = [1, 1, 3, 4, 2, 2, 8, 1, 4] + dup4 = ["a", "a", "c", "d", "d"] unique1 = deduplicate(dup1) unique2 = deduplicate(dup2) + unique3 = deduplicate(dup3) + unique4 = deduplicate(dup4) assert unique1 == @[1, 3, 4, 2, 8] assert unique2 == @["a", "c", "d"] + assert unique3 == @[1, 3, 4, 2, 8] + assert unique4 == @["a", "c", "d"] block: # zip test let short = @[1, 2, 3] long = @[6, 5, 4, 3, 2, 1] words = @["one", "two", "three"] + ashort = [1, 2, 3] + along = [6, 5, 4, 3, 2, 1] + awords = ["one", "two", "three"] zip1 = zip(short, long) zip2 = zip(short, words) + zip3 = zip(ashort, along) + zip4 = zip(ashort, awords) + zip5 = zip(ashort, words) assert zip1 == @[(1, 6), (2, 5), (3, 4)] assert zip2 == @[(1, "one"), (2, "two"), (3, "three")] + assert zip3 == @[(1, 6), (2, 5), (3, 4)] + assert zip4 == @[(1, "one"), (2, "two"), (3, "three")] + assert zip5 == @[(1, "one"), (2, "two"), (3, "three")] assert zip1[2].b == 4 assert zip2[2].b == "three" + assert zip3[2].b == 4 + assert zip4[2].b == "three" + assert zip5[2].b == "three" + + block: # distribute tests + let numbers = @[1, 2, 3, 4, 5, 6, 7] + doAssert numbers.distribute(3) == @[@[1, 2, 3], @[4, 5], @[6, 7]] + doAssert numbers.distribute(6)[0] == @[1, 2] + doAssert numbers.distribute(6)[5] == @[7] + let a = @[1, 2, 3, 4, 5, 6, 7] + doAssert a.distribute(1, true) == @[@[1, 2, 3, 4, 5, 6, 7]] + doAssert a.distribute(1, false) == @[@[1, 2, 3, 4, 5, 6, 7]] + doAssert a.distribute(2, true) == @[@[1, 2, 3, 4], @[5, 6, 7]] + doAssert a.distribute(2, false) == @[@[1, 2, 3, 4], @[5, 6, 7]] + doAssert a.distribute(3, true) == @[@[1, 2, 3], @[4, 5], @[6, 7]] + doAssert a.distribute(3, false) == @[@[1, 2, 3], @[4, 5, 6], @[7]] + doAssert a.distribute(4, true) == @[@[1, 2], @[3, 4], @[5, 6], @[7]] + doAssert a.distribute(4, false) == @[@[1, 2], @[3, 4], @[5, 6], @[7]] + doAssert a.distribute(5, true) == @[@[1, 2], @[3, 4], @[5], @[6], @[7]] + doAssert a.distribute(5, false) == @[@[1, 2], @[3, 4], @[5, 6], @[7], @[]] + doAssert a.distribute(6, true) == @[@[1, 2], @[3], @[4], @[5], @[6], @[7]] + doAssert a.distribute(6, false) == @[ + @[1, 2], @[3, 4], @[5, 6], @[7], @[], @[]] + doAssert a.distribute(8, false) == a.distribute(8, true) + doAssert a.distribute(90, false) == a.distribute(90, true) + var b = @[0] + for f in 1 .. 25: b.add(f) + doAssert b.distribute(5, true)[4].len == 5 + doAssert b.distribute(5, false)[4].len == 2 + + block: # map test + let + numbers = @[1, 4, 5, 8, 9, 7, 4] + anumbers = [1, 4, 5, 8, 9, 7, 4] + m1 = map(numbers, proc(x: int): int = 2*x) + m2 = map(anumbers, proc(x: int): int = 2*x) + assert m1 == @[2, 8, 10, 16, 18, 14, 8] + assert m2 == @[2, 8, 10, 16, 18, 14, 8] + + block: # apply test + var a = @["1", "2", "3", "4"] + apply(a, proc(x: var string) = x &= "42") + assert a == @["142", "242", "342", "442"] block: # filter proc test let colors = @["red", "yellow", "black"] + acolors = ["red", "yellow", "black"] f1 = filter(colors, proc(x: string): bool = x.len < 6) f2 = filter(colors) do (x: string) -> bool : x.len > 5 + f3 = filter(acolors, proc(x: string): bool = x.len < 6) + f4 = filter(acolors) do (x: string) -> bool : x.len > 5 assert f1 == @["red", "black"] assert f2 == @["yellow"] + assert f3 == @["red", "black"] + assert f4 == @["yellow"] block: # filter iterator test let numbers = @[1, 4, 5, 8, 9, 7, 4] + let anumbers = [1, 4, 5, 8, 9, 7, 4] assert toSeq(filter(numbers, proc (x: int): bool = x mod 2 == 0)) == @[4, 8, 4] + assert toSeq(filter(anumbers, proc (x: int): bool = x mod 2 == 0)) == + @[4, 8, 4] block: # keepIf test var floats = @[13.0, 12.5, 5.8, 2.0, 6.1, 9.9, 10.1] keepIf(floats, proc(x: float): bool = x > 10) assert floats == @[13.0, 12.5, 10.1] + block: # delete tests + let outcome = @[1,1,1,1,1,1,1,1] + var dest = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1] + dest.delete(3, 8) + assert outcome == dest, """\ + Deleting range 3-9 from [1,1,1,2,2,2,2,2,2,1,1,1,1,1] + is [1,1,1,1,1,1,1,1]""" + + block: # insert tests + var dest = @[1,1,1,1,1,1,1,1] + let + src = @[2,2,2,2,2,2] + outcome = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1] + dest.insert(src, 3) + assert dest == outcome, """\ + Inserting [2,2,2,2,2,2] into [1,1,1,1,1,1,1,1] + at 3 is [1,1,1,2,2,2,2,2,2,1,1,1,1,1]""" + block: # filterIt test let temperatures = @[-272.15, -2.0, 24.5, 44.31, 99.9, -113.44] @@ -726,37 +899,49 @@ when isMainModule: keepItIf(candidates, it.len == 3 and it[0] == 'b') assert candidates == @["bar", "baz"] - block: # any - let - numbers = @[1, 4, 5, 8, 9, 7, 4] - len0seq : seq[int] = @[] - assert any(numbers, proc (x: int): bool = return x > 8) == true - assert any(numbers, proc (x: int): bool = return x > 9) == false - assert any(len0seq, proc (x: int): bool = return true) == false - - block: # anyIt - let - numbers = @[1, 4, 5, 8, 9, 7, 4] - len0seq : seq[int] = @[] - assert anyIt(numbers, it > 8) == true - assert anyIt(numbers, it > 9) == false - assert anyIt(len0seq, true) == false - block: # all let numbers = @[1, 4, 5, 8, 9, 7, 4] + anumbers = [1, 4, 5, 8, 9, 7, 4] len0seq : seq[int] = @[] assert all(numbers, proc (x: int): bool = return x < 10) == true assert all(numbers, proc (x: int): bool = return x < 9) == false assert all(len0seq, proc (x: int): bool = return false) == true + assert all(anumbers, proc (x: int): bool = return x < 10) == true + assert all(anumbers, proc (x: int): bool = return x < 9) == false block: # allIt let numbers = @[1, 4, 5, 8, 9, 7, 4] + anumbers = [1, 4, 5, 8, 9, 7, 4] len0seq : seq[int] = @[] assert allIt(numbers, it < 10) == true assert allIt(numbers, it < 9) == false assert allIt(len0seq, false) == true + assert allIt(anumbers, it < 10) == true + assert allIt(anumbers, it < 9) == false + + block: # any + let + numbers = @[1, 4, 5, 8, 9, 7, 4] + anumbers = [1, 4, 5, 8, 9, 7, 4] + len0seq : seq[int] = @[] + assert any(numbers, proc (x: int): bool = return x > 8) == true + assert any(numbers, proc (x: int): bool = return x > 9) == false + assert any(len0seq, proc (x: int): bool = return true) == false + assert any(anumbers, proc (x: int): bool = return x > 8) == true + assert any(anumbers, proc (x: int): bool = return x > 9) == false + + block: # anyIt + let + numbers = @[1, 4, 5, 8, 9, 7, 4] + anumbers = [1, 4, 5, 8, 9, 7, 4] + len0seq : seq[int] = @[] + assert anyIt(numbers, it > 8) == true + assert anyIt(numbers, it > 9) == false + assert anyIt(len0seq, true) == false + assert anyIt(anumbers, it > 8) == true + assert anyIt(anumbers, it > 9) == false block: # toSeq test let @@ -792,56 +977,13 @@ when isMainModule: assert multiplication == 495, "Multiplication is (5*(9*(11)))" assert concatenation == "nimiscool" - block: # delete tests - let outcome = @[1,1,1,1,1,1,1,1] - var dest = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1] - dest.delete(3, 8) - assert outcome == dest, """\ - Deleting range 3-9 from [1,1,1,2,2,2,2,2,2,1,1,1,1,1] - is [1,1,1,1,1,1,1,1]""" - - block: # insert tests - var dest = @[1,1,1,1,1,1,1,1] - let - src = @[2,2,2,2,2,2] - outcome = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1] - dest.insert(src, 3) - assert dest == outcome, """\ - Inserting [2,2,2,2,2,2] into [1,1,1,1,1,1,1,1] - at 3 is [1,1,1,2,2,2,2,2,2,1,1,1,1,1]""" - block: # mapIt tests var nums = @[1, 2, 3, 4] strings = nums.mapIt($(4 * it)) nums.applyIt(it * 3) assert nums[0] + nums[3] == 15 - - block: # distribute tests - let numbers = @[1, 2, 3, 4, 5, 6, 7] - doAssert numbers.distribute(3) == @[@[1, 2, 3], @[4, 5], @[6, 7]] - doAssert numbers.distribute(6)[0] == @[1, 2] - doAssert numbers.distribute(6)[5] == @[7] - let a = @[1, 2, 3, 4, 5, 6, 7] - doAssert a.distribute(1, true) == @[@[1, 2, 3, 4, 5, 6, 7]] - doAssert a.distribute(1, false) == @[@[1, 2, 3, 4, 5, 6, 7]] - doAssert a.distribute(2, true) == @[@[1, 2, 3, 4], @[5, 6, 7]] - doAssert a.distribute(2, false) == @[@[1, 2, 3, 4], @[5, 6, 7]] - doAssert a.distribute(3, true) == @[@[1, 2, 3], @[4, 5], @[6, 7]] - doAssert a.distribute(3, false) == @[@[1, 2, 3], @[4, 5, 6], @[7]] - doAssert a.distribute(4, true) == @[@[1, 2], @[3, 4], @[5, 6], @[7]] - doAssert a.distribute(4, false) == @[@[1, 2], @[3, 4], @[5, 6], @[7]] - doAssert a.distribute(5, true) == @[@[1, 2], @[3, 4], @[5], @[6], @[7]] - doAssert a.distribute(5, false) == @[@[1, 2], @[3, 4], @[5, 6], @[7], @[]] - doAssert a.distribute(6, true) == @[@[1, 2], @[3], @[4], @[5], @[6], @[7]] - doAssert a.distribute(6, false) == @[ - @[1, 2], @[3, 4], @[5, 6], @[7], @[], @[]] - doAssert a.distribute(8, false) == a.distribute(8, true) - doAssert a.distribute(90, false) == a.distribute(90, true) - var b = @[0] - for f in 1 .. 25: b.add(f) - doAssert b.distribute(5, true)[4].len == 5 - doAssert b.distribute(5, false)[4].len == 2 + assert strings[2] == "12" block: # newSeqWith tests var seq2D = newSeqWith(4, newSeq[bool](2)) @@ -850,19 +992,5 @@ when isMainModule: seq2D[0][1] = true doAssert seq2D == @[@[true, true], @[true, false], @[false, false], @[false, false]] - block: # cycle tests - let - a = @[1, 2, 3] - b: seq[int] = @[] - - doAssert a.cycle(3) == @[1, 2, 3, 1, 2, 3, 1, 2, 3] - doAssert a.cycle(0) == @[] - #doAssert a.cycle(-1) == @[] # will not compile! - doAssert b.cycle(3) == @[] - - block: # repeat tests - assert repeat(10, 5) == @[10, 10, 10, 10, 10] - assert repeat(@[1,2,3], 2) == @[@[1,2,3], @[1,2,3]] - when not defined(testing): echo "Finished doc tests" diff --git a/lib/pure/collections/sharedstrings.nim b/lib/pure/collections/sharedstrings.nim index a9e194fb4..83edf8d94 100644 --- a/lib/pure/collections/sharedstrings.nim +++ b/lib/pure/collections/sharedstrings.nim @@ -55,7 +55,7 @@ proc `[]=`*(s: var SharedString; i: Natural; value: char) = if i < s.len: s.buffer.data[i+s.first] = value else: raise newException(IndexError, "index out of bounds") -proc `[]`*(s: SharedString; ab: Slice[int]): SharedString = +proc `[]`*(s: SharedString; ab: HSlice[int, int]): SharedString = #incRef(src.buffer) if ab.a < s.len: result.buffer = s.buffer diff --git a/lib/pure/collections/tableimpl.nim b/lib/pure/collections/tableimpl.nim index eec98fcaf..9a5bffcef 100644 --- a/lib/pure/collections/tableimpl.nim +++ b/lib/pure/collections/tableimpl.nim @@ -149,7 +149,7 @@ template delImpl() {.dirty.} = delImplIdx(t, i) template clearImpl() {.dirty.} = - for i in 0 .. <t.data.len: + for i in 0 ..< t.data.len: when compiles(t.data[i].hcode): # CountTable records don't contain a hcode t.data[i].hcode = 0 t.data[i].key = default(type(t.data[i].key)) diff --git a/lib/pure/concurrency/cpuinfo.nim b/lib/pure/concurrency/cpuinfo.nim index 603fee080..f01488811 100644 --- a/lib/pure/concurrency/cpuinfo.nim +++ b/lib/pure/concurrency/cpuinfo.nim @@ -45,8 +45,25 @@ proc countProcessors*(): int {.rtl, extern: "ncpi$1".} = ## returns the numer of the processors/cores the machine has. ## Returns 0 if it cannot be detected. when defined(windows): - var x = getEnv("NUMBER_OF_PROCESSORS") - if x.len > 0: result = parseInt(x.string) + type + SYSTEM_INFO {.final, pure.} = object + u1: int32 + dwPageSize: int32 + lpMinimumApplicationAddress: pointer + lpMaximumApplicationAddress: pointer + dwActiveProcessorMask: ptr int32 + dwNumberOfProcessors: int32 + dwProcessorType: int32 + dwAllocationGranularity: int32 + wProcessorLevel: int16 + wProcessorRevision: int16 + + proc GetSystemInfo(lpSystemInfo: var SYSTEM_INFO) {.stdcall, dynlib: "kernel32", importc: "GetSystemInfo".} + + var + si: SYSTEM_INFO + GetSystemInfo(si) + result = si.dwNumberOfProcessors elif defined(macosx) or defined(bsd): var mib: array[0..3, cint] diff --git a/lib/pure/concurrency/threadpool.nim b/lib/pure/concurrency/threadpool.nim index 2a0dbd2ca..a5eaec86e 100644 --- a/lib/pure/concurrency/threadpool.nim +++ b/lib/pure/concurrency/threadpool.nim @@ -149,7 +149,7 @@ proc selectWorker(w: ptr Worker; fn: WorkerProc; data: pointer): bool = proc cleanFlowVars(w: ptr Worker) = let q = addr(w.q) acquire(q.lock) - for i in 0 .. <q.len: + for i in 0 ..< q.len: GC_unref(cast[RootRef](q.data[i])) #echo "GC_unref" q.len = 0 @@ -401,7 +401,7 @@ proc setup() = gCpus = p currentPoolSize = min(p, MaxThreadPoolSize) readyWorker = addr(workersData[0]) - for i in 0.. <currentPoolSize: activateWorkerThread(i) + for i in 0..<currentPoolSize: activateWorkerThread(i) proc preferSpawn*(): bool = ## Use this proc to determine quickly if a 'spawn' or a direct call is @@ -446,14 +446,24 @@ proc nimSpawn3(fn: WorkerProc; data: pointer) {.compilerProc.} = # implementation of 'spawn' that is used by the code generator. while true: if selectWorker(readyWorker, fn, data): return - for i in 0.. <currentPoolSize: + for i in 0..<currentPoolSize: if selectWorker(addr(workersData[i]), fn, data): return + # determine what to do, but keep in mind this is expensive too: # state.calls < maxPoolSize: warmup phase # (state.calls and 127) == 0: periodic check if state.calls < maxPoolSize or (state.calls and 127) == 0: # ensure the call to 'advice' is atomic: if tryAcquire(stateLock): + if currentPoolSize < minPoolSize: + if not workersData[currentPoolSize].initialized: + activateWorkerThread(currentPoolSize) + let w = addr(workersData[currentPoolSize]) + atomicInc currentPoolSize + if selectWorker(w, fn, data): + release(stateLock) + return + case advice(state) of doNothing: discard of doCreateThread: @@ -533,7 +543,7 @@ proc sync*() = var toRelease = 0 while true: var allReady = true - for i in 0 .. <currentPoolSize: + for i in 0 ..< currentPoolSize: if not allReady: break allReady = allReady and workersData[i].ready if allReady: break diff --git a/lib/pure/future.nim b/lib/pure/future.nim index 2a6d29933..f6592df71 100644 --- a/lib/pure/future.nim +++ b/lib/pure/future.nim @@ -22,7 +22,7 @@ proc createProcType(p, b: NimNode): NimNode {.compileTime.} = case p.kind of nnkPar: - for i in 0 .. <p.len: + for i in 0 ..< p.len: let ident = p[i] var identDefs = newNimNode(nnkIdentDefs) case ident.kind @@ -77,7 +77,7 @@ macro `=>`*(p, b: untyped): untyped = if c[0].kind == nnkIdent and c[0].ident == !"->": var procTy = createProcType(c[1], c[2]) params[0] = procTy[0][0] - for i in 1 .. <procTy[0].len: + for i in 1 ..< procTy[0].len: params.add(procTy[0][i]) else: error("Expected proc type (->) got (" & $c[0].ident & ").") @@ -96,7 +96,7 @@ macro `=>`*(p, b: untyped): untyped = if p[0].kind == nnkIdent and p[0].ident == !"->": var procTy = createProcType(p[1], p[2]) params[0] = procTy[0][0] - for i in 1 .. <procTy[0].len: + for i in 1 ..< procTy[0].len: params.add(procTy[0][i]) else: error("Expected proc type (->) got (" & $p[0].ident & ").") diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index cb4f4f664..de1d332a3 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -883,7 +883,9 @@ proc recvFull(client: HttpClient | AsyncHttpClient, size: int, timeout: int, let data = client.socket.recv(sizeToRecv, timeout) else: let data = await client.socket.recv(sizeToRecv) - if data == "": break # We've been disconnected. + if data == "": + client.close() + break # We've been disconnected. readLen.inc(data.len) if keep: @@ -950,6 +952,7 @@ proc parseBody(client: HttpClient | AsyncHttpClient, if length > 0: let recvLen = await client.recvFull(length, client.timeout, true) if recvLen == 0: + client.close() httpError("Got disconnected while trying to read body.") if recvLen != length: httpError("Received length doesn't match expected length. Wanted " & @@ -962,13 +965,20 @@ proc parseBody(client: HttpClient | AsyncHttpClient, if headers.getOrDefault"Connection" == "close" or httpVersion == "1.0": while true: let recvLen = await client.recvFull(4000, client.timeout, true) - if recvLen == 0: break + if recvLen == 0: + client.close() + break when client is AsyncHttpClient: client.bodyStream.complete() else: client.bodyStream.setPosition(0) + # If the server will close our connection, then no matter the method of + # reading the body, we need to close our socket. + if headers.getOrDefault"Connection" == "close": + client.close() + proc parseResponse(client: HttpClient | AsyncHttpClient, getBody: bool): Future[Response | AsyncResponse] {.multisync.} = @@ -984,7 +994,10 @@ proc parseResponse(client: HttpClient | AsyncHttpClient, line = await client.socket.recvLine(client.timeout) else: line = await client.socket.recvLine() - if line == "": break # We've been disconnected. + if line == "": + # We've been disconnected. + client.close() + break if line == "\c\L": fullyRead = true break @@ -1033,7 +1046,8 @@ proc newConnection(client: HttpClient | AsyncHttpClient, url: Uri) {.multisync.} = if client.currentURL.hostname != url.hostname or client.currentURL.scheme != url.scheme or - client.currentURL.port != url.port: + client.currentURL.port != url.port or + (not client.connected): let isSsl = url.scheme.toLowerAscii() == "https" if isSsl and not defined(ssl): diff --git a/lib/pure/httpcore.nim b/lib/pure/httpcore.nim index a5ab40ca4..f150fa1c1 100644 --- a/lib/pure/httpcore.nim +++ b/lib/pure/httpcore.nim @@ -113,6 +113,9 @@ proc newHttpHeaders*(keyValuePairs: new result result.table = newTable[string, seq[string]](pairs) +proc `$`*(headers: HttpHeaders): string = + return $headers.table + proc clear*(headers: HttpHeaders) = headers.table.clear() diff --git a/lib/pure/includes/osenv.nim b/lib/pure/includes/osenv.nim index 8d2fc235a..ae62a5c4e 100644 --- a/lib/pure/includes/osenv.nim +++ b/lib/pure/includes/osenv.nim @@ -94,7 +94,7 @@ proc findEnvVar(key: string): int = if startsWith(environment[i], temp): return i return -1 -proc getEnv*(key: string): TaintedString {.tags: [ReadEnvEffect].} = +proc getEnv*(key: string, default = ""): TaintedString {.tags: [ReadEnvEffect].} = ## Returns the value of the `environment variable`:idx: named `key`. ## ## If the variable does not exist, "" is returned. To distinguish @@ -108,7 +108,7 @@ proc getEnv*(key: string): TaintedString {.tags: [ReadEnvEffect].} = return TaintedString(substr(environment[i], find(environment[i], '=')+1)) else: var env = c_getenv(key) - if env == nil: return TaintedString("") + if env == nil: return TaintedString(default) result = TaintedString($env) proc existsEnv*(key: string): bool {.tags: [ReadEnvEffect].} = diff --git a/lib/pure/json.nim b/lib/pure/json.nim index 656114fb1..3d86cc9d7 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -37,15 +37,15 @@ ## Retrieving the value of a JSON node can then be achieved using one of the ## helper procedures, which include: ## -## * ``getNum`` -## * ``getFNum`` +## * ``getInt`` +## * ``getFloat`` ## * ``getStr`` -## * ``getBVal`` +## * ``getBool`` ## ## To retrieve the value of ``"key"`` you can do the following: ## ## .. code-block:: Nim -## doAssert jsonNode["key"].getFNum() == 3.14 +## doAssert jsonNode["key"].getFloat() == 3.14 ## ## The ``[]`` operator will raise an exception when the specified field does ## not exist. If you wish to avoid this behaviour you can use the ``{}`` @@ -681,14 +681,25 @@ proc getStr*(n: JsonNode, default: string = ""): string = if n.isNil or n.kind != JString: return default else: return n.str -proc getNum*(n: JsonNode, default: BiggestInt = 0): BiggestInt = +proc getInt*(n: JsonNode, default: int = 0): int = ## Retrieves the int value of a `JInt JsonNode`. ## ## Returns ``default`` if ``n`` is not a ``JInt``, or if ``n`` is nil. if n.isNil or n.kind != JInt: return default + else: return int(n.num) + +proc getBiggestInt*(n: JsonNode, default: BiggestInt = 0): BiggestInt = + ## Retrieves the BiggestInt value of a `JInt JsonNode`. + ## + ## Returns ``default`` if ``n`` is not a ``JInt``, or if ``n`` is nil. + if n.isNil or n.kind != JInt: return default else: return n.num -proc getFNum*(n: JsonNode, default: float = 0.0): float = +proc getNum*(n: JsonNode, default: BiggestInt = 0): BiggestInt {.deprecated.} = + ## Deprecated - use getInt or getBiggestInt instead + getBiggestInt(n, default) + +proc getFloat*(n: JsonNode, default: float = 0.0): float = ## Retrieves the float value of a `JFloat JsonNode`. ## ## Returns ``default`` if ``n`` is not a ``JFloat`` or ``JInt``, or if ``n`` is nil. @@ -698,13 +709,21 @@ proc getFNum*(n: JsonNode, default: float = 0.0): float = of JInt: return float(n.num) else: return default -proc getBVal*(n: JsonNode, default: bool = false): bool = +proc getFNum*(n: JsonNode, default: float = 0.0): float {.deprecated.} = + ## Deprecated - use getFloat instead + getFloat(n, default) + +proc getBool*(n: JsonNode, default: bool = false): bool = ## Retrieves the bool value of a `JBool JsonNode`. ## ## Returns ``default`` if ``n`` is not a ``JBool``, or if ``n`` is nil. if n.isNil or n.kind != JBool: return default else: return n.bval +proc getBVal*(n: JsonNode, default: bool = false): bool {.deprecated.} = + ## Deprecated - use getBVal instead + getBool(n, default) + proc getFields*(n: JsonNode, default = initOrderedTable[string, JsonNode](4)): OrderedTable[string, JsonNode] = @@ -804,13 +823,13 @@ proc toJson(x: NimNode): NimNode {.compiletime.} = of nnkBracket: # array if x.len == 0: return newCall(bindSym"newJArray") result = newNimNode(nnkBracket) - for i in 0 .. <x.len: + for i in 0 ..< x.len: result.add(toJson(x[i])) result = newCall(bindSym"%", result) of nnkTableConstr: # object if x.len == 0: return newCall(bindSym"newJObject") result = newNimNode(nnkTableConstr) - for i in 0 .. <x.len: + for i in 0 ..< x.len: x[i].expectKind nnkExprColonExpr result.add newTree(nnkExprColonExpr, x[i][0], toJson(x[i][1])) result = newCall(bindSym"%", result) @@ -1284,7 +1303,7 @@ else: case getVarType(x) of JArray: result = newJArray() - for i in 0 .. <x.len: + for i in 0 ..< x.len: result.add(x[i].convertObject()) of JObject: result = newJObject() @@ -1342,7 +1361,7 @@ proc getEnum(node: JsonNode, ast: string, T: typedesc): T = # TODO: I shouldn't need this proc. proc convert[T](x: BiggestInt): T = T(x) verifyJsonKind(node, {JInt}, ast) - return convert[T](node.getNum()) + return convert[T](node.getBiggestInt()) else: verifyJsonKind(node, {JString}, ast) return parseEnum[T](node.getStr()) @@ -1430,7 +1449,7 @@ proc processElseBranch(recCaseNode, elseBranch, jsonNode, kindType, # We need to build up a list of conditions from each ``of`` branch so that # we can then negate it to get ``else``. var cond = newIdentNode("false") - for i in 1 .. <len(recCaseNode): + for i in 1 ..< len(recCaseNode): if recCaseNode[i].kind == nnkElse: break @@ -1492,7 +1511,7 @@ proc processObjField(field, jsonNode: NimNode): seq[NimNode] = exprColonExpr.add(getEnumCall) # Iterate through each `of` branch. - for i in 1 .. <field.len: + for i in 1 ..< field.len: case field[i].kind of nnkOfBranch: result.add processOfBranch(field[i], jsonNode, kindType, kindJsonNode) @@ -1621,7 +1640,7 @@ proc createConstructor(typeSym, jsonNode: NimNode): NimNode = ( var list: `typeSym` = @[]; verifyJsonKind(`jsonNode`, {JArray}, astToStr(`jsonNode`)); - for `forLoopI` in 0 .. <`jsonNode`.len: list.add(`constructorNode`); + for `forLoopI` in 0 ..< `jsonNode`.len: list.add(`constructorNode`); list ) of "array": @@ -1635,7 +1654,7 @@ proc createConstructor(typeSym, jsonNode: NimNode): NimNode = ( var list: `typeSym`; verifyJsonKind(`jsonNode`, {JArray}, astToStr(`jsonNode`)); - for `forLoopI` in 0 .. <`jsonNode`.len: list[`forLoopI`] =`constructorNode`; + for `forLoopI` in 0 ..< `jsonNode`.len: list[`forLoopI`] =`constructorNode`; list ) @@ -1664,7 +1683,7 @@ proc postProcessValue(value: NimNode): NimNode = result = postProcess(value) else: result = value - for i in 0 .. <len(result): + for i in 0 ..< len(result): result[i] = postProcessValue(result[i]) proc postProcessExprColonExpr(exprColonExpr, resIdent: NimNode): NimNode = diff --git a/lib/pure/lexbase.nim b/lib/pure/lexbase.nim index cf2e8bb89..15a390f0b 100644 --- a/lib/pure/lexbase.nim +++ b/lib/pure/lexbase.nim @@ -37,6 +37,7 @@ type lineNumber*: int ## the current line number sentinel: int lineStart: int # index of last line start in buffer + offsetBase*: int # use ``offsetBase + bufpos`` to get the offset refillChars: set[char] {.deprecated: [TBaseLexer: BaseLexer].} @@ -107,7 +108,8 @@ proc fillBaseLexer(L: var BaseLexer, pos: int): int = result = pos + 1 # nothing to do else: fillBuffer(L) - L.bufpos = 0 # XXX: is this really correct? + L.offsetBase += pos + L.bufpos = 0 result = 0 proc handleCR*(L: var BaseLexer, pos: int): int = @@ -147,6 +149,7 @@ proc open*(L: var BaseLexer, input: Stream, bufLen: int = 8192; assert(input != nil) L.input = input L.bufpos = 0 + L.offsetBase = 0 L.bufLen = bufLen L.refillChars = refillChars when defined(js): diff --git a/lib/pure/marshal.nim b/lib/pure/marshal.nim index c4c731acf..6ee830786 100644 --- a/lib/pure/marshal.nim +++ b/lib/pure/marshal.nim @@ -283,7 +283,7 @@ proc to*[T](data: string): T = loadAny(newStringStream(data), toAny(result), tab) when not defined(testing) and isMainModule: - template testit(x: expr) = echo($$to[type(x)]($$x)) + template testit(x: untyped) = echo($$to[type(x)]($$x)) var x: array[0..4, array[0..4, string]] = [ ["test", "1", "2", "3", "4"], ["test", "1", "2", "3", "4"], diff --git a/lib/pure/matchers.nim b/lib/pure/matchers.nim index 7022c21d9..6366fee1a 100644 --- a/lib/pure/matchers.nim +++ b/lib/pure/matchers.nim @@ -48,7 +48,7 @@ proc validEmailAddress*(s: string): bool {.noSideEffect, "aero", "jobs", "museum": return true else: return false -proc parseInt*(s: string, value: var int, validRange: Slice[int]) {. +proc parseInt*(s: string, value: var int, validRange: HSlice[int, int]) {. noSideEffect, rtl, extern: "nmatchParseInt".} = ## parses `s` into an integer in the range `validRange`. If successful, ## `value` is modified to contain the result. Otherwise no exception is diff --git a/lib/pure/math.nim b/lib/pure/math.nim index 8037b31b0..7fd8bbcef 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -184,6 +184,8 @@ when not defined(JS): proc pow*(x, y: float32): float32 {.importc: "powf", header: "<math.h>".} proc pow*(x, y: float64): float64 {.importc: "pow", header: "<math.h>".} ## computes x to power raised of y. + ## + ## To compute power between integers, use `^` e.g. 2 ^ 6 proc erf*(x: float32): float32 {.importc: "erff", header: "<math.h>".} proc erf*(x: float64): float64 {.importc: "erf", header: "<math.h>".} diff --git a/lib/pure/nativesockets.nim b/lib/pure/nativesockets.nim index 98fc62a3b..6c8701843 100644 --- a/lib/pure/nativesockets.nim +++ b/lib/pure/nativesockets.nim @@ -496,11 +496,12 @@ proc getLocalAddr*(socket: SocketHandle, domain: Domain): (string, Port) = addr(namelen)) == -1'i32: raiseOSError(osLastError()) # Cannot use INET6_ADDRSTRLEN here, because it's a C define. - var buf: array[64, char] + result[0] = newString(64) if inet_ntop(name.sin6_family.cint, - addr name.sin6_addr, buf.cstring, sizeof(buf).int32).isNil: + addr name.sin6_addr, addr result[0][0], (result[0].len+1).int32).isNil: raiseOSError(osLastError()) - result = ($buf, Port(nativesockets.ntohs(name.sin6_port))) + setLen(result[0], result[0].cstring.len) + result[1] = Port(nativesockets.ntohs(name.sin6_port)) else: raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr") @@ -532,11 +533,12 @@ proc getPeerAddr*(socket: SocketHandle, domain: Domain): (string, Port) = addr(namelen)) == -1'i32: raiseOSError(osLastError()) # Cannot use INET6_ADDRSTRLEN here, because it's a C define. - var buf: array[64, char] + result[0] = newString(64) if inet_ntop(name.sin6_family.cint, - addr name.sin6_addr, buf.cstring, sizeof(buf).int32).isNil: + addr name.sin6_addr, addr result[0][0], (result[0].len+1).int32).isNil: raiseOSError(osLastError()) - result = ($buf, Port(nativesockets.ntohs(name.sin6_port))) + setLen(result[0], result[0].cstring.len) + result[1] = Port(nativesockets.ntohs(name.sin6_port)) else: raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr") diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 215a301b6..a405ce1bd 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -857,13 +857,16 @@ proc close*(socket: Socket) = # shutdown i.e not wait for the peers "close notify" alert with a second # call to SSLShutdown let res = SSLShutdown(socket.sslHandle) - SSLFree(socket.sslHandle) - socket.sslHandle = nil if res == 0: discard elif res != 1: socketError(socket, res) finally: + when defineSsl: + if socket.isSSL and socket.sslHandle != nil: + SSLFree(socket.sslHandle) + socket.sslHandle = nil + socket.fd.close() proc toCInt*(opt: SOBool): cint = diff --git a/lib/pure/options.nim b/lib/pure/options.nim index ad63bbcb6..6d2869bff 100644 --- a/lib/pure/options.nim +++ b/lib/pure/options.nim @@ -153,7 +153,10 @@ proc `==`*(a, b: Option): bool = (a.has and b.has and a.val == b.val) or (not a.has and not b.has) proc `$`*[T](self: Option[T]): string = - ## Returns the contents of this option or `otherwise` if the option is none. + ## Get the string representation of this option. If the option has a value, + ## the result will be `Some(x)` where `x` is the string representation of the contained value. + ## If the option does not have a value, the result will be `None[T]` where `T` is the name of + ## the type contained in the option. if self.has: "Some(" & $self.val & ")" else: diff --git a/lib/pure/os.nim b/lib/pure/os.nim index b85181edf..a1ae4e250 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -790,7 +790,10 @@ iterator walkDir*(dir: string; relative=false): tuple[kind: PathComponent, path: while true: var x = readdir(d) if x == nil: break - var y = $x.d_name + when defined(nimNoArrayToCstringConversion): + var y = $cstring(addr x.d_name) + else: + var y = $x.d_name.cstring if y != "." and y != "..": var s: Stat if not relative: diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 07429b9a9..71d3d9c72 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -280,7 +280,7 @@ proc execProcesses*(cmds: openArray[string], ## executes the commands `cmds` in parallel. Creates `n` processes ## that execute in parallel. The highest return value of all processes ## is returned. Runs `beforeRunEvent` before running each command. - when defined(posix): + when false: # poParentStreams causes problems on Posix, so we simply disable it: var options = options - {poParentStreams} @@ -617,6 +617,7 @@ when defined(Windows) and not defined(useNimRtl): var res: int32 discard getExitCodeProcess(p.fProcessHandle, res) result = res + p.exitStatus = res discard closeHandle(p.fProcessHandle) proc peekExitCode(p: Process): int = @@ -625,6 +626,7 @@ when defined(Windows) and not defined(useNimRtl): else: var res: int32 discard getExitCodeProcess(p.fProcessHandle, res) + if res == 0: return p.exitStatus return res proc inputStream(p: Process): Stream = diff --git a/lib/pure/parsecsv.nim b/lib/pure/parsecsv.nim index 77b145a73..ca0f3f9e0 100644 --- a/lib/pure/parsecsv.nim +++ b/lib/pure/parsecsv.nim @@ -72,7 +72,10 @@ proc raiseEInvalidCsv(filename: string, line, col: int, msg: string) {.noreturn.} = var e: ref CsvError new(e) - e.msg = filename & "(" & $line & ", " & $col & ") Error: " & msg + if filename.len == 0: + e.msg = "Error: " & msg + else: + e.msg = filename & "(" & $line & ", " & $col & ") Error: " & msg raise e proc error(my: CsvParser, pos: int, msg: string) = diff --git a/lib/pure/parseopt2.nim b/lib/pure/parseopt2.nim index 2e8dbe140..a2ff9bf0c 100644 --- a/lib/pure/parseopt2.nim +++ b/lib/pure/parseopt2.nim @@ -35,7 +35,7 @@ type cmd: seq[string] pos: int remainingShortOptions: string - kind*: CmdLineKind ## the dected command line token + kind*: CmdLineKind ## the detected command line token key*, val*: TaintedString ## key and value pair; ``key`` is the option ## or the argument, ``value`` is not "" if ## the option was given a value diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim index b78e8d000..3c790512f 100644 --- a/lib/pure/parseutils.nim +++ b/lib/pure/parseutils.nim @@ -8,6 +8,8 @@ # ## This module contains helpers for parsing tokens, numbers, identifiers, etc. +## +## To unpack raw bytes look at the `streams <streams.html>`_ module. {.deadCodeElim: on.} diff --git a/lib/pure/random.nim b/lib/pure/random.nim index 27fbfad45..e6a9162c5 100644 --- a/lib/pure/random.nim +++ b/lib/pure/random.nim @@ -93,7 +93,7 @@ proc random*(max: float): float {.benign.} = let u = (0x3FFu64 shl 52u64) or (x shr 12u64) result = (cast[float](u) - 1.0) * max -proc random*[T](x: Slice[T]): T = +proc random*[T](x: HSlice[T, T]): T = ## For a slice `a .. b` returns a value in the range `a .. b-1`. result = T(random(x.b - x.a)) + x.a diff --git a/lib/pure/rationals.nim b/lib/pure/rationals.nim index c2ba2b1f3..7fb24c26f 100644 --- a/lib/pure/rationals.nim +++ b/lib/pure/rationals.nim @@ -39,47 +39,13 @@ proc toRational*[T:SomeInteger](x: T): Rational[T] = result.num = x result.den = 1 -proc toRationalSub(x: float, n: int): Rational[int] = - var - a = 0'i64 - b, c, d = 1'i64 - result = 0 // 1 # rational 0 - while b <= n and d <= n: - let ac = (a+c) - let bd = (b+d) - # scale by 1000 so not overflow for high precision - let mediant = (ac.float/1000) / (bd.float/1000) - if x == mediant: - if bd <= n: - result.num = ac.int - result.den = bd.int - return result - elif d > b: - result.num = c.int - result.den = d.int - return result - else: - result.num = a.int - result.den = b.int - return result - elif x > mediant: - a = ac - b = bd - else: - c = ac - d = bd - if (b > n): - return initRational(c.int, d.int) - return initRational(a.int, b.int) - -proc toRational*(x: float, n: int = high(int)): Rational[int] = - ## Calculate the best rational numerator and denominator +proc toRational*(x: float, n: int = high(int32)): Rational[int] = + ## Calculates the best rational numerator and denominator ## that approximates to `x`, where the denominator is ## smaller than `n` (default is the largest possible - ## int to give maximum resolution) + ## int to give maximum resolution). ## - ## The algorithm is based on the Farey sequence named - ## after John Farey + ## The algorithm is based on the theory of continued fractions. ## ## .. code-block:: Nim ## import math, rationals @@ -88,13 +54,24 @@ proc toRational*(x: float, n: int = high(int)): Rational[int] = ## let x = toRational(PI, t) ## let newPI = x.num / x.den ## echo x, " ", newPI, " error: ", PI - newPI, " ", t - if x > 1: - result = toRationalSub(1.0/x, n) - swap(result.num, result.den) - elif x == 1.0: - result = 1 // 1 - else: - result = toRationalSub(x, n) + + # David Eppstein / UC Irvine / 8 Aug 1993 + # With corrections from Arno Formella, May 2008 + var + m11, m22 = 1 + m12, m21 = 0 + ai = int(x) + x = x + while m21 * ai + m22 <= n: + swap m12, m11 + swap m22, m21 + m11 = m12 * ai + m11 + m21 = m22 * ai + m21 + if x == float(ai): break # division by zero + x = 1/(x - float(ai)) + if x > float(high(int32)): break # representation failure + ai = int(x) + result = m11 // m21 proc toFloat*[T](x: Rational[T]): float = ## Convert a rational number `x` to a float. @@ -346,7 +323,14 @@ when isMainModule: assert abs(toFloat(y) - 0.4814814814814815) < 1.0e-7 assert toInt(z) == 0 - assert toRational(0.98765432) == 12345679 // 12500000 - assert toRational(0.1, 1000000) == 1 // 10 - assert toRational(0.9, 1000000) == 9 // 10 - #assert toRational(PI) == 80143857 // 25510582 + assert toRational(0.98765432) == 2111111029 // 2137499919 + assert toRational(PI) == 817696623 // 260280919 + assert toRational(0.1) == 1 // 10 + assert toRational(0.9) == 9 // 10 + + assert toRational(0.0) == 0 // 1 + assert toRational(-0.25) == 1 // -4 + assert toRational(3.2) == 16 // 5 + assert toRational(0.33) == 33 // 100 + assert toRational(0.22) == 11 // 50 + assert toRational(10.0) == 10 // 1 diff --git a/lib/pure/securehash.nim b/lib/pure/securehash.nim index c19146669..57c1f3631 100644 --- a/lib/pure/securehash.nim +++ b/lib/pure/securehash.nim @@ -181,7 +181,7 @@ proc `$`*(self: SecureHash): string = result.add(toHex(int(v), 2)) proc parseSecureHash*(hash: string): SecureHash = - for i in 0.. <Sha1DigestSize: + for i in 0 ..< Sha1DigestSize: Sha1Digest(result)[i] = uint8(parseHexInt(hash[i*2] & hash[i*2 + 1])) proc `==`*(a, b: SecureHash): bool = diff --git a/lib/pure/selectors.nim b/lib/pure/selectors.nim index 506b2cec0..d17b6c253 100644 --- a/lib/pure/selectors.nim +++ b/lib/pure/selectors.nim @@ -162,7 +162,7 @@ elif defined(linux): return @[] raiseOSError(err) if evNum == 0: return @[] - for i in 0 .. <evNum: + for i in 0 ..< evNum: let fd = s.events[i].data.fd.SocketHandle var evSet: set[Event] = {} @@ -253,7 +253,7 @@ elif defined(macosx) or defined(freebsd) or defined(openbsd) or defined(netbsd): return @[] raiseOSError(err) if evNum == 0: return @[] - for i in 0 .. <evNum: + for i in 0 ..< evNum: let fd = s.events[i].ident.SocketHandle var evSet: set[Event] = {} diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim index 69f673990..354e07da3 100644 --- a/lib/pure/streams.nim +++ b/lib/pure/streams.nim @@ -224,6 +224,38 @@ proc peekInt64*(s: Stream): int64 = ## peeks an int64 from the stream `s`. Raises `EIO` if an error occurred. peek(s, result) +proc readUint8*(s: Stream): uint8 = + ## reads an uint8 from the stream `s`. Raises `EIO` if an error occurred. + read(s, result) + +proc peekUint8*(s: Stream): uint8 = + ## peeks an uint8 from the stream `s`. Raises `EIO` if an error occurred. + peek(s, result) + +proc readUint16*(s: Stream): uint16 = + ## reads an uint16 from the stream `s`. Raises `EIO` if an error occurred. + read(s, result) + +proc peekUint16*(s: Stream): uint16 = + ## peeks an uint16 from the stream `s`. Raises `EIO` if an error occurred. + peek(s, result) + +proc readUint32*(s: Stream): uint32 = + ## reads an uint32 from the stream `s`. Raises `EIO` if an error occurred. + read(s, result) + +proc peekUint32*(s: Stream): uint32 = + ## peeks an uint32 from the stream `s`. Raises `EIO` if an error occurred. + peek(s, result) + +proc readUint64*(s: Stream): uint64 = + ## reads an uint64 from the stream `s`. Raises `EIO` if an error occurred. + read(s, result) + +proc peekUint64*(s: Stream): uint64 = + ## peeks an uint64 from the stream `s`. Raises `EIO` if an error occurred. + peek(s, result) + proc readFloat32*(s: Stream): float32 = ## reads a float32 from the stream `s`. Raises `EIO` if an error occurred. read(s, result) diff --git a/lib/pure/strscans.nim b/lib/pure/strscans.nim index bf26d2e59..a54556915 100644 --- a/lib/pure/strscans.nim +++ b/lib/pure/strscans.nim @@ -253,7 +253,7 @@ is performed. for r in collectLinks(body): echo r -In this example both macros are combined seamlessly in order to maximise +In this example both macros are combined seamlessly in order to maximise efficiency and perform different checks. .. code-block:: nim @@ -308,7 +308,7 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b ## See top level documentation of his module of how ``scanf`` works. template matchBind(parser) {.dirty.} = var resLen = genSym(nskLet, "resLen") - conds.add newLetStmt(resLen, newCall(bindSym(parser), input, results[i], idx)) + conds.add newLetStmt(resLen, newCall(bindSym(parser), inp, results[i], idx)) conds.add resLen.notZero conds.add resLen @@ -316,7 +316,8 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b var p = 0 var idx = genSym(nskVar, "idx") var res = genSym(nskVar, "res") - result = newTree(nnkStmtListExpr, newVarStmt(idx, newLit 0), newVarStmt(res, newLit false)) + let inp = genSym(nskLet, "inp") + result = newTree(nnkStmtListExpr, newLetStmt(inp, input), newVarStmt(idx, newLit 0), newVarStmt(res, newLit false)) var conds = newTree(nnkStmtList) var fullMatch = false while p < pattern.len: @@ -325,7 +326,7 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b case pattern[p] of '$': var resLen = genSym(nskLet, "resLen") - conds.add newLetStmt(resLen, newCall(bindSym"skip", input, newLit($pattern[p]), idx)) + conds.add newLetStmt(resLen, newCall(bindSym"skip", inp, newLit($pattern[p]), idx)) conds.add resLen.notZero conds.add resLen of 'w': @@ -347,7 +348,7 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b error("no float var given for $f") inc i of 's': - conds.add newCall(bindSym"inc", idx, newCall(bindSym"skipWhitespace", input, idx)) + conds.add newCall(bindSym"inc", idx, newCall(bindSym"skipWhitespace", inp, idx)) conds.add newEmptyNode() conds.add newEmptyNode() of '.': @@ -364,7 +365,7 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b token.add pattern[q] inc q var resLen = genSym(nskLet, "resLen") - conds.add newLetStmt(resLen, newCall(bindSym"parseUntil", input, results[i], newLit(token), idx)) + conds.add newLetStmt(resLen, newCall(bindSym"parseUntil", inp, results[i], newLit(token), idx)) conds.add newCall(bindSym"!=", resLen, newLit min) conds.add resLen else: @@ -386,7 +387,7 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b let expr = pattern.substr(start, p-1) if i < results.len: var resLen = genSym(nskLet, "resLen") - conds.add newLetStmt(resLen, buildUserCall(expr, input, results[i], idx)) + conds.add newLetStmt(resLen, buildUserCall(expr, inp, results[i], idx)) conds.add newCall(bindSym"!=", resLen, newLit 0) conds.add resLen else: @@ -406,7 +407,7 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b else: discard inc p let expr = pattern.substr(start, p-1) - conds.add newCall(bindSym"inc", idx, buildUserCall(expr, input, idx)) + conds.add newCall(bindSym"inc", idx, buildUserCall(expr, inp, idx)) conds.add newEmptyNode() conds.add newEmptyNode() else: error("invalid format string") @@ -417,13 +418,13 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b token.add pattern[p] inc p var resLen = genSym(nskLet, "resLen") - conds.add newLetStmt(resLen, newCall(bindSym"skip", input, newLit(token), idx)) + conds.add newLetStmt(resLen, newCall(bindSym"skip", inp, newLit(token), idx)) conds.add resLen.notZero conds.add resLen result.add conditionsToIfChain(conds, idx, res, 0) if fullMatch: result.add newCall(bindSym"and", res, - newCall(bindSym">=", idx, newCall(bindSym"len", input))) + newCall(bindSym">=", idx, newCall(bindSym"len", inp))) else: result.add res @@ -684,3 +685,14 @@ when isMainModule: "NimMain c:/users/anwender/projects/nim/lib/system.nim:2613", "main c:/users/anwender/projects/nim/lib/system.nim:2620"] doAssert parseGDB(gdbOut) == result + + # bug #6487 + var count = 0 + + proc test(): string = + inc count + result = ",123123" + + var a: int + discard scanf(test(), ",$i", a) + doAssert count == 1 diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 8b4e6bd05..2b87e0d43 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -138,7 +138,8 @@ proc isAlphaNumeric*(s: string): bool {.noSideEffect, procvar, result = true for c in s: - result = c.isAlphaNumeric() and result + if not c.isAlphaNumeric(): + return false proc isDigit*(s: string): bool {.noSideEffect, procvar, rtl, extern: "nsuIsDigitStr".}= @@ -153,7 +154,8 @@ proc isDigit*(s: string): bool {.noSideEffect, procvar, result = true for c in s: - result = c.isDigit() and result + if not c.isDigit(): + return false proc isSpaceAscii*(s: string): bool {.noSideEffect, procvar, rtl, extern: "nsuIsSpaceAsciiStr".}= @@ -1062,8 +1064,8 @@ proc align*(s: string, count: Natural, padding = ' '): string {. ## ## `padding` characters (by default spaces) are added before `s` resulting in ## right alignment. If ``s.len >= count``, no spaces are added and `s` is - ## returned unchanged. If you need to left align a string use the `repeatChar - ## proc <#repeatChar>`_. Example: + ## returned unchanged. If you need to left align a string use the `alignLeft + ## proc <#alignLeft>`_. Example: ## ## .. code-block:: nim ## assert align("abc", 4) == " abc" @@ -1078,6 +1080,28 @@ proc align*(s: string, count: Natural, padding = ' '): string {. else: result = s +proc alignLeft*(s: string, count: Natural, padding = ' '): string {.noSideEffect.} = + ## Left-Aligns a string `s` with `padding`, so that it is of length `count`. + ## + ## `padding` characters (by default spaces) are added after `s` resulting in + ## left alignment. If ``s.len >= count``, no spaces are added and `s` is + ## returned unchanged. If you need to right align a string use the `align + ## proc <#align>`_. Example: + ## + ## .. code-block:: nim + ## assert alignLeft("abc", 4) == "abc " + ## assert alignLeft("a", 0) == "a" + ## assert alignLeft("1232", 6) == "1232 " + ## assert alignLeft("1232", 6, '#') == "1232##" + if s.len < count: + result = newString(count) + if s.len > 0: + result[0 .. (s.len - 1)] = s + for i in s.len ..< count: + result[i] = padding + else: + result = s + iterator tokenize*(s: string, seps: set[char] = Whitespace): tuple[ token: string, isSep: bool] = ## Tokenizes the string `s` into substrings. @@ -1175,7 +1199,7 @@ proc unindent*(s: string, count: Natural, padding: string = " "): string var indentCount = 0 for j in 0..<count.int: indentCount.inc - if line[j .. j + <padding.len] != padding: + if line[j .. j + padding.len-1] != padding: indentCount = j break result.add(line[indentCount*padding.len .. ^1]) @@ -1306,18 +1330,36 @@ proc join*[T: not string](a: openArray[T], sep: string = ""): string {. add(result, $x) type - SkipTable = array[char, int] - -{.push profiler: off.} -proc preprocessSub(sub: string, a: var SkipTable) = - var m = len(sub) - for i in 0..0xff: a[chr(i)] = m+1 - for i in 0..m-1: a[sub[i]] = m-i -{.pop.} + SkipTable* = array[char, int] -proc findAux(s, sub: string, start, last: int, a: SkipTable): int = - # Fast "quick search" algorithm: - var +proc initSkipTable*(a: var SkipTable, sub: string) + {.noSideEffect, rtl, extern: "nsuInitSkipTable".} = + ## Preprocess table `a` for `sub`. + let m = len(sub) + let m1 = m + 1 + var i = 0 + while i <= 0xff-7: + a[chr(i + 0)] = m1 + a[chr(i + 1)] = m1 + a[chr(i + 2)] = m1 + a[chr(i + 3)] = m1 + a[chr(i + 4)] = m1 + a[chr(i + 5)] = m1 + a[chr(i + 6)] = m1 + a[chr(i + 7)] = m1 + i += 8 + + for i in 0..m-1: + a[sub[i]] = m-i + +proc find*(a: SkipTable, s, sub: string, start: Natural = 0, last: Natural = 0): int + {.noSideEffect, rtl, extern: "nsuFindStrA".} = + ## Searches for `sub` in `s` inside range `start`..`last` using preprocessed table `a`. + ## If `last` is unspecified, it defaults to `s.high`. + ## + ## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned. + let + last = if last==0: s.high else: last m = len(sub) n = last + 1 # search: @@ -1337,17 +1379,6 @@ when not (defined(js) or defined(nimdoc) or defined(nimscript)): else: const hasCStringBuiltin = false -proc find*(s, sub: string, start: Natural = 0, last: Natural = 0): int {.noSideEffect, - rtl, extern: "nsuFindStr".} = - ## Searches for `sub` in `s` inside range `start`..`last`. - ## If `last` is unspecified, it defaults to `s.high`. - ## - ## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned. - var a {.noinit.}: SkipTable - let last = if last==0: s.high else: last - preprocessSub(sub, a) - result = findAux(s, sub, start, last, a) - proc find*(s: string, sub: char, start: Natural = 0, last: Natural = 0): int {.noSideEffect, rtl, extern: "nsuFindChar".} = ## Searches for `sub` in `s` inside range `start`..`last`. @@ -1366,9 +1397,24 @@ proc find*(s: string, sub: char, start: Natural = 0, last: Natural = 0): int {.n else: for i in start..last: if sub == s[i]: return i - return -1 +proc find*(s, sub: string, start: Natural = 0, last: Natural = 0): int {.noSideEffect, + rtl, extern: "nsuFindStr".} = + ## Searches for `sub` in `s` inside range `start`..`last`. + ## If `last` is unspecified, it defaults to `s.high`. + ## + ## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned. + if sub.len > s.len: + return -1 + + if sub.len == 1: + return find(s, sub[0], start, last) + + var a {.noinit.}: SkipTable + initSkipTable(a, sub) + result = find(a, s, sub, start, last) + proc find*(s: string, chars: set[char], start: Natural = 0, last: Natural = 0): int {.noSideEffect, rtl, extern: "nsuFindCharSet".} = ## Searches for `chars` in `s` inside range `start`..`last`. @@ -1500,11 +1546,11 @@ proc replace*(s, sub: string, by = ""): string {.noSideEffect, ## Replaces `sub` in `s` by the string `by`. var a {.noinit.}: SkipTable result = "" - preprocessSub(sub, a) + initSkipTable(a, sub) let last = s.high var i = 0 while true: - var j = findAux(s, sub, i, last, a) + var j = find(a, s, sub, i, last) if j < 0: break add result, substr(s, i, j - 1) add result, by @@ -1534,11 +1580,11 @@ proc replaceWord*(s, sub: string, by = ""): string {.noSideEffect, const wordChars = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\128'..'\255'} var a {.noinit.}: SkipTable result = "" - preprocessSub(sub, a) + initSkipTable(a, sub) var i = 0 let last = s.high while true: - var j = findAux(s, sub, i, last, a) + var j = find(a, s, sub, i, last) if j < 0: break # word boundary? if (j == 0 or s[j-1] notin wordChars) and @@ -1890,17 +1936,32 @@ proc formatBiggestFloat*(f: BiggestFloat, format: FloatFormatMode = ffDefault, frmtstr[3] = '*' frmtstr[4] = floatFormatToChar[format] frmtstr[5] = '\0' - L = c_sprintf(buf, frmtstr, precision, f) + when defined(nimNoArrayToCstringConversion): + L = c_sprintf(addr buf, addr frmtstr, precision, f) + else: + L = c_sprintf(buf, frmtstr, precision, f) else: frmtstr[1] = floatFormatToChar[format] frmtstr[2] = '\0' - L = c_sprintf(buf, frmtstr, f) + when defined(nimNoArrayToCstringConversion): + L = c_sprintf(addr buf, addr frmtstr, f) + else: + L = c_sprintf(buf, frmtstr, f) result = newString(L) for i in 0 ..< L: # Depending on the locale either dot or comma is produced, # but nothing else is possible: if buf[i] in {'.', ','}: result[i] = decimalsep else: result[i] = buf[i] + when defined(vcc): + # VS pre 2015 violates the C standard: "The exponent always contains at + # least two digits, and only as many more digits as necessary to + # represent the exponent." [C11 §7.21.6.1] + # The following post-processing fixes this behavior. + if result.len > 4 and result[^4] == '+' and result[^3] == '0': + result[^3] = result[^2] + result[^2] = result[^1] + result.setLen(result.len - 1) proc formatFloat*(f: float, format: FloatFormatMode = ffDefault, precision: range[0..32] = 16; decimalSep = '.'): string {. @@ -2169,11 +2230,26 @@ proc addf*(s: var string, formatstr: string, a: varargs[string, `$`]) {. if idx >% a.high: invalidFormatString() add s, a[idx] of '{': - var j = i+1 - while formatstr[j] notin {'\0', '}'}: inc(j) - var x = findNormalized(substr(formatstr, i+2, j-1), a) - if x >= 0 and x < high(a): add s, a[x+1] - else: invalidFormatString() + var j = i+2 + var k = 0 + var negative = formatstr[j] == '-' + if negative: inc j + var isNumber = 0 + while formatstr[j] notin {'\0', '}'}: + if formatstr[j] in Digits: + k = k * 10 + ord(formatstr[j]) - ord('0') + if isNumber == 0: isNumber = 1 + else: + isNumber = -1 + inc(j) + if isNumber == 1: + let idx = if not negative: k-1 else: a.len-k + if idx >% a.high: invalidFormatString() + add s, a[idx] + else: + var x = findNormalized(substr(formatstr, i+2, j-1), a) + if x >= 0 and x < high(a): add s, a[x+1] + else: invalidFormatString() i = j+1 of 'a'..'z', 'A'..'Z', '\128'..'\255', '_': var j = i+1 @@ -2250,60 +2326,104 @@ proc format*(formatstr: string, a: varargs[string, `$`]): string {.noSideEffect, proc removeSuffix*(s: var string, chars: set[char] = Newlines) {. rtl, extern: "nsuRemoveSuffixCharSet".} = - ## Removes the first matching character from the string (in-place) given a - ## set of characters. If the set of characters is only equal to `Newlines` - ## then it will remove both the newline and return feed. + ## Removes all characters from `chars` from the end of the string `s` + ## (in-place). + ## ## .. code-block:: nim - ## var - ## userInput = "Hello World!\r\n" - ## otherInput = "Hello!?!" + ## var userInput = "Hello World!*~\r\n" ## userInput.removeSuffix - ## userInput == "Hello World!" - ## userInput.removeSuffix({'!', '?'}) - ## userInput == "Hello World" + ## doAssert userInput == "Hello World!*~" + ## userInput.removeSuffix({'~', '*'}) + ## doAssert userInput == "Hello World!" + ## + ## var otherInput = "Hello!?!" ## otherInput.removeSuffix({'!', '?'}) - ## otherInput == "Hello!?" + ## doAssert otherInput == "Hello" if s.len == 0: return - var last = len(s) - 1 - if chars == Newlines: - if s[last] == '\10': - last -= 1 - if s[last] == '\13': - last -= 1 - else: - if s[last] in chars: - last -= 1 + var last = s.high + while last > -1 and s[last] in chars: last -= 1 s.setLen(last + 1) proc removeSuffix*(s: var string, c: char) {. rtl, extern: "nsuRemoveSuffixChar".} = - ## Removes a single character (in-place) from a string. + ## Removes all occurrences of a single character (in-place) from the end + ## of a string. + ## ## .. code-block:: nim - ## var - ## table = "users" + ## var table = "users" ## table.removeSuffix('s') - ## table == "user" + ## doAssert table == "user" + ## + ## var dots = "Trailing dots......." + ## dots.removeSuffix('.') + ## doAssert dots == "Trailing dots" removeSuffix(s, chars = {c}) proc removeSuffix*(s: var string, suffix: string) {. rtl, extern: "nsuRemoveSuffixString".} = ## Remove the first matching suffix (in-place) from a string. + ## ## .. code-block:: nim - ## var - ## answers = "yeses" + ## var answers = "yeses" ## answers.removeSuffix("es") - ## answers == "yes" + ## doAssert answers == "yes" var newLen = s.len if s.endsWith(suffix): newLen -= len(suffix) s.setLen(newLen) +proc removePrefix*(s: var string, chars: set[char] = Newlines) {. + rtl, extern: "nsuRemovePrefixCharSet".} = + ## Removes all characters from `chars` from the start of the string `s` + ## (in-place). + ## + ## .. code-block:: nim + ## var userInput = "\r\n*~Hello World!" + ## userInput.removePrefix + ## doAssert userInput == "*~Hello World!" + ## userInput.removePrefix({'~', '*'}) + ## doAssert userInput == "Hello World!" + ## + ## var otherInput = "?!?Hello!?!" + ## otherInput.removePrefix({'!', '?'}) + ## doAssert otherInput == "Hello!?!" + var start = 0 + while start < s.len and s[start] in chars: start += 1 + if start > 0: s.delete(0, start - 1) + +proc removePrefix*(s: var string, c: char) {. + rtl, extern: "nsuRemovePrefixChar".} = + ## Removes all occurrences of a single character (in-place) from the start + ## of a string. + ## + ## .. code-block:: nim + ## var ident = "pControl" + ## ident.removePrefix('p') + ## doAssert ident == "Control" + removePrefix(s, chars = {c}) + +proc removePrefix*(s: var string, prefix: string) {. + rtl, extern: "nsuRemovePrefixString".} = + ## Remove the first matching prefix (in-place) from a string. + ## + ## .. code-block:: nim + ## var answers = "yesyes" + ## answers.removePrefix("yes") + ## doAssert answers == "yes" + if s.startsWith(prefix): + s.delete(0, prefix.len - 1) + when isMainModule: doAssert align("abc", 4) == " abc" doAssert align("a", 0) == "a" doAssert align("1232", 6) == " 1232" doAssert align("1232", 6, '#') == "##1232" + doAssert alignLeft("abc", 4) == "abc " + doAssert alignLeft("a", 0) == "a" + doAssert alignLeft("1232", 6) == "1232 " + doAssert alignLeft("1232", 6, '#') == "1232##" + let inp = """ this is a long text -- muchlongerthan10chars and here it goes""" @@ -2313,8 +2433,12 @@ when isMainModule: doAssert formatBiggestFloat(0.00000000001, ffDecimal, 11) == "0.00000000001" doAssert formatBiggestFloat(0.00000000001, ffScientific, 1, ',') in ["1,0e-11", "1,0e-011"] + # bug #6589 + doAssert formatFloat(123.456, ffScientific, precision=0) in + ["1.234560e+02", "1.234560e+002"] doAssert "$# $3 $# $#" % ["a", "b", "c"] == "a c b c" + doAssert "${1}12 ${-1}$2" % ["a", "b"] == "a12 bb" block: # formatSize tests doAssert formatSize((1'i64 shl 31) + (300'i64 shl 20)) == "2.293GiB" diff --git a/lib/pure/times.nim b/lib/pure/times.nim index 68a457084..7dd428904 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -77,20 +77,17 @@ when defined(posix) and not defined(JS): when not defined(freebsd) and not defined(netbsd) and not defined(openbsd): var timezone {.importc, header: "<time.h>".}: int + proc tzset(): void {.importc, header: "<time.h>".} + tzset() elif defined(windows): import winlean - when defined(vcc) or defined(bcc) or defined(icl): - # newest version of Visual C++ defines time_t to be of 64 bits - type TimeImpl {.importc: "time_t", header: "<time.h>".} = int64 - # visual c's c runtime exposes these under a different name - var - timezone {.importc: "_timezone", header: "<time.h>".}: int - else: - type TimeImpl {.importc: "time_t", header: "<time.h>".} = int - var - timezone {.importc, header: "<time.h>".}: int + # newest version of Visual C++ defines time_t to be of 64 bits + type TimeImpl {.importc: "time_t", header: "<time.h>".} = int64 + # visual c's c runtime exposes these under a different name + var + timezone {.importc: "_timezone", header: "<time.h>".}: int type Time* = distinct TimeImpl @@ -1028,7 +1025,7 @@ proc countLeapYears*(yearSpan: int): int = ## counts the number of leap years up to January 1st of a given year. ## Keep in mind that if specified year is a leap year, the leap day ## has not happened before January 1st of that year. - (((yearSpan - 1) / 4) - ((yearSpan - 1) / 100) + ((yearSpan - 1) / 400)).int + (yearSpan - 1) div 4 - (yearSpan - 1) div 100 + (yearSpan - 1) div 400 proc countDays*(yearSpan: int): int = ## Returns the number of days spanned by a given number of years. diff --git a/lib/pure/typetraits.nim b/lib/pure/typetraits.nim index 55c4bf038..3b6f7de1a 100644 --- a/lib/pure/typetraits.nim +++ b/lib/pure/typetraits.nim @@ -31,6 +31,10 @@ proc name*(t: typedesc): string {.magic: "TypeTrait".} ## test(@['A','B']) ## # --> type: seq[char], value: @[A, B] +proc `$`*(t: typedesc): string = + ## An alias for `name`. + name(t) + proc arity*(t: typedesc): int {.magic: "TypeTrait".} ## Returns the arity of the given type @@ -49,3 +53,15 @@ proc stripGenericParams*(t: typedesc): typedesc {.magic: "TypeTrait".} ## This trait is similar to `genericHead`, but instead of producing ## error for non-generic types, it will just return them unmodified +proc supportsCopyMem*(t: typedesc): bool {.magic: "TypeTrait".} + ## This trait returns true iff the type ``t`` is safe to use for + ## `copyMem`:idx:. Other languages name a type like these `blob`:idx:. + + +when isMainModule: + # echo type(42) + import streams + var ss = newStringStream() + ss.write($type(42)) # needs `$` + ss.setPosition(0) + doAssert ss.readAll() == "int" diff --git a/lib/pure/unicode.nim b/lib/pure/unicode.nim index 0c4f15c91..7d9c3108b 100644 --- a/lib/pure/unicode.nim +++ b/lib/pure/unicode.nim @@ -285,7 +285,7 @@ proc runeReverseOffset*(s: string, rev:Positive): (int, int) = proc runeSubStr*(s: string, pos:int, len:int = int.high): string = ## Returns the UTF-8 substring starting at codepoint pos - ## with len codepoints. If pos or len is negativ they count from + ## with len codepoints. If pos or len is negative they count from ## the end of the string. If len is not given it means the longest ## possible string. ## diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim index 3772a213a..7a8d1dad0 100644 --- a/lib/pure/unittest.nim +++ b/lib/pure/unittest.nim @@ -312,7 +312,7 @@ proc ensureInitialized() = if not testsToRun.isValid: testsToRun.init() - when declared(os): + when declared(paramCount): # Read tests to run from the command line. for i in 1 .. paramCount(): testsToRun.incl(paramStr(i)) diff --git a/lib/pure/uri.nim b/lib/pure/uri.nim index d8e4ed52f..c702b054c 100644 --- a/lib/pure/uri.nim +++ b/lib/pure/uri.nim @@ -250,7 +250,7 @@ proc combine*(base: Uri, reference: Uri): Uri = proc combine*(uris: varargs[Uri]): Uri = ## Combines multiple URIs together. result = uris[0] - for i in 1 .. <uris.len: + for i in 1 ..< uris.len: result = combine(result, uris[i]) proc isAbsolute*(uri: Uri): bool = @@ -278,7 +278,9 @@ proc `/`*(x: Uri, path: string): Uri = result = x if result.path.len == 0: - result.path = path + if path[0] != '/': + result.path = "/" + result.path.add(path) return if result.path[result.path.len-1] == '/': @@ -476,6 +478,11 @@ when isMainModule: let foo = parseUri("http://example.com") / "/baz" doAssert foo.path == "/baz" + # bug found on stream 13/10/17 + block: + let foo = parseUri("http://localhost:9515") / "status" + doAssert $foo == "http://localhost:9515/status" + # isAbsolute tests block: doAssert "www.google.com".parseUri().isAbsolute() == false @@ -515,4 +522,6 @@ when isMainModule: doAssert "https://example.com/about".parseUri().isAbsolute == true doAssert "https://example.com/about/staff.html".parseUri().isAbsolute == true doAssert "https://example.com/about/staff.html?".parseUri().isAbsolute == true - doAssert "https://example.com/about/staff.html?parameters".parseUri().isAbsolute == true \ No newline at end of file + doAssert "https://example.com/about/staff.html?parameters".parseUri().isAbsolute == true + + echo("All good!") \ No newline at end of file diff --git a/lib/system.nim b/lib/system.nim index dc3152faf..92c5e009f 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -275,7 +275,7 @@ proc low*[T](x: T): T {.magic: "Low", noSideEffect.} proc low*[I, T](x: typeDesc[array[I, T]]): I {.magic: "Low", noSideEffect.} proc low*(x: cstring): int {.magic: "Low", noSideEffect.} proc low*(x: string): int {.magic: "Low", noSideEffect.} -## returns the lowest possible index of an array, a sequence, a string or + ## returns the lowest possible index of an array, a sequence, a string or ## the lowest possible value of an ordinal value `x`. As a special ## semantic rule, `x` may also be a type identifier. ## @@ -285,6 +285,13 @@ proc low*(x: string): int {.magic: "Low", noSideEffect.} ## low(2) #=> -9223372036854775808 ## low(int) #=> -9223372036854775808 +proc shallowCopy*[T](x: var T, y: T) {.noSideEffect, magic: "ShallowCopy".} + ## use this instead of `=` for a `shallow copy`:idx:. The shallow copy + ## only changes the semantics for sequences and strings (and types which + ## contain those). Be careful with the changed semantics though! There + ## is a reason why the default assignment does a deep copy of sequences + ## and strings. + when defined(nimArrIdx): # :array|openarray|string|seq|cstring|tuple proc `[]`*[I: Ordinal;T](a: T; i: I): T {. @@ -292,15 +299,21 @@ when defined(nimArrIdx): proc `[]=`*[I: Ordinal;T,S](a: T; i: I; x: S) {.noSideEffect, magic: "ArrPut".} proc `=`*[T](dest: var T; src: T) {.noSideEffect, magic: "Asgn".} + when defined(nimNewRuntime): + proc `=destroy`*[T](x: var T) {.inline, magic: "Asgn".} = + ## generic `destructor`:idx: implementation that can be overriden. + discard + proc `=sink`*[T](x: var T; y: T) {.inline, magic: "Asgn".} = + ## generic `sink`:idx: implementation that can be overriden. + shallowCopy(x, y) type - Slice*[T] = object ## builtin slice type - a*, b*: T ## the bounds + HSlice*[T, U] = object ## "heterogenous" slice type + a*: T ## the lower bound (inclusive) + b*: U ## the upper bound (inclusive) + Slice*[T] = HSlice[T, T] ## an alias for ``HSlice[T, T]`` -when defined(nimalias): - {.deprecated: [TSlice: Slice].} - -proc `..`*[T](a, b: T): Slice[T] {.noSideEffect, inline, magic: "DotDot".} = +proc `..`*[T, U](a: T, b: U): HSlice[T, U] {.noSideEffect, inline, magic: "DotDot".} = ## `slice`:idx: operator that constructs an interval ``[a, b]``, both `a` ## and `b` are inclusive. Slices can also be used in the set constructor ## and in ordinal case statements, but then they are special-cased by the @@ -308,7 +321,7 @@ proc `..`*[T](a, b: T): Slice[T] {.noSideEffect, inline, magic: "DotDot".} = result.a = a result.b = b -proc `..`*[T](b: T): Slice[T] {.noSideEffect, inline, magic: "DotDot".} = +proc `..`*[T](b: T): HSlice[int, T] {.noSideEffect, inline, magic: "DotDot".} = ## `slice`:idx: operator that constructs an interval ``[default(T), b]`` result.b = b @@ -638,13 +651,17 @@ proc sizeof*[T](x: T): int {.magic: "SizeOf", noSideEffect.} when defined(nimtypedescfixed): proc sizeof*(x: typedesc): int {.magic: "SizeOf", noSideEffect.} -proc `<`*[T](x: Ordinal[T]): T {.magic: "UnaryLt", noSideEffect.} +proc `<`*[T](x: Ordinal[T]): T {.magic: "UnaryLt", noSideEffect, deprecated.} ## unary ``<`` that can be used for nice looking excluding ranges: ## ## .. code-block:: nim ## for i in 0 .. <10: echo i #=> 0 1 2 3 4 5 6 7 8 9 ## ## Semantically this is the same as ``pred``. + ## + ## **Deprecated since version 0.18.0**. For the common excluding range + ## write ``0 ..< 10`` instead of ``0 .. < 10`` (look at the spacing). + ## For ``<x`` write ``pred(x)``. proc succ*[T](x: Ordinal[T], y = 1): T {.magic: "Succ", noSideEffect.} ## returns the ``y``-th successor of the value ``x``. ``T`` has to be @@ -1150,7 +1167,7 @@ proc contains*[T](x: set[T], y: T): bool {.magic: "InSet", noSideEffect.} ## is achieved by reversing the parameters for ``contains``; ``in`` then ## passes its arguments in reverse order. -proc contains*[T](s: Slice[T], value: T): bool {.noSideEffect, inline.} = +proc contains*[U, V, W](s: HSlice[U, V], value: W): bool {.noSideEffect, inline.} = ## Checks if `value` is within the range of `s`; returns true iff ## `value >= s.a and value <= s.b` ## @@ -1429,7 +1446,8 @@ when defined(nimdoc): ## <#GC_fullCollect>`_. ## ## The proc ``quit(QuitSuccess)`` is called implicitly when your nim - ## program finishes without incident. A raised unhandled exception is + ## program finishes without incident for platforms where this is the + ## expected behavior. A raised unhandled exception is ## equivalent to calling ``quit(QuitFailure)``. ## ## Note that this is a *runtime* call and using ``quit`` inside a macro won't @@ -1444,7 +1462,7 @@ elif defined(genode): header: "<base/sleep.h>".} elif defined(nodejs): - proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit", + proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit", importc: "process.exit", noreturn.} else: @@ -1480,13 +1498,6 @@ proc add *[T](x: var seq[T], y: openArray[T]) {.noSideEffect.} = setLen(x, xl + y.len) for i in 0..high(y): x[xl+i] = y[i] -proc shallowCopy*[T](x: var T, y: T) {.noSideEffect, magic: "ShallowCopy".} - ## use this instead of `=` for a `shallow copy`:idx:. The shallow copy - ## only changes the semantics for sequences and strings (and types which - ## contain those). Be careful with the changed semantics though! There - ## is a reason why the default assignment does a deep copy of sequences - ## and strings. - proc del*[T](x: var seq[T], i: Natural) {.noSideEffect.} = ## deletes the item at index `i` by putting ``x[high(x)]`` into position `i`. ## This is an O(1) operation. @@ -1875,7 +1886,7 @@ proc `$` *(x: float): string {.magic: "FloatToStr", noSideEffect.} proc `$` *(x: bool): string {.magic: "BoolToStr", noSideEffect.} ## The stringify operator for a boolean argument. Returns `x` ## converted to the string "false" or "true". - +# proc `$` *(x: char): string {.magic: "CharToStr", noSideEffect.} ## The stringify operator for a character argument. Returns `x` ## converted to a string. @@ -2065,6 +2076,9 @@ proc max*[T](x, y: T): T = if y <= x: x else: y {.pop.} +proc high*(T: typedesc[SomeReal]): T = Inf +proc low*(T: typedesc[SomeReal]): T = NegInf + proc clamp*[T](x, a, b: T): T = ## limits the value ``x`` within the interval [a, b] ## @@ -2075,7 +2089,7 @@ proc clamp*[T](x, a, b: T): T = if x > b: return b return x -proc len*[T: Ordinal](x: Slice[T]): int {.noSideEffect, inline.} = +proc len*[U: Ordinal; V: Ordinal](x: HSlice[U, V]): int {.noSideEffect, inline.} = ## length of ordinal slice, when x.b < x.a returns zero length ## ## .. code-block:: Nim @@ -2143,7 +2157,7 @@ iterator items*(E: typedesc[enum]): E = for v in low(E)..high(E): yield v -iterator items*[T](s: Slice[T]): T = +iterator items*[T](s: HSlice[T, T]): T = ## iterates over the slice `s`, yielding each value between `s.a` and `s.b` ## (inclusively). for x in s.a..s.b: @@ -2437,20 +2451,28 @@ proc `$`*[T: tuple|object](x: T): string = result.add("...") result.add(")") -proc collectionToString[T: set | seq](x: T, b, e: string): string = - when x is seq: - if x.isNil: return "nil" - result = b +proc collectionToString[T](x: T, prefix, separator, suffix: string): string = + result = prefix var firstElement = true for value in items(x): - if not firstElement: result.add(", ") + if firstElement: + firstElement = false + else: + result.add(separator) + when compiles(value.isNil): - if value.isNil: result.add "nil" - else: result.add($value) + # this branch should not be necessary + if value.isNil: + result.add "nil" + else: + result.add($value) + # prevent temporary string allocation + elif compiles(result.add(value)): + result.add(value) else: result.add($value) - firstElement = false - result.add(e) + + result.add(suffix) proc `$`*[T](x: set[T]): string = ## generic ``$`` operator for sets that is lifted from the components @@ -2458,7 +2480,7 @@ proc `$`*[T](x: set[T]): string = ## ## .. code-block:: nim ## ${23, 45} == "{23, 45}" - collectionToString(x, "{", "}") + collectionToString(x, "{", ", ", "}") proc `$`*[T](x: seq[T]): string = ## generic ``$`` operator for seqs that is lifted from the components @@ -2466,13 +2488,10 @@ proc `$`*[T](x: seq[T]): string = ## ## .. code-block:: nim ## $(@[23, 45]) == "@[23, 45]" - collectionToString(x, "@[", "]") - -when false: - # causes bootstrapping to fail as we use array of chars and cstring should - # match better ... - proc `$`*[T, IDX](x: array[IDX, T]): string = - collectionToString(x, "[", "]") + if x.isNil: + "nil" + else: + collectionToString(x, "@[", ", ", "]") # ----------------- GC interface --------------------------------------------- @@ -2816,7 +2835,7 @@ when not defined(JS): #and not defined(nimscript): fmRead, ## Open the file for read access only. fmWrite, ## Open the file for write access only. ## If the file does not exist, it will be - ## created. + ## created. Existing files will be cleared! fmReadWrite, ## Open the file for read and write access. ## If the file does not exist, it will be ## created. Existing files will be cleared! @@ -2872,7 +2891,7 @@ when not defined(JS): #and not defined(nimscript): importc: when defined(bcc): "setmode" else: "_setmode", header: "<io.h>".} var - O_BINARY {.importc: "O_BINARY", nodecl.}: cint + O_BINARY {.importc: "_O_BINARY", header:"<fcntl.h>".}: cint # we use binary mode on Windows: c_setmode(c_fileno(stdin), O_BINARY) @@ -3329,6 +3348,10 @@ elif defined(JS): include "system/sysio" +proc `$`*[T, IDX](x: array[IDX, T]): string = + ## generic ``$`` operator for arrays that is lifted from the components + collectionToString(x, "[", ", ", "]") + proc quit*(errormsg: string, errorcode = QuitFailure) {.noReturn.} = ## a shorthand for ``echo(errormsg); quit(errorcode)``. echo(errormsg) @@ -3393,6 +3416,29 @@ proc `/`*(x, y: int): float {.inline, noSideEffect.} = ## integer division that results in a float. result = toFloat(x) / toFloat(y) +type + BackwardsIndex* = distinct int ## type that is constructed by ``^`` for + ## reversed array accesses. + +template `^`*(x: int): BackwardsIndex = BackwardsIndex(x) + ## builtin `roof`:idx: operator that can be used for convenient array access. + ## ``a[^x]`` is a shortcut for ``a[a.len-x]``. + +template `..^`*(a, b: untyped): untyped = + ## a shortcut for '.. ^' to avoid the common gotcha that a space between + ## '..' and '^' is required. + a .. ^b + +template `..<`*(a, b: untyped): untyped = + ## a shortcut for 'a..pred(b)'. + a .. pred(b) + +iterator `..<`*[S,T](a: S, b: T): T = + var i = T(a) + while i < b: + yield i + inc i + template spliceImpl(s, a, L, b: untyped): untyped = # make room for additional elements or cut: var shift = b.len - max(0,L) # ignore negative slice size @@ -3406,19 +3452,22 @@ template spliceImpl(s, a, L, b: untyped): untyped = # cut down: setLen(s, newLen) # fill the hole: - for i in 0 .. <b.len: s[a+i] = b[i] + for i in 0 ..< b.len: s[a+i] = b[i] + +template `^^`(s, i: untyped): untyped = + (when i is BackwardsIndex: s.len - int(i) else: int(i)) when hasAlloc or defined(nimscript): - proc `[]`*(s: string, x: Slice[int]): string {.inline.} = + proc `[]`*[T, U](s: string, x: HSlice[T, U]): string {.inline.} = ## slice operation for strings. ## returns the inclusive range [s[x.a], s[x.b]]: ## ## .. code-block:: nim ## var s = "abcdef" ## assert s[1..3] == "bcd" - result = s.substr(x.a, x.b) + result = s.substr(s ^^ x.a, s ^^ x.b) - proc `[]=`*(s: var string, x: Slice[int], b: string) = + proc `[]=`*[T, U](s: var string, x: HSlice[T, U], b: string) = ## slice assignment for strings. If ## ``b.len`` is not exactly the number of elements that are referred to ## by `x`, a `splice`:idx: is performed: @@ -3427,75 +3476,74 @@ when hasAlloc or defined(nimscript): ## var s = "abcdef" ## s[1 .. ^2] = "xyz" ## assert s == "axyzf" - var a = x.a - var L = x.b - a + 1 + var a = s ^^ x.a + var L = (s ^^ x.b) - a + 1 if L == b.len: - for i in 0 .. <L: s[i+a] = b[i] + for i in 0..<L: s[i+a] = b[i] else: spliceImpl(s, a, L, b) -proc `[]`*[Idx, T](a: array[Idx, T], x: Slice[int]): seq[T] = +proc `[]`*[Idx, T, U, V](a: array[Idx, T], x: HSlice[U, V]): seq[T] = ## slice operation for arrays. ## returns the inclusive range [a[x.a], a[x.b]]: ## ## .. code-block:: nim ## var a = [1,2,3,4] ## assert a[0..2] == @[1,2,3] - when low(a) < 0: - {.error: "Slicing for arrays with negative indices is unsupported.".} - var L = x.b - x.a + 1 + let xa = a ^^ x.a + let L = (a ^^ x.b) - xa + 1 result = newSeq[T](L) - for i in 0.. <L: result[i] = a[i + x.a] - -proc `[]=`*[Idx, T](a: var array[Idx, T], x: Slice[int], b: openArray[T]) = - ## slice assignment for arrays. - when low(a) < 0: - {.error: "Slicing for arrays with negative indices is unsupported.".} - var L = x.b - x.a + 1 - if L == b.len: - for i in 0 .. <L: a[i+x.a] = b[i] - else: - sysFatal(RangeError, "different lengths for slice assignment") - -proc `[]`*[Idx, T](a: array[Idx, T], x: Slice[Idx]): seq[T] = - ## slice operation for arrays. - var L = ord(x.b) - ord(x.a) + 1 - newSeq(result, L) - for i in 0.. <L: - result[i] = a[Idx(ord(x.a) + i)] + for i in 0..<L: result[i] = a[Idx(i + xa + int low(a))] -proc `[]=`*[Idx, T](a: var array[Idx, T], x: Slice[Idx], b: openArray[T]) = +proc `[]=`*[Idx, T, U, V](a: var array[Idx, T], x: HSlice[U, V], b: openArray[T]) = ## slice assignment for arrays. - var L = ord(x.b) - ord(x.a) + 1 + let xa = a ^^ x.a + let L = (a ^^ x.b) - xa + 1 if L == b.len: - for i in 0 .. <L: - a[Idx(ord(x.a) + i)] = b[i] + for i in 0..<L: a[Idx(i + xa + int low(a))] = b[i] else: sysFatal(RangeError, "different lengths for slice assignment") -proc `[]`*[T](s: seq[T], x: Slice[int]): seq[T] = +proc `[]`*[T, U, V](s: openArray[T], x: HSlice[U, V]): seq[T] = ## slice operation for sequences. ## returns the inclusive range [s[x.a], s[x.b]]: ## ## .. code-block:: nim ## var s = @[1,2,3,4] ## assert s[0..2] == @[1,2,3] - var a = x.a - var L = x.b - a + 1 + let a = s ^^ x.a + let L = (s ^^ x.b) - a + 1 newSeq(result, L) - for i in 0.. <L: result[i] = s[i + a] + for i in 0 ..< L: result[i] = s[i + a] -proc `[]=`*[T](s: var seq[T], x: Slice[int], b: openArray[T]) = +proc `[]=`*[T, U, V](s: var seq[T], x: HSlice[U, V], b: openArray[T]) = ## slice assignment for sequences. If ## ``b.len`` is not exactly the number of elements that are referred to ## by `x`, a `splice`:idx: is performed. - var a = x.a - var L = x.b - a + 1 + let a = s ^^ x.a + let L = (s ^^ x.b) - a + 1 if L == b.len: - for i in 0 .. <L: s[i+a] = b[i] + for i in 0 ..< L: s[i+a] = b[i] else: spliceImpl(s, a, L, b) +proc `[]`*[T](s: openArray[T]; i: BackwardsIndex): T {.inline.} = s[s.len - int(i)] +proc `[]`*[Idx, T](a: array[Idx, T]; i: BackwardsIndex): T {.inline.} = + a[Idx(a.len - int(i) + int low(a))] +proc `[]`*(s: string; i: BackwardsIndex): char {.inline.} = s[s.len - int(i)] + +proc `[]`*[T](s: var openArray[T]; i: BackwardsIndex): var T {.inline.} = + s[s.len - int(i)] +proc `[]`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex): var T {.inline.} = + a[Idx(a.len - int(i) + int low(a))] + +proc `[]=`*[T](s: var openArray[T]; i: BackwardsIndex; x: T) {.inline.} = + s[s.len - int(i)] = x +proc `[]=`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex; x: T) {.inline.} = + a[Idx(a.len - int(i) + int low(a))] = x +proc `[]=`*(s: var string; i: BackwardsIndex; x: char) {.inline.} = + s[s.len - int(i)] = x + proc slurp*(filename: string): string {.magic: "Slurp".} ## This is an alias for `staticRead <#staticRead>`_. @@ -3836,31 +3884,6 @@ proc procCall*(x: untyped) {.magic: "ProcCall", compileTime.} = ## procCall someMethod(a, b) discard -proc `^`*[T](x: int; y: openArray[T]): int {.noSideEffect, magic: "Roof".} -proc `^`*(x: int): int {.noSideEffect, magic: "Roof".} = - ## builtin `roof`:idx: operator that can be used for convenient array access. - ## ``a[^x]`` is rewritten to ``a[a.len-x]``. However currently the ``a`` - ## expression must not have side effects for this to compile. Note that since - ## this is a builtin, it automatically works for all kinds of - ## overloaded ``[]`` or ``[]=`` accessors. - discard - -template `..^`*(a, b: untyped): untyped = - ## a shortcut for '.. ^' to avoid the common gotcha that a space between - ## '..' and '^' is required. - a .. ^b - -template `..<`*(a, b: untyped): untyped {.dirty.} = - ## a shortcut for '.. <' to avoid the common gotcha that a space between - ## '..' and '<' is required. - a .. <b - -iterator `..<`*[S,T](a: S, b: T): T = - var i = T(a) - while i < b: - yield i - inc i - proc xlen*(x: string): int {.magic: "XLenStr", noSideEffect.} = discard proc xlen*[T](x: seq[T]): int {.magic: "XLenSeq", noSideEffect.} = ## returns the length of a sequence or a string without testing for 'nil'. diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim index 78db96e77..19d27e7d2 100644 --- a/lib/system/alloc.nim +++ b/lib/system/alloc.nim @@ -301,13 +301,14 @@ proc pageAddr(p: pointer): PChunk {.inline.} = result = cast[PChunk](cast[ByteAddress](p) and not PageMask) #sysAssert(Contains(allocator.chunkStarts, pageIndex(result))) -proc writeFreeList(a: MemRegion) = - var it = a.freeChunksList - c_fprintf(stdout, "freeChunksList: %p\n", it) - while it != nil: - c_fprintf(stdout, "it: %p, next: %p, prev: %p, size: %ld\n", - it, it.next, it.prev, it.size) - it = it.next +when false: + proc writeFreeList(a: MemRegion) = + var it = a.freeChunksList + c_fprintf(stdout, "freeChunksList: %p\n", it) + while it != nil: + c_fprintf(stdout, "it: %p, next: %p, prev: %p, size: %ld\n", + it, it.next, it.prev, it.size) + it = it.next const nimMaxHeap {.intdefine.} = 0 diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim index b2f6d314f..0bac979e7 100644 --- a/lib/system/ansi_c.nim +++ b/lib/system/ansi_c.nim @@ -103,8 +103,12 @@ proc c_sprintf(buf, frmt: cstring): cint {. importc: "sprintf", header: "<stdio.h>", varargs, noSideEffect.} # we use it only in a way that cannot lead to security issues -proc c_fileno(f: File): cint {. - importc: "fileno", header: "<fcntl.h>".} +when defined(windows): + proc c_fileno(f: File): cint {. + importc: "_fileno", header: "<stdio.h>".} +else: + proc c_fileno(f: File): cint {. + importc: "fileno", header: "<fcntl.h>".} proc c_malloc(size: csize): pointer {. importc: "malloc", header: "<stdlib.h>".} diff --git a/lib/system/assign.nim b/lib/system/assign.nim index 115df61a7..f061c89cf 100644 --- a/lib/system/assign.nim +++ b/lib/system/assign.nim @@ -61,13 +61,17 @@ proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) = unsureAsgnRef(x, s2) return sysAssert(dest != nil, "genericAssignAux 3") - unsureAsgnRef(x, newSeq(mt, seq.len)) - var dst = cast[ByteAddress](cast[PPointer](dest)[]) if ntfNoRefs in mt.base.flags: + var ss = nimNewSeqOfCap(mt, seq.len) + cast[PGenericSeq](ss).len = seq.len + unsureAsgnRef(x, ss) + var dst = cast[ByteAddress](cast[PPointer](dest)[]) copyMem(cast[pointer](dst +% GenericSeqSize), cast[pointer](cast[ByteAddress](s2) +% GenericSeqSize), seq.len * mt.base.size) else: + unsureAsgnRef(x, newSeq(mt, seq.len)) + var dst = cast[ByteAddress](cast[PPointer](dest)[]) for i in 0..seq.len-1: genericAssignAux( cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize), diff --git a/lib/system/debugger.nim b/lib/system/debugger.nim index cc6919d36..937c0d6f0 100644 --- a/lib/system/debugger.nim +++ b/lib/system/debugger.nim @@ -127,7 +127,7 @@ proc fileMatches(c, bp: cstring): bool = proc canonFilename*(filename: cstring): cstring = ## returns 'nil' if the filename cannot be found. - for i in 0 .. <dbgFilenameLen: + for i in 0 .. dbgFilenameLen-1: result = dbgFilenames[i] if fileMatches(result, filename): return result result = nil @@ -261,7 +261,7 @@ proc genericHash(dest: pointer, mt: PNimType): int = proc dbgRegisterWatchpoint(address: pointer, name: cstring, typ: PNimType) {.compilerproc.} = let L = watchPointsLen - for i in 0.. <L: + for i in 0 .. pred(L): if watchPoints[i].name == name: # address may have changed: watchPoints[i].address = address @@ -288,7 +288,7 @@ var proc checkWatchpoints = let L = watchPointsLen - for i in 0.. <L: + for i in 0 .. pred(L): let newHash = genericHash(watchPoints[i].address, watchPoints[i].typ) if newHash != watchPoints[i].oldValue: dbgWatchpointHook(watchPoints[i].name) diff --git a/lib/system/dyncalls.nim b/lib/system/dyncalls.nim index 2b86ddf25..c8e251d1e 100644 --- a/lib/system/dyncalls.nim +++ b/lib/system/dyncalls.nim @@ -142,7 +142,10 @@ elif defined(windows) or defined(dos): dec(m) k = k div 10 if k == 0: break - result = getProcAddress(cast[THINSTANCE](lib), decorated) + when defined(nimNoArrayToCstringConversion): + result = getProcAddress(cast[THINSTANCE](lib), addr decorated) + else: + result = getProcAddress(cast[THINSTANCE](lib), decorated) if result != nil: return procAddrError(name) diff --git a/lib/system/endb.nim b/lib/system/endb.nim index d4d10a52c..35d8f25c4 100644 --- a/lib/system/endb.nim +++ b/lib/system/endb.nim @@ -76,10 +76,10 @@ proc `==`(a, b: StaticStr): bool = return true proc `==`(a: StaticStr, b: cstring): bool = - result = c_strcmp(a.data, b) == 0 + result = c_strcmp(unsafeAddr a.data, b) == 0 proc write(f: File, s: StaticStr) = - write(f, cstring(s.data)) + write(f, cstring(unsafeAddr s.data)) proc listBreakPoints() = write(stdout, EndbBeg) @@ -260,8 +260,8 @@ proc parseBreakpoint(s: cstring, start: int): Breakpoint = if result.high == 0: result.high = result.low i = scanFilename(s, dbgTemp, i) if dbgTemp.len != 0: - if not hasExt(dbgTemp.data): add(dbgTemp, ".nim") - result.filename = canonFilename(dbgTemp.data.cstring) + if not hasExt(addr dbgTemp.data): add(dbgTemp, ".nim") + result.filename = canonFilename(addr dbgTemp.data) if result.filename.isNil: debugOut("[Warning] no breakpoint could be set; unknown filename ") return @@ -292,12 +292,12 @@ proc dbgEvaluate(stream: File, s: cstring, start: int, f: PFrame) = i = scanAndAppendWord(s, dbgTemp, i) for i in 0 .. getGlobalLen()-1: let v = getGlobal(i) - if c_strcmp(v.name, dbgTemp.data) == 0: + if c_strcmp(v.name, addr dbgTemp.data) == 0: writeVariable(stream, v) else: for i in 0 .. f.len-1: let v = getLocal(f, i) - if c_strcmp(v.name, dbgTemp.data) == 0: + if c_strcmp(v.name, addr dbgTemp.data) == 0: writeVariable(stream, v) proc dbgOut(s: cstring, start: int, currFrame: PFrame) = @@ -306,7 +306,7 @@ proc dbgOut(s: cstring, start: int, currFrame: PFrame) = if dbgTemp.len == 0: invalidCommand() return - var stream = openAppend(dbgTemp.data) + var stream = openAppend(addr dbgTemp.data) if stream == nil: debugOut("[Warning] could not open or create file ") return @@ -320,7 +320,7 @@ proc dbgStackFrame(s: cstring, start: int, currFrame: PFrame) = # just write it to stdout: listFrame(stdout, currFrame) else: - var stream = openAppend(dbgTemp.data) + var stream = openAppend(addr dbgTemp.data) if stream == nil: debugOut("[Warning] could not open or create file ") return @@ -369,7 +369,7 @@ proc commandPrompt() = if not readLine(stdin, dbgUser): break if dbgUser.len == 0: dbgUser.len = oldLen # now look what we have to do: - var i = scanWord(dbgUser.data, dbgTemp, 0) + var i = scanWord(addr dbgUser.data, dbgTemp, 0) template `?`(x: expr): expr = dbgTemp == cstring(x) if ?"s" or ?"step": dbgState = dbStepInto @@ -400,13 +400,13 @@ proc commandPrompt() = prevState = dbgState prevSkipFrame = dbgSkipToFrame dbgState = dbSkipCurrent - dbgEvaluate(stdout, dbgUser.data, i, dbgFramePtr) + dbgEvaluate(stdout, addr dbgUser.data, i, dbgFramePtr) dbgState = prevState dbgSkipToFrame = prevSkipFrame elif ?"o" or ?"out": - dbgOut(dbgUser.data, i, dbgFramePtr) + dbgOut(addr dbgUser.data, i, dbgFramePtr) elif ?"stackframe": - dbgStackFrame(dbgUser.data, i, dbgFramePtr) + dbgStackFrame(addr dbgUser.data, i, dbgFramePtr) elif ?"w" or ?"where": dbgShowExecutionPoint() elif ?"l" or ?"locals": @@ -444,16 +444,16 @@ proc commandPrompt() = elif ?"bt" or ?"backtrace": dbgWriteStackTrace(framePtr) elif ?"b" or ?"break": - createBreakPoint(dbgUser.data, i) + createBreakPoint(addr dbgUser.data, i) elif ?"breakpoints": listBreakPoints() elif ?"toggle": - breakpointToggle(dbgUser.data, i) + breakpointToggle(addr dbgUser.data, i) elif ?"filenames": listFilenames() elif ?"maxdisplay": var parsed: int - i = scanNumber(dbgUser.data, parsed, i) + i = scanNumber(addr dbgUser.data, parsed, i) if dbgUser.data[i-1] in {'0'..'9'}: if parsed == 0: maxDisplayRecDepth = -1 else: maxDisplayRecDepth = parsed diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index db4d70613..f2b5997cc 100644 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -306,8 +306,12 @@ proc raiseExceptionAux(e: ref Exception) = add(buf, " [") xadd(buf, e.name, e.name.len) add(buf, "]\n") - unhandled(buf): - showErrorMessage(buf) + when defined(nimNoArrayToCstringConversion): + template tbuf(): untyped = addr buf + else: + template tbuf(): untyped = buf + unhandled(tbuf()): + showErrorMessage(tbuf()) quitOrDebug() proc raiseException(e: ref Exception, ename: cstring) {.compilerRtl.} = diff --git a/lib/system/gc.nim b/lib/system/gc.nim index a2ff72a30..68bf5f6c2 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -155,14 +155,15 @@ template setColor(c, col) = else: c.refcount = c.refcount and not colorMask or col -proc writeCell(msg: cstring, c: PCell) = - var kind = -1 - var typName: cstring = "nil" - if c.typ != nil: - kind = ord(c.typ.kind) - when defined(nimTypeNames): - if not c.typ.name.isNil: - typName = c.typ.name +when defined(logGC): + proc writeCell(msg: cstring, c: PCell) = + var kind = -1 + var typName: cstring = "nil" + if c.typ != nil: + kind = ord(c.typ.kind) + when defined(nimTypeNames): + if not c.typ.name.isNil: + typName = c.typ.name when leakDetector: c_fprintf(stdout, "[GC] %s: %p %d %s rc=%ld from %s(%ld)\n", @@ -642,9 +643,9 @@ when useMarkForDebug or useBackupGc: forAllChildren(d, waMarkPrecise) proc markGlobals(gch: var GcHeap) = - for i in 0 .. < globalMarkersLen: globalMarkers[i]() + for i in 0 .. globalMarkersLen-1: globalMarkers[i]() let d = gch.additionalRoots.d - for i in 0 .. < gch.additionalRoots.len: markS(gch, d[i]) + for i in 0 .. gch.additionalRoots.len-1: markS(gch, d[i]) when logGC: var @@ -652,7 +653,7 @@ when logGC: cycleCheckALen = 0 proc alreadySeen(c: PCell): bool = - for i in 0 .. <cycleCheckALen: + for i in 0 .. cycleCheckALen-1: if cycleCheckA[i] == c: return true if cycleCheckALen == len(cycleCheckA): gcAssert(false, "cycle detection overflow") diff --git a/lib/system/gc2.nim b/lib/system/gc2.nim index 6dffc323e..70bed8740 100644 --- a/lib/system/gc2.nim +++ b/lib/system/gc2.nim @@ -487,12 +487,12 @@ proc GC_dumpHeap*(file: File) = var spaceIter: ObjectSpaceIter when false: var d = gch.decStack.d - for i in 0 .. < gch.decStack.len: + for i in 0 .. gch.decStack.len-1: if isAllocatedPtr(gch.region, d[i]): c_fprintf(file, "onstack %p\n", d[i]) else: c_fprintf(file, "onstack_invalid %p\n", d[i]) - for i in 0 .. < globalMarkersLen: globalMarkers[i]() + for i in 0 .. globalMarkersLen-1: globalMarkers[i]() while true: let x = allObjectsAsProc(gch.region, addr spaceIter) if spaceIter.state < 0: break @@ -579,7 +579,7 @@ proc markIncremental(gch: var GcHeap): bool = result = true proc markGlobals(gch: var GcHeap) = - for i in 0 .. < globalMarkersLen: globalMarkers[i]() + for i in 0 .. globalMarkersLen-1: globalMarkers[i]() proc doOperation(p: pointer, op: WalkOp) = if p == nil: return diff --git a/lib/system/gc_ms.nim b/lib/system/gc_ms.nim index cfc0dfa8a..272047bb7 100644 --- a/lib/system/gc_ms.nim +++ b/lib/system/gc_ms.nim @@ -450,9 +450,9 @@ when false: quit 1 proc markGlobals(gch: var GcHeap) = - for i in 0 .. < globalMarkersLen: globalMarkers[i]() + for i in 0 .. globalMarkersLen-1: globalMarkers[i]() let d = gch.additionalRoots.d - for i in 0 .. < gch.additionalRoots.len: mark(gch, d[i]) + for i in 0 .. gch.additionalRoots.len-1: mark(gch, d[i]) proc gcMark(gch: var GcHeap, p: pointer) {.inline.} = # the addresses are not as cells on the stack, so turn them to cells: diff --git a/lib/system/nimscript.nim b/lib/system/nimscript.nim index f5b9cf3ed..f91dae41e 100644 --- a/lib/system/nimscript.nim +++ b/lib/system/nimscript.nim @@ -106,7 +106,7 @@ proc cmpic*(a, b: string): int = ## Compares `a` and `b` ignoring case. cmpIgnoreCase(a, b) -proc getEnv*(key: string): string {.tags: [ReadIOEffect].} = +proc getEnv*(key: string; default = ""): string {.tags: [ReadIOEffect].} = ## Retrieves the environment variable of name `key`. builtin diff --git a/lib/system/repr.nim b/lib/system/repr.nim index ab02c58a2..982b07467 100644 --- a/lib/system/repr.nim +++ b/lib/system/repr.nim @@ -16,34 +16,39 @@ proc reprInt(x: int64): string {.compilerproc.} = return $x proc reprFloat(x: float): string {.compilerproc.} = return $x proc reprPointer(x: pointer): string {.compilerproc.} = - var buf: array[0..59, char] - discard c_sprintf(buf, "%p", x) - return $buf + when defined(nimNoArrayToCstringConversion): + result = newString(60) + let n = c_sprintf(addr result[0], "%p", x) + setLen(result, n) + else: + var buf: array[0..59, char] + discard c_sprintf(buf, "%p", x) + return $buf proc `$`(x: uint64): string = if x == 0: result = "0" else: - var buf: array[60, char] + result = newString(60) var i = 0 var n = x while n != 0: let nn = n div 10'u64 - buf[i] = char(n - 10'u64 * nn + ord('0')) + result[i] = char(n - 10'u64 * nn + ord('0')) inc i n = nn + result.setLen i let half = i div 2 # Reverse - for t in 0 .. < half: swap(buf[t], buf[i-t-1]) - result = $buf + for t in 0 .. half-1: swap(result[t], result[i-t-1]) proc reprStrAux(result: var string, s: cstring; len: int) = if cast[pointer](s) == nil: add result, "nil" return add result, reprPointer(cast[pointer](s)) & "\"" - for i in 0.. <len: + for i in 0 .. pred(len): let c = s[i] case c of '"': add result, "\\\"" diff --git a/lib/system/reprjs.nim b/lib/system/reprjs.nim index 5c265a891..658220c11 100644 --- a/lib/system/reprjs.nim +++ b/lib/system/reprjs.nim @@ -9,13 +9,13 @@ # The generic ``repr`` procedure for the javascript backend. proc reprInt(x: int64): string {.compilerproc.} = return $x -proc reprFloat(x: float): string {.compilerproc.} = +proc reprFloat(x: float): string {.compilerproc.} = # Js toString doesn't differentiate between 1.0 and 1, # but we do. if $x == $(x.int): $x & ".0" else: $x -proc reprPointer(p: pointer): string {.compilerproc.} = +proc reprPointer(p: pointer): string {.compilerproc.} = # Do we need to generate the full 8bytes ? In js a pointer is an int anyway var tmp: int {. emit: """ @@ -38,7 +38,7 @@ proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} = result = $typ.node.sons[e].name else: result = $e & " (invalid data!)" - + proc reprChar(x: char): string {.compilerRtl.} = result = "\'" case x @@ -50,7 +50,7 @@ proc reprChar(x: char): string {.compilerRtl.} = proc reprStrAux(result: var string, s: cstring, len: int) = add(result, "\"") - for i in 0 .. <len: + for i in 0 .. len-1: let c = s[i] case c of '"': add(result, "\\\"") @@ -67,7 +67,7 @@ proc reprStr(s: string): string {.compilerRtl.} = if cast[pointer](s).isNil: # Handle nil strings here because they don't have a length field in js # TODO: check for null/undefined before generating call to length in js? - # Also: c backend repr of a nil string is <pointer>"", but repr of an + # Also: c backend repr of a nil string is <pointer>"", but repr of an # array of string that is not initialized is [nil, nil, ...] ?? add(result, "nil") else: @@ -86,7 +86,7 @@ proc addSetElem(result: var string, elem: int, typ: PNimType) = iterator setKeys(s: int): int {.inline.} = # The type of s is a lie, but it's expected to be a set. - # Iterate over the JS object representing a set + # Iterate over the JS object representing a set # and returns the keys as int. var len: int var yieldRes: int @@ -124,16 +124,16 @@ proc initReprClosure(cl: var ReprClosure) = cl.recDepth = -1 # default is to display everything! cl.indent = 0 -proc reprAux(result: var string, p: pointer, typ: PNimType, cl: var ReprClosure) +proc reprAux(result: var string, p: pointer, typ: PNimType, cl: var ReprClosure) -proc reprArray(a: pointer, typ: PNimType, +proc reprArray(a: pointer, typ: PNimType, cl: var ReprClosure): string {.compilerRtl.} = var isNilArrayOrSeq: bool # isnil is not enough here as it would try to deref `a` without knowing what's inside {. emit: """ - if (`a` == null) { + if (`a` == null) { `isNilArrayOrSeq` = true; - } else if (`a`[0] == null) { + } else if (`a`[0] == null) { `isNilArrayOrSeq` = true; } else { `isNilArrayOrSeq` = false; @@ -146,19 +146,19 @@ proc reprArray(a: pointer, typ: PNimType, result = if typ.kind == tySequence: "@[" else: "[" var len: int = 0 var i: int = 0 - + {. emit: "`len` = `a`.length;\n" .} var dereffed: pointer = a - for i in 0 .. < len: + for i in 0 .. len-1: if i > 0 : add(result, ", ") # advance pointer and point to element at index {. emit: """ - `dereffed`_Idx = `i`; + `dereffed`_Idx = `i`; `dereffed` = `a`[`dereffed`_Idx]; """ .} reprAux(result, dereffed, typ.base, cl) - + add(result, "]") proc isPointedToNil(p: pointer): bool {.inline.}= @@ -181,7 +181,7 @@ proc reprRef(result: var string, p: pointer, typ: PNimType, proc reprRecordAux(result: var string, o: pointer, typ: PNimType, cl: var ReprClosure) = add(result, "[") - + var first: bool = true var val: pointer = o if typ.node.len == 0: @@ -192,7 +192,7 @@ proc reprRecordAux(result: var string, o: pointer, typ: PNimType, cl: var ReprCl reprAux(result, val, typ.node.typ, cl) else: # if the object has more than one field, sons is not nil and contains the fields. - for i in 0 .. <typ.node.len: + for i in 0 .. typ.node.len-1: if first: first = false else: add(result, ",\n") @@ -214,11 +214,11 @@ proc reprJSONStringify(p: int): string {.compilerRtl.} = {. emit: "`tmp` = JSON.stringify(`p`);\n" .} result = $tmp -proc reprAux(result: var string, p: pointer, typ: PNimType, +proc reprAux(result: var string, p: pointer, typ: PNimType, cl: var ReprClosure) = if cl.recDepth == 0: add(result, "...") - return + return dec(cl.recDepth) case typ.kind of tyInt..tyInt64, tyUInt..tyUInt64: diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim index 7b6d93fe0..a40fcc67d 100644 --- a/lib/system/sysio.nim +++ b/lib/system/sysio.nim @@ -15,9 +15,12 @@ {.push debugger:off .} # the user does not want to trace a part # of the standard library! - -proc c_fdopen(filehandle: cint, mode: cstring): File {. - importc: "fdopen", header: "<stdio.h>".} +when defined(windows): + proc c_fdopen(filehandle: cint, mode: cstring): File {. + importc: "_fdopen", header: "<stdio.h>".} +else: + proc c_fdopen(filehandle: cint, mode: cstring): File {. + importc: "fdopen", header: "<stdio.h>".} proc c_fputs(c: cstring, f: File): cint {. importc: "fputs", header: "<stdio.h>", tags: [WriteIOEffect].} proc c_fgets(c: cstring, n: cint, f: File): cstring {. @@ -401,4 +404,18 @@ proc setStdIoUnbuffered() = when declared(stdin): discard c_setvbuf(stdin, nil, IONBF, 0) +when declared(stdout): + proc echoBinSafe(args: openArray[string]) {.compilerProc.} = + when not defined(windows): + proc flockfile(f: File) {.importc, noDecl.} + proc funlockfile(f: File) {.importc, noDecl.} + flockfile(stdout) + for s in args: + discard c_fwrite(s.cstring, s.len, 1, stdout) + const linefeed = "\n" # can be 1 or more chars + discard c_fwrite(linefeed.cstring, linefeed.len, 1, stdout) + discard c_fflush(stdout) + when not defined(windows): + funlockfile(stdout) + {.pop.} diff --git a/lib/system/sysspawn.nim b/lib/system/sysspawn.nim index 7da45b4dd..a0d10c446 100644 --- a/lib/system/sysspawn.nim +++ b/lib/system/sysspawn.nim @@ -142,7 +142,7 @@ var workersData: array[NumThreads, Worker] proc setup() = - for i in 0.. <NumThreads: + for i in 0 ..< NumThreads: workersData[i].taskArrived = createCondVar() workersData[i].taskStarted = createFastCondVar() createThread(workers[i], slave, addr(workersData[i])) diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim index 90201202c..0627ef2fb 100644 --- a/lib/system/sysstr.nim +++ b/lib/system/sysstr.nim @@ -24,7 +24,10 @@ proc cmpStrings(a, b: NimString): int {.inline, compilerProc.} = if a == b: return 0 if a == nil: return -1 if b == nil: return 1 - return c_strcmp(a.data, b.data) + when defined(nimNoArrayToCstringConversion): + return c_strcmp(addr a.data, addr b.data) + else: + return c_strcmp(a.data, b.data) proc eqStrings(a, b: NimString): bool {.inline, compilerProc.} = if a == b: return true @@ -275,7 +278,7 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {. GenericSeqSize +% (i*%elemSize)), extGetCellType(result).base, waPush) let len1 = gch.tempStack.len - for i in len0 .. <len1: + for i in len0 ..< len1: doDecRef(gch.tempStack.d[i], LocalHeap, MaybeCyclic) gch.tempStack.len = len0 else: @@ -320,7 +323,10 @@ proc nimIntToStr(x: int): string {.compilerRtl.} = proc add*(result: var string; x: float) = var buf: array[0..64, char] - var n: int = c_sprintf(buf, "%.16g", x) + when defined(nimNoArrayToCstringConversion): + var n: int = c_sprintf(addr buf, "%.16g", x) + else: + var n: int = c_sprintf(buf, "%.16g", x) var hasDot = false for i in 0..n-1: if buf[i] == ',': @@ -332,9 +338,10 @@ proc add*(result: var string; x: float) = buf[n] = '.' buf[n+1] = '0' buf[n+2] = '\0' - # On Windows nice numbers like '1.#INF', '-1.#INF' or '1.#NAN' are produced. + # On Windows nice numbers like '1.#INF', '-1.#INF' or '1.#NAN' + # of '-1.#IND' are produced. # We want to get rid of these here: - if buf[n-1] in {'n', 'N'}: + if buf[n-1] in {'n', 'N', 'D', 'd'}: result.add "nan" elif buf[n-1] == 'F': if buf[0] == '-': @@ -342,7 +349,10 @@ proc add*(result: var string; x: float) = else: result.add "inf" else: - result.add buf + var i = 0 + while buf[i] != '\0': + result.add buf[i] + inc i proc nimFloatToStr(f: float): string {.compilerproc.} = result = newStringOfCap(8) @@ -353,9 +363,9 @@ proc c_strtod(buf: cstring, endptr: ptr cstring): float64 {. const IdentChars = {'a'..'z', 'A'..'Z', '0'..'9', '_'} - powtens = [ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, - 1e20, 1e21, 1e22] + powtens = [1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22] proc nimParseBiggestFloat(s: string, number: var BiggestFloat, start = 0): int {.compilerProc.} = @@ -507,7 +517,10 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat, t[ti-2] = ('0'.ord + abs_exponent mod 10).char; abs_exponent = abs_exponent div 10 t[ti-3] = ('0'.ord + abs_exponent mod 10).char - number = c_strtod(t, nil) + when defined(nimNoArrayToCstringConversion): + number = c_strtod(addr t, nil) + else: + number = c_strtod(t, nil) proc nimInt64ToStr(x: int64): string {.compilerRtl.} = result = newStringOfCap(sizeof(x)*4) diff --git a/lib/system/threads.nim b/lib/system/threads.nim index 96c045e6b..016bf5822 100644 --- a/lib/system/threads.nim +++ b/lib/system/threads.nim @@ -398,7 +398,7 @@ template afterThreadRuns() = threadDestructionHandlers[i]() when not defined(boehmgc) and not hasSharedHeap and not defined(gogc) and not defined(gcRegions): - proc deallocOsPages() + proc deallocOsPages() {.rtl.} when defined(boehmgc): type GCStackBaseProc = proc(sb: pointer, t: pointer) {.noconv.} diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 7a221ceb1..c3229cc7b 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -14,8 +14,8 @@ import dynlib -when defined(vcc): - {.passC: "-DWIN32_LEAN_AND_MEAN".} + +{.passC: "-DWIN32_LEAN_AND_MEAN".} const useWinUnicode* = not defined(useWinAnsi) diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim index 40b54b08d..431ea5912 100644 --- a/lib/wrappers/openssl.nim +++ b/lib/wrappers/openssl.nim @@ -590,13 +590,13 @@ proc md5_Transform*(c: var MD5_CTX; b: ptr cuchar){.importc: "MD5_Transform".} from strutils import toHex, toLowerAscii -proc hexStr (buf:cstring): string = +proc hexStr(buf: cstring): string = # turn md5s output into a nice hex str result = newStringOfCap(32) - for i in 0 .. <16: + for i in 0 ..< 16: result.add toHex(buf[i].ord, 2).toLowerAscii -proc md5_File* (file: string): string {.raises: [IOError,Exception].} = +proc md5_File*(file: string): string {.raises: [IOError,Exception].} = ## Generate MD5 hash for a file. Result is a 32 character # hex string with lowercase characters (like the output # of `md5sum` @@ -611,14 +611,14 @@ proc md5_File* (file: string): string {.raises: [IOError,Exception].} = while(let bytes = f.readChars(buf, 0, sz); bytes > 0): discard md5_update(ctx, buf[0].addr, bytes) - discard md5_final( buf[0].addr, ctx ) + discard md5_final(buf[0].addr, ctx) f.close - result = hexStr(buf) + result = hexStr(addr buf) -proc md5_Str*(str:string): string = - ##Generate MD5 hash for a string. Result is a 32 character - #hex string with lowercase characters +proc md5_Str*(str: string): string = + ## Generate MD5 hash for a string. Result is a 32 character + ## hex string with lowercase characters var ctx: MD5_CTX res: array[MD5_DIGEST_LENGTH,char] @@ -631,5 +631,5 @@ proc md5_Str*(str:string): string = discard md5_update(ctx, input[i].addr, L) i += L - discard md5_final(res,ctx) - result = hexStr(res) + discard md5_final(addr res, ctx) + result = hexStr(addr res) diff --git a/lib/wrappers/pdcurses.nim b/lib/wrappers/pdcurses.nim deleted file mode 100644 index 2d64ac97a..000000000 --- a/lib/wrappers/pdcurses.nim +++ /dev/null @@ -1,1560 +0,0 @@ -# -# -# Nim's Runtime Library -# (c) Copyright 2015 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -{.deadCodeElim: on.} - -discard """ - -curses.h: -#ifdef C2NIM -#dynlib pdcursesdll -#skipinclude -#prefix PDC_ -#def FALSE -#def TRUE -#def NULL -#def bool unsigned char -#def chtype unsigned long -#def cchar_t unsigned long -#def attr_t unsigned long -#def mmask_t unsigned long -#def wchar_t char -#def PDCEX -#cdecl -#endif - -pdcwin.h: -#ifdef C2NIM -#dynlib pdcursesdll -#skipinclude -#prefix pdc_ -#prefix PDC_ -#stdcall -#endif -""" - -when defined(windows): - import windows - - when defined(nimOldDlls): - const pdcursesdll = "pdcurses.dll" - elif defined(cpu64): - const pdcursesdll = "pdcurses64.dll" - else: - const pdcursesdll = "pdcurses32.dll" - - const - unixOS = false - {.pragma: extdecl, stdcall.} - -when not defined(windows): - const - unixOS = true - {.pragma: extdecl, cdecl.} - -type - cunsignedchar = char - cunsignedlong = uint32 - -const - BUILD* = 3401 - PDCURSES* = 1 # PDCurses-only routines - XOPEN* = 1 # X/Open Curses routines - SYSVcurses* = 1 # System V Curses routines - BSDcurses* = 1 # BSD Curses routines - CHTYPE_LONG* = 1 # size of chtype; long - ERR* = (- 1) - OK* = 0 - BUTTON_RELEASED* = 0x00000000 - BUTTON_PRESSED* = 0x00000001 - BUTTON_CLICKED* = 0x00000002 - BUTTON_DOUBLE_CLICKED* = 0x00000003 - BUTTON_TRIPLE_CLICKED* = 0x00000004 - BUTTON_MOVED* = 0x00000005 # PDCurses - WHEEL_SCROLLED* = 0x00000006 # PDCurses - BUTTON_ACTION_MASK* = 0x00000007 # PDCurses - BUTTON_MODIFIER_MASK* = 0x00000038 # PDCurses - MOUSE_MOVED* = 0x00000008 - MOUSE_POSITION* = 0x00000010 - MOUSE_WHEEL_UP* = 0x00000020 - MOUSE_WHEEL_DOWN* = 0x00000040 - BUTTON1_RELEASED* = 0x00000001 - BUTTON1_PRESSED* = 0x00000002 - BUTTON1_CLICKED* = 0x00000004 - BUTTON1_DOUBLE_CLICKED* = 0x00000008 - BUTTON1_TRIPLE_CLICKED* = 0x00000010 - BUTTON1_MOVED* = 0x00000010 # PDCurses - BUTTON2_RELEASED* = 0x00000020 - BUTTON2_PRESSED* = 0x00000040 - BUTTON2_CLICKED* = 0x00000080 - BUTTON2_DOUBLE_CLICKED* = 0x00000100 - BUTTON2_TRIPLE_CLICKED* = 0x00000200 - BUTTON2_MOVED* = 0x00000200 # PDCurses - BUTTON3_RELEASED* = 0x00000400 - BUTTON3_PRESSED* = 0x00000800 - BUTTON3_CLICKED* = 0x00001000 - BUTTON3_DOUBLE_CLICKED* = 0x00002000 - BUTTON3_TRIPLE_CLICKED* = 0x00004000 - BUTTON3_MOVED* = 0x00004000 # PDCurses - BUTTON4_RELEASED* = 0x00008000 - BUTTON4_PRESSED* = 0x00010000 - BUTTON4_CLICKED* = 0x00020000 - BUTTON4_DOUBLE_CLICKED* = 0x00040000 - BUTTON4_TRIPLE_CLICKED* = 0x00080000 - BUTTON5_RELEASED* = 0x00100000 - BUTTON5_PRESSED* = 0x00200000 - BUTTON5_CLICKED* = 0x00400000 - BUTTON5_DOUBLE_CLICKED* = 0x00800000 - BUTTON5_TRIPLE_CLICKED* = 0x01000000 - MOUSE_WHEEL_SCROLL* = 0x02000000 # PDCurses - BUTTON_MODIFIER_SHIFT* = 0x04000000 # PDCurses - BUTTON_MODIFIER_CONTROL* = 0x08000000 # PDCurses - BUTTON_MODIFIER_ALT* = 0x10000000 # PDCurses - ALL_MOUSE_EVENTS* = 0x1FFFFFFF - REPORT_MOUSE_POSITION* = 0x20000000 - A_NORMAL* = 0 - A_ALTCHARSET* = 0x00010000 - A_RIGHTLINE* = 0x00020000 - A_LEFTLINE* = 0x00040000 - A_INVIS* = 0x00080000 - A_UNDERLINE* = 0x00100000 - A_REVERSE* = 0x00200000 - A_BLINK* = 0x00400000 - A_BOLD* = 0x00800000 - A_ATTRIBUTES* = 0xFFFF0000 - A_CHARTEXT* = 0x0000FFFF - A_COLOR* = 0xFF000000 - A_ITALIC* = A_INVIS - A_PROTECT* = (A_UNDERLINE or A_LEFTLINE or A_RIGHTLINE) - ATTR_SHIFT* = 19 - COLOR_SHIFT* = 24 - A_STANDOUT* = (A_REVERSE or A_BOLD) # X/Open - A_DIM* = A_NORMAL - CHR_MSK* = A_CHARTEXT # Obsolete - ATR_MSK* = A_ATTRIBUTES # Obsolete - ATR_NRM* = A_NORMAL # Obsolete - WA_ALTCHARSET* = A_ALTCHARSET - WA_BLINK* = A_BLINK - WA_BOLD* = A_BOLD - WA_DIM* = A_DIM - WA_INVIS* = A_INVIS - WA_LEFT* = A_LEFTLINE - WA_PROTECT* = A_PROTECT - WA_REVERSE* = A_REVERSE - WA_RIGHT* = A_RIGHTLINE - WA_STANDOUT* = A_STANDOUT - WA_UNDERLINE* = A_UNDERLINE - WA_HORIZONTAL* = A_NORMAL - WA_LOW* = A_NORMAL - WA_TOP* = A_NORMAL - WA_VERTICAL* = A_NORMAL - COLOR_BLACK* = 0 - COLOR_RED* = 1 - COLOR_GREEN* = 2 - COLOR_BLUE* = 4 - COLOR_CYAN* = (COLOR_BLUE or COLOR_GREEN) - COLOR_MAGENTA* = (COLOR_RED or COLOR_BLUE) - COLOR_YELLOW* = (COLOR_RED or COLOR_GREEN) - COLOR_WHITE* = 7 - KEY_CODE_YES* = 0x00000100 # If get_wch() gives a key code - KEY_BREAK* = 0x00000101 # Not on PC KBD - KEY_DOWN* = 0x00000102 # Down arrow key - KEY_UP* = 0x00000103 # Up arrow key - KEY_LEFT* = 0x00000104 # Left arrow key - KEY_RIGHT* = 0x00000105 # Right arrow key - KEY_HOME* = 0x00000106 # home key - KEY_BACKSPACE* = 0x00000107 # not on pc - KEY_F0* = 0x00000108 # function keys; 64 reserved - KEY_DL* = 0x00000148 # delete line - KEY_IL* = 0x00000149 # insert line - KEY_DC* = 0x0000014A # delete character - KEY_IC* = 0x0000014B # insert char or enter ins mode - KEY_EIC* = 0x0000014C # exit insert char mode - KEY_CLEAR* = 0x0000014D # clear screen - KEY_EOS* = 0x0000014E # clear to end of screen - KEY_EOL* = 0x0000014F # clear to end of line - KEY_SF* = 0x00000150 # scroll 1 line forward - KEY_SR* = 0x00000151 # scroll 1 line back (reverse) - KEY_NPAGE* = 0x00000152 # next page - KEY_PPAGE* = 0x00000153 # previous page - KEY_STAB* = 0x00000154 # set tab - KEY_CTAB* = 0x00000155 # clear tab - KEY_CATAB* = 0x00000156 # clear all tabs - KEY_ENTER* = 0x00000157 # enter or send (unreliable) - KEY_SRESET* = 0x00000158 # soft/reset (partial/unreliable) - KEY_RESET* = 0x00000159 # reset/hard reset (unreliable) - KEY_PRINT* = 0x0000015A # print/copy - KEY_LL* = 0x0000015B # home down/bottom (lower left) - KEY_ABORT* = 0x0000015C # abort/terminate key (any) - KEY_SHELP* = 0x0000015D # short help - KEY_LHELP* = 0x0000015E # long help - KEY_BTAB* = 0x0000015F # Back tab key - KEY_BEG* = 0x00000160 # beg(inning) key - KEY_CANCEL* = 0x00000161 # cancel key - KEY_CLOSE* = 0x00000162 # close key - KEY_COMMAND* = 0x00000163 # cmd (command) key - KEY_COPY* = 0x00000164 # copy key - KEY_CREATE* = 0x00000165 # create key - KEY_END* = 0x00000166 # end key - KEY_EXIT* = 0x00000167 # exit key - KEY_FIND* = 0x00000168 # find key - KEY_HELP* = 0x00000169 # help key - KEY_MARK* = 0x0000016A # mark key - KEY_MESSAGE* = 0x0000016B # message key - KEY_MOVE* = 0x0000016C # move key - KEY_NEXT* = 0x0000016D # next object key - KEY_OPEN* = 0x0000016E # open key - KEY_OPTIONS* = 0x0000016F # options key - KEY_PREVIOUS* = 0x00000170 # previous object key - KEY_REDO* = 0x00000171 # redo key - KEY_REFERENCE* = 0x00000172 # ref(erence) key - KEY_REFRESH* = 0x00000173 # refresh key - KEY_REPLACE* = 0x00000174 # replace key - KEY_RESTART* = 0x00000175 # restart key - KEY_RESUME* = 0x00000176 # resume key - KEY_SAVE* = 0x00000177 # save key - KEY_SBEG* = 0x00000178 # shifted beginning key - KEY_SCANCEL* = 0x00000179 # shifted cancel key - KEY_SCOMMAND* = 0x0000017A # shifted command key - KEY_SCOPY* = 0x0000017B # shifted copy key - KEY_SCREATE* = 0x0000017C # shifted create key - KEY_SDC* = 0x0000017D # shifted delete char key - KEY_SDL* = 0x0000017E # shifted delete line key - KEY_SELECT* = 0x0000017F # select key - KEY_SEND* = 0x00000180 # shifted end key - KEY_SEOL* = 0x00000181 # shifted clear line key - KEY_SEXIT* = 0x00000182 # shifted exit key - KEY_SFIND* = 0x00000183 # shifted find key - KEY_SHOME* = 0x00000184 # shifted home key - KEY_SIC* = 0x00000185 # shifted input key - KEY_SLEFT* = 0x00000187 # shifted left arrow key - KEY_SMESSAGE* = 0x00000188 # shifted message key - KEY_SMOVE* = 0x00000189 # shifted move key - KEY_SNEXT* = 0x0000018A # shifted next key - KEY_SOPTIONS* = 0x0000018B # shifted options key - KEY_SPREVIOUS* = 0x0000018C # shifted prev key - KEY_SPRINT* = 0x0000018D # shifted print key - KEY_SREDO* = 0x0000018E # shifted redo key - KEY_SREPLACE* = 0x0000018F # shifted replace key - KEY_SRIGHT* = 0x00000190 # shifted right arrow - KEY_SRSUME* = 0x00000191 # shifted resume key - KEY_SSAVE* = 0x00000192 # shifted save key - KEY_SSUSPEND* = 0x00000193 # shifted suspend key - KEY_SUNDO* = 0x00000194 # shifted undo key - KEY_SUSPEND* = 0x00000195 # suspend key - KEY_UNDO* = 0x00000196 # undo key - ALT_0* = 0x00000197 - ALT_1* = 0x00000198 - ALT_2* = 0x00000199 - ALT_3* = 0x0000019A - ALT_4* = 0x0000019B - ALT_5* = 0x0000019C - ALT_6* = 0x0000019D - ALT_7* = 0x0000019E - ALT_8* = 0x0000019F - ALT_9* = 0x000001A0 - ALT_A* = 0x000001A1 - ALT_B* = 0x000001A2 - ALT_C* = 0x000001A3 - ALT_D* = 0x000001A4 - ALT_E* = 0x000001A5 - ALT_F* = 0x000001A6 - ALT_G* = 0x000001A7 - ALT_H* = 0x000001A8 - ALT_I* = 0x000001A9 - ALT_J* = 0x000001AA - ALT_K* = 0x000001AB - ALT_L* = 0x000001AC - ALT_M* = 0x000001AD - ALT_N* = 0x000001AE - ALT_O* = 0x000001AF - ALT_P* = 0x000001B0 - ALT_Q* = 0x000001B1 - ALT_R* = 0x000001B2 - ALT_S* = 0x000001B3 - ALT_T* = 0x000001B4 - ALT_U* = 0x000001B5 - ALT_V* = 0x000001B6 - ALT_W* = 0x000001B7 - ALT_X* = 0x000001B8 - ALT_Y* = 0x000001B9 - ALT_Z* = 0x000001BA - CTL_LEFT* = 0x000001BB # Control-Left-Arrow - CTL_RIGHT* = 0x000001BC - CTL_PGUP* = 0x000001BD - CTL_PGDN* = 0x000001BE - CTL_HOME* = 0x000001BF - CTL_END* = 0x000001C0 - KEY_A1* = 0x000001C1 # upper left on Virtual keypad - KEY_A2* = 0x000001C2 # upper middle on Virt. keypad - KEY_A3* = 0x000001C3 # upper right on Vir. keypad - KEY_B1* = 0x000001C4 # middle left on Virt. keypad - KEY_B2* = 0x000001C5 # center on Virt. keypad - KEY_B3* = 0x000001C6 # middle right on Vir. keypad - KEY_C1* = 0x000001C7 # lower left on Virt. keypad - KEY_C2* = 0x000001C8 # lower middle on Virt. keypad - KEY_C3* = 0x000001C9 # lower right on Vir. keypad - PADSLASH* = 0x000001CA # slash on keypad - PADENTER* = 0x000001CB # enter on keypad - CTL_PADENTER* = 0x000001CC # ctl-enter on keypad - ALT_PADENTER* = 0x000001CD # alt-enter on keypad - PADSTOP* = 0x000001CE # stop on keypad - PADSTAR* = 0x000001CF # star on keypad - PADMINUS* = 0x000001D0 # minus on keypad - PADPLUS* = 0x000001D1 # plus on keypad - CTL_PADSTOP* = 0x000001D2 # ctl-stop on keypad - CTL_PADCENTER* = 0x000001D3 # ctl-enter on keypad - CTL_PADPLUS* = 0x000001D4 # ctl-plus on keypad - CTL_PADMINUS* = 0x000001D5 # ctl-minus on keypad - CTL_PADSLASH* = 0x000001D6 # ctl-slash on keypad - CTL_PADSTAR* = 0x000001D7 # ctl-star on keypad - ALT_PADPLUS* = 0x000001D8 # alt-plus on keypad - ALT_PADMINUS* = 0x000001D9 # alt-minus on keypad - ALT_PADSLASH* = 0x000001DA # alt-slash on keypad - ALT_PADSTAR* = 0x000001DB # alt-star on keypad - ALT_PADSTOP* = 0x000001DC # alt-stop on keypad - CTL_INS* = 0x000001DD # ctl-insert - ALT_DEL* = 0x000001DE # alt-delete - ALT_INS* = 0x000001DF # alt-insert - CTL_UP* = 0x000001E0 # ctl-up arrow - CTL_DOWN* = 0x000001E1 # ctl-down arrow - CTL_TAB* = 0x000001E2 # ctl-tab - ALT_TAB* = 0x000001E3 - ALT_MINUS* = 0x000001E4 - ALT_EQUAL* = 0x000001E5 - ALT_HOME* = 0x000001E6 - ALT_PGUP* = 0x000001E7 - ALT_PGDN* = 0x000001E8 - ALT_END* = 0x000001E9 - ALT_UP* = 0x000001EA # alt-up arrow - ALT_DOWN* = 0x000001EB # alt-down arrow - ALT_RIGHT* = 0x000001EC # alt-right arrow - ALT_LEFT* = 0x000001ED # alt-left arrow - ALT_ENTER* = 0x000001EE # alt-enter - ALT_ESC* = 0x000001EF # alt-escape - ALT_BQUOTE* = 0x000001F0 # alt-back quote - ALT_LBRACKET* = 0x000001F1 # alt-left bracket - ALT_RBRACKET* = 0x000001F2 # alt-right bracket - ALT_SEMICOLON* = 0x000001F3 # alt-semi-colon - ALT_FQUOTE* = 0x000001F4 # alt-forward quote - ALT_COMMA* = 0x000001F5 # alt-comma - ALT_STOP* = 0x000001F6 # alt-stop - ALT_FSLASH* = 0x000001F7 # alt-forward slash - ALT_BKSP* = 0x000001F8 # alt-backspace - CTL_BKSP* = 0x000001F9 # ctl-backspace - PAD0* = 0x000001FA # keypad 0 - CTL_PAD0* = 0x000001FB # ctl-keypad 0 - CTL_PAD1* = 0x000001FC - CTL_PAD2* = 0x000001FD - CTL_PAD3* = 0x000001FE - CTL_PAD4* = 0x000001FF - CTL_PAD5* = 0x00000200 - CTL_PAD6* = 0x00000201 - CTL_PAD7* = 0x00000202 - CTL_PAD8* = 0x00000203 - CTL_PAD9* = 0x00000204 - ALT_PAD0* = 0x00000205 # alt-keypad 0 - ALT_PAD1* = 0x00000206 - ALT_PAD2* = 0x00000207 - ALT_PAD3* = 0x00000208 - ALT_PAD4* = 0x00000209 - ALT_PAD5* = 0x0000020A - ALT_PAD6* = 0x0000020B - ALT_PAD7* = 0x0000020C - ALT_PAD8* = 0x0000020D - ALT_PAD9* = 0x0000020E - CTL_DEL* = 0x0000020F # clt-delete - ALT_BSLASH* = 0x00000210 # alt-back slash - CTL_ENTER* = 0x00000211 # ctl-enter - SHF_PADENTER* = 0x00000212 # shift-enter on keypad - SHF_PADSLASH* = 0x00000213 # shift-slash on keypad - SHF_PADSTAR* = 0x00000214 # shift-star on keypad - SHF_PADPLUS* = 0x00000215 # shift-plus on keypad - SHF_PADMINUS* = 0x00000216 # shift-minus on keypad - SHF_UP* = 0x00000217 # shift-up on keypad - SHF_DOWN* = 0x00000218 # shift-down on keypad - SHF_IC* = 0x00000219 # shift-insert on keypad - SHF_DC* = 0x0000021A # shift-delete on keypad - KEY_MOUSE* = 0x0000021B # "mouse" key - KEY_SHIFT_L* = 0x0000021C # Left-shift - KEY_SHIFT_R* = 0x0000021D # Right-shift - KEY_CONTROL_L* = 0x0000021E # Left-control - KEY_CONTROL_R* = 0x0000021F # Right-control - KEY_ALT_L* = 0x00000220 # Left-alt - KEY_ALT_R* = 0x00000221 # Right-alt - KEY_RESIZE* = 0x00000222 # Window resize - KEY_SUP* = 0x00000223 # Shifted up arrow - KEY_SDOWN* = 0x00000224 # Shifted down arrow - KEY_MIN* = KEY_BREAK # Minimum curses key value - KEY_MAX* = KEY_SDOWN # Maximum curses key - CLIP_SUCCESS* = 0 - CLIP_ACCESS_ERROR* = 1 - CLIP_EMPTY* = 2 - CLIP_MEMORY_ERROR* = 3 - KEY_MODIFIER_SHIFT* = 1 - KEY_MODIFIER_CONTROL* = 2 - KEY_MODIFIER_ALT* = 4 - KEY_MODIFIER_NUMLOCK* = 8 - -when appType == "gui": - const - BUTTON_SHIFT* = BUTTON_MODIFIER_SHIFT - BUTTON_CONTROL* = BUTTON_MODIFIER_CONTROL - BUTTON_CTRL* = BUTTON_MODIFIER_CONTROL - BUTTON_ALT* = BUTTON_MODIFIER_ALT -else: - const - BUTTON_SHIFT* = 0x00000008 - BUTTON_CONTROL* = 0x00000010 - BUTTON_ALT* = 0x00000020 - -type - TMOUSE_STATUS*{.pure, final.} = object - x*: cint # absolute column, 0 based, measured in characters - y*: cint # absolute row, 0 based, measured in characters - button*: array[0..3 - 1, cshort] # state of each button - changes*: cint # flags indicating what has changed with the mouse - - MEVENT*{.pure, final.} = object - id*: cshort # unused, always 0 - x*: cint - y*: cint - z*: cint # x, y same as TMOUSE_STATUS; z unused - bstate*: cunsignedlong # equivalent to changes + button[], but - # in the same format as used for mousemask() - - WINDOW*{.pure, final.} = object - cury*: cint # current pseudo-cursor - curx*: cint - maxy*: cint # max window coordinates - maxx*: cint - begy*: cint # origin on screen - begx*: cint - flags*: cint # window properties - attrs*: cunsignedlong # standard attributes and colors - bkgd*: cunsignedlong # background, normally blank - clear*: cunsignedchar # causes clear at next refresh - leaveit*: cunsignedchar # leaves cursor where it is - scroll*: cunsignedchar # allows window scrolling - nodelay*: cunsignedchar # input character wait flag - immed*: cunsignedchar # immediate update flag - sync*: cunsignedchar # synchronise window ancestors - use_keypad*: cunsignedchar # flags keypad key mode active - y*: ptr ptr cunsignedlong # pointer to line pointer array - firstch*: ptr cint # first changed character in line - lastch*: ptr cint # last changed character in line - tmarg*: cint # top of scrolling region - bmarg*: cint # bottom of scrolling region - delayms*: cint # milliseconds of delay for getch() - parx*: cint - pary*: cint # coords relative to parent (0,0) - parent*: ptr WINDOW # subwin's pointer to parent win - - PANELOBS*{.pure, final.} = object - above*: ptr PANELOBS - pan*: ptr PANEL - - PANEL*{.pure, final.} = object - win*: ptr WINDOW - wstarty*: cint - wendy*: cint - wstartx*: cint - wendx*: cint - below*: ptr PANEL - above*: ptr PANEL - user*: pointer - obscure*: ptr PANELOBS -{.deprecated: [ - #TMOUSE_STATUS: MOUSE_STATUS, # Name conflict when we drop the `T` - TMEVENT: MEVENT, TWINDOW: WINDOW, - TPANELOBS: PANELOBS, TPANEL:PANEL].} - -when unixOS: - type - SCREEN*{.pure, final.} = object - alive*: cunsignedchar # if initscr() called, and not endwin() - autocr*: cunsignedchar # if cr -> lf - cbreak*: cunsignedchar # if terminal unbuffered - echo*: cunsignedchar # if terminal echo - raw_inp*: cunsignedchar # raw input mode (v. cooked input) - raw_out*: cunsignedchar # raw output mode (7 v. 8 bits) - audible*: cunsignedchar # FALSE if the bell is visual - mono*: cunsignedchar # TRUE if current screen is mono - resized*: cunsignedchar # TRUE if TERM has been resized - orig_attr*: cunsignedchar # TRUE if we have the original colors - orig_fore*: cshort # original screen foreground color - orig_back*: cshort # original screen foreground color - cursrow*: cint # position of physical cursor - curscol*: cint # position of physical cursor - visibility*: cint # visibility of cursor - orig_cursor*: cint # original cursor size - lines*: cint # new value for LINES - cols*: cint # new value for COLS - trap_mbe*: cunsignedlong # trap these mouse button events - map_mbe_to_key*: cunsignedlong # map mouse buttons to slk - mouse_wait*: cint # time to wait (in ms) for a button release after a press - slklines*: cint # lines in use by slk_init() - slk_winptr*: ptr WINDOW # window for slk - linesrippedoff*: cint # lines ripped off via ripoffline() - linesrippedoffontop*: cint # lines ripped off on top via ripoffline() - delaytenths*: cint # 1/10ths second to wait block getch() for - preserve*: cunsignedchar # TRUE if screen background to be preserved - restore*: cint # specifies if screen background to be restored, and how - save_key_modifiers*: cunsignedchar # TRUE if each key modifiers saved with each key press - return_key_modifiers*: cunsignedchar # TRUE if modifier keys are returned as "real" keys - key_code*: cunsignedchar # TRUE if last key is a special key; - XcurscrSize*: cint # size of Xcurscr shared memory block - sb_on*: cunsignedchar - sb_viewport_y*: cint - sb_viewport_x*: cint - sb_total_y*: cint - sb_total_x*: cint - sb_cur_y*: cint - sb_cur_x*: cint - line_color*: cshort # color of line attributes - default -1 - {.deprecated: [TSCREEN: SCREEN].} -else: - type - SCREEN*{.pure, final.} = object - alive*: cunsignedchar # if initscr() called, and not endwin() - autocr*: cunsignedchar # if cr -> lf - cbreak*: cunsignedchar # if terminal unbuffered - echo*: cunsignedchar # if terminal echo - raw_inp*: cunsignedchar # raw input mode (v. cooked input) - raw_out*: cunsignedchar # raw output mode (7 v. 8 bits) - audible*: cunsignedchar # FALSE if the bell is visual - mono*: cunsignedchar # TRUE if current screen is mono - resized*: cunsignedchar # TRUE if TERM has been resized - orig_attr*: cunsignedchar # TRUE if we have the original colors - orig_fore*: cshort # original screen foreground color - orig_back*: cshort # original screen foreground color - cursrow*: cint # position of physical cursor - curscol*: cint # position of physical cursor - visibility*: cint # visibility of cursor - orig_cursor*: cint # original cursor size - lines*: cint # new value for LINES - cols*: cint # new value for COLS - trap_mbe*: cunsignedlong # trap these mouse button events - map_mbe_to_key*: cunsignedlong # map mouse buttons to slk - mouse_wait*: cint # time to wait (in ms) for a button release after a press - slklines*: cint # lines in use by slk_init() - slk_winptr*: ptr WINDOW # window for slk - linesrippedoff*: cint # lines ripped off via ripoffline() - linesrippedoffontop*: cint # lines ripped off on top via ripoffline() - delaytenths*: cint # 1/10ths second to wait block getch() for - preserve*: cunsignedchar # TRUE if screen background to be preserved - restore*: cint # specifies if screen background to be restored, and how - save_key_modifiers*: cunsignedchar # TRUE if each key modifiers saved with each key press - return_key_modifiers*: cunsignedchar # TRUE if modifier keys are returned as "real" keys - key_code*: cunsignedchar # TRUE if last key is a special key; - line_color*: cshort # color of line attributes - default -1 - {.deprecated: [TSCREEN: SCREEN].} - -var - LINES*{.importc: "LINES", dynlib: pdcursesdll.}: cint - COLS*{.importc: "COLS", dynlib: pdcursesdll.}: cint - stdscr*{.importc: "stdscr", dynlib: pdcursesdll.}: ptr WINDOW - curscr*{.importc: "curscr", dynlib: pdcursesdll.}: ptr WINDOW - SP*{.importc: "SP", dynlib: pdcursesdll.}: ptr SCREEN - Mouse_status*{.importc: "Mouse_status", dynlib: pdcursesdll.}: MOUSE_STATUS - COLORS*{.importc: "COLORS", dynlib: pdcursesdll.}: cint - COLOR_PAIRS*{.importc: "COLOR_PAIRS", dynlib: pdcursesdll.}: cint - TABSIZE*{.importc: "TABSIZE", dynlib: pdcursesdll.}: cint - acs_map*{.importc: "acs_map", dynlib: pdcursesdll.}: ptr cunsignedlong - ttytype*{.importc: "ttytype", dynlib: pdcursesdll.}: cstring - -template BUTTON_CHANGED*(x: expr): expr = - (Mouse_status.changes and (1 shl ((x) - 1))) - -template BUTTON_STATUS*(x: expr): expr = - (Mouse_status.button[(x) - 1]) - -template ACS_PICK*(w, n: expr): expr = int32(w) or A_ALTCHARSET - -template KEY_F*(n: expr): expr = KEY_F0 + n - -template COLOR_PAIR*(n: expr): expr = - ((cunsignedlong(n) shl COLOR_SHIFT) and A_COLOR) - -template PAIR_NUMBER*(n: expr): expr = - (((n) and A_COLOR) shr COLOR_SHIFT) - -const - #MOUSE_X_POS* = (Mouse_status.x) - #MOUSE_Y_POS* = (Mouse_status.y) - #A_BUTTON_CHANGED* = (Mouse_status.changes and 7) - #MOUSE_MOVED* = (Mouse_status.changes and MOUSE_MOVED) - #MOUSE_POS_REPORT* = (Mouse_status.changes and MOUSE_POSITION) - #MOUSE_WHEEL_UP* = (Mouse_status.changes and MOUSE_WHEEL_UP) - #MOUSE_WHEEL_DOWN* = (Mouse_status.changes and MOUSE_WHEEL_DOWN) - ACS_ULCORNER* = ACS_PICK('l', '+') - ACS_LLCORNER* = ACS_PICK('m', '+') - ACS_URCORNER* = ACS_PICK('k', '+') - ACS_LRCORNER* = ACS_PICK('j', '+') - ACS_RTEE* = ACS_PICK('u', '+') - ACS_LTEE* = ACS_PICK('t', '+') - ACS_BTEE* = ACS_PICK('v', '+') - ACS_TTEE* = ACS_PICK('w', '+') - ACS_HLINE* = ACS_PICK('q', '-') - ACS_VLINE* = ACS_PICK('x', '|') - ACS_PLUS* = ACS_PICK('n', '+') - ACS_S1* = ACS_PICK('o', '-') - ACS_S9* = ACS_PICK('s', '_') - ACS_DIAMOND* = ACS_PICK('`', '+') - ACS_CKBOARD* = ACS_PICK('a', ':') - ACS_DEGREE* = ACS_PICK('f', '\'') - ACS_PLMINUS* = ACS_PICK('g', '#') - ACS_BULLET* = ACS_PICK('~', 'o') - ACS_LARROW* = ACS_PICK(',', '<') - ACS_RARROW* = ACS_PICK('+', '>') - ACS_DARROW* = ACS_PICK('.', 'v') - ACS_UARROW* = ACS_PICK('-', '^') - ACS_BOARD* = ACS_PICK('h', '#') - ACS_LANTERN* = ACS_PICK('i', '*') - ACS_BLOCK* = ACS_PICK('0', '#') - ACS_S3* = ACS_PICK('p', '-') - ACS_S7* = ACS_PICK('r', '-') - ACS_LEQUAL* = ACS_PICK('y', '<') - ACS_GEQUAL* = ACS_PICK('z', '>') - ACS_PI* = ACS_PICK('{', 'n') - ACS_NEQUAL* = ACS_PICK('|', '+') - ACS_STERLING* = ACS_PICK('}', 'L') - ACS_BSSB* = ACS_ULCORNER - ACS_SSBB* = ACS_LLCORNER - ACS_BBSS* = ACS_URCORNER - ACS_SBBS* = ACS_LRCORNER - ACS_SBSS* = ACS_RTEE - ACS_SSSB* = ACS_LTEE - ACS_SSBS* = ACS_BTEE - ACS_BSSS* = ACS_TTEE - ACS_BSBS* = ACS_HLINE - ACS_SBSB* = ACS_VLINE - ACS_SSSS* = ACS_PLUS -discard """WACS_ULCORNER* = (addr((acs_map['l']))) - WACS_LLCORNER* = (addr((acs_map['m']))) - WACS_URCORNER* = (addr((acs_map['k']))) - WACS_LRCORNER* = (addr((acs_map['j']))) - WACS_RTEE* = (addr((acs_map['u']))) - WACS_LTEE* = (addr((acs_map['t']))) - WACS_BTEE* = (addr((acs_map['v']))) - WACS_TTEE* = (addr((acs_map['w']))) - WACS_HLINE* = (addr((acs_map['q']))) - WACS_VLINE* = (addr((acs_map['x']))) - WACS_PLUS* = (addr((acs_map['n']))) - WACS_S1* = (addr((acs_map['o']))) - WACS_S9* = (addr((acs_map['s']))) - WACS_DIAMOND* = (addr((acs_map['`']))) - WACS_CKBOARD* = (addr((acs_map['a']))) - WACS_DEGREE* = (addr((acs_map['f']))) - WACS_PLMINUS* = (addr((acs_map['g']))) - WACS_BULLET* = (addr((acs_map['~']))) - WACS_LARROW* = (addr((acs_map[',']))) - WACS_RARROW* = (addr((acs_map['+']))) - WACS_DARROW* = (addr((acs_map['.']))) - WACS_UARROW* = (addr((acs_map['-']))) - WACS_BOARD* = (addr((acs_map['h']))) - WACS_LANTERN* = (addr((acs_map['i']))) - WACS_BLOCK* = (addr((acs_map['0']))) - WACS_S3* = (addr((acs_map['p']))) - WACS_S7* = (addr((acs_map['r']))) - WACS_LEQUAL* = (addr((acs_map['y']))) - WACS_GEQUAL* = (addr((acs_map['z']))) - WACS_PI* = (addr((acs_map['{']))) - WACS_NEQUAL* = (addr((acs_map['|']))) - WACS_STERLING* = (addr((acs_map['}']))) - WACS_BSSB* = WACS_ULCORNER - WACS_SSBB* = WACS_LLCORNER - WACS_BBSS* = WACS_URCORNER - WACS_SBBS* = WACS_LRCORNER - WACS_SBSS* = WACS_RTEE - WACS_SSSB* = WACS_LTEE - WACS_SSBS* = WACS_BTEE - WACS_BSSS* = WACS_TTEE - WACS_BSBS* = WACS_HLINE - WACS_SBSB* = WACS_VLINE - WACS_SSSS* = WACS_PLUS""" - -proc addch*(a2: cunsignedlong): cint{.extdecl, importc: "addch", - dynlib: pdcursesdll.} -proc addchnstr*(a2: ptr cunsignedlong; a3: cint): cint{.extdecl, - importc: "addchnstr", dynlib: pdcursesdll.} -proc addchstr*(a2: ptr cunsignedlong): cint{.extdecl, importc: "addchstr", - dynlib: pdcursesdll.} -proc addnstr*(a2: cstring; a3: cint): cint{.extdecl, importc: "addnstr", - dynlib: pdcursesdll.} -proc addstr*(a2: cstring): cint{.extdecl, importc: "addstr", dynlib: pdcursesdll.} -proc attroff*(a2: cunsignedlong): cint{.extdecl, importc: "attroff", - dynlib: pdcursesdll.} -proc attron*(a2: cunsignedlong): cint{.extdecl, importc: "attron", - dynlib: pdcursesdll.} -proc attrset*(a2: cunsignedlong): cint{.extdecl, importc: "attrset", - dynlib: pdcursesdll.} -proc attr_get*(a2: ptr cunsignedlong; a3: ptr cshort; a4: pointer): cint{.extdecl, - importc: "attr_get", dynlib: pdcursesdll.} -proc attr_off*(a2: cunsignedlong; a3: pointer): cint{.extdecl, - importc: "attr_off", dynlib: pdcursesdll.} -proc attr_on*(a2: cunsignedlong; a3: pointer): cint{.extdecl, importc: "attr_on", - dynlib: pdcursesdll.} -proc attr_set*(a2: cunsignedlong; a3: cshort; a4: pointer): cint{.extdecl, - importc: "attr_set", dynlib: pdcursesdll.} -proc baudrate*(): cint{.extdecl, importc: "baudrate", dynlib: pdcursesdll.} -proc beep*(): cint{.extdecl, importc: "beep", dynlib: pdcursesdll.} -proc bkgd*(a2: cunsignedlong): cint{.extdecl, importc: "bkgd", dynlib: pdcursesdll.} -proc bkgdset*(a2: cunsignedlong){.extdecl, importc: "bkgdset", dynlib: pdcursesdll.} -proc border*(a2: cunsignedlong; a3: cunsignedlong; a4: cunsignedlong; - a5: cunsignedlong; a6: cunsignedlong; a7: cunsignedlong; - a8: cunsignedlong; a9: cunsignedlong): cint{.extdecl, - importc: "border", dynlib: pdcursesdll.} -proc box*(a2: ptr WINDOW; a3: cunsignedlong; a4: cunsignedlong): cint{.extdecl, - importc: "box", dynlib: pdcursesdll.} -proc can_change_color*(): cunsignedchar{.extdecl, importc: "can_change_color", - dynlib: pdcursesdll.} -proc cbreak*(): cint{.extdecl, importc: "cbreak", dynlib: pdcursesdll.} -proc chgat*(a2: cint; a3: cunsignedlong; a4: cshort; a5: pointer): cint{.extdecl, - importc: "chgat", dynlib: pdcursesdll.} -proc clearok*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, - importc: "clearok", dynlib: pdcursesdll.} -proc clear*(): cint{.extdecl, importc: "clear", dynlib: pdcursesdll.} -proc clrtobot*(): cint{.extdecl, importc: "clrtobot", dynlib: pdcursesdll.} -proc clrtoeol*(): cint{.extdecl, importc: "clrtoeol", dynlib: pdcursesdll.} -proc color_content*(a2: cshort; a3: ptr cshort; a4: ptr cshort; a5: ptr cshort): cint{. - extdecl, importc: "color_content", dynlib: pdcursesdll.} -proc color_set*(a2: cshort; a3: pointer): cint{.extdecl, importc: "color_set", - dynlib: pdcursesdll.} -proc copywin*(a2: ptr WINDOW; a3: ptr WINDOW; a4: cint; a5: cint; a6: cint; - a7: cint; a8: cint; a9: cint; a10: cint): cint{.extdecl, - importc: "copywin", dynlib: pdcursesdll.} -proc curs_set*(a2: cint): cint{.extdecl, importc: "curs_set", dynlib: pdcursesdll.} -proc def_prog_mode*(): cint{.extdecl, importc: "def_prog_mode", - dynlib: pdcursesdll.} -proc def_shell_mode*(): cint{.extdecl, importc: "def_shell_mode", - dynlib: pdcursesdll.} -proc delay_output*(a2: cint): cint{.extdecl, importc: "delay_output", - dynlib: pdcursesdll.} -proc delch*(): cint{.extdecl, importc: "delch", dynlib: pdcursesdll.} -proc deleteln*(): cint{.extdecl, importc: "deleteln", dynlib: pdcursesdll.} -proc delscreen*(a2: ptr SCREEN){.extdecl, importc: "delscreen", - dynlib: pdcursesdll.} -proc delwin*(a2: ptr WINDOW): cint{.extdecl, importc: "delwin", - dynlib: pdcursesdll.} -proc derwin*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cint; a6: cint): ptr WINDOW{. - extdecl, importc: "derwin", dynlib: pdcursesdll.} -proc doupdate*(): cint{.extdecl, importc: "doupdate", dynlib: pdcursesdll.} -proc dupwin*(a2: ptr WINDOW): ptr WINDOW{.extdecl, importc: "dupwin", - dynlib: pdcursesdll.} -proc echochar*(a2: cunsignedlong): cint{.extdecl, importc: "echochar", - dynlib: pdcursesdll.} -proc echo*(): cint{.extdecl, importc: "echo", dynlib: pdcursesdll.} -proc endwin*(): cint{.extdecl, importc: "endwin", dynlib: pdcursesdll.} -proc erasechar*(): char{.extdecl, importc: "erasechar", dynlib: pdcursesdll.} -proc erase*(): cint{.extdecl, importc: "erase", dynlib: pdcursesdll.} -proc filter*(){.extdecl, importc: "filter", dynlib: pdcursesdll.} -proc flash*(): cint{.extdecl, importc: "flash", dynlib: pdcursesdll.} -proc flushinp*(): cint{.extdecl, importc: "flushinp", dynlib: pdcursesdll.} -proc getbkgd*(a2: ptr WINDOW): cunsignedlong{.extdecl, importc: "getbkgd", - dynlib: pdcursesdll.} -proc getnstr*(a2: cstring; a3: cint): cint{.extdecl, importc: "getnstr", - dynlib: pdcursesdll.} -proc getstr*(a2: cstring): cint{.extdecl, importc: "getstr", dynlib: pdcursesdll.} -proc getwin*(a2: File): ptr WINDOW{.extdecl, importc: "getwin", - dynlib: pdcursesdll.} -proc halfdelay*(a2: cint): cint{.extdecl, importc: "halfdelay", - dynlib: pdcursesdll.} -proc has_colors*(): cunsignedchar{.extdecl, importc: "has_colors", - dynlib: pdcursesdll.} -proc has_ic*(): cunsignedchar{.extdecl, importc: "has_ic", dynlib: pdcursesdll.} -proc has_il*(): cunsignedchar{.extdecl, importc: "has_il", dynlib: pdcursesdll.} -proc hline*(a2: cunsignedlong; a3: cint): cint{.extdecl, importc: "hline", - dynlib: pdcursesdll.} -proc idcok*(a2: ptr WINDOW; a3: cunsignedchar){.extdecl, importc: "idcok", - dynlib: pdcursesdll.} -proc idlok*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, importc: "idlok", - dynlib: pdcursesdll.} -proc immedok*(a2: ptr WINDOW; a3: cunsignedchar){.extdecl, importc: "immedok", - dynlib: pdcursesdll.} -proc inchnstr*(a2: ptr cunsignedlong; a3: cint): cint{.extdecl, - importc: "inchnstr", dynlib: pdcursesdll.} -proc inchstr*(a2: ptr cunsignedlong): cint{.extdecl, importc: "inchstr", - dynlib: pdcursesdll.} -proc inch*(): cunsignedlong{.extdecl, importc: "inch", dynlib: pdcursesdll.} -proc init_color*(a2: cshort; a3: cshort; a4: cshort; a5: cshort): cint{.extdecl, - importc: "init_color", dynlib: pdcursesdll.} -proc init_pair*(a2: cshort; a3: cshort; a4: cshort): cint{.extdecl, - importc: "init_pair", dynlib: pdcursesdll.} -proc initscr*(): ptr WINDOW{.extdecl, importc: "initscr", dynlib: pdcursesdll.} -proc innstr*(a2: cstring; a3: cint): cint{.extdecl, importc: "innstr", - dynlib: pdcursesdll.} -proc insch*(a2: cunsignedlong): cint{.extdecl, importc: "insch", - dynlib: pdcursesdll.} -proc insdelln*(a2: cint): cint{.extdecl, importc: "insdelln", dynlib: pdcursesdll.} -proc insertln*(): cint{.extdecl, importc: "insertln", dynlib: pdcursesdll.} -proc insnstr*(a2: cstring; a3: cint): cint{.extdecl, importc: "insnstr", - dynlib: pdcursesdll.} -proc insstr*(a2: cstring): cint{.extdecl, importc: "insstr", dynlib: pdcursesdll.} -proc instr*(a2: cstring): cint{.extdecl, importc: "instr", dynlib: pdcursesdll.} -proc intrflush*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, - importc: "intrflush", dynlib: pdcursesdll.} -proc isendwin*(): cunsignedchar{.extdecl, importc: "isendwin", dynlib: pdcursesdll.} -proc is_linetouched*(a2: ptr WINDOW; a3: cint): cunsignedchar{.extdecl, - importc: "is_linetouched", dynlib: pdcursesdll.} -proc is_wintouched*(a2: ptr WINDOW): cunsignedchar{.extdecl, - importc: "is_wintouched", dynlib: pdcursesdll.} -proc keyname*(a2: cint): cstring{.extdecl, importc: "keyname", dynlib: pdcursesdll.} -proc keypad*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, importc: "keypad", - dynlib: pdcursesdll.} -proc killchar*(): char{.extdecl, importc: "killchar", dynlib: pdcursesdll.} -proc leaveok*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, - importc: "leaveok", dynlib: pdcursesdll.} -proc longname*(): cstring{.extdecl, importc: "longname", dynlib: pdcursesdll.} -proc meta*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, importc: "meta", - dynlib: pdcursesdll.} -proc move*(a2: cint; a3: cint): cint{.extdecl, importc: "move", - dynlib: pdcursesdll.} -proc mvaddch*(a2: cint; a3: cint; a4: cunsignedlong): cint{.extdecl, - importc: "mvaddch", dynlib: pdcursesdll.} -proc mvaddchnstr*(a2: cint; a3: cint; a4: ptr cunsignedlong; a5: cint): cint{. - extdecl, importc: "mvaddchnstr", dynlib: pdcursesdll.} -proc mvaddchstr*(a2: cint; a3: cint; a4: ptr cunsignedlong): cint{.extdecl, - importc: "mvaddchstr", dynlib: pdcursesdll.} -proc mvaddnstr*(a2: cint; a3: cint; a4: cstring; a5: cint): cint{.extdecl, - importc: "mvaddnstr", dynlib: pdcursesdll.} -proc mvaddstr*(a2: cint; a3: cint; a4: cstring): cint{.extdecl, - importc: "mvaddstr", dynlib: pdcursesdll.} -proc mvchgat*(a2: cint; a3: cint; a4: cint; a5: cunsignedlong; a6: cshort; - a7: pointer): cint{.extdecl, importc: "mvchgat", dynlib: pdcursesdll.} -proc mvcur*(a2: cint; a3: cint; a4: cint; a5: cint): cint{.extdecl, - importc: "mvcur", dynlib: pdcursesdll.} -proc mvdelch*(a2: cint; a3: cint): cint{.extdecl, importc: "mvdelch", - dynlib: pdcursesdll.} -proc mvderwin*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, - importc: "mvderwin", dynlib: pdcursesdll.} -proc mvgetch*(a2: cint; a3: cint): cint{.extdecl, importc: "mvgetch", - dynlib: pdcursesdll.} -proc mvgetnstr*(a2: cint; a3: cint; a4: cstring; a5: cint): cint{.extdecl, - importc: "mvgetnstr", dynlib: pdcursesdll.} -proc mvgetstr*(a2: cint; a3: cint; a4: cstring): cint{.extdecl, - importc: "mvgetstr", dynlib: pdcursesdll.} -proc mvhline*(a2: cint; a3: cint; a4: cunsignedlong; a5: cint): cint{.extdecl, - importc: "mvhline", dynlib: pdcursesdll.} -proc mvinch*(a2: cint; a3: cint): cunsignedlong{.extdecl, importc: "mvinch", - dynlib: pdcursesdll.} -proc mvinchnstr*(a2: cint; a3: cint; a4: ptr cunsignedlong; a5: cint): cint{. - extdecl, importc: "mvinchnstr", dynlib: pdcursesdll.} -proc mvinchstr*(a2: cint; a3: cint; a4: ptr cunsignedlong): cint{.extdecl, - importc: "mvinchstr", dynlib: pdcursesdll.} -proc mvinnstr*(a2: cint; a3: cint; a4: cstring; a5: cint): cint{.extdecl, - importc: "mvinnstr", dynlib: pdcursesdll.} -proc mvinsch*(a2: cint; a3: cint; a4: cunsignedlong): cint{.extdecl, - importc: "mvinsch", dynlib: pdcursesdll.} -proc mvinsnstr*(a2: cint; a3: cint; a4: cstring; a5: cint): cint{.extdecl, - importc: "mvinsnstr", dynlib: pdcursesdll.} -proc mvinsstr*(a2: cint; a3: cint; a4: cstring): cint{.extdecl, - importc: "mvinsstr", dynlib: pdcursesdll.} -proc mvinstr*(a2: cint; a3: cint; a4: cstring): cint{.extdecl, importc: "mvinstr", - dynlib: pdcursesdll.} -proc mvprintw*(a2: cint; a3: cint; a4: cstring): cint{.varargs, extdecl, - importc: "mvprintw", dynlib: pdcursesdll.} -proc mvscanw*(a2: cint; a3: cint; a4: cstring): cint{.varargs, extdecl, - importc: "mvscanw", dynlib: pdcursesdll.} -proc mvvline*(a2: cint; a3: cint; a4: cunsignedlong; a5: cint): cint{.extdecl, - importc: "mvvline", dynlib: pdcursesdll.} -proc mvwaddchnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong; - a6: cint): cint{.extdecl, importc: "mvwaddchnstr", - dynlib: pdcursesdll.} -proc mvwaddchstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong): cint{. - extdecl, importc: "mvwaddchstr", dynlib: pdcursesdll.} -proc mvwaddch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cunsignedlong): cint{. - extdecl, importc: "mvwaddch", dynlib: pdcursesdll.} -proc mvwaddnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring; a6: cint): cint{. - extdecl, importc: "mvwaddnstr", dynlib: pdcursesdll.} -proc mvwaddstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{.extdecl, - importc: "mvwaddstr", dynlib: pdcursesdll.} -proc mvwchgat*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cint; a6: cunsignedlong; - a7: cshort; a8: pointer): cint{.extdecl, importc: "mvwchgat", - dynlib: pdcursesdll.} -proc mvwdelch*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, - importc: "mvwdelch", dynlib: pdcursesdll.} -proc mvwgetch*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, - importc: "mvwgetch", dynlib: pdcursesdll.} -proc mvwgetnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring; a6: cint): cint{. - extdecl, importc: "mvwgetnstr", dynlib: pdcursesdll.} -proc mvwgetstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{.extdecl, - importc: "mvwgetstr", dynlib: pdcursesdll.} -proc mvwhline*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cunsignedlong; a6: cint): cint{. - extdecl, importc: "mvwhline", dynlib: pdcursesdll.} -proc mvwinchnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong; - a6: cint): cint{.extdecl, importc: "mvwinchnstr", - dynlib: pdcursesdll.} -proc mvwinchstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong): cint{. - extdecl, importc: "mvwinchstr", dynlib: pdcursesdll.} -proc mvwinch*(a2: ptr WINDOW; a3: cint; a4: cint): cunsignedlong{.extdecl, - importc: "mvwinch", dynlib: pdcursesdll.} -proc mvwinnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring; a6: cint): cint{. - extdecl, importc: "mvwinnstr", dynlib: pdcursesdll.} -proc mvwinsch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cunsignedlong): cint{. - extdecl, importc: "mvwinsch", dynlib: pdcursesdll.} -proc mvwinsnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring; a6: cint): cint{. - extdecl, importc: "mvwinsnstr", dynlib: pdcursesdll.} -proc mvwinsstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{.extdecl, - importc: "mvwinsstr", dynlib: pdcursesdll.} -proc mvwinstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{.extdecl, - importc: "mvwinstr", dynlib: pdcursesdll.} -proc mvwin*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, importc: "mvwin", - dynlib: pdcursesdll.} -proc mvwprintw*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{.varargs, - extdecl, importc: "mvwprintw", dynlib: pdcursesdll.} -proc mvwscanw*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{.varargs, - extdecl, importc: "mvwscanw", dynlib: pdcursesdll.} -proc mvwvline*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cunsignedlong; a6: cint): cint{. - extdecl, importc: "mvwvline", dynlib: pdcursesdll.} -proc napms*(a2: cint): cint{.extdecl, importc: "napms", dynlib: pdcursesdll.} -proc newpad*(a2: cint; a3: cint): ptr WINDOW{.extdecl, importc: "newpad", - dynlib: pdcursesdll.} -proc newterm*(a2: cstring; a3: File; a4: File): ptr SCREEN{.extdecl, - importc: "newterm", dynlib: pdcursesdll.} -proc newwin*(a2: cint; a3: cint; a4: cint; a5: cint): ptr WINDOW{.extdecl, - importc: "newwin", dynlib: pdcursesdll.} -proc nl*(): cint{.extdecl, importc: "nl", dynlib: pdcursesdll.} -proc nocbreak*(): cint{.extdecl, importc: "nocbreak", dynlib: pdcursesdll.} -proc nodelay*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, - importc: "nodelay", dynlib: pdcursesdll.} -proc noecho*(): cint{.extdecl, importc: "noecho", dynlib: pdcursesdll.} -proc nonl*(): cint{.extdecl, importc: "nonl", dynlib: pdcursesdll.} -proc noqiflush*(){.extdecl, importc: "noqiflush", dynlib: pdcursesdll.} -proc noraw*(): cint{.extdecl, importc: "noraw", dynlib: pdcursesdll.} -proc notimeout*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, - importc: "notimeout", dynlib: pdcursesdll.} -proc overlay*(a2: ptr WINDOW; a3: ptr WINDOW): cint{.extdecl, importc: "overlay", - dynlib: pdcursesdll.} -proc overwrite*(a2: ptr WINDOW; a3: ptr WINDOW): cint{.extdecl, - importc: "overwrite", dynlib: pdcursesdll.} -proc pair_content*(a2: cshort; a3: ptr cshort; a4: ptr cshort): cint{.extdecl, - importc: "pair_content", dynlib: pdcursesdll.} -proc pechochar*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, - importc: "pechochar", dynlib: pdcursesdll.} -proc pnoutrefresh*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cint; a6: cint; - a7: cint; a8: cint): cint{.extdecl, importc: "pnoutrefresh", - dynlib: pdcursesdll.} -proc prefresh*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cint; a6: cint; a7: cint; - a8: cint): cint{.extdecl, importc: "prefresh", dynlib: pdcursesdll.} -proc printw*(a2: cstring): cint{.varargs, extdecl, importc: "printw", - dynlib: pdcursesdll.} -proc putwin*(a2: ptr WINDOW; a3: File): cint{.extdecl, importc: "putwin", - dynlib: pdcursesdll.} -proc qiflush*(){.extdecl, importc: "qiflush", dynlib: pdcursesdll.} -proc raw*(): cint{.extdecl, importc: "raw", dynlib: pdcursesdll.} -proc redrawwin*(a2: ptr WINDOW): cint{.extdecl, importc: "redrawwin", - dynlib: pdcursesdll.} -proc refresh*(): cint{.extdecl, importc: "refresh", dynlib: pdcursesdll.} -proc reset_prog_mode*(): cint{.extdecl, importc: "reset_prog_mode", - dynlib: pdcursesdll.} -proc reset_shell_mode*(): cint{.extdecl, importc: "reset_shell_mode", - dynlib: pdcursesdll.} -proc resetty*(): cint{.extdecl, importc: "resetty", dynlib: pdcursesdll.} -#int ripoffline(int, int (*)(WINDOW *, int)); -proc savetty*(): cint{.extdecl, importc: "savetty", dynlib: pdcursesdll.} -proc scanw*(a2: cstring): cint{.varargs, extdecl, importc: "scanw", - dynlib: pdcursesdll.} -proc scr_dump*(a2: cstring): cint{.extdecl, importc: "scr_dump", - dynlib: pdcursesdll.} -proc scr_init*(a2: cstring): cint{.extdecl, importc: "scr_init", - dynlib: pdcursesdll.} -proc scr_restore*(a2: cstring): cint{.extdecl, importc: "scr_restore", - dynlib: pdcursesdll.} -proc scr_set*(a2: cstring): cint{.extdecl, importc: "scr_set", dynlib: pdcursesdll.} -proc scrl*(a2: cint): cint{.extdecl, importc: "scrl", dynlib: pdcursesdll.} -proc scroll*(a2: ptr WINDOW): cint{.extdecl, importc: "scroll", - dynlib: pdcursesdll.} -proc scrollok*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, - importc: "scrollok", dynlib: pdcursesdll.} -proc set_term*(a2: ptr SCREEN): ptr SCREEN{.extdecl, importc: "set_term", - dynlib: pdcursesdll.} -proc setscrreg*(a2: cint; a3: cint): cint{.extdecl, importc: "setscrreg", - dynlib: pdcursesdll.} -proc slk_attroff*(a2: cunsignedlong): cint{.extdecl, importc: "slk_attroff", - dynlib: pdcursesdll.} -proc slk_attr_off*(a2: cunsignedlong; a3: pointer): cint{.extdecl, - importc: "slk_attr_off", dynlib: pdcursesdll.} -proc slk_attron*(a2: cunsignedlong): cint{.extdecl, importc: "slk_attron", - dynlib: pdcursesdll.} -proc slk_attr_on*(a2: cunsignedlong; a3: pointer): cint{.extdecl, - importc: "slk_attr_on", dynlib: pdcursesdll.} -proc slk_attrset*(a2: cunsignedlong): cint{.extdecl, importc: "slk_attrset", - dynlib: pdcursesdll.} -proc slk_attr_set*(a2: cunsignedlong; a3: cshort; a4: pointer): cint{.extdecl, - importc: "slk_attr_set", dynlib: pdcursesdll.} -proc slk_clear*(): cint{.extdecl, importc: "slk_clear", dynlib: pdcursesdll.} -proc slk_color*(a2: cshort): cint{.extdecl, importc: "slk_color", - dynlib: pdcursesdll.} -proc slk_init*(a2: cint): cint{.extdecl, importc: "slk_init", dynlib: pdcursesdll.} -proc slk_label*(a2: cint): cstring{.extdecl, importc: "slk_label", - dynlib: pdcursesdll.} -proc slk_noutrefresh*(): cint{.extdecl, importc: "slk_noutrefresh", - dynlib: pdcursesdll.} -proc slk_refresh*(): cint{.extdecl, importc: "slk_refresh", dynlib: pdcursesdll.} -proc slk_restore*(): cint{.extdecl, importc: "slk_restore", dynlib: pdcursesdll.} -proc slk_set*(a2: cint; a3: cstring; a4: cint): cint{.extdecl, importc: "slk_set", - dynlib: pdcursesdll.} -proc slk_touch*(): cint{.extdecl, importc: "slk_touch", dynlib: pdcursesdll.} -proc standend*(): cint{.extdecl, importc: "standend", dynlib: pdcursesdll.} -proc standout*(): cint{.extdecl, importc: "standout", dynlib: pdcursesdll.} -proc start_color*(): cint{.extdecl, importc: "start_color", dynlib: pdcursesdll.} -proc subpad*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cint; a6: cint): ptr WINDOW{. - extdecl, importc: "subpad", dynlib: pdcursesdll.} -proc subwin*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cint; a6: cint): ptr WINDOW{. - extdecl, importc: "subwin", dynlib: pdcursesdll.} -proc syncok*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, importc: "syncok", - dynlib: pdcursesdll.} -proc termattrs*(): cunsignedlong{.extdecl, importc: "termattrs", - dynlib: pdcursesdll.} -proc termattrs2*(): cunsignedlong{.extdecl, importc: "term_attrs", - dynlib: pdcursesdll.} -proc termname*(): cstring{.extdecl, importc: "termname", dynlib: pdcursesdll.} -proc timeout*(a2: cint){.extdecl, importc: "timeout", dynlib: pdcursesdll.} -proc touchline*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, - importc: "touchline", dynlib: pdcursesdll.} -proc touchwin*(a2: ptr WINDOW): cint{.extdecl, importc: "touchwin", - dynlib: pdcursesdll.} -proc typeahead*(a2: cint): cint{.extdecl, importc: "typeahead", - dynlib: pdcursesdll.} -proc untouchwin*(a2: ptr WINDOW): cint{.extdecl, importc: "untouchwin", - dynlib: pdcursesdll.} -proc use_env*(a2: cunsignedchar){.extdecl, importc: "use_env", dynlib: pdcursesdll.} -proc vidattr*(a2: cunsignedlong): cint{.extdecl, importc: "vidattr", - dynlib: pdcursesdll.} -proc vid_attr*(a2: cunsignedlong; a3: cshort; a4: pointer): cint{.extdecl, - importc: "vid_attr", dynlib: pdcursesdll.} -#int vidputs(chtype, int (*)(int)); -#int vid_puts(attr_t, short, void *, int (*)(int)); -proc vline*(a2: cunsignedlong; a3: cint): cint{.extdecl, importc: "vline", - dynlib: pdcursesdll.} -proc vwprintw*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, varargs, - importc: "vw_printw", dynlib: pdcursesdll.} -proc vwprintw2*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, varargs, - importc: "vwprintw", dynlib: pdcursesdll.} -proc vwscanw*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, varargs, - importc: "vw_scanw", dynlib: pdcursesdll.} -proc vwscanw2*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, varargs, - importc: "vwscanw", dynlib: pdcursesdll.} -proc waddchnstr*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: cint): cint{.extdecl, - importc: "waddchnstr", dynlib: pdcursesdll.} -proc waddchstr*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl, - importc: "waddchstr", dynlib: pdcursesdll.} -proc waddch*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, importc: "waddch", - dynlib: pdcursesdll.} -proc waddnstr*(a2: ptr WINDOW; a3: cstring; a4: cint): cint{.extdecl, - importc: "waddnstr", dynlib: pdcursesdll.} -proc waddstr*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, importc: "waddstr", - dynlib: pdcursesdll.} -proc wattroff*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, - importc: "wattroff", dynlib: pdcursesdll.} -proc wattron*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, - importc: "wattron", dynlib: pdcursesdll.} -proc wattrset*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, - importc: "wattrset", dynlib: pdcursesdll.} -proc wattr_get*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: ptr cshort; - a5: pointer): cint{.extdecl, importc: "wattr_get", - dynlib: pdcursesdll.} -proc wattr_off*(a2: ptr WINDOW; a3: cunsignedlong; a4: pointer): cint{.extdecl, - importc: "wattr_off", dynlib: pdcursesdll.} -proc wattr_on*(a2: ptr WINDOW; a3: cunsignedlong; a4: pointer): cint{.extdecl, - importc: "wattr_on", dynlib: pdcursesdll.} -proc wattr_set*(a2: ptr WINDOW; a3: cunsignedlong; a4: cshort; a5: pointer): cint{. - extdecl, importc: "wattr_set", dynlib: pdcursesdll.} -proc wbkgdset*(a2: ptr WINDOW; a3: cunsignedlong){.extdecl, importc: "wbkgdset", - dynlib: pdcursesdll.} -proc wbkgd*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, importc: "wbkgd", - dynlib: pdcursesdll.} -proc wborder*(a2: ptr WINDOW; a3: cunsignedlong; a4: cunsignedlong; - a5: cunsignedlong; a6: cunsignedlong; a7: cunsignedlong; - a8: cunsignedlong; a9: cunsignedlong; a10: cunsignedlong): cint{. - extdecl, importc: "wborder", dynlib: pdcursesdll.} -proc wchgat*(a2: ptr WINDOW; a3: cint; a4: cunsignedlong; a5: cshort; - a6: pointer): cint{.extdecl, importc: "wchgat", dynlib: pdcursesdll.} -proc wclear*(a2: ptr WINDOW): cint{.extdecl, importc: "wclear", - dynlib: pdcursesdll.} -proc wclrtobot*(a2: ptr WINDOW): cint{.extdecl, importc: "wclrtobot", - dynlib: pdcursesdll.} -proc wclrtoeol*(a2: ptr WINDOW): cint{.extdecl, importc: "wclrtoeol", - dynlib: pdcursesdll.} -proc wcolor_set*(a2: ptr WINDOW; a3: cshort; a4: pointer): cint{.extdecl, - importc: "wcolor_set", dynlib: pdcursesdll.} -proc wcursyncup*(a2: ptr WINDOW){.extdecl, importc: "wcursyncup", - dynlib: pdcursesdll.} -proc wdelch*(a2: ptr WINDOW): cint{.extdecl, importc: "wdelch", - dynlib: pdcursesdll.} -proc wdeleteln*(a2: ptr WINDOW): cint{.extdecl, importc: "wdeleteln", - dynlib: pdcursesdll.} -proc wechochar*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, - importc: "wechochar", dynlib: pdcursesdll.} -proc werase*(a2: ptr WINDOW): cint{.extdecl, importc: "werase", - dynlib: pdcursesdll.} -proc wgetch*(a2: ptr WINDOW): cint{.extdecl, importc: "wgetch", - dynlib: pdcursesdll.} -proc wgetnstr*(a2: ptr WINDOW; a3: cstring; a4: cint): cint{.extdecl, - importc: "wgetnstr", dynlib: pdcursesdll.} -proc wgetstr*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, importc: "wgetstr", - dynlib: pdcursesdll.} -proc whline*(a2: ptr WINDOW; a3: cunsignedlong; a4: cint): cint{.extdecl, - importc: "whline", dynlib: pdcursesdll.} -proc winchnstr*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: cint): cint{.extdecl, - importc: "winchnstr", dynlib: pdcursesdll.} -proc winchstr*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl, - importc: "winchstr", dynlib: pdcursesdll.} -proc winch*(a2: ptr WINDOW): cunsignedlong{.extdecl, importc: "winch", - dynlib: pdcursesdll.} -proc winnstr*(a2: ptr WINDOW; a3: cstring; a4: cint): cint{.extdecl, - importc: "winnstr", dynlib: pdcursesdll.} -proc winsch*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, importc: "winsch", - dynlib: pdcursesdll.} -proc winsdelln*(a2: ptr WINDOW; a3: cint): cint{.extdecl, importc: "winsdelln", - dynlib: pdcursesdll.} -proc winsertln*(a2: ptr WINDOW): cint{.extdecl, importc: "winsertln", - dynlib: pdcursesdll.} -proc winsnstr*(a2: ptr WINDOW; a3: cstring; a4: cint): cint{.extdecl, - importc: "winsnstr", dynlib: pdcursesdll.} -proc winsstr*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, importc: "winsstr", - dynlib: pdcursesdll.} -proc winstr*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, importc: "winstr", - dynlib: pdcursesdll.} -proc wmove*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, importc: "wmove", - dynlib: pdcursesdll.} -proc wnoutrefresh*(a2: ptr WINDOW): cint{.extdecl, importc: "wnoutrefresh", - dynlib: pdcursesdll.} -proc wprintw*(a2: ptr WINDOW; a3: cstring): cint{.varargs, extdecl, - importc: "wprintw", dynlib: pdcursesdll.} -proc wredrawln*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, - importc: "wredrawln", dynlib: pdcursesdll.} -proc wrefresh*(a2: ptr WINDOW): cint{.extdecl, importc: "wrefresh", - dynlib: pdcursesdll.} -proc wscanw*(a2: ptr WINDOW; a3: cstring): cint{.varargs, extdecl, - importc: "wscanw", dynlib: pdcursesdll.} -proc wscrl*(a2: ptr WINDOW; a3: cint): cint{.extdecl, importc: "wscrl", - dynlib: pdcursesdll.} -proc wsetscrreg*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, - importc: "wsetscrreg", dynlib: pdcursesdll.} -proc wstandend*(a2: ptr WINDOW): cint{.extdecl, importc: "wstandend", - dynlib: pdcursesdll.} -proc wstandout*(a2: ptr WINDOW): cint{.extdecl, importc: "wstandout", - dynlib: pdcursesdll.} -proc wsyncdown*(a2: ptr WINDOW){.extdecl, importc: "wsyncdown", - dynlib: pdcursesdll.} -proc wsyncup*(a2: ptr WINDOW){.extdecl, importc: "wsyncup", dynlib: pdcursesdll.} -proc wtimeout*(a2: ptr WINDOW; a3: cint){.extdecl, importc: "wtimeout", - dynlib: pdcursesdll.} -proc wtouchln*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cint): cint{.extdecl, - importc: "wtouchln", dynlib: pdcursesdll.} -proc wvline*(a2: ptr WINDOW; a3: cunsignedlong; a4: cint): cint{.extdecl, - importc: "wvline", dynlib: pdcursesdll.} -proc addnwstr*(a2: cstring; a3: cint): cint{.extdecl, importc: "addnwstr", - dynlib: pdcursesdll.} -proc addwstr*(a2: cstring): cint{.extdecl, importc: "addwstr", - dynlib: pdcursesdll.} -proc add_wch*(a2: ptr cunsignedlong): cint{.extdecl, importc: "add_wch", - dynlib: pdcursesdll.} -proc add_wchnstr*(a2: ptr cunsignedlong; a3: cint): cint{.extdecl, - importc: "add_wchnstr", dynlib: pdcursesdll.} -proc add_wchstr*(a2: ptr cunsignedlong): cint{.extdecl, importc: "add_wchstr", - dynlib: pdcursesdll.} -proc border_set*(a2: ptr cunsignedlong; a3: ptr cunsignedlong; - a4: ptr cunsignedlong; a5: ptr cunsignedlong; - a6: ptr cunsignedlong; a7: ptr cunsignedlong; - a8: ptr cunsignedlong; a9: ptr cunsignedlong): cint{.extdecl, - importc: "border_set", dynlib: pdcursesdll.} -proc box_set*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: ptr cunsignedlong): cint{. - extdecl, importc: "box_set", dynlib: pdcursesdll.} -proc echo_wchar*(a2: ptr cunsignedlong): cint{.extdecl, importc: "echo_wchar", - dynlib: pdcursesdll.} -proc erasewchar*(a2: cstring): cint{.extdecl, importc: "erasewchar", - dynlib: pdcursesdll.} -proc getbkgrnd*(a2: ptr cunsignedlong): cint{.extdecl, importc: "getbkgrnd", - dynlib: pdcursesdll.} -proc getcchar*(a2: ptr cunsignedlong; a3: cstring; a4: ptr cunsignedlong; - a5: ptr cshort; a6: pointer): cint{.extdecl, importc: "getcchar", - dynlib: pdcursesdll.} -proc getn_wstr*(a2: ptr cint; a3: cint): cint{.extdecl, importc: "getn_wstr", - dynlib: pdcursesdll.} -proc get_wch*(a2: ptr cint): cint{.extdecl, importc: "get_wch", - dynlib: pdcursesdll.} -proc get_wstr*(a2: ptr cint): cint{.extdecl, importc: "get_wstr", - dynlib: pdcursesdll.} -proc hline_set*(a2: ptr cunsignedlong; a3: cint): cint{.extdecl, - importc: "hline_set", dynlib: pdcursesdll.} -proc innwstr*(a2: cstring; a3: cint): cint{.extdecl, importc: "innwstr", - dynlib: pdcursesdll.} -proc ins_nwstr*(a2: cstring; a3: cint): cint{.extdecl, importc: "ins_nwstr", - dynlib: pdcursesdll.} -proc ins_wch*(a2: ptr cunsignedlong): cint{.extdecl, importc: "ins_wch", - dynlib: pdcursesdll.} -proc ins_wstr*(a2: cstring): cint{.extdecl, importc: "ins_wstr", - dynlib: pdcursesdll.} -proc inwstr*(a2: cstring): cint{.extdecl, importc: "inwstr", - dynlib: pdcursesdll.} -proc in_wch*(a2: ptr cunsignedlong): cint{.extdecl, importc: "in_wch", - dynlib: pdcursesdll.} -proc in_wchnstr*(a2: ptr cunsignedlong; a3: cint): cint{.extdecl, - importc: "in_wchnstr", dynlib: pdcursesdll.} -proc in_wchstr*(a2: ptr cunsignedlong): cint{.extdecl, importc: "in_wchstr", - dynlib: pdcursesdll.} -proc key_name*(a2: char): cstring{.extdecl, importc: "key_name", - dynlib: pdcursesdll.} -proc killwchar*(a2: cstring): cint{.extdecl, importc: "killwchar", - dynlib: pdcursesdll.} -proc mvaddnwstr*(a2: cint; a3: cint; a4: cstring; a5: cint): cint{.extdecl, - importc: "mvaddnwstr", dynlib: pdcursesdll.} -proc mvaddwstr*(a2: cint; a3: cint; a4: cstring): cint{.extdecl, - importc: "mvaddwstr", dynlib: pdcursesdll.} -proc mvadd_wch*(a2: cint; a3: cint; a4: ptr cunsignedlong): cint{.extdecl, - importc: "mvadd_wch", dynlib: pdcursesdll.} -proc mvadd_wchnstr*(a2: cint; a3: cint; a4: ptr cunsignedlong; a5: cint): cint{. - extdecl, importc: "mvadd_wchnstr", dynlib: pdcursesdll.} -proc mvadd_wchstr*(a2: cint; a3: cint; a4: ptr cunsignedlong): cint{.extdecl, - importc: "mvadd_wchstr", dynlib: pdcursesdll.} -proc mvgetn_wstr*(a2: cint; a3: cint; a4: ptr cint; a5: cint): cint{.extdecl, - importc: "mvgetn_wstr", dynlib: pdcursesdll.} -proc mvget_wch*(a2: cint; a3: cint; a4: ptr cint): cint{.extdecl, - importc: "mvget_wch", dynlib: pdcursesdll.} -proc mvget_wstr*(a2: cint; a3: cint; a4: ptr cint): cint{.extdecl, - importc: "mvget_wstr", dynlib: pdcursesdll.} -proc mvhline_set*(a2: cint; a3: cint; a4: ptr cunsignedlong; a5: cint): cint{. - extdecl, importc: "mvhline_set", dynlib: pdcursesdll.} -proc mvinnwstr*(a2: cint; a3: cint; a4: cstring; a5: cint): cint{.extdecl, - importc: "mvinnwstr", dynlib: pdcursesdll.} -proc mvins_nwstr*(a2: cint; a3: cint; a4: cstring; a5: cint): cint{.extdecl, - importc: "mvins_nwstr", dynlib: pdcursesdll.} -proc mvins_wch*(a2: cint; a3: cint; a4: ptr cunsignedlong): cint{.extdecl, - importc: "mvins_wch", dynlib: pdcursesdll.} -proc mvins_wstr*(a2: cint; a3: cint; a4: cstring): cint{.extdecl, - importc: "mvins_wstr", dynlib: pdcursesdll.} -proc mvinwstr*(a2: cint; a3: cint; a4: cstring): cint{.extdecl, - importc: "mvinwstr", dynlib: pdcursesdll.} -proc mvin_wch*(a2: cint; a3: cint; a4: ptr cunsignedlong): cint{.extdecl, - importc: "mvin_wch", dynlib: pdcursesdll.} -proc mvin_wchnstr*(a2: cint; a3: cint; a4: ptr cunsignedlong; a5: cint): cint{. - extdecl, importc: "mvin_wchnstr", dynlib: pdcursesdll.} -proc mvin_wchstr*(a2: cint; a3: cint; a4: ptr cunsignedlong): cint{.extdecl, - importc: "mvin_wchstr", dynlib: pdcursesdll.} -proc mvvline_set*(a2: cint; a3: cint; a4: ptr cunsignedlong; a5: cint): cint{. - extdecl, importc: "mvvline_set", dynlib: pdcursesdll.} -proc mvwaddnwstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring; a6: cint): cint{. - extdecl, importc: "mvwaddnwstr", dynlib: pdcursesdll.} -proc mvwaddwstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{. - extdecl, importc: "mvwaddwstr", dynlib: pdcursesdll.} -proc mvwadd_wch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong): cint{. - extdecl, importc: "mvwadd_wch", dynlib: pdcursesdll.} -proc mvwadd_wchnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong; - a6: cint): cint{.extdecl, importc: "mvwadd_wchnstr", - dynlib: pdcursesdll.} -proc mvwadd_wchstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong): cint{. - extdecl, importc: "mvwadd_wchstr", dynlib: pdcursesdll.} -proc mvwgetn_wstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cint; a6: cint): cint{. - extdecl, importc: "mvwgetn_wstr", dynlib: pdcursesdll.} -proc mvwget_wch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cint): cint{. - extdecl, importc: "mvwget_wch", dynlib: pdcursesdll.} -proc mvwget_wstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cint): cint{. - extdecl, importc: "mvwget_wstr", dynlib: pdcursesdll.} -proc mvwhline_set*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong; - a6: cint): cint{.extdecl, importc: "mvwhline_set", - dynlib: pdcursesdll.} -proc mvwinnwstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring; a6: cint): cint{. - extdecl, importc: "mvwinnwstr", dynlib: pdcursesdll.} -proc mvwins_nwstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring; a6: cint): cint{. - extdecl, importc: "mvwins_nwstr", dynlib: pdcursesdll.} -proc mvwins_wch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong): cint{. - extdecl, importc: "mvwins_wch", dynlib: pdcursesdll.} -proc mvwins_wstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{. - extdecl, importc: "mvwins_wstr", dynlib: pdcursesdll.} -proc mvwin_wch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong): cint{. - extdecl, importc: "mvwin_wch", dynlib: pdcursesdll.} -proc mvwin_wchnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong; - a6: cint): cint{.extdecl, importc: "mvwin_wchnstr", - dynlib: pdcursesdll.} -proc mvwin_wchstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong): cint{. - extdecl, importc: "mvwin_wchstr", dynlib: pdcursesdll.} -proc mvwinwstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{. - extdecl, importc: "mvwinwstr", dynlib: pdcursesdll.} -proc mvwvline_set*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong; - a6: cint): cint{.extdecl, importc: "mvwvline_set", - dynlib: pdcursesdll.} -proc pecho_wchar*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl, - importc: "pecho_wchar", dynlib: pdcursesdll.} -proc setcchar*(a2: ptr cunsignedlong; a3: cstring; a4: cunsignedlong; - a5: cshort; a6: pointer): cint{.extdecl, importc: "setcchar", - dynlib: pdcursesdll.} -proc slk_wset*(a2: cint; a3: cstring; a4: cint): cint{.extdecl, - importc: "slk_wset", dynlib: pdcursesdll.} -proc unget_wch*(a2: char): cint{.extdecl, importc: "unget_wch", - dynlib: pdcursesdll.} -proc vline_set*(a2: ptr cunsignedlong; a3: cint): cint{.extdecl, - importc: "vline_set", dynlib: pdcursesdll.} -proc waddnwstr*(a2: ptr WINDOW; a3: cstring; a4: cint): cint{.extdecl, - importc: "waddnwstr", dynlib: pdcursesdll.} -proc waddwstr*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, - importc: "waddwstr", dynlib: pdcursesdll.} -proc wadd_wch*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl, - importc: "wadd_wch", dynlib: pdcursesdll.} -proc wadd_wchnstr*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: cint): cint{. - extdecl, importc: "wadd_wchnstr", dynlib: pdcursesdll.} -proc wadd_wchstr*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl, - importc: "wadd_wchstr", dynlib: pdcursesdll.} -proc wbkgrnd*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl, - importc: "wbkgrnd", dynlib: pdcursesdll.} -proc wbkgrndset*(a2: ptr WINDOW; a3: ptr cunsignedlong){.extdecl, - importc: "wbkgrndset", dynlib: pdcursesdll.} -proc wborder_set*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: ptr cunsignedlong; - a5: ptr cunsignedlong; a6: ptr cunsignedlong; - a7: ptr cunsignedlong; a8: ptr cunsignedlong; - a9: ptr cunsignedlong; a10: ptr cunsignedlong): cint{.extdecl, - importc: "wborder_set", dynlib: pdcursesdll.} -proc wecho_wchar*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl, - importc: "wecho_wchar", dynlib: pdcursesdll.} -proc wgetbkgrnd*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl, - importc: "wgetbkgrnd", dynlib: pdcursesdll.} -proc wgetn_wstr*(a2: ptr WINDOW; a3: ptr cint; a4: cint): cint{.extdecl, - importc: "wgetn_wstr", dynlib: pdcursesdll.} -proc wget_wch*(a2: ptr WINDOW; a3: ptr cint): cint{.extdecl, - importc: "wget_wch", dynlib: pdcursesdll.} -proc wget_wstr*(a2: ptr WINDOW; a3: ptr cint): cint{.extdecl, - importc: "wget_wstr", dynlib: pdcursesdll.} -proc whline_set*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: cint): cint{.extdecl, - importc: "whline_set", dynlib: pdcursesdll.} -proc winnwstr*(a2: ptr WINDOW; a3: cstring; a4: cint): cint{.extdecl, - importc: "winnwstr", dynlib: pdcursesdll.} -proc wins_nwstr*(a2: ptr WINDOW; a3: cstring; a4: cint): cint{.extdecl, - importc: "wins_nwstr", dynlib: pdcursesdll.} -proc wins_wch*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl, - importc: "wins_wch", dynlib: pdcursesdll.} -proc wins_wstr*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, - importc: "wins_wstr", dynlib: pdcursesdll.} -proc winwstr*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, importc: "winwstr", - dynlib: pdcursesdll.} -proc win_wch*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl, - importc: "win_wch", dynlib: pdcursesdll.} -proc win_wchnstr*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: cint): cint{.extdecl, - importc: "win_wchnstr", dynlib: pdcursesdll.} -proc win_wchstr*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl, - importc: "win_wchstr", dynlib: pdcursesdll.} -proc wunctrl*(a2: ptr cunsignedlong): cstring{.extdecl, importc: "wunctrl", - dynlib: pdcursesdll.} -proc wvline_set*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: cint): cint{.extdecl, - importc: "wvline_set", dynlib: pdcursesdll.} -proc getattrs*(a2: ptr WINDOW): cunsignedlong{.extdecl, importc: "getattrs", - dynlib: pdcursesdll.} -proc getbegx*(a2: ptr WINDOW): cint{.extdecl, importc: "getbegx", - dynlib: pdcursesdll.} -proc getbegy*(a2: ptr WINDOW): cint{.extdecl, importc: "getbegy", - dynlib: pdcursesdll.} -proc getmaxx*(a2: ptr WINDOW): cint{.extdecl, importc: "getmaxx", - dynlib: pdcursesdll.} -proc getmaxy*(a2: ptr WINDOW): cint{.extdecl, importc: "getmaxy", - dynlib: pdcursesdll.} -proc getparx*(a2: ptr WINDOW): cint{.extdecl, importc: "getparx", - dynlib: pdcursesdll.} -proc getpary*(a2: ptr WINDOW): cint{.extdecl, importc: "getpary", - dynlib: pdcursesdll.} -proc getcurx*(a2: ptr WINDOW): cint{.extdecl, importc: "getcurx", - dynlib: pdcursesdll.} -proc getcury*(a2: ptr WINDOW): cint{.extdecl, importc: "getcury", - dynlib: pdcursesdll.} -proc traceoff*(){.extdecl, importc: "traceoff", dynlib: pdcursesdll.} -proc traceon*(){.extdecl, importc: "traceon", dynlib: pdcursesdll.} -proc unctrl*(a2: cunsignedlong): cstring{.extdecl, importc: "unctrl", - dynlib: pdcursesdll.} -proc crmode*(): cint{.extdecl, importc: "crmode", dynlib: pdcursesdll.} -proc nocrmode*(): cint{.extdecl, importc: "nocrmode", dynlib: pdcursesdll.} -proc draino*(a2: cint): cint{.extdecl, importc: "draino", dynlib: pdcursesdll.} -proc resetterm*(): cint{.extdecl, importc: "resetterm", dynlib: pdcursesdll.} -proc fixterm*(): cint{.extdecl, importc: "fixterm", dynlib: pdcursesdll.} -proc saveterm*(): cint{.extdecl, importc: "saveterm", dynlib: pdcursesdll.} -proc setsyx*(a2: cint; a3: cint): cint{.extdecl, importc: "setsyx", - dynlib: pdcursesdll.} -proc mouse_set*(a2: cunsignedlong): cint{.extdecl, importc: "mouse_set", - dynlib: pdcursesdll.} -proc mouse_on*(a2: cunsignedlong): cint{.extdecl, importc: "mouse_on", - dynlib: pdcursesdll.} -proc mouse_off*(a2: cunsignedlong): cint{.extdecl, importc: "mouse_off", - dynlib: pdcursesdll.} -proc request_mouse_pos*(): cint{.extdecl, importc: "request_mouse_pos", - dynlib: pdcursesdll.} -proc map_button*(a2: cunsignedlong): cint{.extdecl, importc: "map_button", - dynlib: pdcursesdll.} -proc wmouse_position*(a2: ptr WINDOW; a3: ptr cint; a4: ptr cint){.extdecl, - importc: "wmouse_position", dynlib: pdcursesdll.} -proc getmouse*(): cunsignedlong{.extdecl, importc: "getmouse", dynlib: pdcursesdll.} -proc getbmap*(): cunsignedlong{.extdecl, importc: "getbmap", dynlib: pdcursesdll.} -proc assume_default_colors*(a2: cint; a3: cint): cint{.extdecl, - importc: "assume_default_colors", dynlib: pdcursesdll.} -proc curses_version*(): cstring{.extdecl, importc: "curses_version", - dynlib: pdcursesdll.} -proc has_key*(a2: cint): cunsignedchar{.extdecl, importc: "has_key", - dynlib: pdcursesdll.} -proc use_default_colors*(): cint{.extdecl, importc: "use_default_colors", - dynlib: pdcursesdll.} -proc wresize*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, - importc: "wresize", dynlib: pdcursesdll.} -proc mouseinterval*(a2: cint): cint{.extdecl, importc: "mouseinterval", - dynlib: pdcursesdll.} -proc mousemask*(a2: cunsignedlong; a3: ptr cunsignedlong): cunsignedlong{.extdecl, - importc: "mousemask", dynlib: pdcursesdll.} -proc mouse_trafo*(a2: ptr cint; a3: ptr cint; a4: cunsignedchar): cunsignedchar{. - extdecl, importc: "mouse_trafo", dynlib: pdcursesdll.} -proc nc_getmouse*(a2: ptr MEVENT): cint{.extdecl, importc: "nc_getmouse", - dynlib: pdcursesdll.} -proc ungetmouse*(a2: ptr MEVENT): cint{.extdecl, importc: "ungetmouse", - dynlib: pdcursesdll.} -proc wenclose*(a2: ptr WINDOW; a3: cint; a4: cint): cunsignedchar{.extdecl, - importc: "wenclose", dynlib: pdcursesdll.} -proc wmouse_trafo*(a2: ptr WINDOW; a3: ptr cint; a4: ptr cint; a5: cunsignedchar): cunsignedchar{. - extdecl, importc: "wmouse_trafo", dynlib: pdcursesdll.} -proc addrawch*(a2: cunsignedlong): cint{.extdecl, importc: "addrawch", - dynlib: pdcursesdll.} -proc insrawch*(a2: cunsignedlong): cint{.extdecl, importc: "insrawch", - dynlib: pdcursesdll.} -proc is_termresized*(): cunsignedchar{.extdecl, importc: "is_termresized", - dynlib: pdcursesdll.} -proc mvaddrawch*(a2: cint; a3: cint; a4: cunsignedlong): cint{.extdecl, - importc: "mvaddrawch", dynlib: pdcursesdll.} -proc mvdeleteln*(a2: cint; a3: cint): cint{.extdecl, importc: "mvdeleteln", - dynlib: pdcursesdll.} -proc mvinsertln*(a2: cint; a3: cint): cint{.extdecl, importc: "mvinsertln", - dynlib: pdcursesdll.} -proc mvinsrawch*(a2: cint; a3: cint; a4: cunsignedlong): cint{.extdecl, - importc: "mvinsrawch", dynlib: pdcursesdll.} -proc mvwaddrawch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cunsignedlong): cint{. - extdecl, importc: "mvwaddrawch", dynlib: pdcursesdll.} -proc mvwdeleteln*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, - importc: "mvwdeleteln", dynlib: pdcursesdll.} -proc mvwinsertln*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, - importc: "mvwinsertln", dynlib: pdcursesdll.} -proc mvwinsrawch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cunsignedlong): cint{. - extdecl, importc: "mvwinsrawch", dynlib: pdcursesdll.} -proc raw_output*(a2: cunsignedchar): cint{.extdecl, importc: "raw_output", - dynlib: pdcursesdll.} -proc resize_term*(a2: cint; a3: cint): cint{.extdecl, importc: "resize_term", - dynlib: pdcursesdll.} -proc resize_window*(a2: ptr WINDOW; a3: cint; a4: cint): ptr WINDOW{.extdecl, - importc: "resize_window", dynlib: pdcursesdll.} -proc waddrawch*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, - importc: "waddrawch", dynlib: pdcursesdll.} -proc winsrawch*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, - importc: "winsrawch", dynlib: pdcursesdll.} -proc wordchar*(): char{.extdecl, importc: "wordchar", dynlib: pdcursesdll.} -proc slk_wlabel*(a2: cint): cstring{.extdecl, importc: "slk_wlabel", - dynlib: pdcursesdll.} -proc debug*(a2: cstring){.varargs, extdecl, importc: "PDC_debug", - dynlib: pdcursesdll.} -proc ungetch*(a2: cint): cint{.extdecl, importc: "PDC_ungetch", - dynlib: pdcursesdll.} -proc set_blink*(a2: cunsignedchar): cint{.extdecl, importc: "PDC_set_blink", - dynlib: pdcursesdll.} -proc set_line_color*(a2: cshort): cint{.extdecl, importc: "PDC_set_line_color", - dynlib: pdcursesdll.} -proc set_title*(a2: cstring){.extdecl, importc: "PDC_set_title", - dynlib: pdcursesdll.} -proc clearclipboard*(): cint{.extdecl, importc: "PDC_clearclipboard", - dynlib: pdcursesdll.} -proc freeclipboard*(a2: cstring): cint{.extdecl, importc: "PDC_freeclipboard", - dynlib: pdcursesdll.} -proc getclipboard*(a2: cstringArray; a3: ptr clong): cint{.extdecl, - importc: "PDC_getclipboard", dynlib: pdcursesdll.} -proc setclipboard*(a2: cstring; a3: clong): cint{.extdecl, - importc: "PDC_setclipboard", dynlib: pdcursesdll.} -proc get_input_fd*(): cunsignedlong{.extdecl, importc: "PDC_get_input_fd", - dynlib: pdcursesdll.} -proc get_key_modifiers*(): cunsignedlong{.extdecl, - importc: "PDC_get_key_modifiers", dynlib: pdcursesdll.} -proc return_key_modifiers*(a2: cunsignedchar): cint{.extdecl, - importc: "PDC_return_key_modifiers", dynlib: pdcursesdll.} -proc save_key_modifiers*(a2: cunsignedchar): cint{.extdecl, - importc: "PDC_save_key_modifiers", dynlib: pdcursesdll.} -proc bottom_panel*(pan: ptr PANEL): cint{.extdecl, importc: "bottom_panel", - dynlib: pdcursesdll.} -proc del_panel*(pan: ptr PANEL): cint{.extdecl, importc: "del_panel", - dynlib: pdcursesdll.} -proc hide_panel*(pan: ptr PANEL): cint{.extdecl, importc: "hide_panel", - dynlib: pdcursesdll.} -proc move_panel*(pan: ptr PANEL; starty: cint; startx: cint): cint{.extdecl, - importc: "move_panel", dynlib: pdcursesdll.} -proc new_panel*(win: ptr WINDOW): ptr PANEL{.extdecl, importc: "new_panel", - dynlib: pdcursesdll.} -proc panel_above*(pan: ptr PANEL): ptr PANEL{.extdecl, importc: "panel_above", - dynlib: pdcursesdll.} -proc panel_below*(pan: ptr PANEL): ptr PANEL{.extdecl, importc: "panel_below", - dynlib: pdcursesdll.} -proc panel_hidden*(pan: ptr PANEL): cint{.extdecl, importc: "panel_hidden", - dynlib: pdcursesdll.} -proc panel_userptr*(pan: ptr PANEL): pointer{.extdecl, importc: "panel_userptr", - dynlib: pdcursesdll.} -proc panel_window*(pan: ptr PANEL): ptr WINDOW{.extdecl, importc: "panel_window", - dynlib: pdcursesdll.} -proc replace_panel*(pan: ptr PANEL; win: ptr WINDOW): cint{.extdecl, - importc: "replace_panel", dynlib: pdcursesdll.} -proc set_panel_userptr*(pan: ptr PANEL; uptr: pointer): cint{.extdecl, - importc: "set_panel_userptr", dynlib: pdcursesdll.} -proc show_panel*(pan: ptr PANEL): cint{.extdecl, importc: "show_panel", - dynlib: pdcursesdll.} -proc top_panel*(pan: ptr PANEL): cint{.extdecl, importc: "top_panel", - dynlib: pdcursesdll.} -proc update_panels*(){.extdecl, importc: "update_panels", dynlib: pdcursesdll.} - -when unixOS: - proc Xinitscr*(a2: cint; a3: cstringArray): ptr WINDOW{.extdecl, - importc: "Xinitscr", dynlib: pdcursesdll.} - proc XCursesExit*(){.extdecl, importc: "XCursesExit", dynlib: pdcursesdll.} - proc sb_init*(): cint{.extdecl, importc: "sb_init", dynlib: pdcursesdll.} - proc sb_set_horz*(a2: cint; a3: cint; a4: cint): cint{.extdecl, - importc: "sb_set_horz", dynlib: pdcursesdll.} - proc sb_set_vert*(a2: cint; a3: cint; a4: cint): cint{.extdecl, - importc: "sb_set_vert", dynlib: pdcursesdll.} - proc sb_get_horz*(a2: ptr cint; a3: ptr cint; a4: ptr cint): cint{.extdecl, - importc: "sb_get_horz", dynlib: pdcursesdll.} - proc sb_get_vert*(a2: ptr cint; a3: ptr cint; a4: ptr cint): cint{.extdecl, - importc: "sb_get_vert", dynlib: pdcursesdll.} - proc sb_refresh*(): cint{.extdecl, importc: "sb_refresh", dynlib: pdcursesdll.} - -template getch*(): expr = - wgetch(stdscr) - -template ungetch*(ch: expr): expr = - ungetch(ch) - -template getbegyx*(w, y, x: expr): expr = - y = getbegy(w) - x = getbegx(w) - -template getmaxyx*(w, y, x: expr): expr = - y = getmaxy(w) - x = getmaxx(w) - -template getparyx*(w, y, x: expr): expr = - y = getpary(w) - x = getparx(w) - -template getyx*(w, y, x: expr): expr = - y = getcury(w) - x = getcurx(w) - -template getsyx*(y, x: expr): stmt = - if curscr.leaveit: - (x) = - 1 - (y) = (x) - else: getyx(curscr, (y), (x)) - -template getmouse*(x: expr): expr = - nc_getmouse(x) - -when defined(windows): - var - atrtab*{.importc: "pdc_atrtab", dynlib: pdcursesdll.}: cstring - con_out*{.importc: "pdc_con_out", dynlib: pdcursesdll.}: HANDLE - con_in*{.importc: "pdc_con_in", dynlib: pdcursesdll.}: HANDLE - quick_edit*{.importc: "pdc_quick_edit", dynlib: pdcursesdll.}: DWORD - - proc get_buffer_rows*(): cint{.extdecl, importc: "PDC_get_buffer_rows", - dynlib: pdcursesdll.} diff --git a/lib/wrappers/tinyc.nim b/lib/wrappers/tinyc.nim index 47b505abc..f2ce92d36 100644 --- a/lib/wrappers/tinyc.nim +++ b/lib/wrappers/tinyc.nim @@ -20,16 +20,12 @@ proc openCCState*(): PccState {.importc: "tcc_new", cdecl.} proc closeCCState*(s: PccState) {.importc: "tcc_delete", cdecl.} ## free a TCC compilation context -proc enableDebug*(s: PccState) {.importc: "tcc_enable_debug", cdecl.} - ## add debug information in the generated code - proc setErrorFunc*(s: PccState, errorOpaque: pointer, errorFun: ErrorFunc) {. cdecl, importc: "tcc_set_error_func".} ## set error/warning display callback -proc setWarning*(s: PccState, warningName: cstring, value: int) {.cdecl, - importc: "tcc_set_warning".} - ## set/reset a warning +proc setOptions*(s: PccState, options: cstring) {.cdecl, importc: "tcc_set_options".} + ## set a options # preprocessor @@ -41,7 +37,6 @@ proc addSysincludePath*(s: PccState, pathname: cstring) {.cdecl, importc: "tcc_add_sysinclude_path".} ## add in system include path - proc defineSymbol*(s: PccState, sym, value: cstring) {.cdecl, importc: "tcc_define_symbol".} ## define preprocessor symbol 'sym'. Can put optional value @@ -65,16 +60,12 @@ proc compileString*(s: PccState, buf: cstring): cint {.cdecl, const - OutputMemory*: cint = 0 ## output will be ran in memory (no + OutputMemory*: cint = 1 ## output will be ran in memory (no ## output file) (default) - OutputExe*: cint = 1 ## executable file - OutputDll*: cint = 2 ## dynamic library - OutputObj*: cint = 3 ## object file - OutputPreprocess*: cint = 4 ## preprocessed file (used internally) - - OutputFormatElf*: cint = 0 ## default output format: ELF - OutputFormatBinary*: cint = 1 ## binary image output - OutputFormatCoff*: cint = 2 ## COFF + OutputExe*: cint = 2 ## executable file + OutputDll*: cint = 3 ## dynamic library + OutputObj*: cint = 4 ## object file + OutputPreprocess*: cint = 5 ## preprocessed file (used internally) proc setOutputType*(s: PCCState, outputType: cint): cint {.cdecl, importc: "tcc_set_output_type".} |