diff options
Diffstat (limited to 'lib')
189 files changed, 11665 insertions, 9272 deletions
diff --git a/lib/core/locks.nim b/lib/core/locks.nim index 894965a85..42a3aec7b 100644 --- a/lib/core/locks.nim +++ b/lib/core/locks.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## This module contains Nimrod's support for locks and condition vars. +## This module contains Nim's support for locks and condition vars. ## If the symbol ``preventDeadlocks`` is defined ## (compiled with ``-d:preventDeadlocks``) special logic is added to ## every ``acquire``, ``tryAcquire`` and ``release`` action that ensures at @@ -18,17 +18,19 @@ include "system/syslocks" type - TLock* = TSysLock ## Nimrod lock; whether this is re-entrant + TLock* = TSysLock ## Nim lock; whether this is re-entrant ## or not is unspecified! However, compilation ## in preventDeadlocks-mode guarantees re-entrancy. - TCond* = TSysCond ## Nimrod condition variable + TCond* = TSysCond ## Nim condition variable - FLock* = object of TEffect ## effect that denotes that some lock operation - ## is performed - FAquireLock* = object of FLock ## effect that denotes that some lock is - ## aquired - FReleaseLock* = object of FLock ## effect that denotes that some lock is - ## released + LockEffect* = object of RootEffect ## effect that denotes that some lock operation + ## is performed + AquireEffect* = object of LockEffect ## effect that denotes that some lock is + ## aquired + ReleaseEffect* = object of LockEffect ## effect that denotes that some lock is + ## released +{.deprecated: [FLock: LockEffect, FAquireLock: AquireEffect, + FReleaseLock: ReleaseEffect].} const noDeadlocks = defined(preventDeadlocks) @@ -58,7 +60,7 @@ proc deinitLock*(lock: var TLock) {.inline.} = ## Frees the resources associated with the lock. deinitSys(lock) -proc tryAcquire*(lock: var TLock): bool {.tags: [FAquireLock].} = +proc tryAcquire*(lock: var TLock): bool {.tags: [AquireEffect].} = ## Tries to acquire the given lock. Returns `true` on success. result = tryAcquireSys(lock) when noDeadlocks: @@ -90,7 +92,7 @@ proc tryAcquire*(lock: var TLock): bool {.tags: [FAquireLock].} = inc(locksLen) assert orderedLocks() -proc acquire*(lock: var TLock) {.tags: [FAquireLock].} = +proc acquire*(lock: var TLock) {.tags: [AquireEffect].} = ## Acquires the given lock. when nodeadlocks: var p = addr(lock) @@ -135,7 +137,7 @@ proc acquire*(lock: var TLock) {.tags: [FAquireLock].} = else: acquireSys(lock) -proc release*(lock: var TLock) {.tags: [FReleaseLock].} = +proc release*(lock: var TLock) {.tags: [ReleaseEffect].} = ## Releases the given lock. when nodeadlocks: var p = addr(lock) diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 455f99c9e..db2bfa9a6 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -97,7 +97,7 @@ type TNimSymKinds* = set[TNimrodSymKind] type - TNimrodIdent* = object of TObject + TNimrodIdent* = object of RootObj ## represents a Nimrod identifier in the AST TNimrodSymbol {.final.} = object # hidden @@ -261,7 +261,7 @@ proc getAst*(macroOrTemplate: expr): PNimrodNode {.magic: "ExpandToAst", noSideE ## Obtains the AST nodes returned from a macro or template invocation. ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## macro FooMacro() = ## var ast = getAst(BarTemplate()) @@ -278,7 +278,7 @@ proc quote*(bl: stmt, op = "``"): PNimrodNode {.magic: "QuoteAst", noSideEffect. ## ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## macro check(ex: expr): stmt = ## # this is a simplified version of the check macro from the @@ -422,7 +422,7 @@ proc lispRepr*(n: PNimrodNode): string {.compileTime.} = add(result, ")") macro dumpTree*(s: stmt): stmt {.immediate.} = echo s.treeRepr - ## Accepts a block of nimrod code and prints the parsed abstract syntax + ## Accepts a block of nim code and prints the parsed abstract syntax ## tree using the `toTree` function. Printing is done *at compile time*. ## ## You can use this as a tool to explore the Nimrod's abstract syntax @@ -430,7 +430,7 @@ macro dumpTree*(s: stmt): stmt {.immediate.} = echo s.treeRepr ## a certain expression/statement. macro dumpLisp*(s: stmt): stmt {.immediate.} = echo s.lispRepr - ## Accepts a block of nimrod code and prints the parsed abstract syntax + ## Accepts a block of nim code and prints the parsed abstract syntax ## tree using the `toLisp` function. Printing is done *at compile time*. ## ## See `dumpTree`. @@ -489,7 +489,7 @@ proc newIdentDefs*(name, kind: PNimrodNode; ## ``let`` or ``var`` blocks may have an empty ``kind`` node if the ## identifier is being assigned a value. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## var varSection = newNimNode(nnkVarSection).add( ## newIdentDefs(ident("a"), ident("string")), @@ -501,7 +501,7 @@ proc newIdentDefs*(name, kind: PNimrodNode; ## If you need to create multiple identifiers you need to use the lower level ## ``newNimNode``: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## result = newNimNode(nnkIdentDefs).add( ## ident("a"), ident("b"), ident("c"), ident("string"), @@ -549,7 +549,7 @@ proc newIfStmt*(branches: varargs[tuple[cond, body: PNimrodNode]]): PNimrodNode {.compiletime.} = ## Constructor for ``if`` statements. ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## newIfStmt( ## (Ident, StmtList), @@ -596,7 +596,7 @@ proc `pragma=`*(someProc: PNimrodNode; val: PNimrodNode){.compileTime.}= someProc[4] = val -template badnodekind(k; f): stmt{.immediate.} = +template badNodeKind(k; f): stmt{.immediate.} = assert false, "Invalid node kind $# for macros.`$2`".format(k, f) proc body*(someProc: PNimrodNode): PNimrodNode {.compileTime.} = @@ -608,7 +608,7 @@ proc body*(someProc: PNimrodNode): PNimrodNode {.compileTime.} = of nnkForStmt: return someProc.last else: - badNodeKind someproc.kind, "body" + badNodeKind someProc.kind, "body" proc `body=`*(someProc: PNimrodNode, val: PNimrodNode) {.compileTime.} = case someProc.kind @@ -647,7 +647,7 @@ template findChild*(n: PNimrodNode; cond: expr): PNimrodNode {. immediate, dirty.} = ## Find the first child node matching condition (or nil). ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var res = findChild(n, it.kind == nnkPostfix and ## it.basename.ident == !"foo") block: @@ -742,11 +742,11 @@ proc addIdentIfAbsent*(dest: PNimrodNode, ident: string) {.compiletime.} = when not defined(booting): template emit*(e: static[string]): stmt = - ## accepts a single string argument and treats it as nimrod code + ## accepts a single string argument and treats it as nim code ## that should be inserted verbatim in the program ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## emit("echo " & '"' & "hello world".toUpper & '"') ## macro payload: stmt {.gensym.} = diff --git a/lib/core/typeinfo.nim b/lib/core/typeinfo.nim index 8df1b3dfb..84281485f 100644 --- a/lib/core/typeinfo.nim +++ b/lib/core/typeinfo.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Dominik Picheta, Andreas Rumpf # # See the file "copying.txt", included in this @@ -13,6 +13,7 @@ {.push hints: off.} +include "system/inclrtl.nim" include "system/hti.nim" {.pop.} @@ -50,7 +51,7 @@ type akUInt32 = 43, ## any represents an unsigned int32 akUInt64 = 44, ## any represents an unsigned int64 - TAny* = object {.pure.} ## can represent any nimrod value; NOTE: the wrapped + TAny* = object {.pure.} ## can represent any nim value; NOTE: the wrapped ## value can be modified with its wrapper! This means ## that ``TAny`` keeps a non-traced pointer to its ## wrapped value and **must not** live longer than @@ -68,20 +69,20 @@ type const GenericSeqSize = (2 * sizeof(int)) -proc genericAssign(dest, src: Pointer, mt: PNimType) {.importCompilerProc.} -proc genericShallowAssign(dest, src: Pointer, mt: PNimType) {. +proc genericAssign(dest, src: pointer, mt: PNimType) {.importCompilerProc.} +proc genericShallowAssign(dest, src: pointer, mt: PNimType) {. importCompilerProc.} proc incrSeq(seq: PGenSeq, elemSize: int): PGenSeq {.importCompilerProc.} proc newObj(typ: PNimType, size: int): pointer {.importCompilerProc.} proc newSeq(typ: PNimType, len: int): pointer {.importCompilerProc.} -proc objectInit(dest: Pointer, typ: PNimType) {.importCompilerProc.} +proc objectInit(dest: pointer, typ: PNimType) {.importCompilerProc.} -template `+!!`(a, b: expr): expr = cast[pointer](cast[TAddress](a) + b) +template `+!!`(a, b: expr): expr = cast[pointer](cast[ByteAddress](a) + b) -proc getDiscriminant(aa: Pointer, n: ptr TNimNode): int = +proc getDiscriminant(aa: pointer, n: ptr TNimNode): int = assert(n.kind == nkCase) var d: int - var a = cast[TAddress](aa) + var a = cast[ByteAddress](aa) case n.typ.size of 1: d = ze(cast[ptr int8](a +% n.offset)[]) of 2: d = ze(cast[ptr int16](a +% n.offset)[]) @@ -89,7 +90,7 @@ proc getDiscriminant(aa: Pointer, n: ptr TNimNode): int = else: assert(false) return d -proc selectBranch(aa: Pointer, n: ptr TNimNode): ptr TNimNode = +proc selectBranch(aa: pointer, n: ptr TNimNode): ptr TNimNode = var discr = getDiscriminant(aa, n) if discr <% n.len: result = n.sons[discr] @@ -174,14 +175,14 @@ proc `[]`*(x: TAny, i: int): TAny = of tyArray: var bs = x.rawType.base.size if i >=% x.rawType.size div bs: - raise newException(EInvalidIndex, "index out of bounds") + raise newException(IndexError, "index out of bounds") return newAny(x.value +!! i*bs, x.rawType.base) of tySequence: var s = cast[ppointer](x.value)[] - if s == nil: raise newException(EInvalidValue, "sequence is nil") + if s == nil: raise newException(ValueError, "sequence is nil") var bs = x.rawType.base.size if i >=% cast[PGenSeq](s).len: - raise newException(EInvalidIndex, "index out of bounds") + raise newException(IndexError, "index out of bounds") return newAny(s +!! (GenericSeqSize+i*bs), x.rawType.base) else: assert false @@ -191,15 +192,15 @@ proc `[]=`*(x: TAny, i: int, y: TAny) = of tyArray: var bs = x.rawType.base.size if i >=% x.rawType.size div bs: - raise newException(EInvalidIndex, "index out of bounds") + raise newException(IndexError, "index out of bounds") assert y.rawType == x.rawType.base genericAssign(x.value +!! i*bs, y.value, y.rawType) of tySequence: var s = cast[ppointer](x.value)[] - if s == nil: raise newException(EInvalidValue, "sequence is nil") + if s == nil: raise newException(ValueError, "sequence is nil") var bs = x.rawType.base.size if i >=% cast[PGenSeq](s).len: - raise newException(EInvalidIndex, "index out of bounds") + raise newException(IndexError, "index out of bounds") assert y.rawType == x.rawType.base genericAssign(s +!! (GenericSeqSize+i*bs), y.value, y.rawType) else: assert false @@ -276,7 +277,7 @@ proc cmpIgnoreStyle(a, b: cstring): int {.noSideEffect.} = else: result = c var i = 0 var j = 0 - while True: + while true: while a[i] == '_': inc(i) while b[j] == '_': inc(j) # BUGFIX: typo var aa = toLower(a[i]) @@ -311,12 +312,12 @@ proc `[]=`*(x: TAny, fieldName: string, value: TAny) = when false: if x.rawType.kind == tyObject: t = cast[ptr PNimType](x.value)[] assert x.rawType.kind in {tyTuple, tyObject} - var n = getFieldNode(x.value, t.node, fieldname) + var n = getFieldNode(x.value, t.node, fieldName) if n != nil: assert n.typ == value.rawType genericAssign(x.value +!! n.offset, value.value, value.rawType) else: - raise newException(EInvalidValue, "invalid field name: " & fieldName) + raise newException(ValueError, "invalid field name: " & fieldName) proc `[]`*(x: TAny, fieldName: string): TAny = ## gets a field of `x`; `x` represents an object or a tuple. @@ -325,80 +326,80 @@ proc `[]`*(x: TAny, fieldName: string): TAny = when false: if x.rawType.kind == tyObject: t = cast[ptr PNimType](x.value)[] assert x.rawType.kind in {tyTuple, tyObject} - var n = getFieldNode(x.value, t.node, fieldname) + var n = getFieldNode(x.value, t.node, fieldName) if n != nil: result.value = x.value +!! n.offset result.rawType = n.typ else: - raise newException(EInvalidValue, "invalid field name: " & fieldName) + raise newException(ValueError, "invalid field name: " & fieldName) proc `[]`*(x: TAny): TAny = ## dereference operation for the any `x` that represents a ptr or a ref. - assert x.rawtype.kind in {tyRef, tyPtr} + assert x.rawType.kind in {tyRef, tyPtr} result.value = cast[ppointer](x.value)[] result.rawType = x.rawType.base proc `[]=`*(x, y: TAny) = ## dereference operation for the any `x` that represents a ptr or a ref. - assert x.rawtype.kind in {tyRef, tyPtr} + assert x.rawType.kind in {tyRef, tyPtr} assert y.rawType == x.rawType.base genericAssign(cast[ppointer](x.value)[], y.value, y.rawType) proc getInt*(x: TAny): int = ## retrieve the int value out of `x`. `x` needs to represent an int. - assert skipRange(x.rawtype).kind == tyInt + assert skipRange(x.rawType).kind == tyInt result = cast[ptr int](x.value)[] proc getInt8*(x: TAny): int8 = ## retrieve the int8 value out of `x`. `x` needs to represent an int8. - assert skipRange(x.rawtype).kind == tyInt8 + assert skipRange(x.rawType).kind == tyInt8 result = cast[ptr int8](x.value)[] proc getInt16*(x: TAny): int16 = ## retrieve the int16 value out of `x`. `x` needs to represent an int16. - assert skipRange(x.rawtype).kind == tyInt16 + assert skipRange(x.rawType).kind == tyInt16 result = cast[ptr int16](x.value)[] proc getInt32*(x: TAny): int32 = ## retrieve the int32 value out of `x`. `x` needs to represent an int32. - assert skipRange(x.rawtype).kind == tyInt32 + assert skipRange(x.rawType).kind == tyInt32 result = cast[ptr int32](x.value)[] proc getInt64*(x: TAny): int64 = ## retrieve the int64 value out of `x`. `x` needs to represent an int64. - assert skipRange(x.rawtype).kind == tyInt64 + assert skipRange(x.rawType).kind == tyInt64 result = cast[ptr int64](x.value)[] -proc getBiggestInt*(x: TAny): biggestInt = +proc getBiggestInt*(x: TAny): BiggestInt = ## retrieve the integer value out of `x`. `x` needs to represent ## some integer, a bool, a char, an enum or a small enough bit set. - ## The value might be sign-extended to ``biggestInt``. - var t = skipRange(x.rawtype) + ## The value might be sign-extended to ``BiggestInt``. + var t = skipRange(x.rawType) case t.kind - of tyInt: result = biggestInt(cast[ptr int](x.value)[]) - of tyInt8: result = biggestInt(cast[ptr int8](x.value)[]) - of tyInt16: result = biggestInt(cast[ptr int16](x.value)[]) - of tyInt32: result = biggestInt(cast[ptr int32](x.value)[]) - of tyInt64, tyUInt64: result = biggestInt(cast[ptr int64](x.value)[]) - of tyBool: result = biggestInt(cast[ptr bool](x.value)[]) - of tyChar: result = biggestInt(cast[ptr char](x.value)[]) + of tyInt: result = BiggestInt(cast[ptr int](x.value)[]) + of tyInt8: result = BiggestInt(cast[ptr int8](x.value)[]) + of tyInt16: result = BiggestInt(cast[ptr int16](x.value)[]) + of tyInt32: result = BiggestInt(cast[ptr int32](x.value)[]) + of tyInt64, tyUInt64: result = BiggestInt(cast[ptr int64](x.value)[]) + of tyBool: result = BiggestInt(cast[ptr bool](x.value)[]) + of tyChar: result = BiggestInt(cast[ptr char](x.value)[]) of tyEnum, tySet: case t.size of 1: result = ze64(cast[ptr int8](x.value)[]) of 2: result = ze64(cast[ptr int16](x.value)[]) - of 4: result = biggestInt(cast[ptr int32](x.value)[]) - of 8: result = biggestInt(cast[ptr int64](x.value)[]) + of 4: result = BiggestInt(cast[ptr int32](x.value)[]) + of 8: result = BiggestInt(cast[ptr int64](x.value)[]) else: assert false - of tyUInt: result = biggestInt(cast[ptr uint](x.value)[]) - of tyUInt8: result = biggestInt(cast[ptr uint8](x.value)[]) - of tyUInt16: result = biggestInt(cast[ptr uint16](x.value)[]) - of tyUInt32: result = biggestInt(cast[ptr uint32](x.value)[]) + of tyUInt: result = BiggestInt(cast[ptr uint](x.value)[]) + of tyUInt8: result = BiggestInt(cast[ptr uint8](x.value)[]) + of tyUInt16: result = BiggestInt(cast[ptr uint16](x.value)[]) + of tyUInt32: result = BiggestInt(cast[ptr uint32](x.value)[]) else: assert false -proc setBiggestInt*(x: TAny, y: biggestInt) = +proc setBiggestInt*(x: TAny, y: BiggestInt) = ## sets the integer value of `x`. `x` needs to represent ## some integer, a bool, a char, an enum or a small enough bit set. - var t = skipRange(x.rawtype) + var t = skipRange(x.rawType) case t.kind of tyInt: cast[ptr int](x.value)[] = int(y) of tyInt8: cast[ptr int8](x.value)[] = int8(y) @@ -422,37 +423,37 @@ proc setBiggestInt*(x: TAny, y: biggestInt) = proc getUInt*(x: TAny): uint = ## retrieve the uint value out of `x`, `x` needs to represent an uint. - assert skipRange(x.rawtype).kind == tyUInt + assert skipRange(x.rawType).kind == tyUInt result = cast[ptr uint](x.value)[] proc getUInt8*(x: TAny): uint8 = ## retrieve the uint8 value out of `x`, `x` needs to represent an ## uint8. - assert skipRange(x.rawtype).kind == tyUInt8 + assert skipRange(x.rawType).kind == tyUInt8 result = cast[ptr uint8](x.value)[] proc getUInt16*(x: TAny): uint16 = ## retrieve the uint16 value out of `x`, `x` needs to represent an ## uint16. - assert skipRange(x.rawtype).kind == tyUInt16 + assert skipRange(x.rawType).kind == tyUInt16 result = cast[ptr uint16](x.value)[] proc getUInt32*(x: TAny): uint32 = ## retrieve the uint32 value out of `x`, `x` needs to represent an ## uint32. - assert skipRange(x.rawtype).kind == tyUInt32 + assert skipRange(x.rawType).kind == tyUInt32 result = cast[ptr uint32](x.value)[] proc getUInt64*(x: TAny): uint64 = ## retrieve the uint64 value out of `x`, `x` needs to represent an ## uint64. - assert skipRange(x.rawtype).kind == tyUInt64 + assert skipRange(x.rawType).kind == tyUInt64 result = cast[ptr uint64](x.value)[] proc getBiggestUint*(x: TAny): uint64 = ## retrieve the unsigned integer value out of `x`. `x` needs to ## represent an unsigned integer. - var t = skipRange(x.rawtype) + var t = skipRange(x.rawType) case t.kind of tyUInt: result = uint64(cast[ptr uint](x.value)[]) of tyUInt8: result = uint64(cast[ptr uint8](x.value)[]) @@ -464,7 +465,7 @@ proc getBiggestUint*(x: TAny): uint64 = proc setBiggestUint*(x: TAny; y: uint64) = ## sets the unsigned integer value of `c`. `c` needs to represent an ## unsigned integer. - var t = skipRange(x.rawtype) + var t = skipRange(x.rawType) case t.kind: of tyUInt: cast[ptr uint](x.value)[] = uint(y) of tyUInt8: cast[ptr uint8](x.value)[] = uint8(y) @@ -475,13 +476,13 @@ proc setBiggestUint*(x: TAny; y: uint64) = proc getChar*(x: TAny): char = ## retrieve the char value out of `x`. `x` needs to represent a char. - var t = skipRange(x.rawtype) + var t = skipRange(x.rawType) assert t.kind == tyChar result = cast[ptr char](x.value)[] proc getBool*(x: TAny): bool = ## retrieve the bool value out of `x`. `x` needs to represent a bool. - var t = skipRange(x.rawtype) + var t = skipRange(x.rawType) assert t.kind == tyBool result = cast[ptr bool](x.value)[] @@ -495,7 +496,7 @@ proc getEnumOrdinal*(x: TAny, name: string): int = ## gets the enum field ordinal from `name`. `x` needs to represent an enum ## but is only used to access the type information. In case of an error ## ``low(int)`` is returned. - var typ = skipRange(x.rawtype) + var typ = skipRange(x.rawType) assert typ.kind == tyEnum var n = typ.node var s = n.sons @@ -511,7 +512,7 @@ proc getEnumField*(x: TAny, ordinalValue: int): string = ## gets the enum field name as a string. `x` needs to represent an enum ## but is only used to access the type information. The field name of ## `ordinalValue` is returned. - var typ = skipRange(x.rawtype) + var typ = skipRange(x.rawType) assert typ.kind == tyEnum var e = ordinalValue if ntfEnumHole notin typ.flags: @@ -531,51 +532,51 @@ proc getEnumField*(x: TAny): string = proc getFloat*(x: TAny): float = ## retrieve the float value out of `x`. `x` needs to represent an float. - assert skipRange(x.rawtype).kind == tyFloat + assert skipRange(x.rawType).kind == tyFloat result = cast[ptr float](x.value)[] proc getFloat32*(x: TAny): float32 = ## retrieve the float32 value out of `x`. `x` needs to represent an float32. - assert skipRange(x.rawtype).kind == tyFloat32 + assert skipRange(x.rawType).kind == tyFloat32 result = cast[ptr float32](x.value)[] proc getFloat64*(x: TAny): float64 = ## retrieve the float64 value out of `x`. `x` needs to represent an float64. - assert skipRange(x.rawtype).kind == tyFloat64 + assert skipRange(x.rawType).kind == tyFloat64 result = cast[ptr float64](x.value)[] -proc getBiggestFloat*(x: TAny): biggestFloat = +proc getBiggestFloat*(x: TAny): BiggestFloat = ## retrieve the float value out of `x`. `x` needs to represent - ## some float. The value is extended to ``biggestFloat``. - case skipRange(x.rawtype).kind - of tyFloat: result = biggestFloat(cast[ptr Float](x.value)[]) - of tyFloat32: result = biggestFloat(cast[ptr Float32](x.value)[]) - of tyFloat64: result = biggestFloat(cast[ptr Float64](x.value)[]) + ## some float. The value is extended to ``BiggestFloat``. + case skipRange(x.rawType).kind + of tyFloat: result = BiggestFloat(cast[ptr float](x.value)[]) + of tyFloat32: result = BiggestFloat(cast[ptr float32](x.value)[]) + of tyFloat64: result = BiggestFloat(cast[ptr float64](x.value)[]) else: assert false -proc setBiggestFloat*(x: TAny, y: biggestFloat) = +proc setBiggestFloat*(x: TAny, y: BiggestFloat) = ## sets the float value of `x`. `x` needs to represent ## some float. - case skipRange(x.rawtype).kind - of tyFloat: cast[ptr Float](x.value)[] = y - of tyFloat32: cast[ptr Float32](x.value)[] = y.float32 - of tyFloat64: cast[ptr Float64](x.value)[] = y + case skipRange(x.rawType).kind + of tyFloat: cast[ptr float](x.value)[] = y + of tyFloat32: cast[ptr float32](x.value)[] = y.float32 + of tyFloat64: cast[ptr float64](x.value)[] = y else: assert false proc getString*(x: TAny): string = ## retrieve the string value out of `x`. `x` needs to represent a string. - assert x.rawtype.kind == tyString + assert x.rawType.kind == tyString if not isNil(cast[ptr pointer](x.value)[]): result = cast[ptr string](x.value)[] proc setString*(x: TAny, y: string) = ## sets the string value of `x`. `x` needs to represent a string. - assert x.rawtype.kind == tyString + assert x.rawType.kind == tyString cast[ptr string](x.value)[] = y proc getCString*(x: TAny): cstring = ## retrieve the cstring value out of `x`. `x` needs to represent a cstring. - assert x.rawtype.kind == tyCString + assert x.rawType.kind == tyCString result = cast[ptr cstring](x.value)[] proc assign*(x, y: TAny) = @@ -585,9 +586,9 @@ proc assign*(x, y: TAny) = genericAssign(x.value, y.value, y.rawType) iterator elements*(x: TAny): int = - ## iterates over every element of `x` that represents a Nimrod bitset. + ## iterates over every element of `x` that represents a Nim bitset. assert x.rawType.kind == tySet - var typ = x.rawtype + var typ = x.rawType var p = x.value # "typ.slots.len" field is for sets the "first" field var u: int64 @@ -607,9 +608,9 @@ iterator elements*(x: TAny): int = yield i+typ.node.len proc inclSetElement*(x: TAny, elem: int) = - ## includes an element `elem` in `x`. `x` needs to represent a Nimrod bitset. + ## includes an element `elem` in `x`. `x` needs to represent a Nim bitset. assert x.rawType.kind == tySet - var typ = x.rawtype + var typ = x.rawType var p = x.value # "typ.slots.len" field is for sets the "first" field var e = elem - typ.node.len diff --git a/lib/core/unsigned.nim b/lib/core/unsigned.nim index a3ddd4125..7acdf1439 100644 --- a/lib/core/unsigned.nim +++ b/lib/core/unsigned.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/impure/db_mysql.nim b/lib/impure/db_mysql.nim index ce48a32ed..37bea45b4 100644 --- a/lib/impure/db_mysql.nim +++ b/lib/impure/db_mysql.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -82,17 +82,17 @@ proc tryExec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): bool { tags: [FReadDB, FWriteDb].} = ## tries to execute the query and returns true if successful, false otherwise. var q = dbFormat(query, args) - return mysql.RealQuery(db, q, q.len) == 0'i32 + return mysql.realQuery(db, q, q.len) == 0'i32 proc rawExec(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) = var q = dbFormat(query, args) - if mysql.RealQuery(db, q, q.len) != 0'i32: dbError(db) + if mysql.realQuery(db, q, q.len) != 0'i32: dbError(db) proc exec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) {. tags: [FReadDB, FWriteDb].} = ## executes the query and raises EDB if not successful. var q = dbFormat(query, args) - if mysql.RealQuery(db, q, q.len) != 0'i32: dbError(db) + if mysql.realQuery(db, q, q.len) != 0'i32: dbError(db) proc newRow(L: int): TRow = newSeq(result, L) @@ -100,8 +100,8 @@ proc newRow(L: int): TRow = proc properFreeResult(sqlres: mysql.PRES, row: cstringArray) = if row != nil: - while mysql.FetchRow(sqlres) != nil: discard - mysql.FreeResult(sqlres) + while mysql.fetchRow(sqlres) != nil: discard + mysql.freeResult(sqlres) iterator fastRows*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = @@ -109,13 +109,13 @@ iterator fastRows*(db: TDbConn, query: TSqlQuery, ## fast, but potenially dangerous: If the for-loop-body executes another ## query, the results can be undefined. For MySQL this is the case!. rawExec(db, query, args) - var sqlres = mysql.UseResult(db) + var sqlres = mysql.useResult(db) if sqlres != nil: - var L = int(mysql.NumFields(sqlres)) + var L = int(mysql.numFields(sqlres)) var result = newRow(L) var row: cstringArray while true: - row = mysql.FetchRow(sqlres) + row = mysql.fetchRow(sqlres) if row == nil: break for i in 0..L-1: setLen(result[i], 0) @@ -131,11 +131,11 @@ proc getRow*(db: TDbConn, query: TSqlQuery, ## retrieves a single row. If the query doesn't return any rows, this proc ## will return a TRow with empty strings for each column. rawExec(db, query, args) - var sqlres = mysql.UseResult(db) + var sqlres = mysql.useResult(db) if sqlres != nil: - var L = int(mysql.NumFields(sqlres)) + var L = int(mysql.numFields(sqlres)) result = newRow(L) - var row = mysql.FetchRow(sqlres) + var row = mysql.fetchRow(sqlres) if row != nil: for i in 0..L-1: setLen(result[i], 0) @@ -150,13 +150,13 @@ proc getAllRows*(db: TDbConn, query: TSqlQuery, ## executes the query and returns the whole result dataset. result = @[] rawExec(db, query, args) - var sqlres = mysql.UseResult(db) + var sqlres = mysql.useResult(db) if sqlres != nil: - var L = int(mysql.NumFields(sqlres)) + var L = int(mysql.numFields(sqlres)) var row: cstringArray var j = 0 while true: - row = mysql.FetchRow(sqlres) + row = mysql.fetchRow(sqlres) if row == nil: break setLen(result, j+1) newSeq(result[j], L) @@ -166,12 +166,12 @@ proc getAllRows*(db: TDbConn, query: TSqlQuery, else: result[j][i] = $row[i] inc(j) - mysql.FreeResult(sqlres) + mysql.freeResult(sqlres) iterator rows*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = - ## same as `FastRows`, but slower and safe. - for r in items(GetAllRows(db, query, args)): yield r + ## same as `fastRows`, but slower and safe. + for r in items(getAllRows(db, query, args)): yield r proc getValue*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): string {.tags: [FReadDB].} = @@ -179,7 +179,7 @@ proc getValue*(db: TDbConn, query: TSqlQuery, ## result dataset. Returns "" if the dataset contains no rows or the database ## value is NULL. result = "" - for row in FastRows(db, query, args): + for row in fastRows(db, query, args): result = row[0] break @@ -188,16 +188,16 @@ proc tryInsertId*(db: TDbConn, query: TSqlQuery, ## executes the query (typically "INSERT") and returns the ## generated ID for the row or -1 in case of an error. var q = dbFormat(query, args) - if mysql.RealQuery(db, q, q.len) != 0'i32: + if mysql.realQuery(db, q, q.len) != 0'i32: result = -1'i64 else: - result = mysql.InsertId(db) + result = mysql.insertId(db) proc insertId*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): int64 {.tags: [FWriteDb].} = ## executes the query (typically "INSERT") and returns the ## generated ID for the row. - result = TryInsertID(db, query, args) + result = tryInsertID(db, query, args) if result < 0: dbError(db) proc execAffectedRows*(db: TDbConn, query: TSqlQuery, @@ -206,7 +206,7 @@ proc execAffectedRows*(db: TDbConn, query: TSqlQuery, ## runs the query (typically "UPDATE") and returns the ## number of affected rows rawExec(db, query, args) - result = mysql.AffectedRows(db) + result = mysql.affectedRows(db) proc close*(db: TDbConn) {.tags: [FDb].} = ## closes the database connection. @@ -216,7 +216,7 @@ proc open*(connection, user, password, database: string): TDbConn {. tags: [FDb].} = ## opens a database connection. Raises `EDb` if the connection could not ## be established. - result = mysql.Init(nil) + result = mysql.init(nil) if result == nil: dbError("could not open database connection") let colonPos = connection.find(':') @@ -224,9 +224,9 @@ proc open*(connection, user, password, database: string): TDbConn {. else: substr(connection, 0, colonPos-1) port: int32 = if colonPos < 0: 0'i32 else: substr(connection, colonPos+1).parseInt.int32 - if mysql.RealConnect(result, host, user, password, database, + if mysql.realConnect(result, host, user, password, database, port, nil, 0) == nil: var errmsg = $mysql.error(result) - db_mysql.Close(result) + db_mysql.close(result) dbError(errmsg) diff --git a/lib/impure/db_postgres.nim b/lib/impure/db_postgres.nim index 510cb8e45..6691c5703 100644 --- a/lib/impure/db_postgres.nim +++ b/lib/impure/db_postgres.nim @@ -1,7 +1,7 @@ # # -# Nimrod's Runtime Library -# (c) Copyright 2012 Andreas Rumpf +# Nim's Runtime Library +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -16,16 +16,16 @@ type TDbConn* = PPGconn ## encapsulates a database connection TRow* = seq[string] ## a row of a dataset. NULL database values will be ## transformed always to the empty string. - EDb* = object of EIO ## exception that is raised if a database error occurs + EDb* = object of IOError ## exception that is raised if a database error occurs TSqlQuery* = distinct string ## an SQL query string TSqlPrepared* = distinct string ## a identifier for the prepared queries - FDb* = object of FIO ## effect that denotes a database operation - FReadDb* = object of FDB ## effect that denotes a read operation - FWriteDb* = object of FDB ## effect that denotes a write operation + FDb* = object of IOEffect ## effect that denotes a database operation + FReadDb* = object of FDb ## effect that denotes a read operation + FWriteDb* = object of FDb ## effect that denotes a write operation -proc sql*(query: string): TSqlQuery {.noSideEffect, inline.} = +proc sql*(query: string): TSqlQuery {.noSideEffect, inline.} = ## constructs a TSqlQuery from the string `query`. This is supposed to be ## used as a raw-string-literal modifier: ## ``sql"update user set counter = counter + 1"`` @@ -38,7 +38,7 @@ proc dbError*(db: TDbConn) {.noreturn.} = ## raises an EDb exception. var e: ref EDb new(e) - e.msg = $PQerrorMessage(db) + e.msg = $pqErrorMessage(db) raise e proc dbError*(msg: string) {.noreturn.} = @@ -73,30 +73,30 @@ proc tryExec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): bool {.tags: [FReadDB, FWriteDb].} = ## tries to execute the query and returns true if successful, false otherwise. var arr = allocCStringArray(args) - var res = PQexecParams(db, query.string, int32(args.len), nil, arr, + var res = pqexecParams(db, query.string, int32(args.len), nil, arr, nil, nil, 0) deallocCStringArray(arr) - result = PQresultStatus(res) == PGRES_COMMAND_OK - PQclear(res) + result = pqresultStatus(res) == PGRES_COMMAND_OK + pqclear(res) proc exec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) {. tags: [FReadDB, FWriteDb].} = ## executes the query and raises EDB if not successful. var arr = allocCStringArray(args) - var res = PQexecParams(db, query.string, int32(args.len), nil, arr, + var res = pqexecParams(db, query.string, int32(args.len), nil, arr, nil, nil, 0) deallocCStringArray(arr) - if PQresultStatus(res) != PGRES_COMMAND_OK: dbError(db) - PQclear(res) + if pqresultStatus(res) != PGRES_COMMAND_OK: dbError(db) + pqclear(res) proc exec*(db: TDbConn, stmtName: TSqlPrepared, args: varargs[string]) {.tags: [FReadDB, FWriteDb].} = var arr = allocCStringArray(args) - var res = PQexecPrepared(db, stmtName.string, int32(args.len), arr, + var res = pqexecPrepared(db, stmtName.string, int32(args.len), arr, nil, nil, 0) deallocCStringArray(arr) - if PQResultStatus(res) != PGRES_COMMAND_OK: dbError(db) - PQclear(res) + if pqResultStatus(res) != PGRES_COMMAND_OK: dbError(db) + pqclear(res) proc newRow(L: int): TRow = newSeq(result, L) @@ -105,30 +105,30 @@ proc newRow(L: int): TRow = proc setupQuery(db: TDbConn, query: TSqlQuery, args: varargs[string]): PPGresult = var arr = allocCStringArray(args) - result = PQexecParams(db, query.string, int32(args.len), nil, arr, + result = pqexecParams(db, query.string, int32(args.len), nil, arr, nil, nil, 0) deallocCStringArray(arr) - if PQResultStatus(result) != PGRES_TUPLES_OK: dbError(db) + if pqResultStatus(result) != PGRES_TUPLES_OK: dbError(db) proc setupQuery(db: TDbConn, stmtName: TSqlPrepared, args: varargs[string]): PPGresult = var arr = allocCStringArray(args) - result = PQexecPrepared(db, stmtName.string, int32(args.len), arr, + result = pqexecPrepared(db, stmtName.string, int32(args.len), arr, nil, nil, 0) deallocCStringArray(arr) - if PQResultStatus(result) != PGRES_TUPLES_OK: dbError(db) + if pqResultStatus(result) != PGRES_TUPLES_OK: dbError(db) proc prepare*(db: TDbConn; stmtName: string, query: TSqlQuery; nParams: int): TSqlPrepared = - var res = PQprepare(db, stmtName, query.string, int32(nParams), nil) - if PQResultStatus(res) != PGRES_COMMAND_OK: dbError(db) + var res = pqprepare(db, stmtName, query.string, int32(nParams), nil) + if pqResultStatus(res) != PGRES_COMMAND_OK: dbError(db) return TSqlPrepared(stmtName) proc setRow(res: PPGresult, r: var TRow, line, cols: int32) = for col in 0..cols-1: setLen(r[col], 0) - var x = PQgetvalue(res, line, col) - if x == nil: + let x = pqgetvalue(res, line, col) + if x.isNil: r[col] = nil else: add(r[col], x) @@ -139,67 +139,67 @@ iterator fastRows*(db: TDbConn, query: TSqlQuery, ## fast, but potenially dangerous: If the for-loop-body executes another ## query, the results can be undefined. For Postgres it is safe though. var res = setupQuery(db, query, args) - var L = PQnfields(res) + var L = pqnfields(res) var result = newRow(L) - for i in 0..PQntuples(res)-1: + for i in 0..pqntuples(res)-1: setRow(res, result, i, L) yield result - PQclear(res) + pqclear(res) iterator fastRows*(db: TDbConn, stmtName: TSqlPrepared, args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = ## executes the prepared query and iterates over the result dataset. var res = setupQuery(db, stmtName, args) - var L = PQnfields(res) + var L = pqNfields(res) var result = newRow(L) - for i in 0..PQntuples(res)-1: + for i in 0..pqNtuples(res)-1: setRow(res, result, i, L) yield result - PQclear(res) + pqClear(res) proc getRow*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = ## retrieves a single row. If the query doesn't return any rows, this proc ## will return a TRow with empty strings for each column. var res = setupQuery(db, query, args) - var L = PQnfields(res) + var L = pqnfields(res) result = newRow(L) setRow(res, result, 0, L) - PQclear(res) + pqclear(res) proc getRow*(db: TDbConn, stmtName: TSqlPrepared, - args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = - var res = setupQuery(db, stmtName, args) - var L = PQnfields(res) - result = newRow(L) - setRow(res, result, 0, L) - PQclear(res) + args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = + var res = setupQuery(db, stmtName, args) + var L = pqNfields(res) + result = newRow(L) + setRow(res, result, 0, L) + pqClear(res) proc getAllRows*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): seq[TRow] {.tags: [FReadDB].} = ## executes the query and returns the whole result dataset. result = @[] - for r in FastRows(db, query, args): + for r in fastRows(db, query, args): result.add(r) proc getAllRows*(db: TDbConn, stmtName: TSqlPrepared, args: varargs[string, `$`]): seq[TRow] {.tags: [FReadDB].} = ## executes the prepared query and returns the whole result dataset. result = @[] - for r in FastRows(db, stmtName, args): + for r in fastRows(db, stmtName, args): result.add(r) iterator rows*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = - ## same as `FastRows`, but slower and safe. - for r in items(GetAllRows(db, query, args)): yield r + ## same as `fastRows`, but slower and safe. + for r in items(getAllRows(db, query, args)): yield r proc getValue*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): string {.tags: [FReadDB].} = ## executes the query and returns the first column of the first row of the ## result dataset. Returns "" if the dataset contains no rows or the database ## value is NULL. - var x = PQgetvalue(setupQuery(db, query, args), 0, 0) + var x = pqgetvalue(setupQuery(db, query, args), 0, 0) result = if isNil(x): "" else: $x proc tryInsertID*(db: TDbConn, query: TSqlQuery, @@ -208,10 +208,10 @@ proc tryInsertID*(db: TDbConn, query: TSqlQuery, ## generated ID for the row or -1 in case of an error. For Postgre this adds ## ``RETURNING id`` to the query, so it only works if your primary key is ## named ``id``. - var x = PQgetvalue(setupQuery(db, TSqlQuery(string(query) & " RETURNING id"), + var x = pqgetvalue(setupQuery(db, TSqlQuery(string(query) & " RETURNING id"), args), 0, 0) if not isNil(x): - result = ParseBiggestInt($x) + result = parseBiggestInt($x) else: result = -1 @@ -221,7 +221,7 @@ proc insertID*(db: TDbConn, query: TSqlQuery, ## generated ID for the row. For Postgre this adds ## ``RETURNING id`` to the query, so it only works if your primary key is ## named ``id``. - result = TryInsertID(db, query, args) + result = tryInsertID(db, query, args) if result < 0: dbError(db) proc execAffectedRows*(db: TDbConn, query: TSqlQuery, @@ -230,14 +230,14 @@ proc execAffectedRows*(db: TDbConn, query: TSqlQuery, ## executes the query (typically "UPDATE") and returns the ## number of affected rows. var q = dbFormat(query, args) - var res = PQExec(db, q) - if PQresultStatus(res) != PGRES_COMMAND_OK: dbError(db) - result = parseBiggestInt($PQcmdTuples(res)) - PQclear(res) + var res = pqExec(db, q) + if pqresultStatus(res) != PGRES_COMMAND_OK: dbError(db) + result = parseBiggestInt($pqcmdTuples(res)) + pqclear(res) proc close*(db: TDbConn) {.tags: [FDb].} = ## closes the database connection. - if db != nil: PQfinish(db) + if db != nil: pqfinish(db) proc open*(connection, user, password, database: string): TDbConn {. tags: [FDb].} = @@ -249,16 +249,14 @@ proc open*(connection, user, password, database: string): TDbConn {. ## ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## - ## con = Open("", "", "", "host=localhost port=5432 dbname=mydb") + ## con = open("", "", "", "host=localhost port=5432 dbname=mydb") ## ## See http://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING ## for more information. ## ## Note that the connection parameter is not used but exists to maintain - ## the nimrod db api. - result = PQsetdbLogin(nil, nil, nil, nil, database, user, password) - if PQStatus(result) != CONNECTION_OK: dbError(result) # result = nil - - + ## the nim db api. + result = pqsetdbLogin(nil, nil, nil, nil, database, user, password) + if pqStatus(result) != CONNECTION_OK: dbError(result) # result = nil diff --git a/lib/impure/db_sqlite.nim b/lib/impure/db_sqlite.nim index 809ee7039..bc9e0b591 100644 --- a/lib/impure/db_sqlite.nim +++ b/lib/impure/db_sqlite.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -16,13 +16,13 @@ type TDbConn* = PSqlite3 ## encapsulates a database connection TRow* = seq[string] ## a row of a dataset. NULL database values will be ## transformed always to the empty string. - EDb* = object of EIO ## exception that is raised if a database error occurs + EDb* = object of IOError ## exception that is raised if a database error occurs TSqlQuery* = distinct string ## an SQL query string - FDb* = object of FIO ## effect that denotes a database operation - FReadDb* = object of FDB ## effect that denotes a read operation - FWriteDb* = object of FDB ## effect that denotes a write operation + FDb* = object of IOEffect ## effect that denotes a database operation + FReadDb* = object of FDb ## effect that denotes a read operation + FWriteDb* = object of FDb ## effect that denotes a write operation proc sql*(query: string): TSqlQuery {.noSideEffect, inline.} = ## constructs a TSqlQuery from the string `query`. This is supposed to be @@ -65,16 +65,16 @@ proc dbFormat(formatstr: TSqlQuery, args: varargs[string]): string = add(result, c) proc tryExec*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): bool {.tags: [FReadDB, FWriteDb].} = + args: varargs[string, `$`]): bool {.tags: [FReadDb, FWriteDb].} = ## tries to execute the query and returns true if successful, false otherwise. var q = dbFormat(query, args) - var stmt: sqlite3.PStmt + var stmt: sqlite3.Pstmt if prepare_v2(db, q, q.len.cint, stmt, nil) == SQLITE_OK: if step(stmt) == SQLITE_DONE: result = finalize(stmt) == SQLITE_OK proc exec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) {. - tags: [FReadDB, FWriteDb].} = + tags: [FReadDb, FWriteDb].} = ## executes the query and raises EDB if not successful. if not tryExec(db, query, args): dbError(db) @@ -83,11 +83,11 @@ proc newRow(L: int): TRow = for i in 0..L-1: result[i] = "" proc setupQuery(db: TDbConn, query: TSqlQuery, - args: varargs[string]): PStmt = + args: varargs[string]): Pstmt = var q = dbFormat(query, args) if prepare_v2(db, q, q.len.cint, result, nil) != SQLITE_OK: dbError(db) -proc setRow(stmt: PStmt, r: var TRow, cols: cint) = +proc setRow(stmt: Pstmt, r: var TRow, cols: cint) = for col in 0..cols-1: setLen(r[col], column_bytes(stmt, col)) # set capacity setLen(r[col], 0) @@ -95,12 +95,12 @@ proc setRow(stmt: PStmt, r: var TRow, cols: cint) = if not isNil(x): add(r[col], x) iterator fastRows*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = + args: varargs[string, `$`]): TRow {.tags: [FReadDb].} = ## executes the query and iterates over the result dataset. This is very ## fast, but potenially dangerous: If the for-loop-body executes another ## query, the results can be undefined. For Sqlite it is safe though. var stmt = setupQuery(db, query, args) - var L = (columnCount(stmt)) + var L = (column_count(stmt)) var result = newRow(L) while step(stmt) == SQLITE_ROW: setRow(stmt, result, L) @@ -108,30 +108,30 @@ iterator fastRows*(db: TDbConn, query: TSqlQuery, if finalize(stmt) != SQLITE_OK: dbError(db) proc getRow*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = + args: varargs[string, `$`]): TRow {.tags: [FReadDb].} = ## retrieves a single row. If the query doesn't return any rows, this proc ## will return a TRow with empty strings for each column. var stmt = setupQuery(db, query, args) - var L = (columnCount(stmt)) + var L = (column_count(stmt)) result = newRow(L) if step(stmt) == SQLITE_ROW: setRow(stmt, result, L) if finalize(stmt) != SQLITE_OK: dbError(db) proc getAllRows*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): seq[TRow] {.tags: [FReadDB].} = + args: varargs[string, `$`]): seq[TRow] {.tags: [FReadDb].} = ## executes the query and returns the whole result dataset. result = @[] for r in fastRows(db, query, args): result.add(r) iterator rows*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = + args: varargs[string, `$`]): TRow {.tags: [FReadDb].} = ## same as `FastRows`, but slower and safe. for r in fastRows(db, query, args): yield r proc getValue*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): string {.tags: [FReadDB].} = + args: varargs[string, `$`]): string {.tags: [FReadDb].} = ## executes the query and returns the first column of the first row of the ## result dataset. Returns "" if the dataset contains no rows or the database ## value is NULL. @@ -153,7 +153,7 @@ proc tryInsertID*(db: TDbConn, query: TSqlQuery, ## executes the query (typically "INSERT") and returns the ## generated ID for the row or -1 in case of an error. var q = dbFormat(query, args) - var stmt: sqlite3.PStmt + var stmt: sqlite3.Pstmt result = -1 if prepare_v2(db, q, q.len.cint, stmt, nil) == SQLITE_OK: if step(stmt) == SQLITE_DONE: @@ -172,18 +172,18 @@ proc insertID*(db: TDbConn, query: TSqlQuery, proc execAffectedRows*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): int64 {. - tags: [FReadDB, FWriteDb].} = + tags: [FReadDb, FWriteDb].} = ## executes the query (typically "UPDATE") and returns the ## number of affected rows. exec(db, query, args) result = changes(db) -proc close*(db: TDbConn) {.tags: [FDB].} = +proc close*(db: TDbConn) {.tags: [FDb].} = ## closes the database connection. if sqlite3.close(db) != SQLITE_OK: dbError(db) proc open*(connection, user, password, database: string): TDbConn {. - tags: [FDB].} = + tags: [FDb].} = ## opens a database connection. Raises `EDb` if the connection could not ## be established. Only the ``connection`` parameter is used for ``sqlite``. var db: TDbConn diff --git a/lib/impure/dialogs.nim b/lib/impure/dialogs.nim index 00ba2663e..4ea66a6e6 100644 --- a/lib/impure/dialogs.nim +++ b/lib/impure/dialogs.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -8,7 +8,7 @@ # -## This module implements portable dialogs for Nimrod; the implementation +## This module implements portable dialogs for Nim; the implementation ## builds on the GTK interface. On Windows, native dialogs are shown instead. import @@ -200,14 +200,14 @@ proc chooseDir*(window: PWindow, root: string = ""): string = BrowseInfo: TBrowseInfo DisplayName: array [0..MAX_PATH, char] TempPath: array [0..MAX_PATH, char] - Result = "" + result = "" #BrowseInfo.hwndOwner = Application.Handle BrowseInfo.pszDisplayName = DisplayName BrowseInfo.ulFlags = 1 #BIF_RETURNONLYFSDIRS lpItemID = SHBrowseForFolder(cast[LPBrowseInfo](addr(BrowseInfo))) if lpItemId != nil: discard SHGetPathFromIDList(lpItemID, TempPath) - Result = $TempPath + result = $TempPath discard GlobalFreePtr(lpItemID) else: var chooser = file_chooser_dialog_new("Select Directory", window, diff --git a/lib/impure/fenv.nim b/lib/impure/fenv.nim index 9d7c8809b..1859f7be7 100644 --- a/lib/impure/fenv.nim +++ b/lib/impure/fenv.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -42,16 +42,6 @@ var ## case the default environment will be used type - TFloatClass* = enum ## describes the class a floating point value belongs to. - ## This is the type that is returned by `classify`. - fcNormal, ## value is an ordinary nonzero floating point value - fcSubnormal, ## value is a subnormal (a very small) floating point value - fcZero, ## value is zero - fcNegZero, ## value is the negative zero - fcNan, ## value is Not-A-Number (NAN) - fcInf, ## value is positive infinity - fcNegInf ## value is negative infinity - Tfenv* {.importc: "fenv_t", header: "<fenv.h>", final, pure.} = object ## Represents the entire floating-point environment. The ## floating-point environment refers collectively to any diff --git a/lib/impure/graphics.nim b/lib/impure/graphics.nim index 2c8e96460..dfadb46ee 100644 --- a/lib/impure/graphics.nim +++ b/lib/impure/graphics.nim @@ -1,20 +1,20 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf, Dominik Picheta # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## This module implements graphical output for Nimrod; the current +## This module implements graphical output for Nim; the current ## implementation uses SDL but the interface is meant to support multiple ## backends some day. There is no need to init SDL as this module does that ## implicitly. import colors, math from sdl import PSurface # Bug -from sdl_ttf import OpenFont, closeFont +from sdl_ttf import openFont, closeFont type TRect* = tuple[x, y, width, height: int] @@ -25,24 +25,24 @@ type w*, h*: Natural s*: sdl.PSurface - EGraphics* = object of EIO + EGraphics* = object of IOError TFont {.pure, final.} = object f: sdl_ttf.PFont - color: SDL.TColor + color: sdl.TColor PFont* = ref TFont ## represents a font -proc toSdlColor*(c: TColor): Sdl.TColor = - ## Convert colors.TColor to SDL.TColor +proc toSdlColor*(c: Color): sdl.TColor = + ## Convert colors.TColor to sdl.TColor var x = c.extractRGB result.r = x.r and 0xff result.g = x.g and 0xff result.b = x.b and 0xff -proc createSdlColor*(sur: PSurface, c: TColor, alpha: int = 0): int32 = +proc createSdlColor*(sur: PSurface, c: Color, alpha: int = 0): int32 = ## Creates a color using ``sdl.MapRGBA``. var x = c.extractRGB - return sdl.MapRGBA(sur.s.format, x.r and 0xff, x.g and 0xff, + return sdl.mapRGBA(sur.s.format, x.r and 0xff, x.g and 0xff, x.b and 0xff, alpha and 0xff) proc toSdlRect*(r: TRect): sdl.TRect = @@ -53,7 +53,7 @@ proc toSdlRect*(r: TRect): sdl.TRect = result.h = uint16(r.height) proc raiseEGraphics = - raise newException(EGraphics, $SDL.GetError()) + raise newException(EGraphics, $sdl.getError()) proc surfaceFinalizer(s: PSurface) = sdl.freeSurface(s.s) @@ -62,21 +62,21 @@ proc newSurface*(width, height: int): PSurface = new(result, surfaceFinalizer) result.w = width result.h = height - result.s = SDL.CreateRGBSurface(SDL.SWSURFACE, width, height, + result.s = sdl.createRGBSurface(sdl.SWSURFACE, width, height, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0) if result.s == nil: raiseEGraphics() - assert(not sdl.MustLock(result.s)) + assert(not sdl.mustLock(result.s)) proc fontFinalizer(f: PFont) = closeFont(f.f) proc newFont*(name = "VeraMono.ttf", size = 9, color = colBlack): PFont = ## Creates a new font object. Raises ``EIO`` if the font cannot be loaded. new(result, fontFinalizer) - result.f = OpenFont(name, size.cint) + result.f = openFont(name, size.cint) if result.f == nil: - raise newException(EIO, "Could not open font file: " & name) + raise newException(IOError, "Could not open font file: " & name) result.color = toSdlColor(color) var @@ -92,7 +92,7 @@ proc newScreenSurface*(width, height: int): PSurface = new(result, surfaceFinalizer) result.w = width result.h = height - result.s = SDL.SetVideoMode(width, height, 0, 0) + result.s = sdl.setVideoMode(width, height, 0, 0) if result.s == nil: raiseEGraphics() @@ -100,7 +100,7 @@ proc writeToBMP*(sur: PSurface, filename: string) = ## Saves the contents of the surface `sur` to the file `filename` as a ## BMP file. if sdl.saveBMP(sur.s, filename) != 0: - raise newException(EIO, "cannot write: " & filename) + raise newException(IOError, "cannot write: " & filename) type TPixels = array[0..1000_000-1, int32] @@ -110,44 +110,44 @@ template setPix(video, pitch, x, y, col: expr): stmt = video[y * pitch + x] = int32(col) template getPix(video, pitch, x, y: expr): expr = - colors.TColor(video[y * pitch + x]) + colors.Color(video[y * pitch + x]) const ColSize = 4 -proc getPixel(sur: PSurface, x, y: Natural): colors.TColor {.inline.} = +proc getPixel(sur: PSurface, x, y: Natural): colors.Color {.inline.} = assert x <% sur.w assert y <% sur.h result = getPix(cast[PPixels](sur.s.pixels), sur.s.pitch.int div ColSize, x, y) -proc setPixel(sur: PSurface, x, y: Natural, col: colors.TColor) {.inline.} = +proc setPixel(sur: PSurface, x, y: Natural, col: colors.Color) {.inline.} = assert x <% sur.w assert y <% sur.h var pixs = cast[PPixels](sur.s.pixels) #pixs[y * (sur.s.pitch div colSize) + x] = int(col) setPix(pixs, sur.s.pitch.int div ColSize, x, y, col) -proc `[]`*(sur: PSurface, p: TPoint): TColor = +proc `[]`*(sur: PSurface, p: TPoint): Color = ## get pixel at position `p`. No range checking is done! result = getPixel(sur, p.x, p.y) -proc `[]`*(sur: PSurface, x, y: int): TColor = +proc `[]`*(sur: PSurface, x, y: int): Color = ## get pixel at position ``(x, y)``. No range checking is done! result = getPixel(sur, x, y) -proc `[]=`*(sur: PSurface, p: TPoint, col: TColor) = +proc `[]=`*(sur: PSurface, p: TPoint, col: Color) = ## set the pixel at position `p`. No range checking is done! setPixel(sur, p.x, p.y, col) -proc `[]=`*(sur: PSurface, x, y: int, col: TColor) = +proc `[]=`*(sur: PSurface, x, y: int, col: Color) = ## set the pixel at position ``(x, y)``. No range checking is done! setPixel(sur, x, y, col) proc blit*(destSurf: PSurface, destRect: TRect, srcSurf: PSurface, srcRect: TRect) = ## Copies ``srcSurf`` into ``destSurf`` - var destTRect, srcTRect: SDL.TRect + var destTRect, srcTRect: sdl.TRect destTRect.x = int16(destRect.x) destTRect.y = int16(destRect.y) @@ -159,12 +159,12 @@ proc blit*(destSurf: PSurface, destRect: TRect, srcSurf: PSurface, srcTRect.w = uint16(srcRect.width) srcTRect.h = uint16(srcRect.height) - if SDL.blitSurface(srcSurf.s, addr(srcTRect), destSurf.s, addr(destTRect)) != 0: + if sdl.blitSurface(srcSurf.s, addr(srcTRect), destSurf.s, addr(destTRect)) != 0: raiseEGraphics() proc textBounds*(text: string, font = defaultFont): tuple[width, height: int] = var w, h: cint - if sdl_ttf.SizeUTF8(font.f, text, w, h) < 0: raiseEGraphics() + if sdl_ttf.sizeUTF8(font.f, text, w, h) < 0: raiseEGraphics() result.width = int(w) result.height = int(h) @@ -175,21 +175,21 @@ proc drawText*(sur: PSurface, p: TPoint, text: string, font = defaultFont) = new(textSur, surfaceFinalizer) # Render the text - textSur.s = sdl_ttf.RenderTextBlended(font.f, text, font.color) + textSur.s = sdl_ttf.renderTextBlended(font.f, text, font.color) # Merge the text surface with sur sur.blit((p.x, p.y, sur.w, sur.h), textSur, (0, 0, sur.w, sur.h)) proc drawText*(sur: PSurface, p: TPoint, text: string, - bg: TColor, font = defaultFont) = + bg: Color, font = defaultFont) = ## Draws text, at location ``p`` with font ``font``. ``bg`` ## is the background color. var textSur: PSurface # This surface will have the text drawn on it new(textSur, surfaceFinalizer) - textSur.s = sdl_ttf.RenderTextShaded(font.f, text, font.color, toSdlColor(bg)) + textSur.s = sdl_ttf.renderTextShaded(font.f, text, font.color, toSdlColor(bg)) # Merge the text surface with sur sur.blit((p.x, p.y, sur.w, sur.h), textSur, (0, 0, sur.w, sur.h)) -proc drawCircle*(sur: PSurface, p: TPoint, r: Natural, color: TColor) = +proc drawCircle*(sur: PSurface, p: TPoint, r: Natural, color: Color) = ## draws a circle with center `p` and radius `r` with the given color ## onto the surface `sur`. var video = cast[PPixels](sur.s.pixels) @@ -229,7 +229,7 @@ proc `>-<`(val: int, s: PSurface): int {.inline.} = proc `>|<`(val: int, s: PSurface): int {.inline.} = return if val < 0: 0 elif val >= s.h: s.h-1 else: val -proc drawLine*(sur: PSurface, p1, p2: TPoint, color: TColor) = +proc drawLine*(sur: PSurface, p1, p2: TPoint, color: Color) = ## draws a line between the two points `p1` and `p2` with the given color ## onto the surface `sur`. var stepx, stepy: int = 0 @@ -273,7 +273,7 @@ proc drawLine*(sur: PSurface, p1, p2: TPoint, color: TColor) = fraction = fraction + dx setPix(video, pitch, x0, y0, color) -proc drawHorLine*(sur: PSurface, x, y, w: Natural, Color: TColor) = +proc drawHorLine*(sur: PSurface, x, y, w: Natural, color: Color) = ## draws a horizontal line from (x,y) to (x+w-1, y). var video = cast[PPixels](sur.s.pixels) var pitch = sur.s.pitch.int div ColSize @@ -282,7 +282,7 @@ proc drawHorLine*(sur: PSurface, x, y, w: Natural, Color: TColor) = for i in 0 .. min(sur.s.w-x, w)-1: setPix(video, pitch, x + i, y, color) -proc drawVerLine*(sur: PSurface, x, y, h: Natural, Color: TColor) = +proc drawVerLine*(sur: PSurface, x, y, h: Natural, color: Color) = ## draws a vertical line from (x,y) to (x, y+h-1). var video = cast[PPixels](sur.s.pixels) var pitch = sur.s.pitch.int div ColSize @@ -291,7 +291,7 @@ proc drawVerLine*(sur: PSurface, x, y, h: Natural, Color: TColor) = for i in 0 .. min(sur.s.h-y, h)-1: setPix(video, pitch, x, y + i, color) -proc fillCircle*(s: PSurface, p: TPoint, r: Natural, color: TColor) = +proc fillCircle*(s: PSurface, p: TPoint, r: Natural, color: Color) = ## draws a circle with center `p` and radius `r` with the given color ## onto the surface `sur` and fills it. var a = 1 - r @@ -301,11 +301,11 @@ proc fillCircle*(s: PSurface, p: TPoint, r: Natural, color: TColor) = var y = p.y while px <= py: # Fill up the middle half of the circle - DrawVerLine(s, x + px, y, py + 1, color) - DrawVerLine(s, x + px, y - py, py, color) + drawVerLine(s, x + px, y, py + 1, color) + drawVerLine(s, x + px, y - py, py, color) if px != 0: - DrawVerLine(s, x - px, y, py + 1, color) - DrawVerLine(s, x - px, y - py, py, color) + drawVerLine(s, x - px, y, py + 1, color) + drawVerLine(s, x - px, y - py, py, color) if a < 0: a = a + (2 * px + 3) else: @@ -313,13 +313,13 @@ proc fillCircle*(s: PSurface, p: TPoint, r: Natural, color: TColor) = py = py - 1 # Fill up the left/right half of the circle if py >= px: - DrawVerLine(s, x + py + 1, y, px + 1, color) - DrawVerLine(s, x + py + 1, y - px, px, color) - DrawVerLine(s, x - py - 1, y, px + 1, color) - DrawVerLine(s, x - py - 1, y - px, px, color) + drawVerLine(s, x + py + 1, y, px + 1, color) + drawVerLine(s, x + py + 1, y - px, px, color) + drawVerLine(s, x - py - 1, y, px + 1, color) + drawVerLine(s, x - py - 1, y - px, px, color) px = px + 1 -proc drawRect*(sur: PSurface, r: TRect, color: TColor) = +proc drawRect*(sur: PSurface, r: TRect, color: Color) = ## draws a rectangle. var video = cast[PPixels](sur.s.pixels) var pitch = sur.s.pitch.int div ColSize @@ -337,78 +337,78 @@ proc drawRect*(sur: PSurface, r: TRect, color: TColor) = setPix(video, pitch, r.x, r.y + i, color) setPix(video, pitch, r.x + minW - 1, r.y + i, color) # Draw right side -proc fillRect*(sur: PSurface, r: TRect, col: TColor) = +proc fillRect*(sur: PSurface, r: TRect, col: Color) = ## Fills a rectangle using sdl's ``FillRect`` function. var rect = toSdlRect(r) - if sdl.FillRect(sur.s, addr(rect), sur.createSdlColor(col)) == -1: + if sdl.fillRect(sur.s, addr(rect), sur.createSdlColor(col)) == -1: raiseEGraphics() -proc plot4EllipsePoints(sur: PSurface, CX, CY, X, Y: Natural, col: TColor) = +proc plot4EllipsePoints(sur: PSurface, cx, cy, x, y: Natural, col: Color) = var video = cast[PPixels](sur.s.pixels) var pitch = sur.s.pitch.int div ColSize - if CX+X <= sur.s.w-1: - if CY+Y <= sur.s.h-1: setPix(video, pitch, CX+X, CY+Y, col) - if CY-Y <= sur.s.h-1: setPix(video, pitch, CX+X, CY-Y, col) - if CX-X <= sur.s.w-1: - if CY+Y <= sur.s.h-1: setPix(video, pitch, CX-X, CY+Y, col) - if CY-Y <= sur.s.h-1: setPix(video, pitch, CX-X, CY-Y, col) - -proc drawEllipse*(sur: PSurface, CX, CY, XRadius, YRadius: Natural, - col: TColor) = + if cx+x <= sur.s.w-1: + if cy+y <= sur.s.h-1: setPix(video, pitch, cx+x, cy+y, col) + if cy-y <= sur.s.h-1: setPix(video, pitch, cx+x, cy-y, col) + if cx-x <= sur.s.w-1: + if cy+y <= sur.s.h-1: setPix(video, pitch, cx-x, cy+y, col) + if cy-y <= sur.s.h-1: setPix(video, pitch, cx-x, cy-y, col) + +proc drawEllipse*(sur: PSurface, cx, cy, xRadius, yRadius: Natural, + col: Color) = ## Draws an ellipse, ``CX`` and ``CY`` specify the center X and Y of the ## ellipse, ``XRadius`` and ``YRadius`` specify half the width and height ## of the ellipse. var - X, Y: Natural - XChange, YChange: Int - EllipseError: Natural - TwoASquare, TwoBSquare: Natural - StoppingX, StoppingY: Natural + x, y: Natural + xChange, yChange: int + ellipseError: Natural + twoASquare, twoBSquare: Natural + stoppingX, stoppingY: Natural - TwoASquare = 2 * XRadius * XRadius - TwoBSquare = 2 * YRadius * YRadius - X = XRadius - Y = 0 - XChange = YRadius * YRadius * (1 - 2 * XRadius) - YChange = XRadius * XRadius - EllipseError = 0 - StoppingX = TwoBSquare * XRadius - StoppingY = 0 + twoASquare = 2 * xRadius * xRadius + twoBSquare = 2 * yRadius * yRadius + x = xRadius + y = 0 + xChange = yRadius * yRadius * (1 - 2 * xRadius) + yChange = xRadius * xRadius + ellipseError = 0 + stoppingX = twoBSquare * xRadius + stoppingY = 0 - while StoppingX >= StoppingY: # 1st set of points, y` > - 1 - sur.Plot4EllipsePoints(CX, CY, X, Y, col) - inc(Y) - inc(StoppingY, TwoASquare) - inc(EllipseError, YChange) - inc(YChange, TwoASquare) - if (2 * EllipseError + XChange) > 0 : + while stoppingX >= stoppingY: # 1st set of points, y` > - 1 + sur.plot4EllipsePoints(cx, cy, x, y, col) + inc(y) + inc(stoppingY, twoASquare) + inc(ellipseError, yChange) + inc(yChange, twoASquare) + if (2 * ellipseError + xChange) > 0 : dec(x) - dec(StoppingX, TwoBSquare) - inc(EllipseError, XChange) - inc(XChange, TwoBSquare) + dec(stoppingX, twoBSquare) + inc(ellipseError, xChange) + inc(xChange, twoBSquare) # 1st point set is done; start the 2nd set of points - X = 0 - Y = YRadius - XChange = YRadius * YRadius - YChange = XRadius * XRadius * (1 - 2 * YRadius) - EllipseError = 0 - StoppingX = 0 - StoppingY = TwoASquare * YRadius - while StoppingX <= StoppingY: - sur.Plot4EllipsePoints(CX, CY, X, Y, col) - inc(X) - inc(StoppingX, TwoBSquare) - inc(EllipseError, XChange) - inc(XChange,TwoBSquare) - if (2 * EllipseError + YChange) > 0: - dec(Y) - dec(StoppingY, TwoASquare) - inc(EllipseError, YChange) - inc(YChange,TwoASquare) + x = 0 + y = yRadius + xChange = yRadius * yRadius + yChange = xRadius * xRadius * (1 - 2 * yRadius) + ellipseError = 0 + stoppingX = 0 + stoppingY = twoASquare * yRadius + while stoppingX <= stoppingY: + sur.plot4EllipsePoints(cx, cy, x, y, col) + inc(x) + inc(stoppingX, twoBSquare) + inc(ellipseError, xChange) + inc(xChange,twoBSquare) + if (2 * ellipseError + yChange) > 0: + dec(y) + dec(stoppingY, twoASquare) + inc(ellipseError, yChange) + inc(yChange,twoASquare) -proc plotAA(sur: PSurface, x, y: int, c: float, color: TColor) = +proc plotAA(sur: PSurface, x, y: int, c: float, color: Color) = if (x > 0 and x < sur.s.w) and (y > 0 and y < sur.s.h): var video = cast[PPixels](sur.s.pixels) var pitch = sur.s.pitch.int div ColSize @@ -424,7 +424,7 @@ template cround(x: expr): expr = ipart(x + 0.5) template fpart(x: expr): expr = x - ipart(x) template rfpart(x: expr): expr = 1.0 - fpart(x) -proc drawLineAA*(sur: PSurface, p1, p2: TPoint, color: TColor) = +proc drawLineAA*(sur: PSurface, p1, p2: TPoint, color: Color) = ## Draws a anti-aliased line from ``p1`` to ``p2``, using Xiaolin Wu's ## line algorithm var (x1, x2, y1, y2) = (p1.x.toFloat(), p2.x.toFloat(), @@ -444,11 +444,11 @@ proc drawLineAA*(sur: PSurface, p1, p2: TPoint, color: TColor) = swap(x2, y2) swap(dx, dy) - template doPlot(x, y: int, c: float, color: TColor): stmt = + template doPlot(x, y: int, c: float, color: Color): stmt = if ax < ay: - sur.PlotAA(y, x, c, color) + sur.plotAA(y, x, c, color) else: - sur.PlotAA(x, y, c, color) + sur.plotAA(x, y, c, color) if x2 < x1: swap(x1, x2) @@ -482,22 +482,22 @@ proc drawLineAA*(sur: PSurface, p1, p2: TPoint, color: TColor) = intery = intery + gradient inc(x) -proc fillSurface*(sur: PSurface, color: TColor) = +proc fillSurface*(sur: PSurface, color: Color) = ## Fills the entire surface with ``color``. - if sdl.FillRect(sur.s, nil, sur.createSdlColor(color)) == -1: + if sdl.fillRect(sur.s, nil, sur.createSdlColor(color)) == -1: raiseEGraphics() template withEvents*(surf: PSurface, event: expr, actions: stmt): stmt {. immediate.} = ## Simple template which creates an event loop. ``Event`` is the name of the ## variable containing the TEvent object. - while True: - var event: SDL.TEvent - if SDL.WaitEvent(addr(event)) == 1: + while true: + var event: sdl.TEvent + if sdl.waitEvent(addr(event)) == 1: actions -if sdl.Init(sdl.INIT_VIDEO) < 0: raiseEGraphics() -if sdl_ttf.Init() < 0: raiseEGraphics() +if sdl.init(sdl.INIT_VIDEO) < 0: raiseEGraphics() +if sdl_ttf.init() < 0: raiseEGraphics() when isMainModule: var surf = newScreenSurface(800, 600) @@ -539,19 +539,19 @@ when isMainModule: withEvents(surf, event): var eventp = addr(event) case event.kind: - of SDL.QUITEV: + of sdl.QUITEV: break - of SDL.KEYDOWN: - var evk = sdl.EvKeyboard(eventp) - if evk.keysym.sym == SDL.K_LEFT: + of sdl.KEYDOWN: + var evk = sdl.evKeyboard(eventp) + if evk.keysym.sym == sdl.K_LEFT: surf.drawHorLine(395, 300, 50, colBlack) echo("Drawing") - elif evk.keysym.sym == SDL.K_ESCAPE: + elif evk.keysym.sym == sdl.K_ESCAPE: break else: echo(evk.keysym.sym) - of SDL.MOUSEBUTTONDOWN: - var mbd = sdl.EvMouseButton(eventp) + of sdl.MOUSEBUTTONDOWN: + var mbd = sdl.evMouseButton(eventp) if mouseStartX == -1 or mouseStartY == -1: mouseStartX = int(mbd.x) mouseStartY = int(mbd.y) @@ -560,16 +560,16 @@ when isMainModule: mouseStartX = -1 mouseStartY = -1 - of SDL.MouseMotion: - var mm = sdl.EvMouseMotion(eventp) + of sdl.MOUSEMOTION: + var mm = sdl.evMouseMotion(eventp) if mouseStartX != -1 and mouseStartY != -1: surf.drawLineAA((mouseStartX, mouseStartY), (int(mm.x), int(mm.y)), colPurple) #echo(mm.x, " ", mm.y, " ", mm.yrel) else: - #echo(event.kind) + discard "echo(event.kind)" - SDL.UpdateRect(surf.s, 0, 0, 800, 600) + sdl.updateRect(surf.s, 0, 0, 800, 600) surf.writeToBMP("test.bmp") - SDL.Quit() + sdl.quit() diff --git a/lib/impure/osinfo_posix.nim b/lib/impure/osinfo_posix.nim index 4fde82012..1baff8c55 100644 --- a/lib/impure/osinfo_posix.nim +++ b/lib/impure/osinfo_posix.nim @@ -1,20 +1,21 @@ import posix, strutils, os -type - Tstatfs {.importc: "struct statfs64", - header: "<sys/statfs.h>", final, pure.} = object - f_type: int - f_bsize: int - f_blocks: int - f_bfree: int - f_bavail: int - f_files: int - f_ffree: int - f_fsid: int - f_namelen: int +when false: + type + Tstatfs {.importc: "struct statfs64", + header: "<sys/statfs.h>", final, pure.} = object + f_type: int + f_bsize: int + f_blocks: int + f_bfree: int + f_bavail: int + f_files: int + f_ffree: int + f_fsid: int + f_namelen: int -proc statfs(path: string, buf: var Tstatfs): int {. - importc, header: "<sys/vfs.h>".} + proc statfs(path: string, buf: var Tstatfs): int {. + importc, header: "<sys/vfs.h>".} proc getSystemVersion*(): string = @@ -23,7 +24,7 @@ proc getSystemVersion*(): string = var unix_info: TUtsname if uname(unix_info) != 0: - os.OSError() + os.raiseOSError(osLastError()) if $unix_info.sysname == "Linux": # Linux diff --git a/lib/impure/osinfo_win.nim b/lib/impure/osinfo_win.nim index 572e50273..f423a34a3 100644 --- a/lib/impure/osinfo_win.nim +++ b/lib/impure/osinfo_win.nim @@ -375,7 +375,7 @@ proc getFileSize*(file: string): BiggestInt = var hFile = findFirstFileA(file, fileData) if hFile == INVALID_HANDLE_VALUE: - raise newException(EIO, $getLastError()) + raise newException(IOError, $getLastError()) return fileData.nFileSizeLow @@ -386,10 +386,10 @@ proc getDiskFreeSpaceEx*(lpDirectoryName: cstring, lpFreeBytesAvailableToCaller, proc getPartitionInfo*(partition: string): TPartitionInfo = ## Retrieves partition info, for example ``partition`` may be ``"C:\"`` - var FreeBytes, TotalBytes, TotalFreeBytes: TFiletime - var res = getDiskFreeSpaceEx(r"C:\", FreeBytes, TotalBytes, - TotalFreeBytes) - return (FreeBytes, TotalBytes) + var freeBytes, totalBytes, totalFreeBytes: TFiletime + discard getDiskFreeSpaceEx(r"C:\", freeBytes, totalBytes, + totalFreeBytes) + return (freeBytes, totalBytes) when isMainModule: var r = getMemoryInfo() diff --git a/lib/impure/rdstdin.nim b/lib/impure/rdstdin.nim index 1037d3bda..07ef13fd9 100644 --- a/lib/impure/rdstdin.nim +++ b/lib/impure/rdstdin.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -15,13 +15,13 @@ when defined(Windows): proc readLineFromStdin*(prompt: string): TaintedString {. - tags: [FReadIO, FWriteIO].} = + tags: [ReadIOEffect, WriteIOEffect].} = ## Reads a line from stdin. stdout.write(prompt) result = readLine(stdin) proc readLineFromStdin*(prompt: string, line: var TaintedString): bool {. - tags: [FReadIO, FWriteIO].} = + tags: [ReadIOEffect, WriteIOEffect].} = ## Reads a `line` from stdin. `line` must not be ## ``nil``! May throw an IO exception. ## A line of text may be delimited by ``CR``, ``LF`` or @@ -35,7 +35,7 @@ else: import readline, history proc readLineFromStdin*(prompt: string): TaintedString {. - tags: [FReadIO, FWriteIO].} = + tags: [ReadIOEffect, WriteIOEffect].} = var buffer = readline.readLine(prompt) if isNil(buffer): quit(0) result = TaintedString($buffer) @@ -44,7 +44,7 @@ else: readline.free(buffer) proc readLineFromStdin*(prompt: string, line: var TaintedString): bool {. - tags: [FReadIO, FWriteIO].} = + tags: [ReadIOEffect, WriteIOEffect].} = var buffer = readline.readLine(prompt) if isNil(buffer): quit(0) line = TaintedString($buffer) diff --git a/lib/impure/re.nim b/lib/impure/re.nim index ac07b2d6b..6e3a69c62 100644 --- a/lib/impure/re.nim +++ b/lib/impure/re.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## Regular expression support for Nimrod. Consider using the pegs module +## Regular expression support for Nim. Consider using the pegs module ## instead. ## This module is implemented by providing a wrapper around the ## `PRCE (Perl-Compatible Regular Expressions) <http://www.pcre.org>`_ @@ -28,7 +28,7 @@ const ## More subpatterns cannot be captured! type - TRegexFlag* = enum ## options for regular expressions + RegexFlag* = enum ## options for regular expressions reIgnoreCase = 0, ## do caseless matching reMultiLine = 1, ## ``^`` and ``$`` match newlines within data reDotAll = 2, ## ``.`` matches anything including NL @@ -36,17 +36,20 @@ type reStudy = 4 ## study the expression (may be omitted if the ## expression will be used only once) - TRegexDesc {.pure, final.} = object + RegexDesc = object h: PPcre e: ptr TExtra - TRegex* = ref TRegexDesc ## a compiled regular expression + Regex* = ref RegexDesc ## a compiled regular expression - EInvalidRegEx* = object of EInvalidValue + RegexError* = object of ValueError ## is raised if the pattern is no valid regular expression. +{.deprecated: [TRegexFlag: RegexFlag, TRegexDesc: RegexDesc, TRegex: Regex, + EInvalidRegEx: RegexError].} + proc raiseInvalidRegex(msg: string) {.noinline, noreturn.} = - var e: ref EInvalidRegEx + var e: ref RegexError new(e) e.msg = msg raise e @@ -55,11 +58,11 @@ proc rawCompile(pattern: string, flags: cint): PPcre = var msg: cstring offset: cint - result = pcre.Compile(pattern, flags, addr(msg), addr(offset), nil) + result = pcre.compile(pattern, flags, addr(msg), addr(offset), nil) if result == nil: raiseInvalidRegex($msg & "\n" & pattern & "\n" & repeatChar(offset) & "^\n") -proc finalizeRegEx(x: TRegex) = +proc finalizeRegEx(x: Regex) = # XXX This is a hack, but PCRE does not export its "free" function properly. # Sigh. The hack relies on PCRE's implementation (see ``pcre_get.c``). # Fortunately the implementation is unlikely to change. @@ -67,8 +70,8 @@ proc finalizeRegEx(x: TRegex) = if not isNil(x.e): pcre.free_substring(cast[cstring](x.e)) -proc re*(s: string, flags = {reExtended, reStudy}): TRegex = - ## Constructor of regular expressions. Note that Nimrod's +proc re*(s: string, flags = {reExtended, reStudy}): Regex = + ## Constructor of regular expressions. Note that Nim's ## extended raw string literals support this syntax ``re"[abc]"`` as ## a short form for ``re(r"[abc]")``. new(result, finalizeRegEx) @@ -78,39 +81,39 @@ proc re*(s: string, flags = {reExtended, reStudy}): TRegex = result.e = pcre.study(result.h, 0, msg) if not isNil(msg): raiseInvalidRegex($msg) -proc matchOrFind(s: string, pattern: TRegex, matches: var openArray[string], +proc matchOrFind(s: string, pattern: Regex, matches: var openArray[string], start, flags: cint): cint = var - rawMatches: array[0..maxSubpatterns * 3 - 1, cint] - res = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, start, flags, - cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3) + rawMatches: array[0..MaxSubpatterns * 3 - 1, cint] + res = pcre.exec(pattern.h, pattern.e, s, len(s).cint, start, flags, + cast[ptr cint](addr(rawMatches)), MaxSubpatterns * 3) if res < 0'i32: return res for i in 1..int(res)-1: var a = rawMatches[i * 2] var b = rawMatches[i * 2 + 1] if a >= 0'i32: matches[i-1] = substr(s, int(a), int(b)-1) - else: matches[i-1] = "" + else: matches[i-1] = nil return rawMatches[1] - rawMatches[0] -proc findBounds*(s: string, pattern: TRegex, matches: var openArray[string], +proc findBounds*(s: string, pattern: Regex, matches: var openArray[string], start = 0): tuple[first, last: int] = ## returns the starting position and end position of `pattern` in `s` ## and the captured ## substrings in the array `matches`. If it does not match, nothing ## is written into `matches` and ``(-1,0)`` is returned. var - rawMatches: array[0..maxSubpatterns * 3 - 1, cint] - res = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, start.cint, 0'i32, - cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3) + rawMatches: array[0..MaxSubpatterns * 3 - 1, cint] + res = pcre.exec(pattern.h, pattern.e, s, len(s).cint, start.cint, 0'i32, + cast[ptr cint](addr(rawMatches)), MaxSubpatterns * 3) if res < 0'i32: return (-1, 0) for i in 1..int(res)-1: var a = rawMatches[i * 2] var b = rawMatches[i * 2 + 1] if a >= 0'i32: matches[i-1] = substr(s, int(a), int(b)-1) - else: matches[i-1] = "" + else: matches[i-1] = nil return (rawMatches[0].int, rawMatches[1].int - 1) -proc findBounds*(s: string, pattern: TRegex, +proc findBounds*(s: string, pattern: Regex, matches: var openArray[tuple[first, last: int]], start = 0): tuple[first, last: int] = ## returns the starting position and end position of ``pattern`` in ``s`` @@ -118,9 +121,9 @@ proc findBounds*(s: string, pattern: TRegex, ## If it does not match, nothing is written into `matches` and ## ``(-1,0)`` is returned. var - rawMatches: array[0..maxSubpatterns * 3 - 1, cint] - res = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, start.cint, 0'i32, - cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3) + rawMatches: array[0..MaxSubpatterns * 3 - 1, cint] + res = pcre.exec(pattern.h, pattern.e, s, len(s).cint, start.cint, 0'i32, + cast[ptr cint](addr(rawMatches)), MaxSubpatterns * 3) if res < 0'i32: return (-1, 0) for i in 1..int(res)-1: var a = rawMatches[i * 2] @@ -129,25 +132,25 @@ proc findBounds*(s: string, pattern: TRegex, else: matches[i-1] = (-1,0) return (rawMatches[0].int, rawMatches[1].int - 1) -proc findBounds*(s: string, pattern: TRegex, +proc findBounds*(s: string, pattern: Regex, start = 0): tuple[first, last: int] = ## returns the starting position of `pattern` in `s`. If it does not ## match, ``(-1,0)`` is returned. var rawMatches: array[0..3 - 1, cint] - res = pcre.Exec(pattern.h, nil, s, len(s).cint, start.cint, 0'i32, + res = pcre.exec(pattern.h, nil, s, len(s).cint, start.cint, 0'i32, cast[ptr cint](addr(rawMatches)), 3) if res < 0'i32: return (int(res), 0) return (int(rawMatches[0]), int(rawMatches[1]-1)) -proc matchOrFind(s: string, pattern: TRegex, start, flags: cint): cint = - var rawMatches: array [0..maxSubpatterns * 3 - 1, cint] - result = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, start, flags, - cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3) +proc matchOrFind(s: string, pattern: Regex, start, flags: cint): cint = + var rawMatches: array [0..MaxSubpatterns * 3 - 1, cint] + result = pcre.exec(pattern.h, pattern.e, s, len(s).cint, start, flags, + cast[ptr cint](addr(rawMatches)), MaxSubpatterns * 3) if result >= 0'i32: result = rawMatches[1] - rawMatches[0] -proc match*(s: string, pattern: TRegex, matches: var openArray[string], +proc match*(s: string, pattern: Regex, matches: var openArray[string], start = 0): bool = ## returns ``true`` if ``s[start..]`` matches the ``pattern`` and ## the captured substrings in the array ``matches``. If it does not @@ -156,67 +159,67 @@ proc match*(s: string, pattern: TRegex, matches: var openArray[string], return matchOrFind(s, pattern, matches, start.cint, pcre.ANCHORED) == cint(s.len - start) -proc match*(s: string, pattern: TRegex, start = 0): bool = +proc match*(s: string, pattern: Regex, start = 0): bool = ## returns ``true`` if ``s[start..]`` matches the ``pattern``. return matchOrFind(s, pattern, start.cint, pcre.ANCHORED) == cint(s.len-start) -proc matchLen*(s: string, pattern: TRegex, matches: var openArray[string], +proc matchLen*(s: string, pattern: Regex, matches: var openArray[string], start = 0): int = ## the same as ``match``, but it returns the length of the match, ## if there is no match, -1 is returned. Note that a match length ## of zero can happen. return matchOrFind(s, pattern, matches, start.cint, pcre.ANCHORED) -proc matchLen*(s: string, pattern: TRegex, start = 0): int = +proc matchLen*(s: string, pattern: Regex, start = 0): int = ## the same as ``match``, but it returns the length of the match, ## if there is no match, -1 is returned. Note that a match length ## of zero can happen. return matchOrFind(s, pattern, start.cint, pcre.ANCHORED) -proc find*(s: string, pattern: TRegex, matches: var openArray[string], +proc find*(s: string, pattern: Regex, matches: var openArray[string], start = 0): int = ## returns the starting position of ``pattern`` in ``s`` and the captured ## substrings in the array ``matches``. If it does not match, nothing ## is written into ``matches`` and -1 is returned. var - rawMatches: array[0..maxSubpatterns * 3 - 1, cint] - res = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, start.cint, 0'i32, - cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3) + rawMatches: array[0..MaxSubpatterns * 3 - 1, cint] + res = pcre.exec(pattern.h, pattern.e, s, len(s).cint, start.cint, 0'i32, + cast[ptr cint](addr(rawMatches)), MaxSubpatterns * 3) if res < 0'i32: return res for i in 1..int(res)-1: var a = rawMatches[i * 2] var b = rawMatches[i * 2 + 1] if a >= 0'i32: matches[i-1] = substr(s, int(a), int(b)-1) - else: matches[i-1] = "" + else: matches[i-1] = nil return rawMatches[0] -proc find*(s: string, pattern: TRegex, start = 0): int = +proc find*(s: string, pattern: Regex, start = 0): int = ## returns the starting position of ``pattern`` in ``s``. If it does not ## match, -1 is returned. var rawMatches: array[0..3 - 1, cint] - res = pcre.Exec(pattern.h, nil, s, len(s).cint, start.cint, 0'i32, + res = pcre.exec(pattern.h, nil, s, len(s).cint, start.cint, 0'i32, cast[ptr cint](addr(rawMatches)), 3) if res < 0'i32: return res return rawMatches[0] -iterator findAll*(s: string, pattern: TRegex, start = 0): string = +iterator findAll*(s: string, pattern: Regex, start = 0): string = ## Yields all matching *substrings* of `s` that match `pattern`. ## ## Note that since this is an iterator you should not modify the string you ## are iterating over: bad things could happen. var i = int32(start) - var rawMatches: array[0..maxSubpatterns * 3 - 1, cint] + var rawMatches: array[0..MaxSubpatterns * 3 - 1, cint] while true: - let res = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, i, 0'i32, - cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3) + let res = pcre.exec(pattern.h, pattern.e, s, len(s).cint, i, 0'i32, + cast[ptr cint](addr(rawMatches)), MaxSubpatterns * 3) if res < 0'i32: break let a = rawMatches[0] let b = rawMatches[1] yield substr(s, int(a), int(b)-1) i = b -proc findAll*(s: string, pattern: TRegex, start = 0): seq[string] = +proc findAll*(s: string, pattern: Regex, start = 0): seq[string] = ## returns all matching *substrings* of `s` that match `pattern`. ## If it does not match, @[] is returned. accumulateResult(findAll(s, pattern, start)) @@ -224,11 +227,11 @@ proc findAll*(s: string, pattern: TRegex, start = 0): seq[string] = when not defined(nimhygiene): {.pragma: inject.} -template `=~` *(s: string, pattern: TRegex): expr = +template `=~` *(s: string, pattern: Regex): expr = ## This calls ``match`` with an implicit declared ``matches`` array that ## can be used in the scope of the ``=~`` call: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## if line =~ re"\s*(\w+)\s*\=\s*(\w+)": ## # matches a key=value pair: @@ -242,41 +245,41 @@ template `=~` *(s: string, pattern: TRegex): expr = ## else: ## echo("syntax error") ## - bind maxSubPatterns + bind MaxSubPatterns when not declaredInScope(matches): var matches {.inject.}: array[0..MaxSubpatterns-1, string] match(s, pattern, matches) # ------------------------- more string handling ------------------------------ -proc contains*(s: string, pattern: TRegex, start = 0): bool = +proc contains*(s: string, pattern: Regex, start = 0): bool = ## same as ``find(s, pattern, start) >= 0`` return find(s, pattern, start) >= 0 -proc contains*(s: string, pattern: TRegex, matches: var openArray[string], +proc contains*(s: string, pattern: Regex, matches: var openArray[string], start = 0): bool = ## same as ``find(s, pattern, matches, start) >= 0`` return find(s, pattern, matches, start) >= 0 -proc startsWith*(s: string, prefix: TRegex): bool = +proc startsWith*(s: string, prefix: Regex): bool = ## returns true if `s` starts with the pattern `prefix` result = matchLen(s, prefix) >= 0 -proc endsWith*(s: string, suffix: TRegex): bool = +proc endsWith*(s: string, suffix: Regex): bool = ## returns true if `s` ends with the pattern `prefix` for i in 0 .. s.len-1: if matchLen(s, suffix, i) == s.len - i: return true -proc replace*(s: string, sub: TRegex, by = ""): string = +proc replace*(s: string, sub: Regex, by = ""): string = ## Replaces `sub` in `s` by the string `by`. Captures cannot be ## accessed in `by`. Examples: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "var1=key; var2=key2".replace(re"(\w+)'='(\w+)") ## ## Results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## "; " result = "" @@ -289,24 +292,26 @@ proc replace*(s: string, sub: TRegex, by = ""): string = prev = match.last + 1 add(result, substr(s, prev)) -proc replacef*(s: string, sub: TRegex, by: string): string = +proc replacef*(s: string, sub: Regex, by: string): string = ## Replaces `sub` in `s` by the string `by`. Captures can be accessed in `by` ## with the notation ``$i`` and ``$#`` (see strutils.`%`). Examples: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "var1=key; var2=key2".replacef(re"(\w+)'='(\w+)", "$1<-$2$2") ## ## Results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## "var1<-keykey; val2<-key2key2" result = "" - var caps: array[0..maxSubpatterns-1, string] + var caps: array[0..MaxSubpatterns-1, string] var prev = 0 while true: var match = findBounds(s, sub, caps, prev) if match.first < 0: break + assert result != nil + assert s != nil add(result, substr(s, prev, match.first-1)) addf(result, by, caps) prev = match.last + 1 @@ -314,7 +319,7 @@ proc replacef*(s: string, sub: TRegex, by: string): string = when false: result = "" var i = 0 - var caps: array[0..maxSubpatterns-1, string] + var caps: array[0..MaxSubpatterns-1, string] while i < s.len: var x = matchLen(s, sub, caps, i) if x <= 0: @@ -327,12 +332,12 @@ proc replacef*(s: string, sub: TRegex, by: string): string = add(result, substr(s, i)) proc parallelReplace*(s: string, subs: openArray[ - tuple[pattern: TRegex, repl: string]]): string = + tuple[pattern: Regex, repl: string]]): string = ## Returns a modified copy of `s` with the substitutions in `subs` ## applied in parallel. result = "" var i = 0 - var caps: array[0..maxSubpatterns-1, string] + var caps: array[0..MaxSubpatterns-1, string] while i < s.len: block searchSubs: for j in 0..high(subs): @@ -347,26 +352,26 @@ proc parallelReplace*(s: string, subs: openArray[ add(result, substr(s, i)) proc transformFile*(infile, outfile: string, - subs: openArray[tuple[pattern: TRegex, repl: string]]) = + subs: openArray[tuple[pattern: Regex, repl: string]]) = ## reads in the file `infile`, performs a parallel replacement (calls ## `parallelReplace`) and writes back to `outfile`. Raises ``EIO`` if an ## error occurs. This is supposed to be used for quick scripting. var x = readFile(infile).string writeFile(outfile, x.parallelReplace(subs)) -iterator split*(s: string, sep: TRegex): string = +iterator split*(s: string, sep: Regex): string = ## Splits the string `s` into substrings. ## ## Substrings are separated by the regular expression `sep`. ## Examples: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for word in split("00232this02939is39an22example111", re"\d+"): ## writeln(stdout, word) ## ## Results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "this" ## "is" ## "an" @@ -386,7 +391,7 @@ iterator split*(s: string, sep: TRegex): string = if first < last: yield substr(s, first, last-1) -proc split*(s: string, sep: TRegex): seq[string] = +proc split*(s: string, sep: Regex): seq[string] = ## Splits the string `s` into substrings. accumulateResult(split(s, sep)) @@ -447,6 +452,14 @@ when isMainModule: assert matches[1] == "abc" else: assert false + + if "abc" =~ re"(cba)?.*": + assert matches[0] == nil + else: assert false + + if "abc" =~ re"().*": + assert matches[0] == "" + else: assert false assert "var1=key; var2=key2".endsWith(re"\w+=\w+") assert("var1=key; var2=key2".replacef(re"(\w+)=(\w+)", "$1<-$2$2") == diff --git a/lib/impure/ssl.nim b/lib/impure/ssl.nim index 54d524c7b..bb7cfc0d3 100644 --- a/lib/impure/ssl.nim +++ b/lib/impure/ssl.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Dominik Picheta # # See the file "copying.txt", included in this @@ -8,31 +8,31 @@ # ## This module provides an easy to use sockets-style -## nimrod interface to the OpenSSL library. +## nim interface to the OpenSSL library. {.deprecated.} import openssl, strutils, os type - TSecureSocket* {.final.} = object - ssl: PSSL - bio: PBIO + TSecureSocket* = object + ssl: SslPtr + bio: BIO proc connect*(sock: var TSecureSocket, address: string, - port: int): Int = + port: int): int = ## Connects to the specified `address` on the specified `port`. ## Returns the result of the certificate validation. SslLoadErrorStrings() ERR_load_BIO_strings() if SSL_library_init() != 1: - OSError() + raiseOSError(osLastError()) var ctx = SSL_CTX_new(SSLv23_client_method()) if ctx == nil: ERR_print_errors_fp(stderr) - OSError() + raiseOSError(osLastError()) #if SSL_CTX_load_verify_locations(ctx, # "/tmp/openssl-0.9.8e/certs/vsign1.pem", NIL) == 0: @@ -41,14 +41,14 @@ proc connect*(sock: var TSecureSocket, address: string, sock.bio = BIO_new_ssl_connect(ctx) if BIO_get_ssl(sock.bio, addr(sock.ssl)) == 0: - OSError() + raiseOSError(osLastError()) if BIO_set_conn_hostname(sock.bio, address & ":" & $port) != 1: - OSError() + raiseOSError(osLastError()) if BIO_do_connect(sock.bio) <= 0: ERR_print_errors_fp(stderr) - OSError() + raiseOSError(osLastError()) result = SSL_get_verify_result(sock.ssl) @@ -57,30 +57,30 @@ proc recvLine*(sock: TSecureSocket, line: var TaintedString): bool = ## Returns false when no data is available to be read. ## `Line` must be initialized and not nil! setLen(line.string, 0) - while True: + while true: var c: array[0..0, char] var n = BIO_read(sock.bio, c, c.len.cint) - if n <= 0: return False + if n <= 0: return false if c[0] == '\r': n = BIO_read(sock.bio, c, c.len.cint) if n > 0 and c[0] == '\L': - return True + return true elif n <= 0: - return False - elif c[0] == '\L': return True + return false + elif c[0] == '\L': return true add(line.string, c) proc send*(sock: TSecureSocket, data: string) = ## Writes `data` to the socket. if BIO_write(sock.bio, data, data.len.cint) <= 0: - OSError() + raiseOSError(osLastError()) proc close*(sock: TSecureSocket) = ## Closes the socket if BIO_free(sock.bio) <= 0: ERR_print_errors_fp(stderr) - OSError() + raiseOSError(osLastError()) when isMainModule: var s: TSecureSocket diff --git a/lib/impure/web.nim b/lib/impure/web.nim deleted file mode 100644 index 5f04422d1..000000000 --- a/lib/impure/web.nim +++ /dev/null @@ -1,63 +0,0 @@ -# -# -# Nimrod's Runtime Library -# (c) Copyright 2012 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## This module contains simple high-level procedures for dealing with the -## web. Use cases: -## -## * requesting URLs -## * sending and retrieving emails -## * sending and retrieving files from an FTP server -## -## Currently only requesting URLs is implemented. The implementation depends -## on the libcurl library! -## -## **Deprecated since version 0.8.8:** Use the -## `httpclient <httpclient.html>`_ module instead. -## - -{.deprecated.} - -import libcurl, streams - -proc curlwrapperWrite(p: pointer, size, nmemb: int, - data: pointer): int {.cdecl.} = - var stream = cast[PStream](data) - stream.writeData(p, size*nmemb) - return size*nmemb - -proc URLretrieveStream*(url: string): PStream = - ## retrieves the given `url` and returns a stream which one can read from to - ## obtain the contents. Returns nil if an error occurs. - result = newStringStream() - var hCurl = easy_init() - if hCurl == nil: return nil - if easy_setopt(hCurl, OPT_URL, url) != E_OK: return nil - if easy_setopt(hCurl, OPT_WRITEFUNCTION, - curlwrapperWrite) != E_OK: return nil - if easy_setopt(hCurl, OPT_WRITEDATA, result) != E_OK: return nil - if easy_perform(hCurl) != E_OK: return nil - easy_cleanup(hCurl) - -proc URLretrieveString*(url: string): TaintedString = - ## retrieves the given `url` and returns the contents. Returns nil if an - ## error occurs. - var stream = newStringStream() - var hCurl = easy_init() - if hCurl == nil: return - if easy_setopt(hCurl, OPT_URL, url) != E_OK: return - if easy_setopt(hCurl, OPT_WRITEFUNCTION, - curlwrapperWrite) != E_OK: return - if easy_setopt(hCurl, OPT_WRITEDATA, stream) != E_OK: return - if easy_perform(hCurl) != E_OK: return - easy_cleanup(hCurl) - result = stream.data.TaintedString - -when isMainModule: - echo URLretrieveString("http://nimrod-code.org/") - diff --git a/lib/impure/zipfiles.nim b/lib/impure/zipfiles.nim index b9f89dda0..c22294061 100644 --- a/lib/impure/zipfiles.nim +++ b/lib/impure/zipfiles.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -13,18 +13,18 @@ import streams, libzip, times, os type - TZipArchive* = object of TObject ## represents a zip archive - mode: TFileMode + TZipArchive* = object of RootObj ## represents a zip archive + mode: FileMode w: PZip proc zipError(z: var TZipArchive) = - var e: ref EIO + var e: ref IOError new(e) e.msg = $zip_strerror(z.w) raise e -proc open*(z: var TZipArchive, filename: string, mode: TFileMode = fmRead): bool = +proc open*(z: var TZipArchive, filename: string, mode: FileMode = fmRead): bool = ## Opens a zip file for reading, writing or appending. All file modes are ## supported. Returns true iff successful, false otherwise. var err, flags: int32 @@ -57,7 +57,7 @@ proc addFile*(z: var TZipArchive, dest, src: string) = ## may contain a path that will be created. assert(z.mode != fmRead) if not fileExists(src): - raise newException(EIO, "File '" & src & "' does not exist") + raise newException(IOError, "File '" & src & "' does not exist") var zipsrc = zip_source_file(z.w, src, 0, -1) if zipsrc == nil: #echo("Dest: " & dest) @@ -74,7 +74,7 @@ proc addFile*(z: var TZipArchive, file: string) = proc mySourceCallback(state, data: pointer, len: int, cmd: TZipSourceCmd): int {.cdecl.} = - var src = cast[PStream](state) + var src = cast[Stream](state) case cmd of ZIP_SOURCE_OPEN: if src.setPositionImpl != nil: setPosition(src, 0) # reset @@ -95,7 +95,7 @@ proc mySourceCallback(state, data: pointer, len: int, of constZIP_SOURCE_FREE: GC_unref(src) else: assert(false) -proc addFile*(z: var TZipArchive, dest: string, src: PStream) = +proc addFile*(z: var TZipArchive, dest: string, src: Stream) = ## Adds a file named with `dest` to the archive `z`. `dest` ## may contain a path. The file's content is read from the `src` stream. assert(z.mode != fmRead) @@ -109,14 +109,14 @@ proc addFile*(z: var TZipArchive, dest: string, src: PStream) = # -------------- zip file stream --------------------------------------------- type - TZipFileStream = object of TStream + TZipFileStream = object of StreamObj f: PZipFile PZipFileStream* = ref TZipFileStream ## a reader stream of a file within a zip archive -proc fsClose(s: PStream) = zip_fclose(PZipFileStream(s).f) -proc fsReadData(s: PStream, buffer: pointer, bufLen: int): int = +proc fsClose(s: Stream) = zip_fclose(PZipFileStream(s).f) +proc fsReadData(s: Stream, buffer: pointer, bufLen: int): int = result = zip_fread(PZipFileStream(s).f, buffer, bufLen) proc newZipFileStream(f: PZipFile): PZipFileStream = @@ -146,7 +146,7 @@ iterator walkFiles*(z: var TZipArchive): string = inc(i) -proc extractFile*(z: var TZipArchive, srcFile: string, dest: PStream) = +proc extractFile*(z: var TZipArchive, srcFile: string, dest: Stream) = ## extracts a file from the zip archive `z` to the destination stream. var strm = getStream(z, srcFile) while true: diff --git a/lib/js/dom.nim b/lib/js/dom.nim index 951d8e835..91b260a64 100644 --- a/lib/js/dom.nim +++ b/lib/js/dom.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -14,7 +14,7 @@ when not defined(js) and not defined(Nimdoc): {.error: "This module only works on the JavaScript platform".} type - TEventHandlers* {.importc.} = object of TObject + TEventHandlers* {.importc.} = object of RootObj onabort*: proc (event: ref TEvent) {.nimcall.} onblur*: proc (event: ref TEvent) {.nimcall.} onchange*: proc (event: ref TEvent) {.nimcall.} @@ -124,14 +124,14 @@ type embeds*: seq[ref TEmbed] links*: seq[ref TLink] - TLink* {.importc.} = object of TObject + TLink* {.importc.} = object of RootObj name*: cstring target*: cstring text*: cstring x*: int y*: int - TEmbed* {.importc.} = object of TObject + TEmbed* {.importc.} = object of RootObj height*: int hspace*: int name*: cstring @@ -142,12 +142,12 @@ type play*: proc () {.nimcall.} stop*: proc () {.nimcall.} - TAnchor* {.importc.} = object of TObject + TAnchor* {.importc.} = object of RootObj name*: cstring text*: cstring x*, y*: int - TApplet* {.importc.} = object of TObject + TApplet* {.importc.} = object of RootObj TElement* {.importc.} = object of TEventHandlers checked*: bool @@ -166,7 +166,7 @@ type select*: proc () {.nimcall.} options*: seq[ref TOption] - TOption* {.importc.} = object of TObject + TOption* {.importc.} = object of RootObj defaultSelected*: bool selected*: bool selectedIndex*: int @@ -209,7 +209,7 @@ type DocumentTypeNode, DocumentFragmentNode, NotationNode - TNode* {.importc.} = object of TObject + TNode* {.importc.} = object of RootObj attributes*: seq[ref TNode] childNodes*: seq[ref TNode] data*: cstring @@ -241,7 +241,7 @@ type setAttributeNode*: proc (attr: ref TNode) {.nimcall.} style*: ref TStyle - TStyle* {.importc.} = object of TObject + TStyle* {.importc.} = object of RootObj background*: cstring backgroundAttachment*: cstring backgroundColor*: cstring @@ -335,7 +335,7 @@ type removeAttribute*: proc (attr: cstring, caseSensitive=false) {.nimcall.} setAttribute*: proc (attr, value: cstring, caseSensitive=false) {.nimcall.} - TEvent* {.importc.} = object of TObject + TEvent* {.importc.} = object of RootObj altKey*, ctrlKey*, shiftKey*: bool button*: int clientX*, clientY*: int @@ -373,7 +373,7 @@ type SUBMIT*: int UNLOAD*: int - TLocation* {.importc.} = object of TObject + TLocation* {.importc.} = object of RootObj hash*: cstring host*: cstring hostname*: cstring @@ -385,13 +385,13 @@ type reload*: proc () {.nimcall.} replace*: proc (s: cstring) {.nimcall.} - THistory* {.importc.} = object of TObject + THistory* {.importc.} = object of RootObj length*: int back*: proc () {.nimcall.} forward*: proc () {.nimcall.} go*: proc (pagesToJump: int) {.nimcall.} - TNavigator* {.importc.} = object of TObject + TNavigator* {.importc.} = object of RootObj appCodeName*: cstring appName*: cstring appVersion*: cstring @@ -402,18 +402,18 @@ type javaEnabled*: proc (): bool {.nimcall.} mimeTypes*: seq[ref TMimeType] - TPlugin* {.importc.} = object of TObject + TPlugin* {.importc.} = object of RootObj description*: cstring filename*: cstring name*: cstring - TMimeType* {.importc.} = object of TObject + TMimeType* {.importc.} = object of RootObj description*: cstring enabledPlugin*: ref TPlugin suffixes*: seq[cstring] `type`*: cstring - TLocationBar* {.importc.} = object of TObject + TLocationBar* {.importc.} = object of RootObj visible*: bool TMenuBar* = TLocationBar TPersonalBar* = TLocationBar @@ -421,7 +421,7 @@ type TToolBar* = TLocationBar TStatusBar* = TLocationBar - TScreen* {.importc.} = object of TObject + TScreen* {.importc.} = object of RootObj availHeight*: int availWidth*: int colorDepth*: int @@ -429,8 +429,8 @@ type pixelDepth*: int width*: int - TTimeOut* {.importc.} = object of TObject - TInterval* {.importc.} = object of TObject + TTimeOut* {.importc.} = object of RootObj + TInterval* {.importc.} = object of RootObj var window* {.importc, nodecl.}: ref TWindow @@ -446,7 +446,7 @@ proc unescape*(uri: cstring): cstring {.importc, nodecl.} proc decodeURIComponent*(uri: cstring): cstring {.importc, nodecl.} proc encodeURIComponent*(uri: cstring): cstring {.importc, nodecl.} -proc isFinite*(x: biggestFloat): bool {.importc, nodecl.} -proc isNaN*(x: biggestFloat): bool {.importc, nodecl.} -proc parseFloat*(s: cstring): biggestFloat {.importc, nodecl.} +proc isFinite*(x: BiggestFloat): bool {.importc, nodecl.} +proc isNaN*(x: BiggestFloat): bool {.importc, nodecl.} +proc parseFloat*(s: cstring): BiggestFloat {.importc, nodecl.} proc parseInt*(s: cstring): int {.importc, nodecl.} diff --git a/lib/nimbase.h b/lib/nimbase.h index b43094227..ac90081d8 100644 --- a/lib/nimbase.h +++ b/lib/nimbase.h @@ -1,7 +1,7 @@ /* - Nimrod's Runtime Library - (c) Copyright 2013 Andreas Rumpf + Nim's Runtime Library + (c) Copyright 2014 Andreas Rumpf See the file "copying.txt", included in this distribution, for details about the copyright. @@ -141,9 +141,11 @@ __clang__ /* these compilers have a fastcall so use it: */ # define N_NIMCALL(rettype, name) rettype __fastcall name # define N_NIMCALL_PTR(rettype, name) rettype (__fastcall *name) +# define N_RAW_NIMCALL __fastcall #else # define N_NIMCALL(rettype, name) rettype name /* no modifier */ # define N_NIMCALL_PTR(rettype, name) rettype (*name) +# define N_RAW_NIMCALL #endif #define N_CLOSURE(rettype, name) N_NIMCALL(rettype, name) @@ -175,9 +177,9 @@ __clang__ # define NIM_NIL 0 struct NimException { - NimException(struct E_Base* exp, const char* msg): exp(exp), msg(msg) {} + NimException(struct Exception* exp, const char* msg): exp(exp), msg(msg) {} - struct E_Base* exp; + struct Exception* exp; const char* msg; }; #else @@ -382,3 +384,9 @@ static inline void GCGuard (void *ptr) { asm volatile ("" :: "X" (ptr)); } "error: 'assert_numbits' declared as an array with a negative size" */ typedef int assert_numbits[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(NI)*8 ? 1 : -1]; #endif + +#ifdef __cplusplus +# define NIM_EXTERNC extern "C" +#else +# define NIM_EXTERNC +#endif diff --git a/lib/nimrtl.nim b/lib/nimrtl.nim index 68b7d7bd9..96dab1284 100644 --- a/lib/nimrtl.nim +++ b/lib/nimrtl.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/packages/docutils/highlite.nim b/lib/packages/docutils/highlite.nim index ff371f4e1..d4bd94e5e 100644 --- a/lib/packages/docutils/highlite.nim +++ b/lib/packages/docutils/highlite.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -23,7 +23,7 @@ type gtTagStart, gtTagEnd, gtKey, gtValue, gtRawData, gtAssembler, gtPreprocessor, gtDirective, gtCommand, gtRule, gtHyperlink, gtLabel, gtReference, gtOther - TGeneralTokenizer* = object of TObject + TGeneralTokenizer* = object of RootObj kind*: TTokenClass start*, length*: int buf: cstring @@ -31,11 +31,11 @@ type state: TTokenClass TSourceLanguage* = enum - langNone, langNimrod, langCpp, langCsharp, langC, langJava + langNone, langNim, langNimrod, langCpp, langCsharp, langC, langJava const - sourceLanguageToStr*: array[TSourceLanguage, string] = ["none", "Nimrod", - "C++", "C#", "C", "Java"] + sourceLanguageToStr*: array[TSourceLanguage, string] = ["none", + "Nim", "Nimrod", "C++", "C#", "C", "Java"] tokenClassToStr*: array[TTokenClass, string] = ["Eof", "None", "Whitespace", "DecNumber", "BinNumber", "HexNumber", "OctNumber", "FloatNumber", "Identifier", "Keyword", "StringLit", "LongStringLit", "CharLit", @@ -46,7 +46,7 @@ const # The following list comes from doc/keywords.txt, make sure it is # synchronized with this array by running the module itself as a test case. - nimrodKeywords = ["addr", "and", "as", "asm", "atomic", "bind", "block", + nimKeywords = ["addr", "and", "as", "asm", "atomic", "bind", "block", "break", "case", "cast", "const", "continue", "converter", "discard", "distinct", "div", "do", "elif", "else", "end", "enum", "except", "export", "finally", "for", "from", "generic", "if", "import", "in", "include", @@ -79,7 +79,7 @@ proc deinitGeneralTokenizer*(g: var TGeneralTokenizer) = discard proc nimGetKeyword(id: string): TTokenClass = - for k in nimrodKeywords: + for k in nimKeywords: if cmpIgnoreStyle(id, k) == 0: return gtKeyword result = gtIdentifier when false: @@ -542,7 +542,7 @@ proc javaNextToken(g: var TGeneralTokenizer) = proc getNextToken*(g: var TGeneralTokenizer, lang: TSourceLanguage) = case lang of langNone: assert false - of langNimrod: nimNextToken(g) + of langNim, langNimrod: nimNextToken(g) of langCpp: cppNextToken(g) of langCsharp: csharpNextToken(g) of langC: cNextToken(g) @@ -557,7 +557,7 @@ when isMainModule: keywords = input.split() break doAssert(not keywords.isNil, "Couldn't read any keywords.txt file!") - doAssert keywords.len == nimrodKeywords.len, "No matching lengths" + doAssert keywords.len == nimKeywords.len, "No matching lengths" for i in 0..keywords.len-1: - #echo keywords[i], " == ", nimrodKeywords[i] - doAssert keywords[i] == nimrodKeywords[i], "Unexpected keyword" + #echo keywords[i], " == ", nimKeywords[i] + doAssert keywords[i] == nimKeywords[i], "Unexpected keyword" diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim index 23459ade6..b21d51c93 100644 --- a/lib/packages/docutils/rst.nim +++ b/lib/packages/docutils/rst.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -17,7 +17,7 @@ import type TRstParseOption* = enum ## options for the RST parser roSkipPounds, ## skip ``#`` at line beginning (documentation - ## embedded in Nimrod comments) + ## embedded in Nim comments) roSupportSmilies, ## make the RST parser support smilies like ``:)`` roSupportRawDirective, ## support the ``raw`` directive (don't support ## it for sandboxing) @@ -66,8 +66,8 @@ proc getArgument*(n: PRstNode): string # ----------------------------- scanner part -------------------------------- const - SymChars: TCharSet = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF'} - SmileyStartChars: TCharSet = {':', ';', '8'} + SymChars: set[char] = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF'} + SmileyStartChars: set[char] = {':', ';', '8'} Smilies = { ":D": "icon_e_biggrin", ":-D": "icon_e_biggrin", @@ -111,21 +111,21 @@ const type TTokType = enum tkEof, tkIndent, tkWhite, tkWord, tkAdornment, tkPunct, tkOther - TToken{.final.} = object # a RST token + TToken = object # a RST token kind*: TTokType # the type of the token ival*: int # the indentation or parsed integer value symbol*: string # the parsed symbol as string line*, col*: int # line and column of the token TTokenSeq = seq[TToken] - TLexer = object of TObject + TLexer = object of RootObj buf*: cstring bufpos*: int line*, col*, baseIndent*: int skipPounds*: bool -proc getThing(L: var TLexer, tok: var TToken, s: TCharSet) = +proc getThing(L: var TLexer, tok: var TToken, s: set[char]) = tok.kind = tkWord tok.line = L.line tok.col = L.col @@ -273,7 +273,7 @@ type findFile: TFindFileHandler # How to find files. PSharedState = ref TSharedState - TRstParser = object of TObject + TRstParser = object of RootObj idx*: int tok*: TTokenSeq s*: PSharedState @@ -282,7 +282,7 @@ type line*, col*: int hasToc*: bool - EParseError* = object of EInvalidValue + EParseError* = object of ValueError proc whichMsgClass*(k: TMsgKind): TMsgClass = ## returns which message class `k` belongs to. diff --git a/lib/packages/docutils/rstast.nim b/lib/packages/docutils/rstast.nim index 8f946d973..52af672df 100644 --- a/lib/packages/docutils/rstast.nim +++ b/lib/packages/docutils/rstast.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -286,7 +286,7 @@ proc renderRstToRst*(n: PRstNode, result: var string) = var d: TRenderContext renderRstToRst(d, n, result) -proc renderRstToJsonNode(node: PRstNode): PJsonNode = +proc renderRstToJsonNode(node: PRstNode): JsonNode = result = %[ (key: "kind", val: %($node.kind)), @@ -295,7 +295,7 @@ proc renderRstToJsonNode(node: PRstNode): PJsonNode = if node.text != nil: result.add("text", %node.text) if node.sons != nil and len(node.sons) > 0: - var accm = newSeq[PJsonNode](len(node.sons)) + var accm = newSeq[JsonNode](len(node.sons)) for i, son in node.sons: accm[i] = renderRstToJsonNode(son) result.add("sons", %accm) diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index e9bae69b5..02b0afd2f 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -35,16 +35,16 @@ type outHtml, # output is HTML outLatex # output is Latex - TTocEntry{.final.} = object + TTocEntry = object n*: PRstNode refname*, header*: string TMetaEnum* = enum metaNone, metaTitle, metaSubtitle, metaAuthor, metaVersion - TRstGenerator* = object of TObject + TRstGenerator* = object of RootObj target*: TOutputTarget - config*: PStringTable + config*: StringTableRef splitAfter*: int # split too long entries in the TOC tocPart*: seq[TTocEntry] hasToc*: bool @@ -57,21 +57,21 @@ type currentSection: string ## \ ## Stores the empty string or the last headline/overline found in the rst ## document, so it can be used as a prettier name for term index generation. - seenIndexTerms: TTable[string, int] ## \ + seenIndexTerms: Table[string, int] ## \ ## Keeps count of same text index terms to generate different identifiers ## for hyperlinks. See renderIndexTerm proc for details. PDoc = var TRstGenerator ## Alias to type less. proc initRstGenerator*(g: var TRstGenerator, target: TOutputTarget, - config: PStringTable, filename: string, + config: StringTableRef, filename: string, options: TRstParseOptions, findFile: TFindFileHandler, msgHandler: TMsgHandler) = ## Initializes a ``TRstGenerator``. ## ## You need to call this before using a ``TRstGenerator`` with any other - ## procs in this module. Pass a non ``nil`` ``PStringTable`` value as + ## procs in this module. Pass a non ``nil`` ``StringTableRef`` value as ## `config` with parameters used by the HTML output generator. If you don't ## know what to use, pass the results of the `defaultConfig() ## <#defaultConfig>_` proc. @@ -103,7 +103,7 @@ proc initRstGenerator*(g: var TRstGenerator, target: TOutputTarget, ## ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## import packages/docutils/rstgen ## @@ -231,7 +231,7 @@ proc renderRstToOut*(d: var TRstGenerator, n: PRstNode, result: var string) ## ``initRstGenerator`` and parse a rst file with ``rstParse`` from the ## `packages/docutils/rst module <rst.html>`_. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## # ...configure gen and rst vars... ## var generatedHTML = "" @@ -341,13 +341,13 @@ proc renderIndexTerm*(d: PDoc, n: PRstNode, result: var string) = [id, term]) type - TIndexEntry {.pure, final.} = object + TIndexEntry = object keyword: string link: string linkTitle: string ## If not nil, contains a prettier text for the href linkDesc: string ## If not nil, the title attribute of the final href - TIndexedDocs {.pure, final.} = TTable[TIndexEntry, seq[TIndexEntry]] ## \ + TIndexedDocs = Table[TIndexEntry, seq[TIndexEntry]] ## \ ## Contains the index sequences for doc types. ## ## The key is a *fake* TIndexEntry which will contain the title of the @@ -597,7 +597,7 @@ proc mergeIndexes*(dir: string): string = ## Merges all index files in `dir` and returns the generated index as HTML. ## ## This proc will first scan `dir` for index files with the ``.idx`` - ## extension previously created by commands like ``nimrod doc|rst2html`` + ## extension previously created by commands like ``nim doc|rst2html`` ## which use the ``--index:on`` switch. These index files are the result of ## calls to `setIndexTerm() <#setIndexTerm>`_ and `writeIndexFile() ## <#writeIndexFile>`_, so they are simple tab separated files. @@ -768,7 +768,7 @@ proc renderCodeBlock(d: PDoc, n: PRstNode, result: var string) = var langstr = strip(getArgument(n)) var lang: TSourceLanguage if langstr == "": - lang = langNimrod # default language + lang = langNim # default language else: lang = getSourceLanguage(langstr) @@ -1011,7 +1011,7 @@ proc formatNamedVars*(frmt: string, varnames: openArray[string], inc(i) if i > L-1 or frmt[i] notin {'0'..'9'}: break if j > high(varvalues) + 1: - raise newException(EInvalidValue, "invalid index: " & $j) + raise newException(ValueError, "invalid index: " & $j) num = j add(result, varvalues[j - 1]) of 'A'..'Z', 'a'..'z', '\x80'..'\xFF': @@ -1024,13 +1024,13 @@ proc formatNamedVars*(frmt: string, varnames: openArray[string], if idx >= 0: add(result, varvalues[idx]) else: - raise newException(EInvalidValue, "unknown substitution var: " & id) + raise newException(ValueError, "unknown substitution var: " & id) of '{': var id = "" inc(i) while frmt[i] != '}': if frmt[i] == '\0': - raise newException(EInvalidValue, "'}' expected") + raise newException(ValueError, "'}' expected") add(id, frmt[i]) inc(i) inc(i) # skip } @@ -1038,9 +1038,9 @@ proc formatNamedVars*(frmt: string, varnames: openArray[string], var idx = getVarIdx(varnames, id) if idx >= 0: add(result, varvalues[idx]) else: - raise newException(EInvalidValue, "unknown substitution var: " & id) + raise newException(ValueError, "unknown substitution var: " & id) else: - raise newException(EInvalidValue, "unknown substitution: $" & $frmt[i]) + raise newException(ValueError, "unknown substitution: $" & $frmt[i]) var start = i while i < L: if frmt[i] != '$': inc(i) @@ -1048,10 +1048,10 @@ proc formatNamedVars*(frmt: string, varnames: openArray[string], if i-1 >= start: add(result, substr(frmt, start, i - 1)) -proc defaultConfig*(): PStringTable = +proc defaultConfig*(): StringTableRef = ## Returns a default configuration for embedded HTML generation. ## - ## The returned ``PStringTable`` contains the paramters used by the HTML + ## The returned ``StringTableRef`` contains the paramters used by the HTML ## engine to build the final output. For information on what these parameters ## are and their purpose, please look up the file ``config/nimdoc.cfg`` ## bundled with the compiler. @@ -1113,7 +1113,7 @@ $content # ---------- forum --------------------------------------------------------- proc rstToHtml*(s: string, options: TRstParseOptions, - config: PStringTable): string = + config: StringTableRef): string = ## Converts an input rst string into embeddable HTML. ## ## This convenience proc parses any input string using rst markup (it doesn't @@ -1123,7 +1123,7 @@ proc rstToHtml*(s: string, options: TRstParseOptions, ## work. For an explanation of the ``config`` parameter see the ## ``initRstGenerator`` proc. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## import packages/docutils/rstgen, strtabs ## ## echo rstToHtml("*Hello* **world**!", {}, diff --git a/lib/posix/epoll.nim b/lib/posix/epoll.nim index ee04348e8..5565a5ae8 100644 --- a/lib/posix/epoll.nim +++ b/lib/posix/epoll.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Dominik Picheta # # See the file "copying.txt", included in this diff --git a/lib/posix/inotify.nim b/lib/posix/inotify.nim index 852eb12fa..c6f0633ff 100644 --- a/lib/posix/inotify.nim +++ b/lib/posix/inotify.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Dominik Picheta # # See the file "copying.txt", included in this diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index 9334ceeae..deb120372 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -13,14 +13,14 @@ # net/if, sys/socket, sys/uio, netinet/in, netinet/tcp, netdb ## This is a raw POSIX interface module. It does not not provide any -## convenience: cstrings are used instead of proper Nimrod strings and +## convenience: cstrings are used instead of proper Nim strings and ## return codes indicate errors. If you want exceptions -## and a proper Nimrod-like interface, use the OS module or write a wrapper. +## and a proper Nim-like interface, use the OS module or write a wrapper. ## Coding conventions: ## ALL types are named the same as in the POSIX standard except that they start ## with 'T' or 'P' (if they are pointers) and without the '_t' suffix to be -## consistent with Nimrod conventions. If an identifier is a Nimrod keyword +## consistent with Nim conventions. If an identifier is a Nim keyword ## the \`identifier\` notation is used. ## ## This library relies on the header files of your C compiler. The @@ -29,7 +29,7 @@ {.deadCodeElim:on.} -from times import TTime +from times import Time const hasSpawnH = not defined(haiku) # should exist for every Posix system nowadays @@ -83,8 +83,11 @@ else: ## A type representing a directory stream. type - TSocketHandle* = distinct cint # The type used to represent socket descriptors + SocketHandle* = distinct cint # The type used to represent socket descriptors +{.deprecated: [TSocketHandle: SocketHandle].} + +type Tdirent* {.importc: "struct dirent", header: "<dirent.h>", final, pure.} = object ## dirent_t struct d_ino*: Tino ## File serial number. @@ -248,9 +251,9 @@ type ## For a typed memory object, the length in bytes. ## For other file types, the use of this field is ## unspecified. - st_atime*: TTime ## Time of last access. - st_mtime*: TTime ## Time of last data modification. - st_ctime*: TTime ## Time of last status change. + st_atime*: Time ## Time of last access. + st_mtime*: Time ## Time of last data modification. + st_ctime*: Time ## Time of last status change. st_blksize*: Tblksize ## A file system-specific preferred I/O block size ## for this object. In some file system types, this ## may vary from file to file. @@ -291,7 +294,7 @@ type tm_isdst*: cint ## Daylight Savings flag. Ttimespec* {.importc: "struct timespec", header: "<time.h>", final, pure.} = object ## struct timespec - tv_sec*: TTime ## Seconds. + tv_sec*: Time ## Seconds. tv_nsec*: int ## Nanoseconds. titimerspec* {.importc: "struct itimerspec", header: "<time.h>", final, pure.} = object ## struct itimerspec @@ -365,12 +368,12 @@ type sched_ss_max_repl*: cint ## Maximum pending replenishments for ## sporadic server. - Ttimeval* {.importc: "struct timeval", header: "<sys/select.h>", - final, pure.} = object ## struct timeval + Timeval* {.importc: "struct timeval", header: "<sys/select.h>", + final, pure.} = object ## struct timeval tv_sec*: int ## Seconds. tv_usec*: int ## Microseconds. TFdSet* {.importc: "fd_set", header: "<sys/select.h>", - final, pure.} = object + final, pure.} = object Tmcontext* {.importc: "mcontext_t", header: "<ucontext.h>", final, pure.} = object Tucontext* {.importc: "ucontext_t", header: "<ucontext.h>", @@ -403,11 +406,11 @@ when hasSpawnH: header: "<spawn.h>", final, pure.} = object type - TSocklen* {.importc: "socklen_t", header: "<sys/socket.h>".} = cuint + Socklen* {.importc: "socklen_t", header: "<sys/socket.h>".} = cuint TSa_Family* {.importc: "sa_family_t", header: "<sys/socket.h>".} = cint - TSockAddr* {.importc: "struct sockaddr", header: "<sys/socket.h>", - pure, final.} = object ## struct sockaddr + SockAddr* {.importc: "struct sockaddr", header: "<sys/socket.h>", + pure, final.} = object ## struct sockaddr sa_family*: TSa_Family ## Address family. sa_data*: array [0..255, char] ## Socket address (variable-length data). @@ -430,17 +433,17 @@ type Tmsghdr* {.importc: "struct msghdr", pure, final, header: "<sys/socket.h>".} = object ## struct msghdr msg_name*: pointer ## Optional address. - msg_namelen*: TSocklen ## Size of address. + msg_namelen*: Socklen ## Size of address. msg_iov*: ptr TIOVec ## Scatter/gather array. msg_iovlen*: cint ## Members in msg_iov. msg_control*: pointer ## Ancillary data; see below. - msg_controllen*: TSocklen ## Ancillary data buffer len. + msg_controllen*: Socklen ## Ancillary data buffer len. msg_flags*: cint ## Flags on received message. Tcmsghdr* {.importc: "struct cmsghdr", pure, final, header: "<sys/socket.h>".} = object ## struct cmsghdr - cmsg_len*: TSocklen ## Data byte count, including the cmsghdr. + cmsg_len*: Socklen ## Data byte count, including the cmsghdr. cmsg_level*: cint ## Originating protocol. cmsg_type*: cint ## Protocol-specific type. @@ -455,15 +458,15 @@ type TInAddrT* {.importc: "in_addr_t", pure, final, header: "<netinet/in.h>".} = int32 ## unsigned! - TInAddr* {.importc: "struct in_addr", pure, final, + InAddr* {.importc: "struct in_addr", pure, final, header: "<netinet/in.h>".} = object ## struct in_addr s_addr*: TInAddrScalar - Tsockaddr_in* {.importc: "struct sockaddr_in", pure, final, + Sockaddr_in* {.importc: "struct sockaddr_in", pure, final, header: "<netinet/in.h>".} = object ## struct sockaddr_in sin_family*: TSa_Family ## AF_INET. sin_port*: TInPort ## Port number. - sin_addr*: TInAddr ## IP address. + sin_addr*: InAddr ## IP address. TIn6Addr* {.importc: "struct in6_addr", pure, final, header: "<netinet/in.h>".} = object ## struct in6_addr @@ -482,7 +485,7 @@ type ipv6mr_multiaddr*: TIn6Addr ## IPv6 multicast address. ipv6mr_interface*: cint ## Interface index. - Thostent* {.importc: "struct hostent", pure, final, + Hostent* {.importc: "struct hostent", pure, final, header: "<netdb.h>".} = object ## struct hostent h_name*: cstring ## Official name of the host. h_aliases*: cstringArray ## A pointer to an array of pointers to @@ -512,8 +515,8 @@ type ## a null pointer. p_proto*: cint ## The protocol number. - TServent* {.importc: "struct servent", pure, final, - header: "<netdb.h>".} = object ## struct servent + Servent* {.importc: "struct servent", pure, final, + header: "<netdb.h>".} = object ## struct servent s_name*: cstring ## Official name of the service. s_aliases*: cstringArray ## A pointer to an array of pointers to ## alternative service names, terminated by @@ -523,16 +526,16 @@ type s_proto*: cstring ## The name of the protocol to use when ## contacting the service. - Taddrinfo* {.importc: "struct addrinfo", pure, final, + AddrInfo* {.importc: "struct addrinfo", pure, final, header: "<netdb.h>".} = object ## struct addrinfo ai_flags*: cint ## Input flags. ai_family*: cint ## Address family of socket. ai_socktype*: cint ## Socket type. ai_protocol*: cint ## Protocol of socket. - ai_addrlen*: TSocklen ## Length of socket address. - ai_addr*: ptr TSockAddr ## Socket address of socket. + ai_addrlen*: Socklen ## Length of socket address. + ai_addr*: ptr SockAddr ## Socket address of socket. ai_canonname*: cstring ## Canonical name of service location. - ai_next*: ptr Taddrinfo ## Pointer to next in list. + ai_next*: ptr AddrInfo ## Pointer to next in list. TPollfd* {.importc: "struct pollfd", pure, final, header: "<poll.h>".} = object ## struct pollfd @@ -542,6 +545,11 @@ type Tnfds* {.importc: "nfds_t", header: "<poll.h>".} = cint +{.deprecated: [TSockaddr_in: Sockaddr_in, TAddrinfo: AddrInfo, + TSockAddr: SockAddr, TSockLen: SockLen, TTimeval: Timeval, + Thostent: Hostent, TServent: Servent, + TInAddr: InAddr].} + var errno* {.importc, header: "<errno.h>".}: cint ## error variable h_errno* {.importc, header: "<netdb.h>".}: cint @@ -1756,7 +1764,7 @@ proc ntohl*(a1: int32): int32 {.importc, header: "<arpa/inet.h>".} proc ntohs*(a1: int16): int16 {.importc, header: "<arpa/inet.h>".} proc inet_addr*(a1: cstring): TInAddrT {.importc, header: "<arpa/inet.h>".} -proc inet_ntoa*(a1: TInAddr): cstring {.importc, header: "<arpa/inet.h>".} +proc inet_ntoa*(a1: InAddr): cstring {.importc, header: "<arpa/inet.h>".} proc inet_ntop*(a1: cint, a2: pointer, a3: cstring, a4: int32): cstring {. importc, header: "<arpa/inet.h>".} proc inet_pton*(a1: cint, a2: cstring, a3: pointer): cint {. @@ -1786,7 +1794,7 @@ proc dlopen*(a1: cstring, a2: cint): pointer {.importc, header: "<dlfcn.h>".} proc dlsym*(a1: pointer, a2: cstring): pointer {.importc, header: "<dlfcn.h>".} proc creat*(a1: cstring, a2: TMode): cint {.importc, header: "<fcntl.h>".} -proc fcntl*(a1: cint | TSocketHandle, a2: cint): cint {.varargs, importc, header: "<fcntl.h>".} +proc fcntl*(a1: cint | SocketHandle, a2: cint): cint {.varargs, importc, header: "<fcntl.h>".} proc open*(a1: cstring, a2: cint): cint {.varargs, importc, header: "<fcntl.h>".} proc posix_fadvise*(a1: cint, a2, a3: TOff, a4: cint): cint {. importc, header: "<fcntl.h>".} @@ -2050,7 +2058,7 @@ proc access*(a1: cstring, a2: cint): cint {.importc, header: "<unistd.h>".} proc alarm*(a1: cint): cint {.importc, header: "<unistd.h>".} proc chdir*(a1: cstring): cint {.importc, header: "<unistd.h>".} proc chown*(a1: cstring, a2: Tuid, a3: TGid): cint {.importc, header: "<unistd.h>".} -proc close*(a1: cint | TSocketHandle): cint {.importc, header: "<unistd.h>".} +proc close*(a1: cint | SocketHandle): cint {.importc, header: "<unistd.h>".} proc confstr*(a1: cint, a2: cstring, a3: int): int {.importc, header: "<unistd.h>".} proc crypt*(a1, a2: cstring): cstring {.importc, header: "<unistd.h>".} proc ctermid*(a1: cstring): cstring {.importc, header: "<unistd.h>".} @@ -2235,22 +2243,22 @@ proc clock_nanosleep*(a1: TClockId, a2: cint, a3: var Ttimespec, proc clock_settime*(a1: TClockId, a2: var Ttimespec): cint {. importc, header: "<time.h>".} -proc ctime*(a1: var TTime): cstring {.importc, header: "<time.h>".} -proc ctime_r*(a1: var TTime, a2: cstring): cstring {.importc, header: "<time.h>".} -proc difftime*(a1, a2: TTime): cdouble {.importc, header: "<time.h>".} +proc ctime*(a1: var Time): cstring {.importc, header: "<time.h>".} +proc ctime_r*(a1: var Time, a2: cstring): cstring {.importc, header: "<time.h>".} +proc difftime*(a1, a2: Time): cdouble {.importc, header: "<time.h>".} proc getdate*(a1: cstring): ptr Ttm {.importc, header: "<time.h>".} -proc gmtime*(a1: var TTime): ptr Ttm {.importc, header: "<time.h>".} -proc gmtime_r*(a1: var TTime, a2: var Ttm): ptr Ttm {.importc, header: "<time.h>".} -proc localtime*(a1: var TTime): ptr Ttm {.importc, header: "<time.h>".} -proc localtime_r*(a1: var TTime, a2: var Ttm): ptr Ttm {.importc, header: "<time.h>".} -proc mktime*(a1: var Ttm): TTime {.importc, header: "<time.h>".} -proc timegm*(a1: var Ttm): TTime {.importc, header: "<time.h>".} +proc gmtime*(a1: var Time): ptr Ttm {.importc, header: "<time.h>".} +proc gmtime_r*(a1: var Time, a2: var Ttm): ptr Ttm {.importc, header: "<time.h>".} +proc localtime*(a1: var Time): ptr Ttm {.importc, header: "<time.h>".} +proc localtime_r*(a1: var Time, a2: var Ttm): ptr Ttm {.importc, header: "<time.h>".} +proc mktime*(a1: var Ttm): Time {.importc, header: "<time.h>".} +proc timegm*(a1: var Ttm): Time {.importc, header: "<time.h>".} proc nanosleep*(a1, a2: var Ttimespec): cint {.importc, header: "<time.h>".} proc strftime*(a1: cstring, a2: int, a3: cstring, a4: var Ttm): int {.importc, header: "<time.h>".} proc strptime*(a1, a2: cstring, a3: var Ttm): cstring {.importc, header: "<time.h>".} -proc time*(a1: var TTime): TTime {.importc, header: "<time.h>".} +proc time*(a1: var Time): Time {.importc, header: "<time.h>".} proc timer_create*(a1: var TClockId, a2: var TsigEvent, a3: var Ttimer): cint {.importc, header: "<time.h>".} proc timer_delete*(a1: var Ttimer): cint {.importc, header: "<time.h>".} @@ -2330,14 +2338,15 @@ proc strerror*(errnum: cint): cstring {.importc, header: "<string.h>".} proc hstrerror*(herrnum: cint): cstring {.importc, header: "<netdb.h>".} proc FD_CLR*(a1: cint, a2: var TFdSet) {.importc, header: "<sys/select.h>".} -proc FD_ISSET*(a1: cint | TSocketHandle, a2: var TFdSet): cint {. +proc FD_ISSET*(a1: cint | SocketHandle, a2: var TFdSet): cint {. importc, header: "<sys/select.h>".} -proc FD_SET*(a1: cint | TSocketHandle, a2: var TFdSet) {.importc, header: "<sys/select.h>".} +proc FD_SET*(a1: cint | SocketHandle, a2: var TFdSet) {. + importc: "FD_SET", header: "<sys/select.h>".} proc FD_ZERO*(a1: var TFdSet) {.importc, header: "<sys/select.h>".} proc pselect*(a1: cint, a2, a3, a4: ptr TFdSet, a5: ptr Ttimespec, a6: var Tsigset): cint {.importc, header: "<sys/select.h>".} -proc select*(a1: cint | TSocketHandle, a2, a3, a4: ptr TFdSet, a5: ptr Ttimeval): cint {. +proc select*(a1: cint | SocketHandle, a2, a3, a4: ptr TFdSet, a5: ptr Timeval): cint {. importc, header: "<sys/select.h>".} when hasSpawnH: @@ -2413,48 +2422,48 @@ proc CMSG_FIRSTHDR*(mhdr: ptr Tmsghdr): ptr Tcmsghdr {. importc, header: "<sys/socket.h>".} const - INVALID_SOCKET* = TSocketHandle(-1) + INVALID_SOCKET* = SocketHandle(-1) -proc `==`*(x, y: TSocketHandle): bool {.borrow.} +proc `==`*(x, y: SocketHandle): bool {.borrow.} -proc accept*(a1: TSocketHandle, a2: ptr TSockAddr, a3: ptr TSocklen): TSocketHandle {. +proc accept*(a1: SocketHandle, a2: ptr SockAddr, a3: ptr Socklen): SocketHandle {. importc, header: "<sys/socket.h>".} -proc bindSocket*(a1: TSocketHandle, a2: ptr TSockAddr, a3: TSocklen): cint {. +proc bindSocket*(a1: SocketHandle, a2: ptr SockAddr, a3: Socklen): cint {. importc: "bind", header: "<sys/socket.h>".} ## is Posix's ``bind``, because ``bind`` is a reserved word -proc connect*(a1: TSocketHandle, a2: ptr TSockAddr, a3: TSocklen): cint {. +proc connect*(a1: SocketHandle, a2: ptr SockAddr, a3: Socklen): cint {. importc, header: "<sys/socket.h>".} -proc getpeername*(a1: TSocketHandle, a2: ptr TSockAddr, a3: ptr TSocklen): cint {. +proc getpeername*(a1: SocketHandle, a2: ptr SockAddr, a3: ptr Socklen): cint {. importc, header: "<sys/socket.h>".} -proc getsockname*(a1: TSocketHandle, a2: ptr TSockAddr, a3: ptr TSocklen): cint {. +proc getsockname*(a1: SocketHandle, a2: ptr SockAddr, a3: ptr Socklen): cint {. importc, header: "<sys/socket.h>".} -proc getsockopt*(a1: TSocketHandle, a2, a3: cint, a4: pointer, a5: ptr TSocklen): cint {. +proc getsockopt*(a1: SocketHandle, a2, a3: cint, a4: pointer, a5: ptr Socklen): cint {. importc, header: "<sys/socket.h>".} -proc listen*(a1: TSocketHandle, a2: cint): cint {. +proc listen*(a1: SocketHandle, a2: cint): cint {. importc, header: "<sys/socket.h>".} -proc recv*(a1: TSocketHandle, a2: pointer, a3: int, a4: cint): int {. +proc recv*(a1: SocketHandle, a2: pointer, a3: int, a4: cint): int {. importc, header: "<sys/socket.h>".} -proc recvfrom*(a1: TSocketHandle, a2: pointer, a3: int, a4: cint, - a5: ptr TSockAddr, a6: ptr TSocklen): int {. +proc recvfrom*(a1: SocketHandle, a2: pointer, a3: int, a4: cint, + a5: ptr SockAddr, a6: ptr Socklen): int {. importc, header: "<sys/socket.h>".} -proc recvmsg*(a1: TSocketHandle, a2: ptr Tmsghdr, a3: cint): int {. +proc recvmsg*(a1: SocketHandle, a2: ptr Tmsghdr, a3: cint): int {. importc, header: "<sys/socket.h>".} -proc send*(a1: TSocketHandle, a2: pointer, a3: int, a4: cint): int {. +proc send*(a1: SocketHandle, a2: pointer, a3: int, a4: cint): int {. importc, header: "<sys/socket.h>".} -proc sendmsg*(a1: TSocketHandle, a2: ptr Tmsghdr, a3: cint): int {. +proc sendmsg*(a1: SocketHandle, a2: ptr Tmsghdr, a3: cint): int {. importc, header: "<sys/socket.h>".} -proc sendto*(a1: TSocketHandle, a2: pointer, a3: int, a4: cint, a5: ptr TSockAddr, - a6: TSocklen): int {. +proc sendto*(a1: SocketHandle, a2: pointer, a3: int, a4: cint, a5: ptr SockAddr, + a6: Socklen): int {. importc, header: "<sys/socket.h>".} -proc setsockopt*(a1: TSocketHandle, a2, a3: cint, a4: pointer, a5: TSocklen): cint {. +proc setsockopt*(a1: SocketHandle, a2, a3: cint, a4: pointer, a5: Socklen): cint {. importc, header: "<sys/socket.h>".} -proc shutdown*(a1: TSocketHandle, a2: cint): cint {. +proc shutdown*(a1: SocketHandle, a2: cint): cint {. importc, header: "<sys/socket.h>".} -proc socket*(a1, a2, a3: cint): TSocketHandle {. +proc socket*(a1, a2, a3: cint): SocketHandle {. importc, header: "<sys/socket.h>".} proc sockatmark*(a1: cint): cint {. importc, header: "<sys/socket.h>".} @@ -2508,21 +2517,21 @@ proc endhostent*() {.importc, header: "<netdb.h>".} proc endnetent*() {.importc, header: "<netdb.h>".} proc endprotoent*() {.importc, header: "<netdb.h>".} proc endservent*() {.importc, header: "<netdb.h>".} -proc freeaddrinfo*(a1: ptr Taddrinfo) {.importc, header: "<netdb.h>".} +proc freeaddrinfo*(a1: ptr AddrInfo) {.importc, header: "<netdb.h>".} proc gai_strerror*(a1: cint): cstring {.importc, header: "<netdb.h>".} -proc getaddrinfo*(a1, a2: cstring, a3: ptr Taddrinfo, - a4: var ptr Taddrinfo): cint {.importc, header: "<netdb.h>".} +proc getaddrinfo*(a1, a2: cstring, a3: ptr AddrInfo, + a4: var ptr AddrInfo): cint {.importc, header: "<netdb.h>".} -proc gethostbyaddr*(a1: pointer, a2: TSocklen, a3: cint): ptr Thostent {. +proc gethostbyaddr*(a1: pointer, a2: Socklen, a3: cint): ptr Hostent {. importc, header: "<netdb.h>".} -proc gethostbyname*(a1: cstring): ptr Thostent {.importc, header: "<netdb.h>".} -proc gethostent*(): ptr Thostent {.importc, header: "<netdb.h>".} +proc gethostbyname*(a1: cstring): ptr Hostent {.importc, header: "<netdb.h>".} +proc gethostent*(): ptr Hostent {.importc, header: "<netdb.h>".} -proc getnameinfo*(a1: ptr TSockAddr, a2: TSocklen, - a3: cstring, a4: TSocklen, a5: cstring, - a6: TSocklen, a7: cint): cint {.importc, header: "<netdb.h>".} +proc getnameinfo*(a1: ptr SockAddr, a2: Socklen, + a3: cstring, a4: Socklen, a5: cstring, + a6: Socklen, a7: cint): cint {.importc, header: "<netdb.h>".} proc getnetbyaddr*(a1: int32, a2: cint): ptr Tnetent {.importc, header: "<netdb.h>".} proc getnetbyname*(a1: cstring): ptr Tnetent {.importc, header: "<netdb.h>".} @@ -2532,10 +2541,10 @@ proc getprotobyname*(a1: cstring): ptr TProtoent {.importc, header: "<netdb.h>". proc getprotobynumber*(a1: cint): ptr TProtoent {.importc, header: "<netdb.h>".} proc getprotoent*(): ptr TProtoent {.importc, header: "<netdb.h>".} -proc getservbyname*(a1, a2: cstring): ptr TServent {.importc, header: "<netdb.h>".} -proc getservbyport*(a1: cint, a2: cstring): ptr TServent {. +proc getservbyname*(a1, a2: cstring): ptr Servent {.importc, header: "<netdb.h>".} +proc getservbyport*(a1: cint, a2: cstring): ptr Servent {. importc, header: "<netdb.h>".} -proc getservent*(): ptr TServent {.importc, header: "<netdb.h>".} +proc getservent*(): ptr Servent {.importc, header: "<netdb.h>".} proc sethostent*(a1: cint) {.importc, header: "<netdb.h>".} proc setnetent*(a1: cint) {.importc, header: "<netdb.h>".} @@ -2548,7 +2557,7 @@ proc poll*(a1: ptr TPollfd, a2: Tnfds, a3: int): cint {. proc realpath*(name, resolved: cstring): cstring {. importc: "realpath", header: "<stdlib.h>".} -proc utimes*(path: cstring, times: ptr array [2, Ttimeval]): int {. +proc utimes*(path: cstring, times: ptr array [2, Timeval]): int {. importc: "utimes", header: "<sys/time.h>".} ## Sets file access and modification times. ## diff --git a/lib/prelude.nim b/lib/prelude.nim index 50b4d4092..940864207 100644 --- a/lib/prelude.nim +++ b/lib/prelude.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -10,12 +10,12 @@ ## This is an include file that simply imports common modules for your ## convenience: ## -## .. code-block:: nimrod +## .. code-block:: nim ## include prelude ## ## Same as: ## -## .. code-block:: nimrod +## .. code-block:: nim ## import os, strutils, times, parseutils, parseopt, hashes, tables, sets import os, strutils, times, parseutils, parseopt, hashes, tables, sets diff --git a/lib/pure/actors.nim b/lib/pure/actors.nim index 2d902debe..f2c50ce4c 100644 --- a/lib/pure/actors.nim +++ b/lib/pure/actors.nim @@ -1,19 +1,19 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## `Actor`:idx: support for Nimrod. An actor is implemented as a thread with +## `Actor`:idx: support for Nim. An actor is implemented as a thread with ## a channel as its inbox. This module requires the ``--threads:on`` ## command line switch. ## ## Example: ## -## .. code-block:: nimrod +## .. code-block:: nim ## ## var ## a: TActorPool[int, void] @@ -21,6 +21,11 @@ ## for i in 0 .. < 300: ## a.spawn(i, proc (x: int) {.thread.} = echo x) ## a.join() +## +## **Note**: This whole module is deprecated. Use `threadpool` and ``spawn`` +## instead. + +{.deprecated.} from os import sleep diff --git a/lib/pure/actors.nimrod.cfg b/lib/pure/actors.nim.cfg index c6bb9c545..c6bb9c545 100644 --- a/lib/pure/actors.nimrod.cfg +++ b/lib/pure/actors.nim.cfg diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim index 89c83a8a4..0358a9a81 100644 --- a/lib/pure/algorithm.nim +++ b/lib/pure/algorithm.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -10,10 +10,13 @@ ## This module implements some common generic algorithms. type - TSortOrder* = enum ## sort order + SortOrder* = enum ## sort order Descending, Ascending -proc `*`*(x: int, order: TSortOrder): int {.inline.} = +{.deprecated: [TSortOrder: SortOrder].} + + +proc `*`*(x: int, order: SortOrder): int {.inline.} = ## flips `x` if ``order == Descending``; ## if ``order == Ascending`` then `x` is returned. ## `x` is supposed to be the result of a comparator, ie ``< 0`` for @@ -69,7 +72,7 @@ proc smartBinarySearch*[T](a: openArray[T], key: T): int = const onlySafeCode = true -proc lowerBound*[T](a: openarray[T], key: T, cmp: proc(x,y: T): int {.closure.}): int = +proc lowerBound*[T](a: openArray[T], key: T, cmp: proc(x,y: T): int {.closure.}): int = ## same as binarySearch except that if key is not in `a` then this ## returns the location where `key` would be if it were. In other ## words if you have a sorted sequence and you call insert(thing, elm, lowerBound(thing, elm)) @@ -98,9 +101,9 @@ proc lowerBound*[T](a: openarray[T], key: T, cmp: proc(x,y: T): int {.closure.}) else: count = step -proc lowerBound*[T](a: openarray[T], key: T): int = lowerBound(a, key, cmp[T]) +proc lowerBound*[T](a: openArray[T], key: T): int = lowerBound(a, key, cmp[T]) proc merge[T](a, b: var openArray[T], lo, m, hi: int, - cmp: proc (x, y: T): int {.closure.}, order: TSortOrder) = + cmp: proc (x, y: T): int {.closure.}, order: SortOrder) = template `<-` (a, b: expr) = when false: a = b @@ -147,16 +150,16 @@ proc merge[T](a, b: var openArray[T], lo, m, hi: int, proc sort*[T](a: var openArray[T], cmp: proc (x, y: T): int {.closure.}, - order = TSortOrder.Ascending) = - ## Default Nimrod sort. The sorting is guaranteed to be stable and + order = SortOrder.Ascending) = + ## Default Nim sort. The sorting is guaranteed to be stable and ## the worst case is guaranteed to be O(n log n). ## The current implementation uses an iterative ## mergesort to achieve this. It uses a temporary sequence of - ## length ``a.len div 2``. Currently Nimrod does not support a + ## length ``a.len div 2``. Currently Nim does not support a ## sensible default argument for ``cmp``, so you have to provide one ## of your own. However, the ``system.cmp`` procs can be used: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## sort(myIntArray, system.cmp[int]) ## @@ -167,7 +170,7 @@ proc sort*[T](a: var openArray[T], ## You can inline adhoc comparison procs with the `do notation ## <manual.html#do-notation>`_. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## people.sort do (x, y: Person) -> int: ## result = cmp(x.surname, y.surname) @@ -184,7 +187,7 @@ proc sort*[T](a: var openArray[T], dec(m, s*2) s = s*2 -proc product*[T](x: openarray[seq[T]]): seq[seq[T]] = +proc product*[T](x: openArray[seq[T]]): seq[seq[T]] = ## produces the Cartesian product of the array. Warning: complexity ## may explode. result = @[] diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 0ea8ef43b..073cd3576 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Dominik Picheta # # See the file "copying.txt", included in this @@ -13,45 +13,143 @@ import os, oids, tables, strutils, macros, times import rawsockets, net -export TPort, TSocketFlags +export Port, SocketFlag #{.injectStmt: newGcInvariant().} ## AsyncDispatch -## ------------- +## ************* ## -## This module implements a brand new dispatcher based on Futures. -## On Windows IOCP is used and on other operating systems the ``selectors`` -## module is used instead. +## This module implements asynchronous IO. This includes a dispatcher, +## a ``Future`` type implementation, and an ``async`` macro which allows +## asynchronous code to be written in a synchronous style with the ``await`` +## keyword. ## -## **Note:** This module is still largely experimental. +## The dispatcher acts as a kind of event loop. You must call ``poll`` on it +## (or a function which does so for you such as ``waitFor`` or ``runForever``) +## in order to poll for any outstanding events. The underlying implementation +## is based on epoll on Linux, IO Completion Ports on Windows and select on +## other operating systems. +## +## The ``poll`` function will not, on its own, return any events. Instead +## an appropriate ``Future`` object will be completed. A ``Future`` is a +## type which holds a value which is not yet available, but which *may* be +## available in the future. You can check whether a future is finished +## by using the ``finished`` function. When a future is finished it means that +## either the value that it holds is now available or it holds an error instead. +## The latter situation occurs when the operation to complete a future fails +## with an exception. You can distinguish between the two situations with the +## ``failed`` function. +## +## Future objects can also store a callback procedure which will be called +## automatically once the future completes. +## +## Futures therefore can be thought of as an implementation of the proactor +## pattern. In this +## pattern you make a request for an action, and once that action is fulfilled +## a future is completed with the result of that action. Requests can be +## made by calling the appropriate functions. For example: calling the ``recv`` +## function will create a request for some data to be read from a socket. The +## future which the ``recv`` function returns will then complete once the +## requested amount of data is read **or** an exception occurs. +## +## Code to read some data from a socket may look something like this: +## +## .. code-block::nim +## var future = socket.recv(100) +## future.callback = +## proc () = +## echo(future.read) +## +## All asynchronous functions returning a ``Future`` will not block. They +## will not however return immediately. An asynchronous function will have +## code which will be executed before an asynchronous request is made, in most +## cases this code sets up the request. +## +## In the above example, the ``recv`` function will return a brand new +## ``Future`` instance once the request for data to be read from the socket +## is made. This ``Future`` instance will complete once the requested amount +## of data is read, in this case it is 100 bytes. The second line sets a +## callback on this future which will be called once the future completes. +## All the callback does is write the data stored in the future to ``stdout``. +## The ``read`` function is used for this and it checks whether the future +## completes with an error for you (if it did it will simply raise the +## error), if there is no error however it returns the value of the future. +## +## Asynchronous procedures +## ----------------------- +## +## Asynchronous procedures remove the pain of working with callbacks. They do +## this by allowing you to write asynchronous code the same way as you would +## write synchronous code. +## +## An asynchronous procedure is marked using the ``{.async.}`` pragma. +## When marking a procedure with the ``{.async.}`` pragma it must have a +## ``Future[T]`` return type or no return type at all. If you do not specify +## a return type then ``Future[void]`` is assumed. +## +## Inside asynchronous procedures ``await`` can be used to call any +## procedures which return a +## ``Future``; this includes asynchronous procedures. When a procedure is +## "awaited", the asynchronous procedure it is awaited in will +## suspend its execution +## until the awaited procedure's Future completes. At which point the +## asynchronous procedure will resume its execution. During the period +## when an asynchronous procedure is suspended other asynchronous procedures +## will be run by the dispatcher. +## +## The ``await`` call may be used in many contexts. It can be used on the right +## hand side of a variable declaration: ``var data = await socket.recv(100)``, +## in which case the variable will be set to the value of the future +## automatically. It can be used to await a ``Future`` object, and it can +## be used to await a procedure returning a ``Future[void]``: +## ``await socket.send("foobar")``. +## +## Discarding futures +## ------------------ +## +## Futures should **never** be discarded. This is because they may contain +## errors. If you do not care for the result of a Future then you should +## use the ``asyncCheck`` procedure instead of the ``discard`` keyword. +## +## Examples +## -------- +## +## For examples take a look at the documentation for the modules implementing +## asynchronous IO. A good place to start is the +## `asyncnet module <asyncnet.html>`_. +## +## Limitations/Bugs +## ---------------- +## +## * ``except`` statement (without `try`) does not work inside async procedures. +## * The effect system (``raises: []``) does not work with async procedures. +## * Can't await in a ``except`` body -# TODO: ``except`` statement (without `try`) does not work. -# TODO: Multiple exception names in a ``except`` don't work. -# TODO: The effect system (raises: []) has trouble with my try transformation. -# TODO: Can't await in a 'except' body -# TODO: getCurrentException(Msg) don't work # TODO: Check if yielded future is nil and throw a more meaningful exception # -- Futures type - PFutureBase* = ref object of PObject + FutureBase* = ref object of RootObj ## Untyped future. cb: proc () {.closure,gcsafe.} finished: bool - error*: ref EBase + error*: ref Exception ## Stored exception errorStackTrace*: string when not defined(release): stackTrace: string ## For debugging purposes only. id: int fromProc: string - PFuture*[T] = ref object of PFutureBase - value: T + Future*[T] = ref object of FutureBase ## Typed future. + value: T ## Stored value + +{.deprecated: [PFutureBase: FutureBase, PFuture: Future].} -var currentID* = 0 -proc newFuture*[T](fromProc: string = "unspecified"): PFuture[T] = + +var currentID = 0 +proc newFuture*[T](fromProc: string = "unspecified"): Future[T] = ## Creates a new future. ## ## Specifying ``fromProc``, which is a string specifying the name of the proc @@ -64,7 +162,7 @@ proc newFuture*[T](fromProc: string = "unspecified"): PFuture[T] = result.fromProc = fromProc currentID.inc() -proc checkFinished[T](future: PFuture[T]) = +proc checkFinished[T](future: Future[T]) = when not defined(release): if future.finished: echo("<-----> ", future.id, " ", future.fromProc) @@ -77,7 +175,7 @@ proc checkFinished[T](future: PFuture[T]) = echo getStackTrace() assert false -proc complete*[T](future: PFuture[T], val: T) = +proc complete*[T](future: Future[T], val: T) = ## Completes ``future`` with value ``val``. #assert(not future.finished, "Future already finished, cannot finish twice.") checkFinished(future) @@ -87,7 +185,7 @@ proc complete*[T](future: PFuture[T], val: T) = if future.cb != nil: future.cb() -proc complete*(future: PFuture[void]) = +proc complete*(future: Future[void]) = ## Completes a void ``future``. #assert(not future.finished, "Future already finished, cannot finish twice.") checkFinished(future) @@ -96,7 +194,7 @@ proc complete*(future: PFuture[void]) = if future.cb != nil: future.cb() -proc fail*[T](future: PFuture[T], error: ref EBase) = +proc fail*[T](future: Future[T], error: ref Exception) = ## Completes ``future`` with ``error``. #assert(not future.finished, "Future already finished, cannot finish twice.") checkFinished(future) @@ -112,8 +210,9 @@ proc fail*[T](future: PFuture[T], error: ref EBase) = # TODO: This may turn out to be a bad idea. # Turns out this is a bad idea. #raise error + discard -proc `callback=`*(future: PFutureBase, cb: proc () {.closure,gcsafe.}) = +proc `callback=`*(future: FutureBase, cb: proc () {.closure,gcsafe.}) = ## Sets the callback proc to be called when the future completes. ## ## If future has already completed then ``cb`` will be called immediately. @@ -124,23 +223,24 @@ proc `callback=`*(future: PFutureBase, cb: proc () {.closure,gcsafe.}) = if future.finished: future.cb() -proc `callback=`*[T](future: PFuture[T], - cb: proc (future: PFuture[T]) {.closure,gcsafe.}) = +proc `callback=`*[T](future: Future[T], + cb: proc (future: Future[T]) {.closure,gcsafe.}) = ## Sets the callback proc to be called when the future completes. ## ## If future has already completed then ``cb`` will be called immediately. future.callback = proc () = cb(future) -proc echoOriginalStackTrace[T](future: PFuture[T]) = +proc echoOriginalStackTrace[T](future: Future[T]) = # TODO: Come up with something better. when not defined(release): echo("Original stack trace in ", future.fromProc, ":") - if not future.errorStackTrace.isNil() and future.errorStackTrace != "": + if not future.errorStackTrace.isNil and future.errorStackTrace != "": echo(future.errorStackTrace) else: echo("Empty or nil stack trace.") + echo("Continuing...") -proc read*[T](future: PFuture[T]): T = +proc read*[T](future: Future[T]): T = ## Retrieves the value of ``future``. Future must be finished otherwise ## this function will fail with a ``EInvalidValue`` exception. ## @@ -153,24 +253,28 @@ proc read*[T](future: PFuture[T]): T = return future.value else: # TODO: Make a custom exception type for this? - raise newException(EInvalidValue, "Future still in progress.") + raise newException(ValueError, "Future still in progress.") -proc readError*[T](future: PFuture[T]): ref EBase = +proc readError*[T](future: Future[T]): ref Exception = + ## Retrieves the exception stored in ``future``. + ## + ## An ``ValueError`` exception will be thrown if no exception exists + ## in the specified Future. if future.error != nil: return future.error else: - raise newException(EInvalidValue, "No error in future.") + raise newException(ValueError, "No error in future.") -proc finished*[T](future: PFuture[T]): bool = +proc finished*[T](future: Future[T]): bool = ## Determines whether ``future`` has completed. ## ## ``True`` may indicate an error or a value. Use ``failed`` to distinguish. future.finished -proc failed*(future: PFutureBase): bool = +proc failed*(future: FutureBase): bool = ## Determines whether ``future`` completed with an error. - future.error != nil + return future.error != nil -proc asyncCheck*[T](future: PFuture[T]) = +proc asyncCheck*[T](future: Future[T]) = ## Sets a callback on ``future`` which raises an exception if the future ## finished with an error. ## @@ -181,7 +285,7 @@ proc asyncCheck*[T](future: PFuture[T]) = echoOriginalStackTrace(future) raise future.error -proc `and`*[T, Y](fut1: PFuture[T], fut2: PFuture[Y]): PFuture[void] = +proc `and`*[T, Y](fut1: Future[T], fut2: Future[Y]): Future[void] = ## Returns a future which will complete once both ``fut1`` and ``fut2`` ## complete. var retFuture = newFuture[void]("asyncdispatch.`and`") @@ -193,7 +297,7 @@ proc `and`*[T, Y](fut1: PFuture[T], fut2: PFuture[Y]): PFuture[void] = if fut1.finished: retFuture.complete() return retFuture -proc `or`*[T, Y](fut1: PFuture[T], fut2: PFuture[Y]): PFuture[void] = +proc `or`*[T, Y](fut1: Future[T], fut2: Future[Y]): Future[void] = ## Returns a future which will complete once either ``fut1`` or ``fut2`` ## complete. var retFuture = newFuture[void]("asyncdispatch.`or`") @@ -204,8 +308,8 @@ proc `or`*[T, Y](fut1: PFuture[T], fut2: PFuture[Y]): PFuture[void] = return retFuture type - PDispatcherBase = ref object of PObject - timers: seq[tuple[finishAt: float, fut: PFuture[void]]] + PDispatcherBase = ref object of RootRef + timers: seq[tuple[finishAt: float, fut: Future[void]]] proc processTimers(p: PDispatcherBase) = var oldTimers = p.timers @@ -219,21 +323,21 @@ proc processTimers(p: PDispatcherBase) = when defined(windows) or defined(nimdoc): import winlean, sets, hashes type - TCompletionKey = dword + TCompletionKey = Dword TCompletionData* = object - sock: TAsyncFD - cb: proc (sock: TAsyncFD, bytesTransferred: DWORD, - errcode: TOSErrorCode) {.closure,gcsafe.} + fd*: TAsyncFD # TODO: Rename this. + cb*: proc (fd: TAsyncFD, bytesTransferred: Dword, + errcode: OSErrorCode) {.closure,gcsafe.} PDispatcher* = ref object of PDispatcherBase ioPort: THandle - handles: TSet[TAsyncFD] + handles: HashSet[TAsyncFD] TCustomOverlapped = object of TOVERLAPPED data*: TCompletionData - PCustomOverlapped = ref TCustomOverlapped + PCustomOverlapped* = ref TCustomOverlapped TAsyncFD* = distinct int @@ -243,7 +347,7 @@ when defined(windows) or defined(nimdoc): proc newDispatcher*(): PDispatcher = ## Creates a new Dispatcher instance. new result - result.ioPort = CreateIOCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 1) + result.ioPort = createIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 1) result.handles = initSet[TAsyncFD]() result.timers = @[] @@ -253,19 +357,19 @@ when defined(windows) or defined(nimdoc): if gDisp.isNil: gDisp = newDispatcher() result = gDisp - proc register*(sock: TAsyncFD) = - ## Registers ``sock`` with the dispatcher. + proc register*(fd: TAsyncFD) = + ## Registers ``fd`` with the dispatcher. let p = getGlobalDispatcher() - if CreateIOCompletionPort(sock.THandle, p.ioPort, - cast[TCompletionKey](sock), 1) == 0: - osError(osLastError()) - p.handles.incl(sock) + if createIoCompletionPort(fd.THandle, p.ioPort, + cast[TCompletionKey](fd), 1) == 0: + raiseOSError(osLastError()) + p.handles.incl(fd) - proc verifyPresence(sock: TAsyncFD) = - ## Ensures that socket has been registered with the dispatcher. + proc verifyPresence(fd: TAsyncFD) = + ## Ensures that file descriptor has been registered with the dispatcher. let p = getGlobalDispatcher() - if sock notin p.handles: - raise newException(EInvalidValue, + if fd notin p.handles: + raise newException(ValueError, "Operation performed on a socket which has not been registered with" & " the dispatcher yet.") @@ -273,40 +377,40 @@ when defined(windows) or defined(nimdoc): ## Waits for completion events and processes them. let p = getGlobalDispatcher() if p.handles.len == 0 and p.timers.len == 0: - raise newException(EInvalidValue, + raise newException(ValueError, "No handles or timers registered in dispatcher.") let llTimeout = if timeout == -1: winlean.INFINITE else: timeout.int32 - var lpNumberOfBytesTransferred: DWORD + var lpNumberOfBytesTransferred: Dword var lpCompletionKey: ULONG var customOverlapped: PCustomOverlapped - let res = GetQueuedCompletionStatus(p.ioPort, + let res = getQueuedCompletionStatus(p.ioPort, addr lpNumberOfBytesTransferred, addr lpCompletionKey, - cast[ptr POverlapped](addr customOverlapped), llTimeout).bool + cast[ptr POVERLAPPED](addr customOverlapped), llTimeout).bool # http://stackoverflow.com/a/12277264/492186 # TODO: http://www.serverframework.com/handling-multiple-pending-socket-read-and-write-operations.html if res: # This is useful for ensuring the reliability of the overlapped struct. - assert customOverlapped.data.sock == lpCompletionKey.TAsyncFD + assert customOverlapped.data.fd == lpCompletionKey.TAsyncFD - customOverlapped.data.cb(customOverlapped.data.sock, - lpNumberOfBytesTransferred, TOSErrorCode(-1)) + customOverlapped.data.cb(customOverlapped.data.fd, + lpNumberOfBytesTransferred, OSErrorCode(-1)) GC_unref(customOverlapped) else: let errCode = osLastError() if customOverlapped != nil: - assert customOverlapped.data.sock == lpCompletionKey.TAsyncFD - customOverlapped.data.cb(customOverlapped.data.sock, + assert customOverlapped.data.fd == lpCompletionKey.TAsyncFD + customOverlapped.data.cb(customOverlapped.data.fd, lpNumberOfBytesTransferred, errCode) GC_unref(customOverlapped) else: if errCode.int32 == WAIT_TIMEOUT: # Timed out discard - else: osError(errCode) + else: raiseOSError(errCode) # Timer processing. processTimers(p) @@ -315,72 +419,72 @@ when defined(windows) or defined(nimdoc): var acceptExPtr: pointer = nil var getAcceptExSockAddrsPtr: pointer = nil - proc initPointer(s: TSocketHandle, func: var pointer, guid: var TGUID): bool = + proc initPointer(s: SocketHandle, func: var pointer, guid: var TGUID): bool = # Ref: https://github.com/powdahound/twisted/blob/master/twisted/internet/iocpreactor/iocpsupport/winsock_pointers.c - var bytesRet: DWord + var bytesRet: Dword func = nil result = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, addr guid, - sizeof(TGUID).dword, addr func, sizeof(pointer).DWORD, + sizeof(TGUID).Dword, addr func, sizeof(pointer).Dword, addr bytesRet, nil, nil) == 0 proc initAll() = let dummySock = newRawSocket() if not initPointer(dummySock, connectExPtr, WSAID_CONNECTEX): - osError(osLastError()) + raiseOSError(osLastError()) if not initPointer(dummySock, acceptExPtr, WSAID_ACCEPTEX): - osError(osLastError()) + raiseOSError(osLastError()) if not initPointer(dummySock, getAcceptExSockAddrsPtr, WSAID_GETACCEPTEXSOCKADDRS): - osError(osLastError()) + raiseOSError(osLastError()) - proc connectEx(s: TSocketHandle, name: ptr TSockAddr, namelen: cint, - lpSendBuffer: pointer, dwSendDataLength: dword, - lpdwBytesSent: PDWORD, lpOverlapped: POverlapped): bool = - if connectExPtr.isNil: raise newException(EInvalidValue, "Need to initialise ConnectEx().") + proc connectEx(s: SocketHandle, name: ptr TSockAddr, namelen: cint, + lpSendBuffer: pointer, dwSendDataLength: Dword, + lpdwBytesSent: PDword, lpOverlapped: POVERLAPPED): bool = + if connectExPtr.isNil: raise newException(ValueError, "Need to initialise ConnectEx().") let func = - cast[proc (s: TSocketHandle, name: ptr TSockAddr, namelen: cint, - lpSendBuffer: pointer, dwSendDataLength: dword, - lpdwBytesSent: PDWORD, lpOverlapped: POverlapped): bool {.stdcall,gcsafe.}](connectExPtr) + cast[proc (s: SocketHandle, name: ptr TSockAddr, namelen: cint, + lpSendBuffer: pointer, dwSendDataLength: Dword, + lpdwBytesSent: PDword, lpOverlapped: POVERLAPPED): bool {.stdcall,gcsafe.}](connectExPtr) result = func(s, name, namelen, lpSendBuffer, dwSendDataLength, lpdwBytesSent, lpOverlapped) - proc acceptEx(listenSock, acceptSock: TSocketHandle, lpOutputBuffer: pointer, + proc acceptEx(listenSock, acceptSock: SocketHandle, lpOutputBuffer: pointer, dwReceiveDataLength, dwLocalAddressLength, - dwRemoteAddressLength: DWORD, lpdwBytesReceived: PDWORD, - lpOverlapped: POverlapped): bool = - if acceptExPtr.isNil: raise newException(EInvalidValue, "Need to initialise AcceptEx().") + dwRemoteAddressLength: Dword, lpdwBytesReceived: PDword, + lpOverlapped: POVERLAPPED): bool = + if acceptExPtr.isNil: raise newException(ValueError, "Need to initialise AcceptEx().") let func = - cast[proc (listenSock, acceptSock: TSocketHandle, lpOutputBuffer: pointer, + cast[proc (listenSock, acceptSock: SocketHandle, lpOutputBuffer: pointer, dwReceiveDataLength, dwLocalAddressLength, - dwRemoteAddressLength: DWORD, lpdwBytesReceived: PDWORD, - lpOverlapped: POverlapped): bool {.stdcall,gcsafe.}](acceptExPtr) + dwRemoteAddressLength: Dword, lpdwBytesReceived: PDword, + lpOverlapped: POVERLAPPED): bool {.stdcall,gcsafe.}](acceptExPtr) result = func(listenSock, acceptSock, lpOutputBuffer, dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength, lpdwBytesReceived, lpOverlapped) proc getAcceptExSockaddrs(lpOutputBuffer: pointer, - dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength: DWORD, - LocalSockaddr: ptr ptr TSockAddr, LocalSockaddrLength: lpint, - RemoteSockaddr: ptr ptr TSockAddr, RemoteSockaddrLength: lpint) = + dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength: Dword, + LocalSockaddr: ptr ptr TSockAddr, LocalSockaddrLength: LPInt, + RemoteSockaddr: ptr ptr TSockAddr, RemoteSockaddrLength: LPInt) = if getAcceptExSockAddrsPtr.isNil: - raise newException(EInvalidValue, "Need to initialise getAcceptExSockAddrs().") + raise newException(ValueError, "Need to initialise getAcceptExSockAddrs().") let func = cast[proc (lpOutputBuffer: pointer, dwReceiveDataLength, dwLocalAddressLength, - dwRemoteAddressLength: DWORD, LocalSockaddr: ptr ptr TSockAddr, - LocalSockaddrLength: lpint, RemoteSockaddr: ptr ptr TSockAddr, - RemoteSockaddrLength: lpint) {.stdcall,gcsafe.}](getAcceptExSockAddrsPtr) + dwRemoteAddressLength: Dword, LocalSockaddr: ptr ptr TSockAddr, + LocalSockaddrLength: LPInt, RemoteSockaddr: ptr ptr TSockAddr, + RemoteSockaddrLength: LPInt) {.stdcall,gcsafe.}](getAcceptExSockAddrsPtr) func(lpOutputBuffer, dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength, LocalSockaddr, LocalSockaddrLength, RemoteSockaddr, RemoteSockaddrLength) - proc connect*(socket: TAsyncFD, address: string, port: TPort, - af = AF_INET): PFuture[void] = + proc connect*(socket: TAsyncFD, address: string, port: Port, + af = AF_INET): Future[void] = ## Connects ``socket`` to server at ``address:port``. ## - ## Returns a ``PFuture`` which will complete when the connection succeeds + ## Returns a ``Future`` which will complete when the connection succeeds ## or an error occurs. verifyPresence(socket) var retFuture = newFuture[void]("connect") @@ -389,31 +493,31 @@ when defined(windows) or defined(nimdoc): saddr.sin_family = int16(toInt(af)) saddr.sin_port = 0 saddr.sin_addr.s_addr = INADDR_ANY - if bindAddr(socket.TSocketHandle, cast[ptr TSockAddr](addr(saddr)), + if bindAddr(socket.SocketHandle, cast[ptr TSockAddr](addr(saddr)), sizeof(saddr).TSockLen) < 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) var aiList = getAddrInfo(address, port, af) var success = false - var lastError: TOSErrorCode + var lastError: OSErrorCode var it = aiList while it != nil: # "the OVERLAPPED structure must remain valid until the I/O completes" # http://blogs.msdn.com/b/oldnewthing/archive/2011/02/02/10123392.aspx var ol = PCustomOverlapped() GC_ref(ol) - ol.data = TCompletionData(sock: socket, cb: - proc (sock: TAsyncFD, bytesCount: DWord, errcode: TOSErrorCode) = + ol.data = TCompletionData(fd: socket, cb: + proc (fd: TAsyncFD, bytesCount: Dword, errcode: OSErrorCode) = if not retFuture.finished: - if errcode == TOSErrorCode(-1): + if errcode == OSErrorCode(-1): retFuture.complete() else: - retFuture.fail(newException(EOS, osErrorMsg(errcode))) + retFuture.fail(newException(OSError, osErrorMsg(errcode))) ) - var ret = connectEx(socket.TSocketHandle, it.ai_addr, - sizeof(TSockAddrIn).cint, nil, 0, nil, - cast[POverlapped](ol)) + var ret = connectEx(socket.SocketHandle, it.ai_addr, + sizeof(Tsockaddr_in).cint, nil, 0, nil, + cast[POVERLAPPED](ol)) if ret: # Request to connect completed immediately. success = true @@ -435,15 +539,17 @@ when defined(windows) or defined(nimdoc): dealloc(aiList) if not success: - retFuture.fail(newException(EOS, osErrorMsg(lastError))) + retFuture.fail(newException(OSError, osErrorMsg(lastError))) return retFuture proc recv*(socket: TAsyncFD, size: int, - flags = {TSocketFlags.SafeDisconn}): PFuture[string] = + flags = {SocketFlag.SafeDisconn}): Future[string] = ## Reads **up to** ``size`` bytes from ``socket``. Returned future will ## complete once all the data requested is read, a part of the data has been ## read, or the socket has disconnected in which case the future will ## complete with a value of ``""``. + ## + ## **Warning**: The ``Peek`` socket flag is not supported on Windows. # Things to note: @@ -453,19 +559,21 @@ when defined(windows) or defined(nimdoc): # '\0' in the message currently signifies a socket disconnect. Who # knows what will happen when someone sends that to our socket. verifyPresence(socket) + assert SocketFlag.Peek notin flags, "Peek not supported on Windows." + var retFuture = newFuture[string]("recv") var dataBuf: TWSABuf dataBuf.buf = cast[cstring](alloc0(size)) dataBuf.len = size - var bytesReceived: DWord - var flagsio = flags.toOSFlags().DWord + var bytesReceived: Dword + var flagsio = flags.toOSFlags().Dword var ol = PCustomOverlapped() GC_ref(ol) - ol.data = TCompletionData(sock: socket, cb: - proc (sock: TAsyncFD, bytesCount: DWord, errcode: TOSErrorCode) = + ol.data = TCompletionData(fd: socket, cb: + proc (fd: TAsyncFD, bytesCount: Dword, errcode: OSErrorCode) = if not retFuture.finished: - if errcode == TOSErrorCode(-1): + if errcode == OSErrorCode(-1): if bytesCount == 0 and dataBuf.buf[0] == '\0': retFuture.complete("") else: @@ -477,14 +585,14 @@ when defined(windows) or defined(nimdoc): if flags.isDisconnectionError(errcode): retFuture.complete("") else: - retFuture.fail(newException(EOS, osErrorMsg(errcode))) + retFuture.fail(newException(OSError, osErrorMsg(errcode))) if dataBuf.buf != nil: dealloc dataBuf.buf dataBuf.buf = nil ) - let ret = WSARecv(socket.TSocketHandle, addr dataBuf, 1, addr bytesReceived, - addr flagsio, cast[POverlapped](ol), nil) + let ret = WSARecv(socket.SocketHandle, addr dataBuf, 1, addr bytesReceived, + addr flagsio, cast[POVERLAPPED](ol), nil) if ret == -1: let err = osLastError() if err.int32 != ERROR_IO_PENDING: @@ -495,7 +603,7 @@ when defined(windows) or defined(nimdoc): if flags.isDisconnectionError(err): retFuture.complete("") else: - retFuture.fail(newException(EOS, osErrorMsg(err))) + retFuture.fail(newException(OSError, osErrorMsg(err))) elif ret == 0 and bytesReceived == 0 and dataBuf.buf[0] == '\0': # We have to ensure that the buffer is empty because WSARecv will tell # us immediatelly when it was disconnected, even when there is still @@ -527,7 +635,7 @@ when defined(windows) or defined(nimdoc): return retFuture proc send*(socket: TAsyncFD, data: string, - flags = {TSocketFlags.SafeDisconn}): PFuture[void] = + flags = {SocketFlag.SafeDisconn}): Future[void] = ## Sends ``data`` to ``socket``. The returned future will complete once all ## data has been sent. verifyPresence(socket) @@ -537,23 +645,23 @@ when defined(windows) or defined(nimdoc): dataBuf.buf = data # since this is not used in a callback, this is fine dataBuf.len = data.len - var bytesReceived, lowFlags: DWord + var bytesReceived, lowFlags: Dword var ol = PCustomOverlapped() GC_ref(ol) - ol.data = TCompletionData(sock: socket, cb: - proc (sock: TAsyncFD, bytesCount: DWord, errcode: TOSErrorCode) = + ol.data = TCompletionData(fd: socket, cb: + proc (fd: TAsyncFD, bytesCount: Dword, errcode: OSErrorCode) = if not retFuture.finished: - if errcode == TOSErrorCode(-1): + if errcode == OSErrorCode(-1): retFuture.complete() else: if flags.isDisconnectionError(errcode): retFuture.complete() else: - retFuture.fail(newException(EOS, osErrorMsg(errcode))) + retFuture.fail(newException(OSError, osErrorMsg(errcode))) ) - let ret = WSASend(socket.TSocketHandle, addr dataBuf, 1, addr bytesReceived, - lowFlags, cast[POverlapped](ol), nil) + let ret = WSASend(socket.SocketHandle, addr dataBuf, 1, addr bytesReceived, + lowFlags, cast[POVERLAPPED](ol), nil) if ret == -1: let err = osLastError() if err.int32 != ERROR_IO_PENDING: @@ -561,7 +669,7 @@ when defined(windows) or defined(nimdoc): if flags.isDisconnectionError(err): retFuture.complete() else: - retFuture.fail(newException(EOS, osErrorMsg(err))) + retFuture.fail(newException(OSError, osErrorMsg(err))) else: retFuture.complete() # We don't deallocate ``ol`` here because even though this completed @@ -569,8 +677,8 @@ when defined(windows) or defined(nimdoc): # free ``ol``. return retFuture - proc acceptAddr*(socket: TAsyncFD, flags = {TSocketFlags.SafeDisconn}): - PFuture[tuple[address: string, client: TAsyncFD]] = + proc acceptAddr*(socket: TAsyncFD, flags = {SocketFlag.SafeDisconn}): + Future[tuple[address: string, client: TAsyncFD]] = ## Accepts a new connection. Returns a future containing the client socket ## corresponding to that connection and the remote address of the client. ## The future will complete when the connection is successfully accepted. @@ -586,28 +694,28 @@ when defined(windows) or defined(nimdoc): var retFuture = newFuture[tuple[address: string, client: TAsyncFD]]("acceptAddr") var clientSock = newRawSocket() - if clientSock == osInvalidSocket: osError(osLastError()) + if clientSock == osInvalidSocket: raiseOSError(osLastError()) const lpOutputLen = 1024 var lpOutputBuf = newString(lpOutputLen) - var dwBytesReceived: DWORD - let dwReceiveDataLength = 0.DWORD # We don't want any data to be read. - let dwLocalAddressLength = DWORD(sizeof (TSockaddr_in) + 16) - let dwRemoteAddressLength = DWORD(sizeof(TSockaddr_in) + 16) + var dwBytesReceived: Dword + let dwReceiveDataLength = 0.Dword # We don't want any data to be read. + let dwLocalAddressLength = Dword(sizeof (Tsockaddr_in) + 16) + let dwRemoteAddressLength = Dword(sizeof(Tsockaddr_in) + 16) template completeAccept(): stmt {.immediate, dirty.} = var listenSock = socket let setoptRet = setsockopt(clientSock, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, addr listenSock, sizeof(listenSock).TSockLen) - if setoptRet != 0: osError(osLastError()) + if setoptRet != 0: raiseOSError(osLastError()) - var LocalSockaddr, RemoteSockaddr: ptr TSockAddr + var localSockaddr, remoteSockaddr: ptr TSockAddr var localLen, remoteLen: int32 getAcceptExSockaddrs(addr lpOutputBuf[0], dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength, - addr LocalSockaddr, addr localLen, - addr RemoteSockaddr, addr remoteLen) + addr localSockaddr, addr localLen, + addr remoteSockaddr, addr remoteLen) register(clientSock.TAsyncFD) # TODO: IPv6. Check ``sa_family``. http://stackoverflow.com/a/9212542/492186 retFuture.complete( @@ -625,25 +733,25 @@ when defined(windows) or defined(nimdoc): else: retFuture.complete(newAcceptFut.read) else: - retFuture.fail(newException(EOS, osErrorMsg(errcode))) + retFuture.fail(newException(OSError, osErrorMsg(errcode))) var ol = PCustomOverlapped() GC_ref(ol) - ol.data = TCompletionData(sock: socket, cb: - proc (sock: TAsyncFD, bytesCount: DWord, errcode: TOSErrorCode) = + ol.data = TCompletionData(fd: socket, cb: + proc (fd: TAsyncFD, bytesCount: Dword, errcode: OSErrorCode) = if not retFuture.finished: - if errcode == TOSErrorCode(-1): + if errcode == OSErrorCode(-1): completeAccept() else: failAccept(errcode) ) # http://msdn.microsoft.com/en-us/library/windows/desktop/ms737524%28v=vs.85%29.aspx - let ret = acceptEx(socket.TSocketHandle, clientSock, addr lpOutputBuf[0], + let ret = acceptEx(socket.SocketHandle, clientSock, addr lpOutputBuf[0], dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength, - addr dwBytesReceived, cast[POverlapped](ol)) + addr dwBytesReceived, cast[POVERLAPPED](ol)) if not ret: let err = osLastError() @@ -658,17 +766,23 @@ when defined(windows) or defined(nimdoc): return retFuture - proc newAsyncRawSocket*(domain: TDomain = AF_INET, - typ: TType = SOCK_STREAM, - protocol: TProtocol = IPPROTO_TCP): TAsyncFD = + proc newAsyncRawSocket*(domain, typ, protocol: cint): TAsyncFD = + ## Creates a new socket and registers it with the dispatcher implicitly. + result = newRawSocket(domain, typ, protocol).TAsyncFD + result.SocketHandle.setBlocking(false) + register(result) + + proc newAsyncRawSocket*(domain: Domain = AF_INET, + typ: SockType = SOCK_STREAM, + protocol: Protocol = IPPROTO_TCP): TAsyncFD = ## Creates a new socket and registers it with the dispatcher implicitly. result = newRawSocket(domain, typ, protocol).TAsyncFD - result.TSocketHandle.setBlocking(false) + result.SocketHandle.setBlocking(false) register(result) proc closeSocket*(socket: TAsyncFD) = ## Closes a socket and ensures that it is unregistered. - socket.TSocketHandle.close() + socket.SocketHandle.close() getGlobalDispatcher().handles.excl(socket) proc unregister*(fd: TAsyncFD) = @@ -692,10 +806,10 @@ else: type TAsyncFD* = distinct cint - TCallback = proc (sock: TAsyncFD): bool {.closure,gcsafe.} + TCallback = proc (fd: TAsyncFD): bool {.closure,gcsafe.} PData* = ref object of PObject - sock: TAsyncFD + fd: TAsyncFD readCBs: seq[TCallback] writeCBs: seq[TCallback] @@ -714,51 +828,56 @@ else: if gDisp.isNil: gDisp = newDispatcher() result = gDisp - proc update(sock: TAsyncFD, events: set[TEvent]) = + proc update(fd: TAsyncFD, events: set[TEvent]) = let p = getGlobalDispatcher() - assert sock.TSocketHandle in p.selector - discard p.selector.update(sock.TSocketHandle, events) + assert fd.SocketHandle in p.selector + discard p.selector.update(fd.SocketHandle, events) - proc register(sock: TAsyncFD) = + proc register*(fd: TAsyncFD) = let p = getGlobalDispatcher() - var data = PData(sock: sock, readCBs: @[], writeCBs: @[]) - p.selector.register(sock.TSocketHandle, {}, data.PObject) + var data = PData(fd: fd, readCBs: @[], writeCBs: @[]) + p.selector.register(fd.SocketHandle, {}, data.PObject) + + proc newAsyncRawSocket*(domain: cint, typ: cint, protocol: cint): TAsyncFD = + result = newRawSocket(domain, typ, protocol).TAsyncFD + result.SocketHandle.setBlocking(false) + register(result) proc newAsyncRawSocket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, protocol: TProtocol = IPPROTO_TCP): TAsyncFD = result = newRawSocket(domain, typ, protocol).TAsyncFD - result.TSocketHandle.setBlocking(false) + result.SocketHandle.setBlocking(false) register(result) proc closeSocket*(sock: TAsyncFD) = let disp = getGlobalDispatcher() - sock.TSocketHandle.close() - disp.selector.unregister(sock.TSocketHandle) + sock.SocketHandle.close() + disp.selector.unregister(sock.SocketHandle) proc unregister*(fd: TAsyncFD) = - getGlobalDispatcher().selector.unregister(fd.TSocketHandle) + getGlobalDispatcher().selector.unregister(fd.SocketHandle) - proc addRead(sock: TAsyncFD, cb: TCallback) = + proc addRead*(fd: TAsyncFD, cb: TCallback) = let p = getGlobalDispatcher() - if sock.TSocketHandle notin p.selector: + if fd.SocketHandle notin p.selector: raise newException(EInvalidValue, "File descriptor not registered.") - p.selector[sock.TSocketHandle].data.PData.readCBs.add(cb) - update(sock, p.selector[sock.TSocketHandle].events + {EvRead}) + p.selector[fd.SocketHandle].data.PData.readCBs.add(cb) + update(fd, p.selector[fd.SocketHandle].events + {EvRead}) - proc addWrite(sock: TAsyncFD, cb: TCallback) = + proc addWrite*(fd: TAsyncFD, cb: TCallback) = let p = getGlobalDispatcher() - if sock.TSocketHandle notin p.selector: + if fd.SocketHandle notin p.selector: raise newException(EInvalidValue, "File descriptor not registered.") - p.selector[sock.TSocketHandle].data.PData.writeCBs.add(cb) - update(sock, p.selector[sock.TSocketHandle].events + {EvWrite}) + p.selector[fd.SocketHandle].data.PData.writeCBs.add(cb) + update(fd, p.selector[fd.SocketHandle].events + {EvWrite}) proc poll*(timeout = 500) = let p = getGlobalDispatcher() for info in p.selector.select(timeout): let data = PData(info.key.data) - assert data.sock == info.key.fd.TAsyncFD - #echo("In poll ", data.sock.cint) + assert data.fd == info.key.fd.TAsyncFD + #echo("In poll ", data.fd.cint) if EvRead in info.events: # Callback may add items to ``data.readCBs`` which causes issues if # we are iterating over ``data.readCBs`` at the same time. We therefore @@ -766,7 +885,7 @@ else: let currentCBs = data.readCBs data.readCBs = @[] for cb in currentCBs: - if not cb(data.sock): + if not cb(data.fd): # Callback wants to be called again. data.readCBs.add(cb) @@ -774,7 +893,7 @@ else: let currentCBs = data.writeCBs data.writeCBs = @[] for cb in currentCBs: - if not cb(data.sock): + if not cb(data.fd): # Callback wants to be called again. data.writeCBs.add(cb) @@ -783,18 +902,19 @@ else: if data.readCBs.len != 0: newEvents = {EvRead} if data.writeCBs.len != 0: newEvents = newEvents + {EvWrite} if newEvents != info.key.events: - update(data.sock, newEvents) + update(data.fd, newEvents) else: # FD no longer a part of the selector. Likely been closed # (e.g. socket disconnected). + discard processTimers(p) proc connect*(socket: TAsyncFD, address: string, port: TPort, - af = AF_INET): PFuture[void] = + af = AF_INET): Future[void] = var retFuture = newFuture[void]("connect") - proc cb(sock: TAsyncFD): bool = + proc cb(fd: TAsyncFD): bool = # We have connected. retFuture.complete() return true @@ -804,7 +924,7 @@ else: var lastError: TOSErrorCode var it = aiList while it != nil: - var ret = connect(socket.TSocketHandle, it.ai_addr, it.ai_addrlen.TSocklen) + var ret = connect(socket.SocketHandle, it.ai_addr, it.ai_addrlen.Socklen) if ret == 0: # Request to connect completed immediately. success = true @@ -826,14 +946,14 @@ else: return retFuture proc recv*(socket: TAsyncFD, size: int, - flags = {TSocketFlags.SafeDisconn}): PFuture[string] = + flags = {TSocketFlags.SafeDisconn}): Future[string] = var retFuture = newFuture[string]("recv") var readBuffer = newString(size) proc cb(sock: TAsyncFD): bool = result = true - let res = recv(sock.TSocketHandle, addr readBuffer[0], size.cint, + let res = recv(sock.SocketHandle, addr readBuffer[0], size.cint, flags.toOSFlags()) #echo("recv cb res: ", res) if res < 0: @@ -857,7 +977,7 @@ else: return retFuture proc send*(socket: TAsyncFD, data: string, - flags = {TSocketFlags.SafeDisconn}): PFuture[void] = + flags = {TSocketFlags.SafeDisconn}): Future[void] = var retFuture = newFuture[void]("send") var written = 0 @@ -866,7 +986,7 @@ else: result = true let netSize = data.len-written var d = data.cstring - let res = send(sock.TSocketHandle, addr d[written], netSize.cint, + let res = send(sock.SocketHandle, addr d[written], netSize.cint, MSG_NOSIGNAL) if res < 0: let lastError = osLastError() @@ -889,15 +1009,15 @@ else: return retFuture proc acceptAddr*(socket: TAsyncFD, flags = {TSocketFlags.SafeDisconn}): - PFuture[tuple[address: string, client: TAsyncFD]] = + Future[tuple[address: string, client: TAsyncFD]] = var retFuture = newFuture[tuple[address: string, client: TAsyncFD]]("acceptAddr") proc cb(sock: TAsyncFD): bool = result = true - var sockAddress: Tsockaddr_in - var addrLen = sizeof(sockAddress).TSocklen - var client = accept(sock.TSocketHandle, - cast[ptr TSockAddr](addr(sockAddress)), addr(addrLen)) + var sockAddress: SockAddr_in + var addrLen = sizeof(sockAddress).Socklen + var client = accept(sock.SocketHandle, + cast[ptr SockAddr](addr(sockAddress)), addr(addrLen)) if client == osInvalidSocket: let lastError = osLastError() assert lastError.int32 notin {EWOULDBLOCK, EAGAIN} @@ -914,7 +1034,7 @@ else: addRead(socket, cb) return retFuture -proc sleepAsync*(ms: int): PFuture[void] = +proc sleepAsync*(ms: int): Future[void] = ## Suspends the execution of the current async procedure for the next ## ``ms`` miliseconds. var retFuture = newFuture[void]("sleepAsync") @@ -923,14 +1043,14 @@ proc sleepAsync*(ms: int): PFuture[void] = return retFuture proc accept*(socket: TAsyncFD, - flags = {TSocketFlags.SafeDisconn}): PFuture[TAsyncFD] = + flags = {SocketFlag.SafeDisconn}): Future[TAsyncFD] = ## Accepts a new connection. Returns a future containing the client socket ## corresponding to that connection. ## The future will complete when the connection is successfully accepted. var retFut = newFuture[TAsyncFD]("accept") var fut = acceptAddr(socket, flags) fut.callback = - proc (future: PFuture[tuple[address: string, client: TAsyncFD]]) = + proc (future: Future[tuple[address: string, client: TAsyncFD]]) = assert future.finished if future.failed: retFut.fail(future.error) @@ -940,7 +1060,7 @@ proc accept*(socket: TAsyncFD, # -- Await Macro -template createCb*(retFutureSym, iteratorNameSym, +template createCb(retFutureSym, iteratorNameSym, name: expr): stmt {.immediate.} = var nameIterVar = iteratorNameSym #{.push stackTrace: off.} @@ -963,29 +1083,50 @@ template createCb*(retFutureSym, iteratorNameSym, cb() #{.pop.} proc generateExceptionCheck(futSym, - exceptBranch, rootReceiver, fromNode: PNimrodNode): PNimrodNode {.compileTime.} = - if exceptBranch == nil: + tryStmt, rootReceiver, fromNode: PNimrodNode): PNimrodNode {.compileTime.} = + if tryStmt.kind == nnkNilLit: result = rootReceiver else: - if exceptBranch[0].kind == nnkStmtList: - result = newIfStmt( - (newDotExpr(futSym, newIdentNode("failed")), - exceptBranch[0] - ) - ) - else: - expectKind(exceptBranch[1], nnkStmtList) - result = newIfStmt( - (newDotExpr(futSym, newIdentNode("failed")), - newIfStmt( - (infix(newDotExpr(futSym, newIdentNode("error")), "of", exceptBranch[0]), - exceptBranch[1]) - ) - ) - ) + var exceptionChecks: seq[tuple[cond, body: PNimrodNode]] = @[] + let errorNode = newDotExpr(futSym, newIdentNode("error")) + 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: PNimrodNode + for i in 0 .. <exceptBranch.len: + let child = exceptBranch[i] + if child.kind == nnkIdent: + let cond = infix(errorNode, "of", child) + if exceptIdentCount == 0: + ifCond = cond + else: + ifCond = infix(ifCond, "or", cond) + else: + break + exceptIdentCount.inc + + expectKind(exceptBranch[exceptIdentCount], nnkStmtList) + exceptionChecks.add((ifCond, exceptBranch[exceptIdentCount])) + # -> -> else: raise futSym.error + exceptionChecks.add((newIdentNode("true"), + newNimNode(nnkRaiseStmt).add(errorNode))) + # Read the future if there is no error. + # -> else: futSym.read let elseNode = newNimNode(nnkElse, fromNode) elseNode.add newNimNode(nnkStmtList, fromNode) elseNode[0].add rootReceiver + + let ifBody = newStmtList() + ifBody.add newCall(newIdentNode("setCurrentException"), errorNode) + ifBody.add newIfStmt(exceptionChecks) + ifBody.add newCall(newIdentNode("setCurrentException"), newNilLit()) + + result = newIfStmt( + (newDotExpr(futSym, newIdentNode("failed")), ifBody) + ) result.add elseNode template createVar(result: var PNimrodNode, futSymName: string, @@ -997,25 +1138,25 @@ template createVar(result: var PNimrodNode, futSymName: string, result.add newVarStmt(futSym, asyncProc) # -> var future<x> = y result.add newNimNode(nnkYieldStmt, fromNode).add(futSym) # -> yield future<x> valueReceiver = newDotExpr(futSym, newIdentNode("read")) # -> future<x>.read - result.add generateExceptionCheck(futSym, exceptBranch, rootReceiver, fromNode) + result.add generateExceptionCheck(futSym, tryStmt, rootReceiver, fromNode) proc processBody(node, retFutureSym: PNimrodNode, subTypeIsVoid: bool, - exceptBranch: PNimrodNode): PNimrodNode {.compileTime.} = + tryStmt: PNimrodNode): PNimrodNode {.compileTime.} = #echo(node.treeRepr) result = node case node.kind of nnkReturnStmt: result = newNimNode(nnkStmtList, node) if node[0].kind == nnkEmpty: - if not subtypeIsVoid: + if not subTypeIsVoid: result.add newCall(newIdentNode("complete"), retFutureSym, newIdentNode("result")) else: result.add newCall(newIdentNode("complete"), retFutureSym) else: result.add newCall(newIdentNode("complete"), retFutureSym, - node[0].processBody(retFutureSym, subtypeIsVoid, exceptBranch)) + node[0].processBody(retFutureSym, subTypeIsVoid, tryStmt)) result.add newNimNode(nnkReturnStmt, node).add(newNilLit()) return # Don't process the children of this return stmt @@ -1070,7 +1211,7 @@ proc processBody(node, retFutureSym: PNimrodNode, res: PNimrodNode): bool {.compileTime.} = result = false while i < n[0].len: - var processed = processBody(n[0][i], retFutureSym, subtypeIsVoid, n[1]) + var processed = processBody(n[0][i], retFutureSym, subTypeIsVoid, n) if processed.kind != n[0][i].kind or processed.len != n[0][i].len: expectKind(processed, nnkStmtList) expectKind(processed[2][1], nnkElse) @@ -1090,7 +1231,7 @@ proc processBody(node, retFutureSym: PNimrodNode, else: discard for i in 0 .. <result.len: - result[i] = processBody(result[i], retFutureSym, subtypeIsVoid, exceptBranch) + result[i] = processBody(result[i], retFutureSym, subTypeIsVoid, tryStmt) proc getName(node: PNimrodNode): string {.compileTime.} = case node.kind @@ -1113,12 +1254,12 @@ macro async*(prc: stmt): stmt {.immediate.} = hint("Processing " & prc[0].getName & " as an async proc.") let returnType = prc[3][0] - # Verify that the return type is a PFuture[T] + # Verify that the return type is a Future[T] if returnType.kind == nnkIdent: - error("Expected return type of 'PFuture' got '" & $returnType & "'") + error("Expected return type of 'Future' got '" & $returnType & "'") elif returnType.kind == nnkBracketExpr: - if $returnType[0] != "PFuture": - error("Expected return type of 'PFuture' got '" & $returnType[0] & "'") + if $returnType[0] != "Future": + error("Expected return type of 'Future' got '" & $returnType[0] & "'") let subtypeIsVoid = returnType.kind == nnkEmpty or (returnType.kind == nnkBracketExpr and @@ -1139,7 +1280,7 @@ macro async*(prc: stmt): stmt {.immediate.} = subRetType), newLit(prc[0].getName)))) # Get type from return type of this proc - # -> iterator nameIter(): PFutureBase {.closure.} = + # -> iterator nameIter(): FutureBase {.closure.} = # -> var result: T # -> <proc_body> # -> complete(retFuture, result) @@ -1155,14 +1296,14 @@ macro async*(prc: stmt): stmt {.immediate.} = # -> complete(retFuture) procBody.add(newCall(newIdentNode("complete"), retFutureSym)) - var closureIterator = newProc(iteratorNameSym, [newIdentNode("PFutureBase")], + var closureIterator = newProc(iteratorNameSym, [newIdentNode("FutureBase")], procBody, nnkIteratorDef) closureIterator[4] = newNimNode(nnkPragma, prc[6]).add(newIdentNode("closure")) outerProcBody.add(closureIterator) # -> createCb(retFuture) var cbName = newIdentNode("cb") - var procCb = newCall("createCb", retFutureSym, iteratorNameSym, + var procCb = newCall(bindSym"createCb", retFutureSym, iteratorNameSym, newStrLitNode(prc[0].getName)) outerProcBody.add procCb @@ -1178,16 +1319,16 @@ macro async*(prc: stmt): stmt {.immediate.} = if subtypeIsVoid: # Add discardable pragma. if returnType.kind == nnkEmpty: - # Add PFuture[void] - result[3][0] = parseExpr("PFuture[void]") + # Add Future[void] + result[3][0] = parseExpr("Future[void]") result[6] = outerProcBody #echo(treeRepr(result)) - #if prc[0].getName == "getFile": + #if prc[0].getName == "catch": # echo(toStrLit(result)) -proc recvLine*(socket: TAsyncFD): PFuture[string] {.async.} = +proc recvLine*(socket: TAsyncFD): Future[string] {.async.} = ## Reads a line of data from ``socket``. Returned future will complete once ## a full line is read or an error occurs. ## @@ -1200,6 +1341,11 @@ proc recvLine*(socket: TAsyncFD): PFuture[string] {.async.} = ## If the socket is disconnected in the middle of a line (before ``\r\L`` ## is read) then line will be set to ``""``. ## The partial line **will be lost**. + ## + ## **Warning**: This assumes that lines are delimited by ``\r\L``. + ## + ## **Note**: This procedure is mostly used for testing. You likely want to + ## use ``asyncnet.recvLine`` instead. template addNLIfEmpty(): stmt = if result.len == 0: @@ -1212,9 +1358,8 @@ proc recvLine*(socket: TAsyncFD): PFuture[string] {.async.} = if c.len == 0: return "" if c == "\r": - c = await recv(socket, 1, {TSocketFlags.SafeDisconn, TSocketFlags.Peek}) - if c.len > 0 and c == "\L": - discard await recv(socket, 1) + c = await recv(socket, 1) + assert c == "\l" addNLIfEmpty() return elif c == "\L": @@ -1227,10 +1372,9 @@ proc runForever*() = while true: poll() -proc waitFor*[T](fut: PFuture[T]) = +proc waitFor*[T](fut: PFuture[T]): T = ## **Blocks** the current thread until the specified future completes. while not fut.finished: poll() - if fut.failed: - raise fut.error + fut.read diff --git a/lib/pure/asyncfile.nim b/lib/pure/asyncfile.nim new file mode 100644 index 000000000..c09cb5a35 --- /dev/null +++ b/lib/pure/asyncfile.nim @@ -0,0 +1,325 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2014 Dominik Picheta +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This module implements asynchronous file handling. +## +## .. code-block:: Nim +## import asyncfile, asyncdispatch, os +## +## proc main() {.async.} = +## var file = openAsync(getTempDir() / "foobar.txt", fmReadWrite) +## await file.write("test") +## file.setFilePos(0) +## let data = await file.readAll() +## doAssert data == "test" +## file.close() +## +## waitFor main() + +import asyncdispatch, os + +when defined(windows): + import winlean +else: + import posix + +type + AsyncFile = ref object + fd: TAsyncFd + offset: int64 + +when defined(windows): + proc getDesiredAccess(mode: TFileMode): int32 = + case mode + of fmRead: + result = GENERIC_READ + of fmWrite, fmAppend: + result = GENERIC_WRITE + of fmReadWrite, fmReadWriteExisting: + result = GENERIC_READ or GENERIC_WRITE + + proc getCreationDisposition(mode: TFileMode, filename: string): int32 = + case mode + of fmRead, fmReadWriteExisting: + OPEN_EXISTING + of fmAppend, fmReadWrite, fmWrite: + if fileExists(filename): + OPEN_EXISTING + else: + CREATE_NEW +else: + proc getPosixFlags(mode: TFileMode): cint = + case mode + of fmRead: + result = O_RDONLY + of fmWrite: + result = O_WRONLY or O_CREAT + of fmAppend: + result = O_WRONLY or O_CREAT or O_APPEND + of fmReadWrite: + result = O_RDWR or O_CREAT + of fmReadWriteExisting: + result = O_RDWR + result = result or O_NONBLOCK + +proc getFileSize(f: AsyncFile): int64 = + ## Retrieves the specified file's size. + when defined(windows): + var high: DWord + let low = getFileSize(f.fd.THandle, addr high) + if low == INVALID_FILE_SIZE: + raiseOSError() + return (high shl 32) or low + +proc openAsync*(filename: string, mode = fmRead): AsyncFile = + ## Opens a file specified by the path in ``filename`` using + ## the specified ``mode`` asynchronously. + new result + when defined(windows): + let flags = FILE_FLAG_OVERLAPPED or FILE_ATTRIBUTE_NORMAL + let desiredAccess = getDesiredAccess(mode) + let creationDisposition = getCreationDisposition(mode, filename) + when useWinUnicode: + result.fd = createFileW(newWideCString(filename), desiredAccess, + FILE_SHARE_READ, + nil, creationDisposition, flags, 0).TAsyncFd + else: + result.fd = createFileA(filename, desiredAccess, + FILE_SHARE_READ, + nil, creationDisposition, flags, 0).TAsyncFd + + if result.fd.THandle == INVALID_HANDLE_VALUE: + raiseOSError() + + register(result.fd) + + if mode == fmAppend: + result.offset = getFileSize(result) + + else: + let flags = getPosixFlags(mode) + # RW (Owner), RW (Group), R (Other) + let perm = S_IRUSR or S_IWUSR or S_IRGRP or S_IWGRP or S_IROTH + result.fd = open(filename, flags, perm).TAsyncFD + if result.fd.cint == -1: + raiseOSError() + + register(result.fd) + +proc read*(f: AsyncFile, size: int): Future[string] = + ## Read ``size`` bytes from the specified file asynchronously starting at + ## the current position of the file pointer. + ## + ## If the file pointer is past the end of the file then an empty string is + ## returned. + var retFuture = newFuture[string]("asyncfile.read") + + when defined(windows): + var buffer = alloc0(size) + + var ol = PCustomOverlapped() + GC_ref(ol) + ol.data = TCompletionData(fd: f.fd, cb: + proc (fd: TAsyncFD, bytesCount: Dword, errcode: OSErrorCode) = + if not retFuture.finished: + if errcode == OSErrorCode(-1): + assert bytesCount > 0 + assert bytesCount <= size + var data = newString(bytesCount) + copyMem(addr data[0], buffer, bytesCount) + f.offset.inc bytesCount + retFuture.complete($data) + else: + if errcode.int32 == ERROR_HANDLE_EOF: + retFuture.complete("") + else: + retFuture.fail(newException(OSError, osErrorMsg(errcode))) + if buffer != nil: + dealloc buffer + buffer = nil + ) + ol.offset = DWord(f.offset and 0xffffffff) + ol.offsetHigh = DWord(f.offset shr 32) + + # According to MSDN we're supposed to pass nil to lpNumberOfBytesRead. + let ret = readFile(f.fd.THandle, buffer, size.int32, nil, + cast[POVERLAPPED](ol)) + if not ret.bool: + let err = osLastError() + if err.int32 != ERROR_IO_PENDING: + if buffer != nil: + dealloc buffer + buffer = nil + GC_unref(ol) + retFuture.fail(newException(OSError, osErrorMsg(err))) + else: + # Request completed immediately. + var bytesRead: DWord + let overlappedRes = getOverlappedResult(f.fd.THandle, + cast[POverlapped](ol)[], bytesRead, false.WinBool) + if not overlappedRes.bool: + let err = osLastError() + if err.int32 == ERROR_HANDLE_EOF: + retFuture.complete("") + else: + retFuture.fail(newException(OSError, osErrorMsg(osLastError()))) + else: + assert bytesRead > 0 + assert bytesRead <= size + var data = newString(bytesRead) + copyMem(addr data[0], buffer, bytesRead) + f.offset.inc bytesRead + retFuture.complete($data) + else: + var readBuffer = newString(size) + + proc cb(fd: TAsyncFD): bool = + result = true + let res = read(fd.cint, addr readBuffer[0], size.cint) + if res < 0: + let lastError = osLastError() + if lastError.int32 != EAGAIN: + retFuture.fail(newException(EOS, osErrorMsg(lastError))) + else: + result = false # We still want this callback to be called. + elif res == 0: + # EOF + retFuture.complete("") + else: + readBuffer.setLen(res) + f.offset.inc(res) + retFuture.complete(readBuffer) + + if not cb(f.fd): + addRead(f.fd, cb) + + return retFuture + +proc readLine*(f: AsyncFile): Future[string] {.async.} = + ## Reads a single line from the specified file asynchronously. + result = "" + while true: + var c = await read(f, 1) + if c[0] == '\c': + c = await read(f, 1) + break + if c[0] == '\L' or c == "": + break + else: + result.add(c) + +proc getFilePos*(f: AsyncFile): int64 = + ## Retrieves the current position of the file pointer that is + ## used to read from the specified file. The file's first byte has the + ## index zero. + f.offset + +proc setFilePos*(f: AsyncFile, pos: int64) = + ## Sets the position of the file pointer that is used for read/write + ## operations. The file's first byte has the index zero. + f.offset = pos + when not defined(windows): + let ret = lseek(f.fd.cint, pos, SEEK_SET) + if ret == -1: + raiseOSError() + +proc readAll*(f: AsyncFile): Future[string] {.async.} = + ## Reads all data from the specified file. + result = "" + while true: + let data = await read(f, 4000) + if data.len == 0: + return + result.add data + +proc write*(f: AsyncFile, data: string): Future[void] = + ## Writes ``data`` to the file specified asynchronously. + ## + ## The returned Future will complete once all data has been written to the + ## specified file. + var retFuture = newFuture[void]("asyncfile.write") + var copy = data + when defined(windows): + var buffer = alloc0(data.len) + copyMem(buffer, addr copy[0], data.len) + + var ol = PCustomOverlapped() + GC_ref(ol) + ol.data = TCompletionData(fd: f.fd, cb: + proc (fd: TAsyncFD, bytesCount: DWord, errcode: OSErrorCode) = + if not retFuture.finished: + if errcode == OSErrorCode(-1): + assert bytesCount == data.len.int32 + f.offset.inc(data.len) + retFuture.complete() + else: + retFuture.fail(newException(OSError, osErrorMsg(errcode))) + if buffer != nil: + dealloc buffer + buffer = nil + ) + ol.offset = DWord(f.offset and 0xffffffff) + ol.offsetHigh = DWord(f.offset shr 32) + + # According to MSDN we're supposed to pass nil to lpNumberOfBytesWritten. + let ret = writeFile(f.fd.THandle, buffer, data.len.int32, nil, + cast[POVERLAPPED](ol)) + if not ret.bool: + let err = osLastError() + if err.int32 != ERROR_IO_PENDING: + if buffer != nil: + dealloc buffer + buffer = nil + GC_unref(ol) + retFuture.fail(newException(OSError, osErrorMsg(err))) + else: + # Request completed immediately. + var bytesWritten: DWord + let overlappedRes = getOverlappedResult(f.fd.THandle, + cast[POverlapped](ol)[], bytesWritten, false.WinBool) + if not overlappedRes.bool: + retFuture.fail(newException(OSError, osErrorMsg(osLastError()))) + else: + assert bytesWritten == data.len.int32 + f.offset.inc(data.len) + retFuture.complete() + else: + var written = 0 + + proc cb(fd: TAsyncFD): bool = + result = true + let remainderSize = data.len-written + let res = write(fd.cint, addr copy[written], remainderSize.cint) + if res < 0: + let lastError = osLastError() + if lastError.int32 != EAGAIN: + retFuture.fail(newException(EOS, osErrorMsg(lastError))) + else: + result = false # We still want this callback to be called. + else: + written.inc res + f.offset.inc res + if res != remainderSize: + result = false # We still have data to write. + else: + retFuture.complete() + + if not cb(f.fd): + addWrite(f.fd, cb) + return retFuture + +proc close*(f: AsyncFile) = + ## Closes the file specified. + when defined(windows): + if not closeHandle(f.fd.THandle).bool: + raiseOSError() + else: + if close(f.fd.cint) == -1: + raiseOSError() + diff --git a/lib/pure/asyncftpclient.nim b/lib/pure/asyncftpclient.nim index f1b1d1400..fc38dc31a 100644 --- a/lib/pure/asyncftpclient.nim +++ b/lib/pure/asyncftpclient.nim @@ -1,28 +1,46 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Dominik Picheta # See the file "copying.txt", included in this # distribution, for details about the copyright. # +## This module implement an asynchronous FTP client. +## +## Examples +## -------- +## +## .. code-block::nim +## +## var ftp = newAsyncFtpClient("example.com", user = "test", pass = "test") +## proc main(ftp: AsyncFtpClient) {.async.} = +## await ftp.connect() +## echo await ftp.pwd() +## echo await ftp.listDirs() +## await ftp.store("payload.jpg", "payload.jpg") +## await ftp.retrFile("payload.jpg", "payload2.jpg") +## echo("Finished") +## +## waitFor main(ftp) + import asyncdispatch, asyncnet, strutils, parseutils, os, times -from ftpclient import TFtpBase, EInvalidReply, TFtpEvent -from net import bufferSize +from ftpclient import FtpBaseObj, ReplyError, FtpEvent +from net import BufferSize type - TAsyncFtpClient* = TFtpBase[PAsyncSocket] - PAsyncFtpClient* = ref TAsyncFtpClient + AsyncFtpClientObj* = FtpBaseObj[AsyncSocket] + AsyncFtpClient* = ref AsyncFtpClientObj ProgressChangedProc* = proc (total, progress: BiggestInt, speed: float): - PFuture[void] {.closure, gcsafe.} + Future[void] {.closure, gcsafe.} -proc expectReply(ftp: PAsyncFtpClient): PFuture[TaintedString] = +proc expectReply(ftp: AsyncFtpClient): Future[TaintedString] = result = ftp.csock.recvLine() -proc send*(ftp: PAsyncFtpClient, m: string): PFuture[TaintedString] {.async.} = +proc send*(ftp: AsyncFtpClient, m: string): Future[TaintedString] {.async.} = ## Send a message to the server, and wait for a primary reply. ## ``\c\L`` is added for you. await ftp.csock.send(m & "\c\L") @@ -31,11 +49,11 @@ proc send*(ftp: PAsyncFtpClient, m: string): PFuture[TaintedString] {.async.} = proc assertReply(received: TaintedString, expected: varargs[string]) = for i in items(expected): if received.string.startsWith(i): return - raise newException(EInvalidReply, + raise newException(ReplyError, "Expected reply '$1' got: $2" % [expected.join("' or '"), received.string]) -proc pasv(ftp: PAsyncFtpClient) {.async.} = +proc pasv(ftp: AsyncFtpClient) {.async.} = ## Negotiate a data connection. ftp.dsock = newAsyncSocket() @@ -46,13 +64,13 @@ proc pasv(ftp: PAsyncFtpClient) {.async.} = var ip = nums[0.. -3] var port = nums[-2.. -1] var properPort = port[0].parseInt()*256+port[1].parseInt() - await ftp.dsock.connect(ip.join("."), TPort(properPort.toU16)) - ftp.dsockConnected = True + await ftp.dsock.connect(ip.join("."), Port(properPort.toU16)) + ftp.dsockConnected = true proc normalizePathSep(path: string): string = return replace(path, '\\', '/') -proc connect*(ftp: PAsyncFtpClient) {.async.} = +proc connect*(ftp: AsyncFtpClient) {.async.} = ## Connect to the FTP server specified by ``ftp``. await ftp.csock.connect(ftp.address, ftp.port) @@ -69,21 +87,21 @@ proc connect*(ftp: PAsyncFtpClient) {.async.} = if ftp.pass != "": assertReply(await(ftp.send("PASS " & ftp.pass)), "230") -proc pwd*(ftp: PAsyncFtpClient): PFuture[TaintedString] {.async.} = +proc pwd*(ftp: AsyncFtpClient): Future[TaintedString] {.async.} = ## Returns the current working directory. let wd = await ftp.send("PWD") assertReply wd, "257" return wd.string.captureBetween('"').TaintedString # " -proc cd*(ftp: PAsyncFtpClient, dir: string) {.async.} = +proc cd*(ftp: AsyncFtpClient, dir: string) {.async.} = ## Changes the current directory on the remote FTP server to ``dir``. assertReply(await(ftp.send("CWD " & dir.normalizePathSep)), "250") -proc cdup*(ftp: PAsyncFtpClient) {.async.} = +proc cdup*(ftp: AsyncFtpClient) {.async.} = ## Changes the current directory to the parent of the current directory. assertReply(await(ftp.send("CDUP")), "200") -proc getLines(ftp: PAsyncFtpClient): PFuture[string] {.async.} = +proc getLines(ftp: AsyncFtpClient): Future[string] {.async.} = ## Downloads text data in ASCII mode result = "" assert ftp.dsockConnected @@ -96,7 +114,7 @@ proc getLines(ftp: PAsyncFtpClient): PFuture[string] {.async.} = assertReply(await(ftp.expectReply()), "226") -proc listDirs*(ftp: PAsyncFtpClient, dir = ""): PFuture[seq[string]] {.async.} = +proc listDirs*(ftp: AsyncFtpClient, dir = ""): Future[seq[string]] {.async.} = ## Returns a list of filenames in the given directory. If ``dir`` is "", ## the current directory is used. If ``async`` is true, this ## function will return immediately and it will be your job to @@ -107,13 +125,13 @@ proc listDirs*(ftp: PAsyncFtpClient, dir = ""): PFuture[seq[string]] {.async.} = result = splitLines(await ftp.getLines()) -proc existsFile*(ftp: PAsyncFtpClient, file: string): PFuture[bool] {.async.} = +proc existsFile*(ftp: AsyncFtpClient, file: string): Future[bool] {.async.} = ## Determines whether ``file`` exists. var files = await ftp.listDirs() for f in items(files): if f.normalizePathSep == file.normalizePathSep: return true -proc createDir*(ftp: PAsyncFtpClient, dir: string, recursive = false){.async.} = +proc createDir*(ftp: AsyncFtpClient, dir: string, recursive = false){.async.} = ## Creates a directory ``dir``. If ``recursive`` is true, the topmost ## subdirectory of ``dir`` will be created first, following the secondmost... ## etc. this allows you to give a full path as the ``dir`` without worrying @@ -123,14 +141,14 @@ proc createDir*(ftp: PAsyncFtpClient, dir: string, recursive = false){.async.} = else: var reply = TaintedString"" var previousDirs = "" - for p in split(dir, {os.dirSep, os.altSep}): + for p in split(dir, {os.DirSep, os.AltSep}): if p != "": previousDirs.add(p) reply = await ftp.send("MKD " & previousDirs) previousDirs.add('/') assertReply reply, "257" -proc chmod*(ftp: PAsyncFtpClient, path: string, +proc chmod*(ftp: AsyncFtpClient, path: string, permissions: set[TFilePermission]) {.async.} = ## Changes permission of ``path`` to ``permissions``. var userOctal = 0 @@ -152,7 +170,7 @@ proc chmod*(ftp: PAsyncFtpClient, path: string, assertReply(await(ftp.send("SITE CHMOD " & perm & " " & path.normalizePathSep)), "200") -proc list*(ftp: PAsyncFtpClient, dir = ""): PFuture[string] {.async.} = +proc list*(ftp: AsyncFtpClient, dir = ""): Future[string] {.async.} = ## Lists all files in ``dir``. If ``dir`` is ``""``, uses the current ## working directory. await ftp.pasv() @@ -162,7 +180,7 @@ proc list*(ftp: PAsyncFtpClient, dir = ""): PFuture[string] {.async.} = result = await ftp.getLines() -proc retrText*(ftp: PAsyncFtpClient, file: string): PFuture[string] {.async.} = +proc retrText*(ftp: AsyncFtpClient, file: string): Future[string] {.async.} = ## Retrieves ``file``. File must be ASCII text. await ftp.pasv() let reply = await ftp.send("RETR " & file.normalizePathSep) @@ -170,13 +188,13 @@ proc retrText*(ftp: PAsyncFtpClient, file: string): PFuture[string] {.async.} = result = await ftp.getLines() -proc getFile(ftp: PAsyncFtpClient, file: TFile, total: BiggestInt, +proc getFile(ftp: AsyncFtpClient, file: TFile, total: BiggestInt, onProgressChanged: ProgressChangedProc) {.async.} = assert ftp.dsockConnected var progress = 0 var progressInSecond = 0 var countdownFut = sleepAsync(1000) - var dataFut = ftp.dsock.recv(bufferSize) + var dataFut = ftp.dsock.recv(BufferSize) while ftp.dsockConnected: await dataFut or countdownFut if countdownFut.finished: @@ -191,20 +209,20 @@ proc getFile(ftp: PAsyncFtpClient, file: TFile, total: BiggestInt, progress.inc(data.len) progressInSecond.inc(data.len) file.write(data) - dataFut = ftp.dsock.recv(bufferSize) + dataFut = ftp.dsock.recv(BufferSize) else: - ftp.dsockConnected = False + ftp.dsockConnected = false assertReply(await(ftp.expectReply()), "226") proc defaultOnProgressChanged*(total, progress: BiggestInt, - speed: float): PFuture[void] {.nimcall,gcsafe.} = + speed: float): Future[void] {.nimcall,gcsafe.} = ## Default FTP ``onProgressChanged`` handler. Does nothing. result = newFuture[void]() #echo(total, " ", progress, " ", speed) result.complete() -proc retrFile*(ftp: PAsyncFtpClient, file, dest: string, +proc retrFile*(ftp: AsyncFtpClient, file, dest: string, onProgressChanged = defaultOnProgressChanged) {.async.} = ## Downloads ``file`` and saves it to ``dest``. ## The ``EvRetr`` event is passed to the specified ``handleEvent`` function @@ -215,14 +233,14 @@ proc retrFile*(ftp: PAsyncFtpClient, file, dest: string, var reply = await ftp.send("RETR " & file.normalizePathSep) assertReply reply, ["125", "150"] if {'(', ')'} notin reply.string: - raise newException(EInvalidReply, "Reply has no file size.") - var fileSize: biggestInt + raise newException(ReplyError, "Reply has no file size.") + var fileSize: BiggestInt if reply.string.captureBetween('(', ')').parseBiggestInt(fileSize) == 0: - raise newException(EInvalidReply, "Reply has no file size.") + raise newException(ReplyError, "Reply has no file size.") await getFile(ftp, destFile, fileSize, onProgressChanged) -proc doUpload(ftp: PAsyncFtpClient, file: TFile, +proc doUpload(ftp: AsyncFtpClient, file: TFile, onProgressChanged: ProgressChangedProc) {.async.} = assert ftp.dsockConnected @@ -231,7 +249,7 @@ proc doUpload(ftp: PAsyncFtpClient, file: TFile, var progress = 0 var progressInSecond = 0 var countdownFut = sleepAsync(1000) - var sendFut: PFuture[void] = nil + var sendFut: Future[void] = nil while ftp.dsockConnected: if sendFut == nil or sendFut.finished: progress.inc(data.len) @@ -255,7 +273,7 @@ proc doUpload(ftp: PAsyncFtpClient, file: TFile, await countdownFut or sendFut -proc storeFile*(ftp: PAsyncFtpClient, file, dest: string, +proc store*(ftp: AsyncFtpClient, file, dest: string, onProgressChanged = defaultOnProgressChanged) {.async.} = ## Uploads ``file`` to ``dest`` on the remote FTP server. Usage of this ## function asynchronously is recommended to view the progress of @@ -271,9 +289,9 @@ proc storeFile*(ftp: PAsyncFtpClient, file, dest: string, await doUpload(ftp, destFile, onProgressChanged) -proc newAsyncFtpClient*(address: string, port = TPort(21), - user, pass = ""): PAsyncFtpClient = - ## Creates a new ``PAsyncFtpClient`` object. +proc newAsyncFtpClient*(address: string, port = Port(21), + user, pass = ""): AsyncFtpClient = + ## Creates a new ``AsyncFtpClient`` object. new result result.user = user result.pass = pass @@ -284,11 +302,11 @@ proc newAsyncFtpClient*(address: string, port = TPort(21), when isMainModule: var ftp = newAsyncFtpClient("example.com", user = "test", pass = "test") - proc main(ftp: PAsyncFtpClient) {.async.} = + proc main(ftp: AsyncFtpClient) {.async.} = await ftp.connect() echo await ftp.pwd() echo await ftp.listDirs() - await ftp.storeFile("payload.jpg", "payload.jpg") + await ftp.store("payload.jpg", "payload.jpg") await ftp.retrFile("payload.jpg", "payload2.jpg") echo("Finished") diff --git a/lib/pure/asynchttpserver.nim b/lib/pure/asynchttpserver.nim index c8bd5cfc1..257fbaeb5 100644 --- a/lib/pure/asynchttpserver.nim +++ b/lib/pure/asynchttpserver.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Dominik Picheta # # See the file "copying.txt", included in this @@ -9,11 +9,24 @@ ## This module implements a high performance asynchronous HTTP server. ## -## **Note:** This module is still largely experimental. +## Examples +## -------- +## +## This example will create an HTTP server on port 8080. The server will +## respond to all requests with a ``200 OK`` response code and "Hello World" +## as the response body. +## +## .. code-block::nim +## var server = newAsyncHttpServer() +## proc cb(req: TRequest) {.async.} = +## await req.respond(Http200, "Hello World") +## +## asyncCheck server.serve(Port(8080), cb) +## runForever() import strtabs, asyncnet, asyncdispatch, parseutils, uri, strutils type - TRequest* = object + Request* = object client*: PAsyncSocket # TODO: Separate this into a Response object? reqMethod*: string headers*: PStringTable @@ -22,10 +35,10 @@ type hostname*: string ## The hostname of the client that made the request. body*: string - PAsyncHttpServer* = ref object + AsyncHttpServer* = ref object socket: PAsyncSocket - THttpCode* = enum + HttpCode* = enum Http200 = "200 OK", Http303 = "303 Moved", Http400 = "400 Bad Request", @@ -33,10 +46,13 @@ type Http500 = "500 Internal Server Error", Http502 = "502 Bad Gateway" - THttpVersion* = enum + HttpVersion* = enum HttpVer11, HttpVer10 +{.deprecated: [TRequest: Request, PAsyncHttpServer: AsyncHttpServer, + THttpCode: HttpCode, THttpVersion: HttpVersion].} + proc `==`*(protocol: tuple[orig: string, major, minor: int], ver: THttpVersion): bool = let major = @@ -49,13 +65,14 @@ proc `==`*(protocol: tuple[orig: string, major, minor: int], result = protocol.major == major and protocol.minor == minor proc newAsyncHttpServer*(): PAsyncHttpServer = + ## Creates a new ``AsyncHttpServer`` instance. new result proc addHeaders(msg: var string, headers: PStringTable) = for k, v in headers: msg.add(k & ": " & v & "\c\L") -proc sendHeaders*(req: TRequest, headers: PStringTable): PFuture[void] = +proc sendHeaders*(req: TRequest, headers: PStringTable): Future[void] = ## Sends the specified headers to the requesting client. var msg = "" addHeaders(msg, headers) @@ -93,13 +110,13 @@ proc parseProtocol(protocol: string): tuple[orig: string, major, minor: int] = i.inc # Skip . i.inc protocol.parseInt(result.minor, i) -proc sendStatus(client: PAsyncSocket, status: string): PFuture[void] = +proc sendStatus(client: PAsyncSocket, status: string): Future[void] = client.send("HTTP/1.1 " & status & "\c\L") proc processClient(client: PAsyncSocket, address: string, callback: proc (request: TRequest): - PFuture[void] {.closure, gcsafe.}) {.async.} = - while true: + Future[void] {.closure, gcsafe.}) {.async.} = + while not client.closed: # GET /path HTTP/1.1 # Header: val # \n @@ -180,12 +197,13 @@ proc processClient(client: PAsyncSocket, address: string, # header states otherwise. # In HTTP 1.0 we assume that the connection should not be persistent. # Unless the connection header states otherwise. + discard else: request.client.close() break -proc serve*(server: PAsyncHttpServer, port: TPort, - callback: proc (request: TRequest): PFuture[void] {.closure,gcsafe.}, +proc serve*(server: PAsyncHttpServer, port: Port, + callback: proc (request: TRequest): Future[void] {.closure,gcsafe.}, address = "") {.async.} = ## Starts the process of listening for incoming HTTP connections on the ## specified address and port. @@ -217,6 +235,6 @@ when isMainModule: "Content-type": "text/plain; charset=utf-8"} await req.respond(Http200, "Hello World", headers.newStringTable()) - asyncCheck server.serve(TPort(5555), cb) + asyncCheck server.serve(Port(5555), cb) runForever() main() diff --git a/lib/pure/asyncio.nim b/lib/pure/asyncio.nim index 6b67bf4b5..0dbc0a3d5 100644 --- a/lib/pure/asyncio.nim +++ b/lib/pure/asyncio.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf, Dominik Picheta # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -10,8 +10,8 @@ include "system/inclrtl" import sockets, os -## This module implements an asynchronous event loop together with asynchronous sockets -## which use this event loop. +## This module implements an asynchronous event loop together with asynchronous +## sockets which use this event loop. ## It is akin to Python's asyncore module. Many modules that use sockets ## have an implementation for this module, those modules should all have a ## ``register`` function which you should use to add the desired objects to a @@ -31,10 +31,10 @@ import sockets, os ## ## Most (if not all) modules that use asyncio provide a userArg which is passed ## on with the events. The type that you set userArg to must be inheriting from -## TObject! +## ``RootObj``! ## ## **Note:** If you want to provide async ability to your module please do not -## use the ``TDelegate`` object, instead use ``PAsyncSocket``. It is possible +## use the ``Delegate`` object, instead use ``AsyncSocket``. It is possible ## that in the future this type's fields will not be exported therefore breaking ## your code. ## @@ -44,10 +44,10 @@ import sockets, os ## Asynchronous sockets ## ==================== ## -## For most purposes you do not need to worry about the ``TDelegate`` type. The -## ``PAsyncSocket`` is what you are after. It's a reference to the ``TAsyncSocket`` -## object. This object defines events which you should overwrite by your own -## procedures. +## For most purposes you do not need to worry about the ``Delegate`` type. The +## ``AsyncSocket`` is what you are after. It's a reference to +## the ``AsyncSocketObj`` object. This object defines events which you should +## overwrite by your own procedures. ## ## For server sockets the only event you need to worry about is the ``handleAccept`` ## event, in your handleAccept proc you should call ``accept`` on the server @@ -57,13 +57,13 @@ import sockets, os ## ## An example ``handleAccept`` follows: ## -## .. code-block:: nimrod +## .. code-block:: nim ## -## var disp: PDispatcher = newDispatcher() +## var disp = newDispatcher() ## ... -## proc handleAccept(s: PAsyncSocket) = +## proc handleAccept(s: AsyncSocket) = ## echo("Accepted client.") -## var client: PAsyncSocket +## var client: AsyncSocket ## new(client) ## s.accept(client) ## client.handleRead = ... @@ -76,103 +76,111 @@ import sockets, os ## the socket has established a connection to a server socket; from that point ## it can be safely written to. ## -## Getting a blocking client from a PAsyncSocket +## Getting a blocking client from an AsyncSocket ## ============================================= ## ## If you need a asynchronous server socket but you wish to process the clients -## synchronously then you can use the ``getSocket`` converter to get a TSocket -## object from the PAsyncSocket object, this can then be combined with ``accept`` -## like so: +## synchronously then you can use the ``getSocket`` converter to get +## a ``Socket`` from the ``AsyncSocket`` object, this can then be combined +## with ``accept`` like so: ## -## .. code-block:: nimrod +## .. code-block:: nim ## -## proc handleAccept(s: PAsyncSocket) = -## var client: TSocket +## proc handleAccept(s: AsyncSocket) = +## var client: Socket ## getSocket(s).accept(client) when defined(windows): - from winlean import TTimeVal, TSocketHandle, TFdSet, FD_ZERO, FD_SET, FD_ISSET, select + from winlean import TimeVal, SocketHandle, FD_SET, FD_ZERO, TFdSet, + FD_ISSET, select else: - from posix import TTimeVal, TSocketHandle, TFdSet, FD_ZERO, FD_SET, FD_ISSET, select + from posix import TimeVal, SocketHandle, FD_SET, FD_ZERO, TFdSet, + FD_ISSET, select type - TDelegate* = object - fd*: TSocketHandle - deleVal*: PObject - - handleRead*: proc (h: PObject) {.nimcall, gcsafe.} - handleWrite*: proc (h: PObject) {.nimcall, gcsafe.} - handleError*: proc (h: PObject) {.nimcall, gcsafe.} - hasDataBuffered*: proc (h: PObject): bool {.nimcall, gcsafe.} + DelegateObj* = object + fd*: SocketHandle + deleVal*: RootRef + + handleRead*: proc (h: RootRef) {.nimcall, gcsafe.} + handleWrite*: proc (h: RootRef) {.nimcall, gcsafe.} + handleError*: proc (h: RootRef) {.nimcall, gcsafe.} + hasDataBuffered*: proc (h: RootRef): bool {.nimcall, gcsafe.} open*: bool - task*: proc (h: PObject) {.nimcall, gcsafe.} - mode*: TFileMode + task*: proc (h: RootRef) {.nimcall, gcsafe.} + mode*: FileMode - PDelegate* = ref TDelegate + Delegate* = ref DelegateObj - PDispatcher* = ref TDispatcher - TDispatcher = object - delegates: seq[PDelegate] + Dispatcher* = ref DispatcherObj + DispatcherObj = object + delegates: seq[Delegate] - PAsyncSocket* = ref TAsyncSocket - TAsyncSocket* = object of TObject - socket: TSocket - info: TInfo + AsyncSocket* = ref AsyncSocketObj + AsyncSocketObj* = object of RootObj + socket: Socket + info: SocketStatus - handleRead*: proc (s: PAsyncSocket) {.closure, gcsafe.} - handleWrite: proc (s: PAsyncSocket) {.closure, gcsafe.} - handleConnect*: proc (s: PAsyncSocket) {.closure, gcsafe.} + handleRead*: proc (s: AsyncSocket) {.closure, gcsafe.} + handleWrite: proc (s: AsyncSocket) {.closure, gcsafe.} + handleConnect*: proc (s: AsyncSocket) {.closure, gcsafe.} - handleAccept*: proc (s: PAsyncSocket) {.closure, gcsafe.} + handleAccept*: proc (s: AsyncSocket) {.closure, gcsafe.} - handleTask*: proc (s: PAsyncSocket) {.closure, gcsafe.} + handleTask*: proc (s: AsyncSocket) {.closure, gcsafe.} lineBuffer: TaintedString ## Temporary storage for ``readLine`` sendBuffer: string ## Temporary storage for ``send`` sslNeedAccept: bool - proto: TProtocol - deleg: PDelegate + proto: Protocol + deleg: Delegate - TInfo* = enum + SocketStatus* = enum SockIdle, SockConnecting, SockConnected, SockListening, SockClosed, SockUDPBound -proc newDelegate*(): PDelegate = +{.deprecated: [TDelegate: DelegateObj, PDelegate: Delegate, + TInfo: SocketStatus, PAsyncSocket: AsyncSocket, TAsyncSocket: AsyncSocketObj, + TDispatcher: DispatcherObj, PDispatcher: Dispatcher, + ].} + + +proc newDelegate*(): Delegate = ## Creates a new delegate. new(result) - result.handleRead = (proc (h: PObject) = discard) - result.handleWrite = (proc (h: PObject) = discard) - result.handleError = (proc (h: PObject) = discard) - result.hasDataBuffered = (proc (h: PObject): bool = return false) - result.task = (proc (h: PObject) = discard) + result.handleRead = (proc (h: RootRef) = discard) + result.handleWrite = (proc (h: RootRef) = discard) + result.handleError = (proc (h: RootRef) = discard) + result.hasDataBuffered = (proc (h: RootRef): bool = return false) + result.task = (proc (h: RootRef) = discard) result.mode = fmRead -proc newAsyncSocket(): PAsyncSocket = +proc newAsyncSocket(): AsyncSocket = new(result) result.info = SockIdle - result.handleRead = (proc (s: PAsyncSocket) = discard) + result.handleRead = (proc (s: AsyncSocket) = discard) result.handleWrite = nil - result.handleConnect = (proc (s: PAsyncSocket) = discard) - result.handleAccept = (proc (s: PAsyncSocket) = discard) - result.handleTask = (proc (s: PAsyncSocket) = discard) + result.handleConnect = (proc (s: AsyncSocket) = discard) + result.handleAccept = (proc (s: AsyncSocket) = discard) + result.handleTask = (proc (s: AsyncSocket) = discard) result.lineBuffer = "".TaintedString result.sendBuffer = "" -proc asyncSocket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, - protocol: TProtocol = IPPROTO_TCP, - buffered = true): PAsyncSocket = +proc asyncSocket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM, + protocol: Protocol = IPPROTO_TCP, + buffered = true): AsyncSocket = ## Initialises an AsyncSocket object. If a socket cannot be initialised ## EOS is raised. result = newAsyncSocket() result.socket = socket(domain, typ, protocol, buffered) result.proto = protocol - if result.socket == invalidSocket: osError(osLastError()) + if result.socket == invalidSocket: raiseOSError(osLastError()) result.socket.setBlocking(false) -proc toAsyncSocket*(sock: TSocket, state: TInfo = SockConnected): PAsyncSocket = +proc toAsyncSocket*(sock: Socket, state: SocketStatus = SockConnected): PAsyncSocket = ## Wraps an already initialized ``TSocket`` into a PAsyncSocket. ## This is useful if you want to use an already connected TSocket as an ## asynchronous PAsyncSocket in asyncio's event loop. @@ -203,57 +211,58 @@ proc toAsyncSocket*(sock: TSocket, state: TInfo = SockConnected): PAsyncSocket = result.socket.setBlocking(false) result.info = state -proc asyncSockHandleRead(h: PObject) = +proc asyncSockHandleRead(h: RootRef) = when defined(ssl): if PAsyncSocket(h).socket.isSSL and not PAsyncSocket(h).socket.gotHandshake: return - if PAsyncSocket(h).info != SockListening: - if PAsyncSocket(h).info != SockConnecting: - PAsyncSocket(h).handleRead(PAsyncSocket(h)) + if AsyncSocket(h).info != SockListening: + if AsyncSocket(h).info != SockConnecting: + AsyncSocket(h).handleRead(AsyncSocket(h)) else: - PAsyncSocket(h).handleAccept(PAsyncSocket(h)) + AsyncSocket(h).handleAccept(AsyncSocket(h)) -proc close*(sock: PAsyncSocket) {.gcsafe.} -proc asyncSockHandleWrite(h: PObject) = +proc close*(sock: AsyncSocket) {.gcsafe.} +proc asyncSockHandleWrite(h: RootRef) = when defined(ssl): if PAsyncSocket(h).socket.isSSL and not PAsyncSocket(h).socket.gotHandshake: return - if PAsyncSocket(h).info == SockConnecting: - PAsyncSocket(h).handleConnect(PAsyncSocket(h)) - PAsyncSocket(h).info = SockConnected + if AsyncSocket(h).info == SockConnecting: + AsyncSocket(h).handleConnect(AsyncSocket(h)) + AsyncSocket(h).info = SockConnected # Stop receiving write events if there is no handleWrite event. - if PAsyncSocket(h).handleWrite == nil: - PAsyncSocket(h).deleg.mode = fmRead + if AsyncSocket(h).handleWrite == nil: + AsyncSocket(h).deleg.mode = fmRead else: - PAsyncSocket(h).deleg.mode = fmReadWrite + AsyncSocket(h).deleg.mode = fmReadWrite else: - if PAsyncSocket(h).sendBuffer != "": - let sock = PAsyncSocket(h) + if AsyncSocket(h).sendBuffer != "": + let sock = AsyncSocket(h) try: let bytesSent = sock.socket.sendAsync(sock.sendBuffer) if bytesSent == 0: # Apparently the socket cannot be written to. Even though select # just told us that it can be... This used to be an assert. Just # do nothing instead. + discard elif bytesSent != sock.sendBuffer.len: sock.sendBuffer = sock.sendBuffer[bytesSent .. -1] elif bytesSent == sock.sendBuffer.len: sock.sendBuffer = "" - if PAsyncSocket(h).handleWrite != nil: - PAsyncSocket(h).handleWrite(PAsyncSocket(h)) - except EOS: + if AsyncSocket(h).handleWrite != nil: + AsyncSocket(h).handleWrite(AsyncSocket(h)) + except OSError: # Most likely the socket closed before the full buffer could be sent to it. sock.close() # TODO: Provide a handleError for users? else: - if PAsyncSocket(h).handleWrite != nil: - PAsyncSocket(h).handleWrite(PAsyncSocket(h)) + if AsyncSocket(h).handleWrite != nil: + AsyncSocket(h).handleWrite(AsyncSocket(h)) else: - PAsyncSocket(h).deleg.mode = fmRead + AsyncSocket(h).deleg.mode = fmRead when defined(ssl): proc asyncSockDoHandshake(h: PObject) {.gcsafe.} = @@ -270,13 +279,13 @@ when defined(ssl): discard PAsyncSocket(h).socket.handshake() -proc asyncSockTask(h: PObject) = +proc asyncSockTask(h: RootRef) = when defined(ssl): h.asyncSockDoHandshake() - PAsyncSocket(h).handleTask(PAsyncSocket(h)) + AsyncSocket(h).handleTask(AsyncSocket(h)) -proc toDelegate(sock: PAsyncSocket): PDelegate = +proc toDelegate(sock: AsyncSocket): Delegate = result = newDelegate() result.deleVal = sock result.fd = getFD(sock.socket) @@ -289,8 +298,8 @@ proc toDelegate(sock: PAsyncSocket): PDelegate = #result.handleError = (proc (h: PObject) = assert(false)) result.hasDataBuffered = - proc (h: PObject): bool {.nimcall.} = - return PAsyncSocket(h).socket.hasDataBuffered() + proc (h: RootRef): bool {.nimcall.} = + return AsyncSocket(h).socket.hasDataBuffered() sock.deleg = result if sock.info notin {SockIdle, SockClosed}: @@ -298,22 +307,22 @@ proc toDelegate(sock: PAsyncSocket): PDelegate = else: sock.deleg.open = false -proc connect*(sock: PAsyncSocket, name: string, port = TPort(0), - af: TDomain = AF_INET) = +proc connect*(sock: AsyncSocket, name: string, port = Port(0), + af: Domain = AF_INET) = ## Begins connecting ``sock`` to ``name``:``port``. sock.socket.connectAsync(name, port, af) sock.info = SockConnecting if sock.deleg != nil: sock.deleg.open = true -proc close*(sock: PAsyncSocket) = +proc close*(sock: AsyncSocket) = ## Closes ``sock``. Terminates any current connections. sock.socket.close() sock.info = SockClosed if sock.deleg != nil: sock.deleg.open = false -proc bindAddr*(sock: PAsyncSocket, port = TPort(0), address = "") = +proc bindAddr*(sock: AsyncSocket, port = Port(0), address = "") = ## Equivalent to ``sockets.bindAddr``. sock.socket.bindAddr(port, address) if sock.proto == IPPROTO_UDP: @@ -321,14 +330,14 @@ proc bindAddr*(sock: PAsyncSocket, port = TPort(0), address = "") = if sock.deleg != nil: sock.deleg.open = true -proc listen*(sock: PAsyncSocket) = +proc listen*(sock: AsyncSocket) = ## Equivalent to ``sockets.listen``. sock.socket.listen() sock.info = SockListening if sock.deleg != nil: sock.deleg.open = true -proc acceptAddr*(server: PAsyncSocket, client: var PAsyncSocket, +proc acceptAddr*(server: AsyncSocket, client: var AsyncSocket, address: var string) = ## Equivalent to ``sockets.acceptAddr``. This procedure should be called in ## a ``handleAccept`` event handler **only** once. @@ -336,7 +345,7 @@ proc acceptAddr*(server: PAsyncSocket, client: var PAsyncSocket, ## **Note**: ``client`` needs to be initialised. assert(client != nil) client = newAsyncSocket() - var c: TSocket + var c: Socket new(c) when defined(ssl): if server.socket.isSSL: @@ -359,7 +368,7 @@ proc acceptAddr*(server: PAsyncSocket, client: var PAsyncSocket, client.sslNeedAccept = false client.info = SockConnected - if c == invalidSocket: socketError(server.socket) + if c == invalidSocket: raiseSocketError(server.socket) c.setBlocking(false) # TODO: Needs to be tested. # deleg.open is set in ``toDelegate``. @@ -369,12 +378,12 @@ proc acceptAddr*(server: PAsyncSocket, client: var PAsyncSocket, client.sendBuffer = "" client.info = SockConnected -proc accept*(server: PAsyncSocket, client: var PAsyncSocket) = +proc accept*(server: AsyncSocket, client: var AsyncSocket) = ## Equivalent to ``sockets.accept``. var dummyAddr = "" server.acceptAddr(client, dummyAddr) -proc acceptAddr*(server: PAsyncSocket): tuple[sock: PAsyncSocket, +proc acceptAddr*(server: AsyncSocket): tuple[sock: AsyncSocket, address: string] {.deprecated.} = ## Equivalent to ``sockets.acceptAddr``. ## @@ -384,7 +393,7 @@ proc acceptAddr*(server: PAsyncSocket): tuple[sock: PAsyncSocket, acceptAddr(server, client, address) return (client, address) -proc accept*(server: PAsyncSocket): PAsyncSocket {.deprecated.} = +proc accept*(server: AsyncSocket): AsyncSocket {.deprecated.} = ## Equivalent to ``sockets.accept``. ## ## **Deprecated since version 0.9.0:** Please use the function above. @@ -392,54 +401,54 @@ proc accept*(server: PAsyncSocket): PAsyncSocket {.deprecated.} = var address = "" server.acceptAddr(result, address) -proc newDispatcher*(): PDispatcher = +proc newDispatcher*(): Dispatcher = new(result) result.delegates = @[] -proc register*(d: PDispatcher, deleg: PDelegate) = +proc register*(d: Dispatcher, deleg: Delegate) = ## Registers delegate ``deleg`` with dispatcher ``d``. d.delegates.add(deleg) -proc register*(d: PDispatcher, sock: PAsyncSocket): PDelegate {.discardable.} = +proc register*(d: Dispatcher, sock: AsyncSocket): Delegate {.discardable.} = ## Registers async socket ``sock`` with dispatcher ``d``. result = sock.toDelegate() d.register(result) -proc unregister*(d: PDispatcher, deleg: PDelegate) = +proc unregister*(d: Dispatcher, deleg: Delegate) = ## Unregisters deleg ``deleg`` from dispatcher ``d``. for i in 0..len(d.delegates)-1: if d.delegates[i] == deleg: d.delegates.del(i) return - raise newException(EInvalidIndex, "Could not find delegate.") + raise newException(IndexError, "Could not find delegate.") -proc isWriteable*(s: PAsyncSocket): bool = +proc isWriteable*(s: AsyncSocket): bool = ## Determines whether socket ``s`` is ready to be written to. var writeSock = @[s.socket] return selectWrite(writeSock, 1) != 0 and s.socket notin writeSock -converter getSocket*(s: PAsyncSocket): TSocket = +converter getSocket*(s: AsyncSocket): Socket = return s.socket -proc isConnected*(s: PAsyncSocket): bool = +proc isConnected*(s: AsyncSocket): bool = ## Determines whether ``s`` is connected. return s.info == SockConnected -proc isListening*(s: PAsyncSocket): bool = +proc isListening*(s: AsyncSocket): bool = ## Determines whether ``s`` is listening for incoming connections. return s.info == SockListening -proc isConnecting*(s: PAsyncSocket): bool = +proc isConnecting*(s: AsyncSocket): bool = ## Determines whether ``s`` is connecting. return s.info == SockConnecting -proc isClosed*(s: PAsyncSocket): bool = +proc isClosed*(s: AsyncSocket): bool = ## Determines whether ``s`` has been closed. return s.info == SockClosed -proc isSendDataBuffered*(s: PAsyncSocket): bool = +proc isSendDataBuffered*(s: AsyncSocket): bool = ## Determines whether ``s`` has data waiting to be sent, i.e. whether this ## socket's sendBuffer contains data. return s.sendBuffer.len != 0 -proc setHandleWrite*(s: PAsyncSocket, - handleWrite: proc (s: PAsyncSocket) {.closure, gcsafe.}) = +proc setHandleWrite*(s: AsyncSocket, + handleWrite: proc (s: AsyncSocket) {.closure, gcsafe.}) = ## Setter for the ``handleWrite`` event. ## ## To remove this event you should use the ``delHandleWrite`` function. @@ -449,12 +458,12 @@ proc setHandleWrite*(s: PAsyncSocket, s.deleg.mode = fmReadWrite s.handleWrite = handleWrite -proc delHandleWrite*(s: PAsyncSocket) = +proc delHandleWrite*(s: AsyncSocket) = ## Removes the ``handleWrite`` event handler on ``s``. s.handleWrite = nil {.push warning[deprecated]: off.} -proc recvLine*(s: PAsyncSocket, line: var TaintedString): bool {.deprecated.} = +proc recvLine*(s: AsyncSocket, line: var TaintedString): bool {.deprecated.} = ## Behaves similar to ``sockets.recvLine``, however it handles non-blocking ## sockets properly. This function guarantees that ``line`` is a full line, ## if this function can only retrieve some data; it will save this data and @@ -483,11 +492,11 @@ proc recvLine*(s: PAsyncSocket, line: var TaintedString): bool {.deprecated.} = of RecvDisconnected: result = true of RecvFail: - s.socketError(async = true) + s.raiseSocketError(async = true) result = false {.pop.} -proc readLine*(s: PAsyncSocket, line: var TaintedString): bool = +proc readLine*(s: AsyncSocket, line: var TaintedString): bool = ## Behaves similar to ``sockets.readLine``, however it handles non-blocking ## sockets properly. This function guarantees that ``line`` is a full line, ## if this function can only retrieve some data; it will save this data and @@ -517,7 +526,7 @@ proc readLine*(s: PAsyncSocket, line: var TaintedString): bool = of ReadDisconnected: result = true -proc send*(sock: PAsyncSocket, data: string) = +proc send*(sock: AsyncSocket, data: string) = ## Sends ``data`` to socket ``sock``. This is basically a nicer implementation ## of ``sockets.sendAsync``. ## @@ -537,19 +546,19 @@ proc send*(sock: PAsyncSocket, data: string) = sock.sendBuffer.add(data[bytesSent .. -1]) sock.deleg.mode = fmReadWrite -proc timeValFromMilliseconds(timeout = 500): TTimeVal = +proc timeValFromMilliseconds(timeout = 500): Timeval = if timeout != -1: var seconds = timeout div 1000 result.tv_sec = seconds.int32 result.tv_usec = ((timeout - seconds * 1000) * 1000).int32 -proc createFdSet(fd: var TFdSet, s: seq[PDelegate], m: var int) = +proc createFdSet(fd: var TFdSet, s: seq[Delegate], m: var int) = FD_ZERO(fd) for i in items(s): m = max(m, int(i.fd)) FD_SET(i.fd, fd) -proc pruneSocketSet(s: var seq[PDelegate], fd: var TFdSet) = +proc pruneSocketSet(s: var seq[Delegate], fd: var TFdSet) = var i = 0 var L = s.len while i < L: @@ -560,9 +569,9 @@ proc pruneSocketSet(s: var seq[PDelegate], fd: var TFdSet) = inc(i) setLen(s, L) -proc select(readfds, writefds, exceptfds: var seq[PDelegate], +proc select(readfds, writefds, exceptfds: var seq[Delegate], timeout = 500): int = - var tv {.noInit.}: TTimeVal = timeValFromMilliseconds(timeout) + var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) var rd, wr, ex: TFdSet var m = 0 @@ -579,7 +588,7 @@ proc select(readfds, writefds, exceptfds: var seq[PDelegate], pruneSocketSet(writefds, (wr)) pruneSocketSet(exceptfds, (ex)) -proc poll*(d: PDispatcher, timeout: int = 500): bool = +proc poll*(d: Dispatcher, timeout: int = 500): bool = ## This function checks for events on all the delegates in the `PDispatcher`. ## It then proceeds to call the correct event handler. ## @@ -592,7 +601,7 @@ proc poll*(d: PDispatcher, timeout: int = 500): bool = ## only be executed after one or more file descriptors becomes readable or ## writeable. result = true - var readDg, writeDg, errorDg: seq[PDelegate] = @[] + var readDg, writeDg, errorDg: seq[Delegate] = @[] var len = d.delegates.len var dc = 0 @@ -640,7 +649,7 @@ proc poll*(d: PDispatcher, timeout: int = 500): bool = for i in items(d.delegates): i.task(i.deleVal) -proc len*(disp: PDispatcher): int = +proc len*(disp: Dispatcher): int = ## Retrieves the amount of delegates in ``disp``. return disp.delegates.len @@ -674,7 +683,7 @@ when isMainModule: proc main = var d = newDispatcher() - var s = AsyncSocket() + var s = asyncSocket() s.connect("amber.tenthbit.net", TPort(6667)) s.handleConnect = proc (s: PAsyncSocket) = @@ -684,7 +693,7 @@ when isMainModule: testRead(s, 1) d.register(s) - var server = AsyncSocket() + var server = asyncSocket() server.handleAccept = proc (s: PAsyncSocket) = testAccept(s, d, 78) diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim index 5095d9461..72fe51a7e 100644 --- a/lib/pure/asyncnet.nim +++ b/lib/pure/asyncnet.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Dominik Picheta # # See the file "copying.txt", included in this @@ -10,26 +10,39 @@ ## This module implements a high-level asynchronous sockets API based on the ## asynchronous dispatcher defined in the ``asyncdispatch`` module. ## -## Example -## ======= +## SSL +## --- +## +## SSL can be enabled by compiling with the ``-d:ssl`` flag. +## +## You must create a new SSL context with the ``newContext`` function defined +## in the ``net`` module. You may then call ``wrapSocket`` on your socket using +## the newly created SSL context to get an SSL socket. +## +## Examples +## -------- +## +## Chat server +## ^^^^^^^^^^^ ## ## The following example demonstrates a simple chat server. ## -## .. code-block::nimrod +## .. code-block::nim ## ## import asyncnet, asyncdispatch ## -## var clients: seq[PAsyncSocket] = @[] +## var clients {.threadvar.}: seq[AsyncSocket] ## -## proc processClient(client: PAsyncSocket) {.async.} = +## proc processClient(client: AsyncSocket) {.async.} = ## while true: ## let line = await client.recvLine() ## for c in clients: ## await c.send(line & "\c\L") ## ## proc serve() {.async.} = +## clients = @[] ## var server = newAsyncSocket() -## server.bindAddr(TPort(12345)) +## server.bindAddr(Port(12345)) ## server.listen() ## ## while true: @@ -41,12 +54,11 @@ ## asyncCheck serve() ## runForever() ## -## -## **Note:** This module is still largely experimental. import asyncdispatch import rawsockets import net +import os when defined(ssl): import openssl @@ -54,15 +66,33 @@ when defined(ssl): type # TODO: I would prefer to just do: # PAsyncSocket* {.borrow: `.`.} = distinct PSocket. But that doesn't work. - TAsyncSocket {.borrow: `.`.} = distinct TSocketImpl - PAsyncSocket* = ref TAsyncSocket + AsyncSocketDesc = object + fd*: SocketHandle + closed*: bool ## determines whether this socket has been closed + case isBuffered*: bool ## determines whether this socket is buffered. + of true: + buffer*: array[0..BufferSize, char] + currPos*: int # current index in buffer + bufLen*: int # current length of buffer + of false: nil + case isSsl: bool + of true: + when defined(ssl): + sslHandle: SslPtr + sslContext: SslContext + bioIn: BIO + bioOut: BIO + of false: nil + AsyncSocket* = ref AsyncSocketDesc + +{.deprecated: [PAsyncSocket: AsyncSocket].} # TODO: Save AF, domain etc info and reuse it in procs which need it like connect. proc newSocket(fd: TAsyncFD, isBuff: bool): PAsyncSocket = assert fd != osInvalidSocket.TAsyncFD - new(result.PSocket) - result.fd = fd.TSocketHandle + new(result) + result.fd = fd.SocketHandle result.isBuffered = isBuff if isBuff: result.currPos = 0 @@ -72,29 +102,114 @@ proc newAsyncSocket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, ## Creates a new asynchronous socket. result = newSocket(newAsyncRawSocket(domain, typ, protocol), buffered) +proc newAsyncSocket*(domain, typ, protocol: cint, buffered = true): PAsyncSocket = + ## Creates a new asynchronous socket. + result = newSocket(newAsyncRawSocket(domain, typ, protocol), buffered) + +when defined(ssl): + proc getSslError(handle: SslPtr, err: cint): cint = + assert err < 0 + var ret = SSLGetError(handle, err.cint) + case ret + of SSL_ERROR_ZERO_RETURN: + raiseSSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") + of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: + return ret + of SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_READ: + return ret + of SSL_ERROR_WANT_X509_LOOKUP: + raiseSSLError("Function for x509 lookup has been called.") + of SSL_ERROR_SYSCALL, SSL_ERROR_SSL: + raiseSSLError() + else: raiseSSLError("Unknown Error") + + proc sendPendingSslData(socket: AsyncSocket, + flags: set[TSocketFlags]) {.async.} = + let len = bioCtrlPending(socket.bioOut) + if len > 0: + var data = newStringOfCap(len) + let read = bioRead(socket.bioOut, addr data[0], len) + assert read != 0 + if read < 0: + raiseSslError() + data.setLen(read) + await socket.fd.TAsyncFd.send(data, flags) + + proc appeaseSsl(socket: AsyncSocket, flags: set[TSocketFlags], + sslError: cint) {.async.} = + case sslError + of SSL_ERROR_WANT_WRITE: + await sendPendingSslData(socket, flags) + of SSL_ERROR_WANT_READ: + var data = await recv(socket.fd.TAsyncFD, BufferSize, flags) + let ret = bioWrite(socket.bioIn, addr data[0], data.len.cint) + if ret < 0: + raiseSSLError() + else: + raiseSSLError("Cannot appease SSL.") + + template sslLoop(socket: AsyncSocket, flags: set[TSocketFlags], + op: expr) = + var opResult {.inject.} = -1.cint + while opResult < 0: + opResult = op + # Bit hackish here. + # TODO: Introduce an async template transformation pragma? + yield sendPendingSslData(socket, flags) + if opResult < 0: + let err = getSslError(socket.sslHandle, opResult.cint) + yield appeaseSsl(socket, flags, err.cint) + proc connect*(socket: PAsyncSocket, address: string, port: TPort, - af = AF_INET): PFuture[void] = + af = AF_INET) {.async.} = ## Connects ``socket`` to server at ``address:port``. ## - ## Returns a ``PFuture`` which will complete when the connection succeeds + ## Returns a ``Future`` which will complete when the connection succeeds ## or an error occurs. - result = connect(socket.fd.TAsyncFD, address, port, af) + await connect(socket.fd.TAsyncFD, address, port, af) + let flags = {TSocketFlags.SafeDisconn} + if socket.isSsl: + when defined(ssl): + sslSetConnectState(socket.sslHandle) + sslLoop(socket, flags, sslDoHandshake(socket.sslHandle)) + +proc readInto(buf: cstring, size: int, socket: PAsyncSocket, + flags: set[TSocketFlags]): Future[int] {.async.} = + if socket.isSsl: + when defined(ssl): + # SSL mode. + sslLoop(socket, flags, + sslRead(socket.sslHandle, buf, size.cint)) + result = opResult + else: + var data = await recv(socket.fd.TAsyncFD, size, flags) + if data.len != 0: + copyMem(buf, addr data[0], data.len) + # Not in SSL mode. + result = data.len proc readIntoBuf(socket: PAsyncSocket, - flags: set[TSocketFlags]): PFuture[int] {.async.} = - var data = await recv(socket.fd.TAsyncFD, BufferSize, flags) - if data.len != 0: - copyMem(addr socket.buffer[0], addr data[0], data.len) - socket.bufLen = data.len + flags: set[TSocketFlags]): Future[int] {.async.} = + result = await readInto(addr socket.buffer[0], BufferSize, socket, flags) socket.currPos = 0 - result = data.len + socket.bufLen = result proc recv*(socket: PAsyncSocket, size: int, - flags = {TSocketFlags.SafeDisconn}): PFuture[string] {.async.} = - ## Reads ``size`` bytes from ``socket``. Returned future will complete once - ## all of the requested data is read. If socket is disconnected during the + flags = {TSocketFlags.SafeDisconn}): Future[string] {.async.} = + ## Reads **up to** ``size`` bytes from ``socket``. + ## + ## For buffered sockets this function will attempt to read all the requested + ## data. It will read this data in ``BufferSize`` chunks. + ## + ## For unbuffered sockets this function makes no effort to read + ## all the data requested. It will return as much data as the operating system + ## gives it. + ## + ## If socket is disconnected during the ## recv operation then the future may complete with only a part of the - ## requested data read. If socket is disconnected and no data is available + ## requested data. + ## + ## If socket is disconnected and no data is available ## to be read then the future will complete with a value of ``""``. if socket.isBuffered: result = newString(size) @@ -126,24 +241,33 @@ proc recv*(socket: PAsyncSocket, size: int, socket.currPos = originalBufPos result.setLen(read) else: - result = await recv(socket.fd.TAsyncFD, size, flags) + result = newString(size) + let read = await readInto(addr result[0], size, socket, flags) + result.setLen(read) proc send*(socket: PAsyncSocket, data: string, - flags = {TSocketFlags.SafeDisconn}): PFuture[void] = + flags = {TSocketFlags.SafeDisconn}) {.async.} = ## Sends ``data`` to ``socket``. The returned future will complete once all ## data has been sent. assert socket != nil - result = send(socket.fd.TAsyncFD, data, flags) + if socket.isSsl: + when defined(ssl): + var copy = data + sslLoop(socket, flags, + sslWrite(socket.sslHandle, addr copy[0], copy.len.cint)) + await sendPendingSslData(socket, flags) + else: + await send(socket.fd.TAsyncFD, data, flags) proc acceptAddr*(socket: PAsyncSocket, flags = {TSocketFlags.SafeDisconn}): - PFuture[tuple[address: string, client: PAsyncSocket]] = + Future[tuple[address: string, client: PAsyncSocket]] = ## Accepts a new connection. Returns a future containing the client socket ## corresponding to that connection and the remote address of the client. ## The future will complete when the connection is successfully accepted. var retFuture = newFuture[tuple[address: string, client: PAsyncSocket]]("asyncnet.acceptAddr") var fut = acceptAddr(socket.fd.TAsyncFD, flags) fut.callback = - proc (future: PFuture[tuple[address: string, client: TAsyncFD]]) = + proc (future: Future[tuple[address: string, client: TAsyncFD]]) = assert future.finished if future.failed: retFuture.fail(future.readError) @@ -154,14 +278,14 @@ proc acceptAddr*(socket: PAsyncSocket, flags = {TSocketFlags.SafeDisconn}): return retFuture proc accept*(socket: PAsyncSocket, - flags = {TSocketFlags.SafeDisconn}): PFuture[PAsyncSocket] = + flags = {TSocketFlags.SafeDisconn}): Future[PAsyncSocket] = ## Accepts a new connection. Returns a future containing the client socket ## corresponding to that connection. ## The future will complete when the connection is successfully accepted. var retFut = newFuture[PAsyncSocket]("asyncnet.accept") var fut = acceptAddr(socket, flags) fut.callback = - proc (future: PFuture[tuple[address: string, client: PAsyncSocket]]) = + proc (future: Future[tuple[address: string, client: PAsyncSocket]]) = assert future.finished if future.failed: retFut.fail(future.readError) @@ -170,7 +294,7 @@ proc accept*(socket: PAsyncSocket, return retFut proc recvLine*(socket: PAsyncSocket, - flags = {TSocketFlags.SafeDisconn}): PFuture[string] {.async.} = + flags = {TSocketFlags.SafeDisconn}): Future[string] {.async.} = ## Reads a line of data from ``socket``. Returned future will complete once ## a full line is read or an error occurs. ## @@ -185,6 +309,9 @@ proc recvLine*(socket: PAsyncSocket, ## The partial line **will be lost**. ## ## **Warning**: The ``Peek`` flag is not yet implemented. + ## + ## **Warning**: ``recvLine`` on unbuffered sockets assumes that the protocol + ## uses ``\r\L`` to delimit a new line. template addNLIfEmpty(): stmt = if result.len == 0: result.add("\c\L") @@ -227,10 +354,8 @@ proc recvLine*(socket: PAsyncSocket, if c.len == 0: return "" if c == "\r": - c = await recv(socket, 1, flags + {TSocketFlags.Peek}) - if c.len > 0 and c == "\L": - let dummy = await recv(socket, 1, flags) - assert dummy == "\L" + c = await recv(socket, 1, flags) # Skip \L + assert c == "\L" addNLIfEmpty() return elif c == "\L": @@ -238,24 +363,68 @@ proc recvLine*(socket: PAsyncSocket, return add(result.string, c) -proc bindAddr*(socket: PAsyncSocket, port = TPort(0), address = "") = - ## Binds ``address``:``port`` to the socket. - ## - ## If ``address`` is "" then ADDR_ANY will be bound. - socket.PSocket.bindAddr(port, address) - -proc listen*(socket: PAsyncSocket, backlog = SOMAXCONN) = +proc listen*(socket: PAsyncSocket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} = ## Marks ``socket`` as accepting connections. ## ``Backlog`` specifies the maximum length of the ## queue of pending connections. ## ## Raises an EOS error upon failure. - socket.PSocket.listen(backlog) + if listen(socket.fd, backlog) < 0'i32: raiseOSError(osLastError()) + +proc bindAddr*(socket: PAsyncSocket, port = Port(0), address = "") {. + tags: [ReadIOEffect].} = + ## Binds ``address``:``port`` to the socket. + ## + ## If ``address`` is "" then ADDR_ANY will be bound. + + if address == "": + var name: Sockaddr_in + when defined(Windows) or defined(nimdoc): + name.sin_family = toInt(AF_INET).int16 + else: + name.sin_family = toInt(AF_INET) + name.sin_port = htons(int16(port)) + name.sin_addr.s_addr = htonl(INADDR_ANY) + if bindAddr(socket.fd, cast[ptr SockAddr](addr(name)), + sizeof(name).Socklen) < 0'i32: + raiseOSError(osLastError()) + else: + var aiList = getAddrInfo(address, port, AF_INET) + if bindAddr(socket.fd, aiList.ai_addr, aiList.ai_addrlen.Socklen) < 0'i32: + dealloc(aiList) + raiseOSError(osLastError()) + dealloc(aiList) proc close*(socket: PAsyncSocket) = ## Closes the socket. socket.fd.TAsyncFD.closeSocket() - # TODO SSL + when defined(ssl): + if socket.isSSL: + let res = SslShutdown(socket.sslHandle) + if res == 0: + if SslShutdown(socket.sslHandle) != 1: + raiseSslError() + elif res != 1: + raiseSslError() + socket.closed = true # TODO: Add extra debugging checks for this. + +when defined(ssl): + proc wrapSocket*(ctx: SslContext, socket: AsyncSocket) = + ## Wraps a socket in an SSL context. This function effectively turns + ## ``socket`` into an SSL socket. + ## + ## **Disclaimer**: This code is not well tested, may be very unsafe and + ## prone to security vulnerabilities. + socket.isSsl = true + socket.sslContext = ctx + socket.sslHandle = SSLNew(PSSLCTX(socket.sslContext)) + if socket.sslHandle == nil: + raiseSslError() + + socket.bioIn = bioNew(bio_s_mem()) + socket.bioOut = bioNew(bio_s_mem()) + sslSetBio(socket.sslHandle, socket.bioIn, socket.bioOut) + when isMainModule: type @@ -280,23 +449,23 @@ when isMainModule: var sock = newAsyncSocket() var f = connect(sock, "irc.freenode.net", TPort(6667)) f.callback = - proc (future: PFuture[void]) = + proc (future: Future[void]) = echo("Connected in future!") for i in 0 .. 50: var recvF = recv(sock, 10) recvF.callback = - proc (future: PFuture[string]) = + proc (future: Future[string]) = echo("Read ", future.read.len, ": ", future.read.repr) elif test == LowServer: var sock = newAsyncSocket() sock.bindAddr(TPort(6667)) sock.listen() - proc onAccept(future: PFuture[PAsyncSocket]) = + proc onAccept(future: Future[PAsyncSocket]) = let client = future.read echo "Accepted ", client.fd.cint var t = send(client, "test\c\L") t.callback = - proc (future: PFuture[void]) = + proc (future: Future[void]) = echo("Send") client.close() diff --git a/lib/pure/base64.nim b/lib/pure/base64.nim index 7b3b0e6f5..41d19dc0f 100644 --- a/lib/pure/base64.nim +++ b/lib/pure/base64.nim @@ -1,127 +1,128 @@ -# -# -# Nimrod's Runtime Library -# (c) Copyright 2010 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## This module implements a base64 encoder and decoder. - -const - cb64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" - -template encodeInternal(s: expr, lineLen: int, newLine: string): stmt {.immediate.} = - ## encodes `s` into base64 representation. After `lineLen` characters, a - ## `newline` is added. - var total = ((len(s) + 2) div 3) * 4 - var numLines = (total + lineLen - 1) div lineLen - if numLines > 0: inc(total, (numLines-1) * newLine.len) - - result = newString(total) - var i = 0 - var r = 0 - var currLine = 0 - while i < s.len - 2: - var a = ord(s[i]) - var b = ord(s[i+1]) - var c = ord(s[i+2]) - result[r] = cb64[a shr 2] - result[r+1] = cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)] - result[r+2] = cb64[((b and 0x0F) shl 2) or ((c and 0xC0) shr 6)] - result[r+3] = cb64[c and 0x3F] - inc(r, 4) - inc(i, 3) - inc(currLine, 4) - if currLine >= lineLen and i != s.len-2: - for x in items(newLine): - result[r] = x - inc(r) - currLine = 0 - - if i < s.len-1: - var a = ord(s[i]) - var b = ord(s[i+1]) - result[r] = cb64[a shr 2] - result[r+1] = cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)] - result[r+2] = cb64[((b and 0x0F) shl 2)] - result[r+3] = '=' - if r+4 != result.len: - setLen(result, r+4) - elif i < s.len: - var a = ord(s[i]) - result[r] = cb64[a shr 2] - result[r+1] = cb64[(a and 3) shl 4] - result[r+2] = '=' - result[r+3] = '=' - if r+4 != result.len: - setLen(result, r+4) - else: - #assert(r == result.len) - -proc encode*[T:TInteger|char](s: openarray[T], lineLen = 75, newLine="\13\10"): string = - ## encodes `s` into base64 representation. After `lineLen` characters, a - ## `newline` is added. - encodeInternal(s, lineLen, newLine) - -proc encode*(s: string, lineLen = 75, newLine="\13\10"): string = - ## encodes `s` into base64 representation. After `lineLen` characters, a - ## `newline` is added. - encodeInternal(s, lineLen, newLine) - -proc decodeByte(b: char): int {.inline.} = - case b - of '+': result = ord('>') - of '0'..'9': result = ord(b) + 4 - of 'A'..'Z': result = ord(b) - ord('A') - of 'a'..'z': result = ord(b) - 71 - else: result = 63 - -proc decode*(s: string): string = - ## decodes a string in base64 representation back into its original form. - ## Whitespace is skipped. - const Whitespace = {' ', '\t', '\v', '\r', '\l', '\f'} - var total = ((len(s) + 3) div 4) * 3 - # total is an upper bound, as we will skip arbitrary whitespace: - result = newString(total) - - var i = 0 - var r = 0 - while true: - while s[i] in Whitespace: inc(i) - if i < s.len-3: - var a = s[i].decodeByte - var b = s[i+1].decodeByte - var c = s[i+2].decodeByte - var d = s[i+3].decodeByte - - result[r] = chr((a shl 2) and 0xff or ((b shr 4) and 0x03)) - result[r+1] = chr((b shl 4) and 0xff or ((c shr 2) and 0x0F)) - result[r+2] = chr((c shl 6) and 0xff or (d and 0x3F)) - inc(r, 3) - inc(i, 4) - else: break - assert i == s.len - # adjust the length: - if i > 0 and s[i-1] == '=': - dec(r) - if i > 1 and s[i-2] == '=': dec(r) - setLen(result, r) - -when isMainModule: - assert encode("leasure.") == "bGVhc3VyZS4=" - assert encode("easure.") == "ZWFzdXJlLg==" - assert encode("asure.") == "YXN1cmUu" - assert encode("sure.") == "c3VyZS4=" - - const longText = """Man is distinguished, not only by his reason, but by this - singular passion from other animals, which is a lust of the mind, - that by a perseverance of delight in the continued and indefatigable - generation of knowledge, exceeds the short vehemence of any carnal - pleasure.""" - const tests = ["", "abc", "xyz", "man", "leasure.", "sure.", "easure.", - "asure.", longText] - for t in items(tests): - assert decode(encode(t)) == t - +# +# +# Nim's Runtime Library +# (c) Copyright 2010 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This module implements a base64 encoder and decoder. + +const + cb64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + +template encodeInternal(s: expr, lineLen: int, newLine: string): stmt {.immediate.} = + ## encodes `s` into base64 representation. After `lineLen` characters, a + ## `newline` is added. + var total = ((len(s) + 2) div 3) * 4 + var numLines = (total + lineLen - 1) div lineLen + if numLines > 0: inc(total, (numLines-1) * newLine.len) + + result = newString(total) + var i = 0 + var r = 0 + var currLine = 0 + while i < s.len - 2: + var a = ord(s[i]) + var b = ord(s[i+1]) + var c = ord(s[i+2]) + result[r] = cb64[a shr 2] + result[r+1] = cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)] + result[r+2] = cb64[((b and 0x0F) shl 2) or ((c and 0xC0) shr 6)] + result[r+3] = cb64[c and 0x3F] + inc(r, 4) + inc(i, 3) + inc(currLine, 4) + if currLine >= lineLen and i != s.len-2: + for x in items(newLine): + result[r] = x + inc(r) + currLine = 0 + + if i < s.len-1: + var a = ord(s[i]) + var b = ord(s[i+1]) + result[r] = cb64[a shr 2] + result[r+1] = cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)] + result[r+2] = cb64[((b and 0x0F) shl 2)] + result[r+3] = '=' + if r+4 != result.len: + setLen(result, r+4) + elif i < s.len: + var a = ord(s[i]) + result[r] = cb64[a shr 2] + result[r+1] = cb64[(a and 3) shl 4] + result[r+2] = '=' + result[r+3] = '=' + if r+4 != result.len: + setLen(result, r+4) + else: + #assert(r == result.len) + discard + +proc encode*[T:SomeInteger|char](s: openarray[T], lineLen = 75, newLine="\13\10"): string = + ## encodes `s` into base64 representation. After `lineLen` characters, a + ## `newline` is added. + encodeInternal(s, lineLen, newLine) + +proc encode*(s: string, lineLen = 75, newLine="\13\10"): string = + ## encodes `s` into base64 representation. After `lineLen` characters, a + ## `newline` is added. + encodeInternal(s, lineLen, newLine) + +proc decodeByte(b: char): int {.inline.} = + case b + of '+': result = ord('>') + of '0'..'9': result = ord(b) + 4 + of 'A'..'Z': result = ord(b) - ord('A') + of 'a'..'z': result = ord(b) - 71 + else: result = 63 + +proc decode*(s: string): string = + ## decodes a string in base64 representation back into its original form. + ## Whitespace is skipped. + const Whitespace = {' ', '\t', '\v', '\r', '\l', '\f'} + var total = ((len(s) + 3) div 4) * 3 + # total is an upper bound, as we will skip arbitrary whitespace: + result = newString(total) + + var i = 0 + var r = 0 + while true: + while s[i] in Whitespace: inc(i) + if i < s.len-3: + var a = s[i].decodeByte + var b = s[i+1].decodeByte + var c = s[i+2].decodeByte + var d = s[i+3].decodeByte + + result[r] = chr((a shl 2) and 0xff or ((b shr 4) and 0x03)) + result[r+1] = chr((b shl 4) and 0xff or ((c shr 2) and 0x0F)) + result[r+2] = chr((c shl 6) and 0xff or (d and 0x3F)) + inc(r, 3) + inc(i, 4) + else: break + assert i == s.len + # adjust the length: + if i > 0 and s[i-1] == '=': + dec(r) + if i > 1 and s[i-2] == '=': dec(r) + setLen(result, r) + +when isMainModule: + assert encode("leasure.") == "bGVhc3VyZS4=" + assert encode("easure.") == "ZWFzdXJlLg==" + assert encode("asure.") == "YXN1cmUu" + assert encode("sure.") == "c3VyZS4=" + + const longText = """Man is distinguished, not only by his reason, but by this + singular passion from other animals, which is a lust of the mind, + that by a perseverance of delight in the continued and indefatigable + generation of knowledge, exceeds the short vehemence of any carnal + pleasure.""" + const tests = ["", "abc", "xyz", "man", "leasure.", "sure.", "easure.", + "asure.", longText] + for t in items(tests): + assert decode(encode(t)) == t + diff --git a/lib/pure/basic2d.nim b/lib/pure/basic2d.nim index f8391a368..f2fc1566b 100644 --- a/lib/pure/basic2d.nim +++ b/lib/pure/basic2d.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Robert Persson # # See the file "copying.txt", included in this @@ -92,7 +92,7 @@ proc point2d*(x,y:float):TPoint2d {.noInit,inline.} let IDMATRIX*:TMatrix2d=matrix2d(1.0,0.0,0.0,1.0,0.0,0.0) ## Quick access to an identity matrix - ORIGO*:TPoint2d=Point2d(0.0,0.0) + ORIGO*:TPoint2d=point2d(0.0,0.0) ## Quick acces to point (0,0) XAXIS*:TVector2d=vector2d(1.0,0.0) ## Quick acces to an 2d x-axis unit vector @@ -212,7 +212,7 @@ proc mirror*(v:TVector2d):TMatrix2d {.noInit.} = xy2=v.x*v.y*2.0*nd sqd=nd*(sqx-sqy) - if nd==inf or nd==neginf: + if nd==Inf or nd==NegInf: return IDMATRIX #mirroring around a zero vector is arbitrary=>just use identity result.setElements( @@ -231,7 +231,7 @@ proc mirror*(org:TPoint2d,v:TVector2d):TMatrix2d {.noInit.} = xy2=v.x*v.y*2.0*nd sqd=nd*(sqx-sqy) - if nd==inf or nd==neginf: + if nd==Inf or nd==NegInf: return IDMATRIX #mirroring around a zero vector is arbitrary=>just use identity result.setElements( @@ -285,7 +285,7 @@ proc inverse*(m:TMatrix2d):TMatrix2d {.noInit.} = ## will be raised. let d=m.determinant if d==0.0: - raise newException(EDivByZero,"Cannot invert a zero determinant matrix") + raise newException(DivByZeroError,"Cannot invert a zero determinant matrix") result.setElements( m.by/d,-m.ay/d, @@ -360,7 +360,7 @@ proc `len=`*(v:var TVector2d,newlen:float) {.noInit.} = v.y=0.0 return - if fac==inf or fac==neginf: + if fac==Inf or fac==NegInf: #to short for float accuracy #do as good as possible: v.x=newlen @@ -431,7 +431,7 @@ proc normalize*(v:var TVector2d) {.inline.}= ## Modifies `v` to have a length of 1.0, keeping its angle. ## If `v` has zero length, an EDivByZero will be raised. if not tryNormalize(v): - raise newException(EDivByZero,"Cannot normalize zero length vector") + raise newException(DivByZeroError,"Cannot normalize zero length vector") proc transformNorm*(v:var TVector2d,t:TMatrix2d)= ## Applies a normal direction transformation `t` onto `v` in place. @@ -447,7 +447,7 @@ proc transformNorm*(v:var TVector2d,t:TMatrix2d)= # | | 0 0 1 | | let d=t.determinant if(d==0.0): - raise newException(EDivByZero,"Matrix is not invertible") + raise newException(DivByZeroError,"Matrix is not invertible") let newx = (t.by*v.x-t.ay*v.y)/d v.y = (t.ax*v.y-t.bx*v.x)/d v.x = newx @@ -461,7 +461,7 @@ proc transformInv*(v:var TVector2d,t:TMatrix2d)= let d=t.determinant if(d==0.0): - raise newException(EDivByZero,"Matrix is not invertible") + raise newException(DivByZeroError,"Matrix is not invertible") let newx=(t.by*v.x-t.bx*v.y)/d v.y = (t.ax*v.y-t.ay*v.x)/d @@ -531,7 +531,7 @@ proc mirror*(v:var TVector2d,mirrvec:TVector2d)= xy2=mirrvec.x*mirrvec.y*2.0*nd sqd=nd*(sqx-sqy) - if nd==inf or nd==neginf: + if nd==Inf or nd==NegInf: return #mirroring around a zero vector is arbitrary=>keep as is is fastest let newx=xy2*v.y+sqd*v.x @@ -703,7 +703,7 @@ proc transformInv*(p:var TPoint2d,t:TMatrix2d){.inline.}= # | TX TY 1 | let d=t.determinant if d==0.0: - raise newException(EDivByZero,"Cannot invert a zero determinant matrix") + raise newException(DivByZeroError,"Cannot invert a zero determinant matrix") let newx= (t.bx*t.ty-t.by*t.tx+p.x*t.by-p.y*t.bx)/d p.y = -(t.ax*t.ty-t.ay*t.tx+p.x*t.ay-p.y*t.ax)/d @@ -820,11 +820,11 @@ proc closestPoint*(p:TPoint2d,pts:varargs[TPoint2d]):TPoint2d= var bestidx=0 - bestdist=p.sqrdist(pts[0]) + bestdist=p.sqrDist(pts[0]) curdist:float for idx in 1..high(pts): - curdist=p.sqrdist(pts[idx]) + curdist=p.sqrDist(pts[idx]) if curdist<bestdist: bestidx=idx bestdist=curdist @@ -852,4 +852,4 @@ proc radToDeg*(rad:float):float {.inline.}= ## converts `rad` radians to degrees rad * RAD2DEGCONST - \ No newline at end of file + diff --git a/lib/pure/basic3d.nim b/lib/pure/basic3d.nim index 540d53fd9..c00764fc5 100644 --- a/lib/pure/basic3d.nim +++ b/lib/pure/basic3d.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Robert Persson # # See the file "copying.txt", included in this @@ -220,7 +220,7 @@ proc rotate*(angle:float,axis:TVector3d):TMatrix3d {.noInit.}= var normax=axis if not normax.tryNormalize: #simplifies matrix computation below a lot - raise newException(EDivByZero,"Cannot rotate around zero length axis") + raise newException(DivByZeroError,"Cannot rotate around zero length axis") let cs=cos(angle) @@ -251,7 +251,7 @@ proc rotate*(angle:float,org:TPoint3d,axis:TVector3d):TMatrix3d {.noInit.}= var normax=axis if not normax.tryNormalize: #simplifies matrix computation below a lot - raise newException(EDivByZero,"Cannot rotate around zero length axis") + raise newException(DivByZeroError,"Cannot rotate around zero length axis") let u=normax.x @@ -348,7 +348,7 @@ proc mirror*(planeperp:TVector3d):TMatrix3d {.noInit.}= # https://en.wikipedia.org/wiki/Transformation_matrix var n=planeperp if not n.tryNormalize: - raise newException(EDivByZero,"Cannot mirror over a plane with a zero length normal") + raise newException(DivByZeroError,"Cannot mirror over a plane with a zero length normal") let a=n.x @@ -375,7 +375,7 @@ proc mirror*(org:TPoint3d,planeperp:TVector3d):TMatrix3d {.noInit.}= # With some fiddling this becomes reasonably simple: var n=planeperp if not n.tryNormalize: - raise newException(EDivByZero,"Cannot mirror over a plane with a zero length normal") + raise newException(DivByZeroError,"Cannot mirror over a plane with a zero length normal") let a=n.x @@ -448,7 +448,7 @@ proc inverse*(m:TMatrix3d):TMatrix3d {.noInit.}= O19=m.bx*m.cy-m.by*m.cx if det==0.0: - raise newException(EDivByZero,"Cannot normalize zero length vector") + raise newException(DivByZeroError,"Cannot normalize zero length vector") result.setElements( (m.bw*O4+m.by*O3-m.bz*O2)/det , (-m.aw*O4-m.ay*O3+m.az*O2)/det, @@ -537,7 +537,7 @@ proc apply*(m:TMatrix3d, x,y,z:var float, translate=false)= # *************************************** # TVector3d implementation # *************************************** -proc Vector3d*(x,y,z:float):TVector3d= +proc vector3d*(x,y,z:float):TVector3d= result.x=x result.y=y result.z=z @@ -559,7 +559,7 @@ proc `len=`*(v:var TVector3d,newlen:float) {.noInit.} = v.z=0.0 return - if fac==inf or fac==neginf: + if fac==Inf or fac==NegInf: #to short for float accuracy #do as good as possible: v.x=newlen @@ -670,7 +670,7 @@ proc normalize*(v:var TVector3d) {.inline.}= ## Modifies `v` to have a length of 1.0, keeping its angle. ## If `v` has zero length, an EDivByZero will be raised. if not tryNormalize(v): - raise newException(EDivByZero,"Cannot normalize zero length vector") + raise newException(DivByZeroError,"Cannot normalize zero length vector") proc rotate*(vec:var TVector3d,angle:float,axis:TVector3d)= ## Rotates `vec` in place, with `angle` radians over `axis`, which passes @@ -681,7 +681,7 @@ proc rotate*(vec:var TVector3d,angle:float,axis:TVector3d)= var normax=axis if not normax.tryNormalize: - raise newException(EDivByZero,"Cannot rotate around zero length axis") + raise newException(DivByZeroError,"Cannot rotate around zero length axis") let cs=cos(angle) @@ -842,9 +842,9 @@ proc bisect*(v1,v2:TVector3d):TVector3d {.noInit.}= # there are actually inifinitely many bisectors, we select just # one of them. result=v1.cross(XAXIS) - if result.sqrlen<1.0e-9: + if result.sqrLen<1.0e-9: result=v1.cross(YAXIS) - if result.sqrlen<1.0e-9: + if result.sqrLen<1.0e-9: result=v1.cross(ZAXIS) # now we should be guaranteed to have succeeded result.normalize @@ -853,7 +853,7 @@ proc bisect*(v1,v2:TVector3d):TVector3d {.noInit.}= # *************************************** # TPoint3d implementation # *************************************** -proc Point3d*(x,y,z:float):TPoint3d= +proc point3d*(x,y,z:float):TPoint3d= result.x=x result.y=y result.z=z diff --git a/lib/pure/browsers.nim b/lib/pure/browsers.nim index 3a8429f81..52035ee48 100644 --- a/lib/pure/browsers.nim +++ b/lib/pure/browsers.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -44,5 +44,5 @@ proc openDefaultBrowser*(url: string) = # we use ``startProcess`` here because we don't want to block! discard startProcess(command=b, args=[url], options={poUseShell}) return - except EOS: + except OSError: discard diff --git a/lib/pure/cgi.nim b/lib/pure/cgi.nim index 31fb24eef..e8977b80b 100644 --- a/lib/pure/cgi.nim +++ b/lib/pure/cgi.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -9,7 +9,7 @@ ## This module implements helper procs for CGI applications. Example: ## -## .. code-block:: Nimrod +## .. code-block:: Nim ## ## import strtabs, cgi ## @@ -31,7 +31,7 @@ import strutils, os, strtabs, cookies -proc URLencode*(s: string): string = +proc encodeUrl*(s: string): string = ## Encodes a value to be HTTP safe: This means that characters in the set ## ``{'A'..'Z', 'a'..'z', '0'..'9', '_'}`` are carried over to the result, ## a space is converted to ``'+'`` and every other character is encoded as @@ -52,7 +52,7 @@ proc handleHexChar(c: char, x: var int) {.inline.} = of 'A'..'F': x = (x shl 4) or (ord(c) - ord('A') + 10) else: assert(false) -proc URLdecode*(s: string): string = +proc decodeUrl*(s: string): string = ## Decodes a value from its HTTP representation: This means that a ``'+'`` ## is converted to a space, ``'%xx'`` (where ``xx`` denotes a hexadecimal ## value) is converted to the character with ordinal number ``xx``, and @@ -74,6 +74,8 @@ proc URLdecode*(s: string): string = inc(j) setLen(result, j) +{.deprecated: [URLDecode: decodeUrl, URLEncode: encodeUrl].} + proc addXmlChar(dest: var string, c: char) {.inline.} = case c of '&': add(dest, "&") @@ -82,7 +84,7 @@ proc addXmlChar(dest: var string, c: char) {.inline.} = of '\"': add(dest, """) else: add(dest, c) -proc XMLencode*(s: string): string = +proc xmlEncode*(s: string): string = ## Encodes a value to be XML safe: ## * ``"`` is replaced by ``"`` ## * ``<`` is replaced by ``<`` @@ -93,32 +95,35 @@ proc XMLencode*(s: string): string = for i in 0..len(s)-1: addXmlChar(result, s[i]) type - ECgi* = object of EIO ## the exception that is raised, if a CGI error occurs - TRequestMethod* = enum ## the used request method + CgiError* = object of IOError ## exception that is raised if a CGI error occurs + RequestMethod* = enum ## the used request method methodNone, ## no REQUEST_METHOD environment variable methodPost, ## query uses the POST method methodGet ## query uses the GET method +{.deprecated: [TRequestMethod: RequestMethod, ECgi: CgiError, + XMLencode: xmlEncode].} + proc cgiError*(msg: string) {.noreturn.} = ## raises an ECgi exception with message `msg`. - var e: ref ECgi + var e: ref CgiError new(e) e.msg = msg raise e -proc getEncodedData(allowedMethods: set[TRequestMethod]): string = - case getenv("REQUEST_METHOD").string +proc getEncodedData(allowedMethods: set[RequestMethod]): string = + case getEnv("REQUEST_METHOD").string of "POST": if methodPost notin allowedMethods: cgiError("'REQUEST_METHOD' 'POST' is not supported") - var L = parseInt(getenv("CONTENT_LENGTH").string) + var L = parseInt(getEnv("CONTENT_LENGTH").string) result = newString(L) if readBuffer(stdin, addr(result[0]), L) != L: cgiError("cannot read from stdin") of "GET": if methodGet notin allowedMethods: cgiError("'REQUEST_METHOD' 'GET' is not supported") - result = getenv("QUERY_STRING").string + result = getEnv("QUERY_STRING").string else: if methodNone notin allowedMethods: cgiError("'REQUEST_METHOD' must be 'POST' or 'GET'") @@ -165,7 +170,7 @@ iterator decodeData*(data: string): tuple[key, value: TaintedString] = elif data[i] == '\0': break else: cgiError("'&' expected") -iterator decodeData*(allowedMethods: set[TRequestMethod] = +iterator decodeData*(allowedMethods: set[RequestMethod] = {methodNone, methodPost, methodGet}): tuple[key, value: TaintedString] = ## Reads and decodes CGI data and yields the (name, value) pairs the ## data consists of. If the client does not use a method listed in the @@ -175,15 +180,15 @@ iterator decodeData*(allowedMethods: set[TRequestMethod] = for key, value in decodeData(data): yield (key, value) -proc readData*(allowedMethods: set[TRequestMethod] = - {methodNone, methodPost, methodGet}): PStringTable = +proc readData*(allowedMethods: set[RequestMethod] = + {methodNone, methodPost, methodGet}): StringTableRef = ## Read CGI data. If the client does not use a method listed in the ## `allowedMethods` set, an `ECgi` exception is raised. result = newStringTable() for name, value in decodeData(allowedMethods): result[name.string] = value.string -proc validateData*(data: PStringTable, validKeys: varargs[string]) = +proc validateData*(data: StringTableRef, validKeys: varargs[string]) = ## validates data; raises `ECgi` if this fails. This checks that each variable ## name of the CGI `data` occurs in the `validKeys` array. for key, val in pairs(data): @@ -192,155 +197,155 @@ proc validateData*(data: PStringTable, validKeys: varargs[string]) = proc getContentLength*(): string = ## returns contents of the ``CONTENT_LENGTH`` environment variable - return getenv("CONTENT_LENGTH").string + return getEnv("CONTENT_LENGTH").string proc getContentType*(): string = ## returns contents of the ``CONTENT_TYPE`` environment variable - return getenv("CONTENT_Type").string + return getEnv("CONTENT_Type").string proc getDocumentRoot*(): string = ## returns contents of the ``DOCUMENT_ROOT`` environment variable - return getenv("DOCUMENT_ROOT").string + return getEnv("DOCUMENT_ROOT").string proc getGatewayInterface*(): string = ## returns contents of the ``GATEWAY_INTERFACE`` environment variable - return getenv("GATEWAY_INTERFACE").string + return getEnv("GATEWAY_INTERFACE").string proc getHttpAccept*(): string = ## returns contents of the ``HTTP_ACCEPT`` environment variable - return getenv("HTTP_ACCEPT").string + return getEnv("HTTP_ACCEPT").string proc getHttpAcceptCharset*(): string = ## returns contents of the ``HTTP_ACCEPT_CHARSET`` environment variable - return getenv("HTTP_ACCEPT_CHARSET").string + return getEnv("HTTP_ACCEPT_CHARSET").string proc getHttpAcceptEncoding*(): string = ## returns contents of the ``HTTP_ACCEPT_ENCODING`` environment variable - return getenv("HTTP_ACCEPT_ENCODING").string + return getEnv("HTTP_ACCEPT_ENCODING").string proc getHttpAcceptLanguage*(): string = ## returns contents of the ``HTTP_ACCEPT_LANGUAGE`` environment variable - return getenv("HTTP_ACCEPT_LANGUAGE").string + return getEnv("HTTP_ACCEPT_LANGUAGE").string proc getHttpConnection*(): string = ## returns contents of the ``HTTP_CONNECTION`` environment variable - return getenv("HTTP_CONNECTION").string + return getEnv("HTTP_CONNECTION").string proc getHttpCookie*(): string = ## returns contents of the ``HTTP_COOKIE`` environment variable - return getenv("HTTP_COOKIE").string + return getEnv("HTTP_COOKIE").string proc getHttpHost*(): string = ## returns contents of the ``HTTP_HOST`` environment variable - return getenv("HTTP_HOST").string + return getEnv("HTTP_HOST").string proc getHttpReferer*(): string = ## returns contents of the ``HTTP_REFERER`` environment variable - return getenv("HTTP_REFERER").string + return getEnv("HTTP_REFERER").string proc getHttpUserAgent*(): string = ## returns contents of the ``HTTP_USER_AGENT`` environment variable - return getenv("HTTP_USER_AGENT").string + return getEnv("HTTP_USER_AGENT").string proc getPathInfo*(): string = ## returns contents of the ``PATH_INFO`` environment variable - return getenv("PATH_INFO").string + return getEnv("PATH_INFO").string proc getPathTranslated*(): string = ## returns contents of the ``PATH_TRANSLATED`` environment variable - return getenv("PATH_TRANSLATED").string + return getEnv("PATH_TRANSLATED").string proc getQueryString*(): string = ## returns contents of the ``QUERY_STRING`` environment variable - return getenv("QUERY_STRING").string + return getEnv("QUERY_STRING").string proc getRemoteAddr*(): string = ## returns contents of the ``REMOTE_ADDR`` environment variable - return getenv("REMOTE_ADDR").string + return getEnv("REMOTE_ADDR").string proc getRemoteHost*(): string = ## returns contents of the ``REMOTE_HOST`` environment variable - return getenv("REMOTE_HOST").string + return getEnv("REMOTE_HOST").string proc getRemoteIdent*(): string = ## returns contents of the ``REMOTE_IDENT`` environment variable - return getenv("REMOTE_IDENT").string + return getEnv("REMOTE_IDENT").string proc getRemotePort*(): string = ## returns contents of the ``REMOTE_PORT`` environment variable - return getenv("REMOTE_PORT").string + return getEnv("REMOTE_PORT").string proc getRemoteUser*(): string = ## returns contents of the ``REMOTE_USER`` environment variable - return getenv("REMOTE_USER").string + return getEnv("REMOTE_USER").string proc getRequestMethod*(): string = ## returns contents of the ``REQUEST_METHOD`` environment variable - return getenv("REQUEST_METHOD").string + return getEnv("REQUEST_METHOD").string proc getRequestURI*(): string = ## returns contents of the ``REQUEST_URI`` environment variable - return getenv("REQUEST_URI").string + return getEnv("REQUEST_URI").string proc getScriptFilename*(): string = ## returns contents of the ``SCRIPT_FILENAME`` environment variable - return getenv("SCRIPT_FILENAME").string + return getEnv("SCRIPT_FILENAME").string proc getScriptName*(): string = ## returns contents of the ``SCRIPT_NAME`` environment variable - return getenv("SCRIPT_NAME").string + return getEnv("SCRIPT_NAME").string proc getServerAddr*(): string = ## returns contents of the ``SERVER_ADDR`` environment variable - return getenv("SERVER_ADDR").string + return getEnv("SERVER_ADDR").string proc getServerAdmin*(): string = ## returns contents of the ``SERVER_ADMIN`` environment variable - return getenv("SERVER_ADMIN").string + return getEnv("SERVER_ADMIN").string proc getServerName*(): string = ## returns contents of the ``SERVER_NAME`` environment variable - return getenv("SERVER_NAME").string + return getEnv("SERVER_NAME").string proc getServerPort*(): string = ## returns contents of the ``SERVER_PORT`` environment variable - return getenv("SERVER_PORT").string + return getEnv("SERVER_PORT").string proc getServerProtocol*(): string = ## returns contents of the ``SERVER_PROTOCOL`` environment variable - return getenv("SERVER_PROTOCOL").string + return getEnv("SERVER_PROTOCOL").string proc getServerSignature*(): string = ## returns contents of the ``SERVER_SIGNATURE`` environment variable - return getenv("SERVER_SIGNATURE").string + return getEnv("SERVER_SIGNATURE").string proc getServerSoftware*(): string = ## returns contents of the ``SERVER_SOFTWARE`` environment variable - return getenv("SERVER_SOFTWARE").string + return getEnv("SERVER_SOFTWARE").string proc setTestData*(keysvalues: varargs[string]) = ## fills the appropriate environment variables to test your CGI application. ## This can only simulate the 'GET' request method. `keysvalues` should ## provide embedded (name, value)-pairs. Example: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## setTestData("name", "Hanz", "password", "12345") - putenv("REQUEST_METHOD", "GET") + putEnv("REQUEST_METHOD", "GET") var i = 0 var query = "" while i < keysvalues.len: - add(query, URLencode(keysvalues[i])) + add(query, encodeUrl(keysvalues[i])) add(query, '=') - add(query, URLencode(keysvalues[i+1])) + add(query, encodeUrl(keysvalues[i+1])) add(query, '&') inc(i, 2) - putenv("QUERY_STRING", query) + putEnv("QUERY_STRING", query) proc writeContentType*() = ## call this before starting to send your HTML data to `stdout`. This ## implements this part of the CGI protocol: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## write(stdout, "Content-type: text/html\n\n") write(stdout, "Content-type: text/html\n\n") @@ -364,11 +369,11 @@ proc writeErrorMessage*(data: string) = stdout.write(data) proc setStackTraceStdout*() = - ## Makes Nimrod output stacktraces to stdout, instead of server log. + ## Makes Nim output stacktraces to stdout, instead of server log. errorMessageWriter = writeErrorMessage proc setStackTraceNewLine*() {.deprecated.} = - ## Makes Nimrod output stacktraces to stdout, instead of server log. + ## Makes Nim output stacktraces to stdout, instead of server log. ## Depracated alias for setStackTraceStdout. setStackTraceStdout() @@ -377,7 +382,7 @@ proc setCookie*(name, value: string) = write(stdout, "Set-Cookie: ", name, "=", value, "\n") var - gcookies {.threadvar.}: PStringTable + gcookies {.threadvar.}: StringTableRef proc getCookie*(name: string): TaintedString = ## Gets a cookie. If no cookie of `name` exists, "" is returned. @@ -391,5 +396,5 @@ proc existsCookie*(name: string): bool = when isMainModule: const test1 = "abc\L+def xyz" - assert UrlEncode(test1) == "abc%0A%2Bdef+xyz" - assert UrlDecode(UrlEncode(test1)) == test1 + assert encodeUrl(test1) == "abc%0A%2Bdef+xyz" + assert decodeUrl(encodeUrl(test1)) == test1 diff --git a/lib/pure/collections/LockFreeHash.nim b/lib/pure/collections/LockFreeHash.nim index b94b542ff..5640838b1 100644 --- a/lib/pure/collections/LockFreeHash.nim +++ b/lib/pure/collections/LockFreeHash.nim @@ -1,8 +1,40 @@ -#nimrod c -t:-march=i686 --cpu:amd64 --threads:on -d:release lockfreehash.nim +#nim c -t:-march=i686 --cpu:amd64 --threads:on -d:release lockfreehash.nim -import baseutils, unsigned, math, hashes +import unsigned, math, hashes +#------------------------------------------------------------------------------ +## Memory Utility Functions + +proc newHeap*[T](): ptr T = + result = cast[ptr T](alloc0(sizeof(T))) + +proc copyNew*[T](x: var T): ptr T = + var + size = sizeof(T) + mem = alloc(size) + copyMem(mem, x.addr, size) + return cast[ptr T](mem) + +proc copyTo*[T](val: var T, dest: int) = + copyMem(pointer(dest), val.addr, sizeof(T)) + +proc allocType*[T](): pointer = alloc(sizeof(T)) + +proc newShared*[T](): ptr T = + result = cast[ptr T](allocShared0(sizeof(T))) + +proc copyShared*[T](x: var T): ptr T = + var + size = sizeof(T) + mem = allocShared(size) + copyMem(mem, x.addr, size) + return cast[ptr T](mem) +#------------------------------------------------------------------------------ +## Pointer arithmetic + +proc `+`*(p: pointer, i: int): pointer {.inline.} = + cast[pointer](cast[int](p) + i) const minTableSize = 8 @@ -194,7 +226,7 @@ proc copySlot[K,V](idx: int, oldTbl: var PConcTable[K,V], newTbl: var PConcTable #Prevent new values from appearing in the old table by priming oldVal = atomic_load_n(oldTbl[idx].value.addr, ATOMIC_RELAXED) while not isPrime(oldVal): - var box = if oldVal == NULL or isTomb(oldVal) : oldVal.setTomb.setPrime + var box = if oldVal == 0 or isTomb(oldVal) : oldVal.setTomb.setPrime else: oldVal.setPrime if atomic_compare_exchange_n(oldTbl[idx].value.addr, oldVal.addr, box, false, ATOMIC_RELAXED, ATOMIC_RELAXED): @@ -209,8 +241,8 @@ proc copySlot[K,V](idx: int, oldTbl: var PConcTable[K,V], newTbl: var PConcTable return false if isTomb(oldVal): echo("oldVal is Tomb!!!, should not happen") - if pop(oldVal) != NULL: - result = setVal(newTbl, pop(oldKey), pop(oldVal), NULL, true) == NULL + if pop(oldVal) != 0: + result = setVal(newTbl, pop(oldKey), pop(oldVal), 0, true) == 0 if result: #echo("Copied a Slot! idx= " & $idx & " key= " & $oldKey & " val= " & $oldVal) else: @@ -323,7 +355,7 @@ proc setVal[K,V](table: var PConcTable[K,V], key: int, val: int, idx = idx and (table.len - 1) #echo("try set idx = " & $idx & "for" & $key) var - probedKey = NULL + probedKey = 0 openKey = atomic_compare_exchange_n(table[idx].key.addr, probedKey.addr, key, false, ATOMIC_RELAXED, ATOMIC_RELAXED) if openKey: @@ -339,7 +371,7 @@ proc setVal[K,V](table: var PConcTable[K,V], key: int, val: int, if keyEQ[K](probedKey, key): #echo("we found the matching slot") break # We found a matching slot - if (not(expVal != NULL and match)) and (probes >= reProbeLimit or key.isTomb): + if (not(expVal != 0 and match)) and (probes >= reProbeLimit or key.isTomb): if key.isTomb: echo("Key is Tombstone") #if probes >= reProbeLimit: echo("Too much probing " & $probes) #echo("try to resize") @@ -361,7 +393,7 @@ proc setVal[K,V](table: var PConcTable[K,V], key: int, val: int, return oldVal nextTable = atomic_load_n(table.next.addr, ATOMIC_SEQ_CST) if nextTable == nil and - ((oldVal == NULL and + ((oldVal == 0 and (probes >= reProbeLimit or table.used / table.len > 0.8)) or (isPrime(oldVal))): if table.used / table.len > 0.8: echo("resize because usage ratio = " & @@ -380,12 +412,12 @@ proc setVal[K,V](table: var PConcTable[K,V], key: int, val: int, if atomic_compare_exchange_n(table[idx].value.addr, oldVal.addr, val, false, ATOMIC_RELEASE, ATOMIC_RELAXED): #echo("val set at table " & $cast[int](table)) - if expVal != NULL: - if (oldVal == NULL or isTomb(oldVal)) and not isTomb(val): + if expVal != 0: + if (oldVal == 0 or isTomb(oldVal)) and not isTomb(val): discard atomic_add_fetch(table.active.addr, 1, ATOMIC_RELAXED) - elif not (oldVal == NULL or isTomb(oldVal)) and isTomb(val): + elif not (oldVal == 0 or isTomb(oldVal)) and isTomb(val): discard atomic_add_fetch(table.active.addr, -1, ATOMIC_RELAXED) - if oldVal == NULL and expVal != NULL: + if oldVal == 0 and expVal != 0: return setTomb(oldVal) else: return oldVal if isPrime(oldVal): @@ -415,7 +447,7 @@ proc getVal[K,V](table: var PConcTable[K,V], key: int): int = if not isPrime(val): if isTomb(val): #echo("val was tomb but not prime") - return NULL + return 0 else: #echo("-GotIt- idx = ", idx, " key = ", key, " val ", val ) return val @@ -427,7 +459,7 @@ proc getVal[K,V](table: var PConcTable[K,V], key: int): int = if probes >= reProbeLimit*4 or key.isTomb: if newTable == nil: #echo("too many probes and no new table ", key, " ", idx ) - return NULL + return 0 else: newTable = helpCopy(table) return getVal(newTable, key) @@ -437,10 +469,10 @@ proc getVal[K,V](table: var PConcTable[K,V], key: int): int = #------------------------------------------------------------------------------ #proc set*(table: var PConcTable[TRaw,TRaw], key: TRaw, val: TRaw) = -# discard setVal(table, pack(key), pack(key), NULL, false) +# discard setVal(table, pack(key), pack(key), 0, false) #proc set*[V](table: var PConcTable[TRaw,V], key: TRaw, val: ptr V) = -# discard setVal(table, pack(key), cast[int](val), NULL, false) +# discard setVal(table, pack(key), cast[int](val), 0, false) proc set*[K,V](table: var PConcTable[K,V], key: var K, val: var V) = when not (K is TRaw): @@ -451,10 +483,10 @@ proc set*[K,V](table: var PConcTable[K,V], key: var K, val: var V) = var newVal = cast[int](copyShared(val)) else: var newVal = pack(val) - var oldPtr = pop(setVal(table, newKey, newVal, NULL, false)) + var oldPtr = pop(setVal(table, newKey, newVal, 0, false)) #echo("oldPtr = ", cast[int](oldPtr), " newPtr = ", cast[int](newPtr)) when not (V is TRaw): - if newVal != oldPtr and oldPtr != NULL: + if newVal != oldPtr and oldPtr != 0: deallocShared(cast[ptr V](oldPtr)) @@ -573,10 +605,3 @@ when isMainModule: # echo(i, " = ", hashInt(i) and 8191) deleteConcTable(table) - - - - - - - diff --git a/lib/pure/collections/baseutils.nim b/lib/pure/collections/baseutils.nim deleted file mode 100644 index 565a89ccb..000000000 --- a/lib/pure/collections/baseutils.nim +++ /dev/null @@ -1,41 +0,0 @@ - - - -#------------------------------------------------------------------------------ -## Useful Constants -const NULL* = 0 - - -#------------------------------------------------------------------------------ -## Memory Utility Functions - -proc newHeap*[T](): ptr T = - result = cast[ptr T](alloc0(sizeof(T))) - -proc copyNew*[T](x: var T): ptr T = - var - size = sizeof(T) - mem = alloc(size) - copyMem(mem, x.addr, size) - return cast[ptr T](mem) - -proc copyTo*[T](val: var T, dest: int) = - copyMem(pointer(dest), val.addr, sizeof(T)) - -proc allocType*[T](): pointer = alloc(sizeof(T)) - -proc newShared*[T](): ptr T = - result = cast[ptr T](allocShared0(sizeof(T))) - -proc copyShared*[T](x: var T): ptr T = - var - size = sizeof(T) - mem = allocShared(size) - copyMem(mem, x.addr, size) - return cast[ptr T](mem) - -#------------------------------------------------------------------------------ -## Pointer arithmetic - -proc `+`*(p: pointer, i: int): pointer {.inline.} = - cast[pointer](cast[int](p) + i) \ No newline at end of file diff --git a/lib/pure/collections/critbits.nim b/lib/pure/collections/critbits.nim index 1fde1f419..8f506409b 100644 --- a/lib/pure/collections/critbits.nim +++ b/lib/pure/collections/critbits.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -12,30 +12,32 @@ ## by Adam Langley. type - TNode[T] = object {.pure, final, acyclic.} + NodeObj[T] = object {.pure, final, acyclic.} byte: int ## byte index of the difference otherbits: char case isLeaf: bool - of false: child: array[0..1, ref TNode[T]] + of false: child: array[0..1, ref NodeObj[T]] of true: key: string when T isnot void: val: T - PNode[T] = ref TNode[T] - TCritBitTree*[T] = object {. + Node[T] = ref NodeObj[T] + CritBitTree*[T] = object {. pure, final.} ## The crit bit tree can either be used ## as a mapping from strings to ## some type ``T`` or as a set of ## strings if ``T`` is void. - root: PNode[T] + root: Node[T] count: int - -proc len*[T](c: TCritBitTree[T]): int = + +{.deprecated: [TCritBitTree: CritBitTree].} + +proc len*[T](c: CritBitTree[T]): int = ## returns the number of elements in `c` in O(1). result = c.count -proc rawGet[T](c: TCritBitTree[T], key: string): PNode[T] = +proc rawGet[T](c: CritBitTree[T], key: string): Node[T] = var it = c.root while it != nil: if not it.isLeaf: @@ -45,15 +47,15 @@ proc rawGet[T](c: TCritBitTree[T], key: string): PNode[T] = else: return if it.key == key: it else: nil -proc contains*[T](c: TCritBitTree[T], key: string): bool {.inline.} = +proc contains*[T](c: CritBitTree[T], key: string): bool {.inline.} = ## returns true iff `c` contains the given `key`. result = rawGet(c, key) != nil -proc hasKey*[T](c: TCritBitTree[T], key: string): bool {.inline.} = +proc hasKey*[T](c: CritBitTree[T], key: string): bool {.inline.} = ## alias for `contains`. result = rawGet(c, key) != nil -proc rawInsert[T](c: var TCritBitTree[T], key: string): PNode[T] = +proc rawInsert[T](c: var CritBitTree[T], key: string): Node[T] = if c.root == nil: new c.root c.root.isleaf = true @@ -84,7 +86,7 @@ proc rawInsert[T](c: var TCritBitTree[T], key: string): PNode[T] = let ch = it.key[newByte] let dir = (1 + (ord(ch) or newOtherBits)) shr 8 - var inner: PNode[T] + var inner: Node[T] new inner new result result.isLeaf = true @@ -106,7 +108,7 @@ proc rawInsert[T](c: var TCritBitTree[T], key: string): PNode[T] = wherep[] = inner inc c.count -proc containsOrIncl*[T](c: var TCritBitTree[T], key: string, val: T): bool = +proc containsOrIncl*[T](c: var CritBitTree[T], key: string, val: T): bool = ## returns true iff `c` contains the given `key`. If the key does not exist ## ``c[key] = val`` is performed. let oldCount = c.count @@ -115,23 +117,23 @@ proc containsOrIncl*[T](c: var TCritBitTree[T], key: string, val: T): bool = when T isnot void: if not result: n.val = val -proc containsOrIncl*(c: var TCritBitTree[void], key: string): bool = +proc containsOrIncl*(c: var CritBitTree[void], key: string): bool = ## returns true iff `c` contains the given `key`. If the key does not exist ## it is inserted into `c`. let oldCount = c.count var n = rawInsert(c, key) result = c.count == oldCount -proc incl*(c: var TCritBitTree[void], key: string) = +proc incl*(c: var CritBitTree[void], key: string) = ## includes `key` in `c`. discard rawInsert(c, key) -proc `[]=`*[T](c: var TCritBitTree[T], key: string, val: T) = +proc `[]=`*[T](c: var CritBitTree[T], key: string, val: T) = ## puts a (key, value)-pair into `t`. var n = rawInsert(c, key) n.val = val -proc `[]`*[T](c: TCritBitTree[T], key: string): T {.inline.} = +proc `[]`*[T](c: CritBitTree[T], key: string): T {.inline.} = ## retrieves the value at ``c[key]``. If `key` is not in `t`, ## default empty value for the type `B` is returned ## and no exception is raised. One can check with ``hasKey`` whether the key @@ -139,22 +141,22 @@ proc `[]`*[T](c: TCritBitTree[T], key: string): T {.inline.} = let n = rawGet(c, key) if n != nil: result = n.val -proc mget*[T](c: var TCritBitTree[T], key: string): var T {.inline.} = +proc mget*[T](c: var CritBitTree[T], key: string): var T {.inline.} = ## retrieves the value at ``c[key]``. The value can be modified. - ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. + ## If `key` is not in `t`, the ``KeyError`` exception is raised. let n = rawGet(c, key) if n != nil: result = n.val - else: raise newException(EInvalidKey, "key not found: " & $key) + else: raise newException(KeyError, "key not found: " & $key) -proc excl*[T](c: var TCritBitTree[T], key: string) = +proc excl*[T](c: var CritBitTree[T], key: string) = ## removes `key` (and its associated value) from the set `c`. ## If the `key` does not exist, nothing happens. var p = c.root var wherep = addr(c.root) - var whereq: ptr PNode = nil + var whereq: ptr Node[T] = nil if p == nil: return var dir = 0 - var q: PNode + var q: Node[T] while not p.isLeaf: whereq = wherep q = p @@ -170,7 +172,7 @@ proc excl*[T](c: var TCritBitTree[T], key: string) = whereq[] = q.child[1 - dir] dec c.count -iterator leaves[T](n: PNode[T]): PNode[T] = +iterator leaves[T](n: Node[T]): Node[T] = if n != nil: # XXX actually we could compute the necessary stack size in advance: # it's rougly log2(c.count). @@ -183,33 +185,33 @@ iterator leaves[T](n: PNode[T]): PNode[T] = assert(it != nil) yield it -iterator keys*[T](c: TCritBitTree[T]): string = +iterator keys*[T](c: CritBitTree[T]): string = ## yields all keys in lexicographical order. for x in leaves(c.root): yield x.key -iterator values*[T](c: TCritBitTree[T]): T = +iterator values*[T](c: CritBitTree[T]): T = ## yields all values of `c` in the lexicographical order of the ## corresponding keys. for x in leaves(c.root): yield x.val -iterator mvalues*[T](c: var TCritBitTree[T]): var T = +iterator mvalues*[T](c: var CritBitTree[T]): var T = ## yields all values of `c` in the lexicographical order of the ## corresponding keys. The values can be modified. for x in leaves(c.root): yield x.val -iterator items*[T](c: TCritBitTree[T]): string = +iterator items*[T](c: CritBitTree[T]): string = ## yields all keys in lexicographical order. for x in leaves(c.root): yield x.key -iterator pairs*[T](c: TCritBitTree[T]): tuple[key: string, val: T] = +iterator pairs*[T](c: CritBitTree[T]): tuple[key: string, val: T] = ## yields all (key, value)-pairs of `c`. for x in leaves(c.root): yield (x.key, x.val) -iterator mpairs*[T](c: var TCritBitTree[T]): tuple[key: string, val: var T] = +iterator mpairs*[T](c: var CritBitTree[T]): tuple[key: string, val: var T] = ## yields all (key, value)-pairs of `c`. The yielded values can be modified. for x in leaves(c.root): yield (x.key, x.val) -proc allprefixedAux[T](c: TCritBitTree[T], key: string): PNode[T] = +proc allprefixedAux[T](c: CritBitTree[T], key: string): Node[T] = var p = c.root var top = p if p != nil: @@ -223,42 +225,42 @@ proc allprefixedAux[T](c: TCritBitTree[T], key: string): PNode[T] = if p.key[i] != key[i]: return result = top -iterator itemsWithPrefix*[T](c: TCritBitTree[T], prefix: string): string = +iterator itemsWithPrefix*[T](c: CritBitTree[T], prefix: string): string = ## yields all keys starting with `prefix`. let top = allprefixedAux(c, prefix) for x in leaves(top): yield x.key -iterator keysWithPrefix*[T](c: TCritBitTree[T], prefix: string): string = +iterator keysWithPrefix*[T](c: CritBitTree[T], prefix: string): string = ## yields all keys starting with `prefix`. let top = allprefixedAux(c, prefix) for x in leaves(top): yield x.key -iterator valuesWithPrefix*[T](c: TCritBitTree[T], prefix: string): T = +iterator valuesWithPrefix*[T](c: CritBitTree[T], prefix: string): T = ## yields all values of `c` starting with `prefix` of the ## corresponding keys. let top = allprefixedAux(c, prefix) for x in leaves(top): yield x.val -iterator mvaluesWithPrefix*[T](c: var TCritBitTree[T], prefix: string): var T = +iterator mvaluesWithPrefix*[T](c: var CritBitTree[T], prefix: string): var T = ## yields all values of `c` starting with `prefix` of the ## corresponding keys. The values can be modified. let top = allprefixedAux(c, prefix) for x in leaves(top): yield x.val -iterator pairsWithPrefix*[T](c: TCritBitTree[T], +iterator pairsWithPrefix*[T](c: CritBitTree[T], prefix: string): tuple[key: string, val: T] = ## yields all (key, value)-pairs of `c` starting with `prefix`. let top = allprefixedAux(c, prefix) for x in leaves(top): yield (x.key, x.val) -iterator mpairsWithPrefix*[T](c: var TCritBitTree[T], +iterator mpairsWithPrefix*[T](c: var CritBitTree[T], prefix: string): tuple[key: string, val: var T] = ## yields all (key, value)-pairs of `c` starting with `prefix`. ## The yielded values can be modified. let top = allprefixedAux(c, prefix) for x in leaves(top): yield (x.key, x.val) -proc `$`*[T](c: TCritBitTree[T]): string = +proc `$`*[T](c: CritBitTree[T]): string = ## turns `c` into a string representation. Example outputs: ## ``{keyA: value, keyB: value}``, ``{:}`` ## If `T` is void the outputs look like: @@ -285,7 +287,7 @@ proc `$`*[T](c: TCritBitTree[T]): string = result.add("}") when isMainModule: - var r: TCritBitTree[void] + var r: CritBitTree[void] r.incl "abc" r.incl "xyz" r.incl "def" diff --git a/lib/pure/collections/intsets.nim b/lib/pure/collections/intsets.nim index f1e67fc0e..5d9c3f445 100644 --- a/lib/pure/collections/intsets.nim +++ b/lib/pure/collections/intsets.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -9,7 +9,7 @@ ## The ``intsets`` module implements an efficient int set implemented as a ## sparse bit set. -## **Note**: Since Nimrod currently does not allow the assignment operator to +## **Note**: Since Nim currently does not allow the assignment operator to ## be overloaded, ``=`` for int sets performs some rather meaningless shallow ## copy; use ``assign`` to get a deep copy. @@ -17,7 +17,7 @@ import os, hashes, math type - TBitScalar = int + BitScalar = int const InitIntSetSize = 8 # must be a power of two! @@ -25,8 +25,8 @@ const BitsPerTrunk = 1 shl TrunkShift # needs to be a power of 2 and # divisible by 64 TrunkMask = BitsPerTrunk - 1 - IntsPerTrunk = BitsPerTrunk div (sizeof(TBitScalar) * 8) - IntShift = 5 + ord(sizeof(TBitScalar) == 8) # 5 or 6, depending on int width + IntsPerTrunk = BitsPerTrunk div (sizeof(BitScalar) * 8) + IntShift = 5 + ord(sizeof(BitScalar) == 8) # 5 or 6, depending on int width IntMask = 1 shl IntShift - 1 type @@ -34,15 +34,16 @@ type TTrunk {.final.} = object next: PTrunk # all nodes are connected with this pointer key: int # start address at bit 0 - bits: array[0..IntsPerTrunk - 1, TBitScalar] # a bit vector + bits: array[0..IntsPerTrunk - 1, BitScalar] # a bit vector TTrunkSeq = seq[PTrunk] - TIntSet* {.final.} = object ## an efficient set of 'int' implemented as a - ## sparse bit set + IntSet* = object ## an efficient set of 'int' implemented as a sparse bit set counter, max: int head: PTrunk data: TTrunkSeq +{.deprecated: [TIntSet: IntSet].} + proc mustRehash(length, counter: int): bool {.inline.} = assert(length > counter) result = (length * 2 < counter * 3) or (length - counter < 4) @@ -50,7 +51,7 @@ proc mustRehash(length, counter: int): bool {.inline.} = proc nextTry(h, maxHash: THash): THash {.inline.} = result = ((5 * h) + 1) and maxHash -proc intSetGet(t: TIntSet, key: int): PTrunk = +proc intSetGet(t: IntSet, key: int): PTrunk = var h = key and t.max while t.data[h] != nil: if t.data[h].key == key: @@ -58,7 +59,7 @@ proc intSetGet(t: TIntSet, key: int): PTrunk = h = nextTry(h, t.max) result = nil -proc intSetRawInsert(t: TIntSet, data: var TTrunkSeq, desc: PTrunk) = +proc intSetRawInsert(t: IntSet, data: var TTrunkSeq, desc: PTrunk) = var h = desc.key and t.max while data[h] != nil: assert(data[h] != desc) @@ -66,7 +67,7 @@ proc intSetRawInsert(t: TIntSet, data: var TTrunkSeq, desc: PTrunk) = assert(data[h] == nil) data[h] = desc -proc intSetEnlarge(t: var TIntSet) = +proc intSetEnlarge(t: var IntSet) = var n: TTrunkSeq var oldMax = t.max t.max = ((t.max + 1) * 2) - 1 @@ -75,7 +76,7 @@ proc intSetEnlarge(t: var TIntSet) = if t.data[i] != nil: intSetRawInsert(t, n, t.data[i]) swap(t.data, n) -proc intSetPut(t: var TIntSet, key: int): PTrunk = +proc intSetPut(t: var IntSet, key: int): PTrunk = var h = key and t.max while t.data[h] != nil: if t.data[h].key == key: @@ -92,7 +93,7 @@ proc intSetPut(t: var TIntSet, key: int): PTrunk = t.head = result t.data[h] = result -proc contains*(s: TIntSet, key: int): bool = +proc contains*(s: IntSet, key: int): bool = ## returns true iff `key` is in `s`. var t = intSetGet(s, `shr`(key, TrunkShift)) if t != nil: @@ -101,14 +102,14 @@ proc contains*(s: TIntSet, key: int): bool = else: result = false -proc incl*(s: var TIntSet, key: int) = +proc incl*(s: var IntSet, key: int) = ## includes an element `key` in `s`. var t = intSetPut(s, `shr`(key, TrunkShift)) var u = key and TrunkMask t.bits[`shr`(u, IntShift)] = t.bits[`shr`(u, IntShift)] or `shl`(1, u and IntMask) -proc excl*(s: var TIntSet, key: int) = +proc excl*(s: var IntSet, key: int) = ## excludes `key` from the set `s`. var t = intSetGet(s, `shr`(key, TrunkShift)) if t != nil: @@ -116,7 +117,7 @@ proc excl*(s: var TIntSet, key: int) = t.bits[`shr`(u, IntShift)] = t.bits[`shr`(u, IntShift)] and not `shl`(1, u and IntMask) -proc containsOrIncl*(s: var TIntSet, key: int): bool = +proc containsOrIncl*(s: var IntSet, key: int): bool = ## returns true if `s` contains `key`, otherwise `key` is included in `s` ## and false is returned. var t = intSetGet(s, `shr`(key, TrunkShift)) @@ -130,14 +131,14 @@ proc containsOrIncl*(s: var TIntSet, key: int): bool = incl(s, key) result = false -proc initIntSet*: TIntSet = +proc initIntSet*: IntSet = ## creates a new int set that is empty. newSeq(result.data, InitIntSetSize) result.max = InitIntSetSize-1 result.counter = 0 result.head = nil -proc assign*(dest: var TIntSet, src: TIntSet) = +proc assign*(dest: var IntSet, src: IntSet) = ## copies `src` to `dest`. `dest` does not need to be initialized by ## `initIntSet`. dest.counter = src.counter @@ -161,7 +162,7 @@ proc assign*(dest: var TIntSet, src: TIntSet) = it = it.next -iterator items*(s: TIntSet): int {.inline.} = +iterator items*(s: IntSet): int {.inline.} = ## iterates over any included element of `s`. var r = s.head while r != nil: @@ -186,11 +187,11 @@ template dollarImpl(): stmt = result.add($key) result.add("}") -proc `$`*(s: TIntSet): string = +proc `$`*(s: IntSet): string = ## The `$` operator for int sets. dollarImpl() -proc empty*(s: TIntSet): bool {.inline.} = +proc empty*(s: IntSet): bool {.inline.} = ## returns true if `s` is empty. This is safe to call even before ## the set has been initialized with `initIntSet`. result = s.counter == 0 diff --git a/lib/pure/collections/lists.nim b/lib/pure/collections/lists.nim index b8f8d20b5..929de5973 100644 --- a/lib/pure/collections/lists.nim +++ b/lib/pure/collections/lists.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -15,52 +15,59 @@ when not defined(nimhygiene): {.pragma: dirty.} type - TDoublyLinkedNode* {.pure, - final.}[T] = object ## a node a doubly linked list consists of - next*, prev*: ref TDoublyLinkedNode[T] + DoublyLinkedNodeObj*[T] = object ## a node a doubly linked list consists of + next*, prev*: ref DoublyLinkedNodeObj[T] value*: T - PDoublyLinkedNode*[T] = ref TDoublyLinkedNode[T] + DoublyLinkedNode*[T] = ref DoublyLinkedNodeObj[T] - TSinglyLinkedNode* {.pure, - final.}[T] = object ## a node a singly linked list consists of - next*: ref TSinglyLinkedNode[T] + SinglyLinkedNodeObj*[T] = object ## a node a singly linked list consists of + next*: ref SinglyLinkedNodeObj[T] value*: T - PSinglyLinkedNode*[T] = ref TSinglyLinkedNode[T] + SinglyLinkedNode*[T] = ref SinglyLinkedNodeObj[T] - TSinglyLinkedList* {.pure, final.}[T] = object ## a singly linked list - head*, tail*: PSinglyLinkedNode[T] + SinglyLinkedList*[T] = object ## a singly linked list + head*, tail*: SinglyLinkedNode[T] - TDoublyLinkedList* {.pure, final.}[T] = object ## a doubly linked list - head*, tail*: PDoublyLinkedNode[T] + DoublyLinkedList*[T] = object ## a doubly linked list + head*, tail*: DoublyLinkedNode[T] - TSinglyLinkedRing* {.pure, final.}[T] = object ## a singly linked ring - head*: PSinglyLinkedNode[T] + SinglyLinkedRing*[T] = object ## a singly linked ring + head*: SinglyLinkedNode[T] - TDoublyLinkedRing* {.pure, final.}[T] = object ## a doubly linked ring - head*: PDoublyLinkedNode[T] - -proc initSinglyLinkedList*[T](): TSinglyLinkedList[T] = + DoublyLinkedRing*[T] = object ## a doubly linked ring + head*: DoublyLinkedNode[T] + +{.deprecated: [TDoublyLinkedNode: DoublyLinkedNodeObj, + PDoublyLinkedNode: DoublyLinkedNode, + TSinglyLinkedNode: SinglyLinkedNodeObj, + PSinglyLinkedNode: SinglyLinkedNode, + TDoublyLinkedList: DoublyLinkedList, + TSinglyLinkedRing: SinglyLinkedRing, + TDoublyLinkedRing: DoublyLinkedRing, + TSinglyLinkedList: SinglyLinkedList].} + +proc initSinglyLinkedList*[T](): SinglyLinkedList[T] = ## creates a new singly linked list that is empty. discard -proc initDoublyLinkedList*[T](): TDoublyLinkedList[T] = +proc initDoublyLinkedList*[T](): DoublyLinkedList[T] = ## creates a new doubly linked list that is empty. discard -proc initSinglyLinkedRing*[T](): TSinglyLinkedRing[T] = +proc initSinglyLinkedRing*[T](): SinglyLinkedRing[T] = ## creates a new singly linked ring that is empty. discard -proc initDoublyLinkedRing*[T](): TDoublyLinkedRing[T] = +proc initDoublyLinkedRing*[T](): DoublyLinkedRing[T] = ## creates a new doubly linked ring that is empty. discard -proc newDoublyLinkedNode*[T](value: T): PDoublyLinkedNode[T] = +proc newDoublyLinkedNode*[T](value: T): DoublyLinkedNode[T] = ## creates a new doubly linked node with the given `value`. new(result) result.value = value -proc newSinglyLinkedNode*[T](value: T): PSinglyLinkedNode[T] = +proc newSinglyLinkedNode*[T](value: T): SinglyLinkedNode[T] = ## creates a new singly linked node with the given `value`. new(result) result.value = value @@ -99,38 +106,38 @@ template findImpl() {.dirty.} = for x in nodes(L): if x.value == value: return x -iterator items*[T](L: TDoublyLinkedList[T]): T = +iterator items*[T](L: DoublyLinkedList[T]): T = ## yields every value of `L`. itemsListImpl() -iterator items*[T](L: TSinglyLinkedList[T]): T = +iterator items*[T](L: SinglyLinkedList[T]): T = ## yields every value of `L`. itemsListImpl() -iterator items*[T](L: TSinglyLinkedRing[T]): T = +iterator items*[T](L: SinglyLinkedRing[T]): T = ## yields every value of `L`. itemsRingImpl() -iterator items*[T](L: TDoublyLinkedRing[T]): T = +iterator items*[T](L: DoublyLinkedRing[T]): T = ## yields every value of `L`. itemsRingImpl() -iterator nodes*[T](L: TSinglyLinkedList[T]): PSinglyLinkedNode[T] = +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: TDoublyLinkedList[T]): PDoublyLinkedNode[T] = +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: TSinglyLinkedRing[T]): PSinglyLinkedNode[T] = +iterator nodes*[T](L: SinglyLinkedRing[T]): SinglyLinkedNode[T] = ## iterates over every node of `x`. Removing the current node from the ## list during traversal is supported. nodesRingImpl() -iterator nodes*[T](L: TDoublyLinkedRing[T]): PDoublyLinkedNode[T] = +iterator nodes*[T](L: DoublyLinkedRing[T]): DoublyLinkedNode[T] = ## iterates over every node of `x`. Removing the current node from the ## list during traversal is supported. nodesRingImpl() @@ -142,73 +149,73 @@ template dollarImpl() {.dirty.} = result.add($x.value) result.add("]") -proc `$`*[T](L: TSinglyLinkedList[T]): string = +proc `$`*[T](L: SinglyLinkedList[T]): string = ## turns a list into its string representation. dollarImpl() -proc `$`*[T](L: TDoublyLinkedList[T]): string = +proc `$`*[T](L: DoublyLinkedList[T]): string = ## turns a list into its string representation. dollarImpl() -proc `$`*[T](L: TSinglyLinkedRing[T]): string = +proc `$`*[T](L: SinglyLinkedRing[T]): string = ## turns a list into its string representation. dollarImpl() -proc `$`*[T](L: TDoublyLinkedRing[T]): string = +proc `$`*[T](L: DoublyLinkedRing[T]): string = ## turns a list into its string representation. dollarImpl() -proc find*[T](L: TSinglyLinkedList[T], value: T): PSinglyLinkedNode[T] = +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: TDoublyLinkedList[T], value: T): PDoublyLinkedNode[T] = +proc find*[T](L: DoublyLinkedList[T], value: T): DoublyLinkedNode[T] = ## searches in the list for a value. Returns nil if the value does not ## exist. findImpl() -proc find*[T](L: TSinglyLinkedRing[T], value: T): PSinglyLinkedNode[T] = +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: TDoublyLinkedRing[T], value: T): PDoublyLinkedNode[T] = +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: TSinglyLinkedList[T], value: T): bool {.inline.} = +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: TDoublyLinkedList[T], value: T): bool {.inline.} = +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: TSinglyLinkedRing[T], value: T): bool {.inline.} = +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 -proc contains*[T](L: TDoublyLinkedRing[T], value: T): bool {.inline.} = +proc contains*[T](L: DoublyLinkedRing[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 prepend*[T](L: var TSinglyLinkedList[T], - n: PSinglyLinkedNode[T]) {.inline.} = +proc prepend*[T](L: var SinglyLinkedList[T], + n: SinglyLinkedNode[T]) {.inline.} = ## prepends a node to `L`. Efficiency: O(1). n.next = L.head L.head = n -proc prepend*[T](L: var TSinglyLinkedList[T], value: T) {.inline.} = +proc prepend*[T](L: var SinglyLinkedList[T], value: T) {.inline.} = ## prepends a node to `L`. Efficiency: O(1). prepend(L, newSinglyLinkedNode(value)) -proc append*[T](L: var TDoublyLinkedList[T], n: PDoublyLinkedNode[T]) = +proc append*[T](L: var DoublyLinkedList[T], n: DoublyLinkedNode[T]) = ## appends a node `n` to `L`. Efficiency: O(1). n.next = nil n.prev = L.tail @@ -218,11 +225,11 @@ proc append*[T](L: var TDoublyLinkedList[T], n: PDoublyLinkedNode[T]) = L.tail = n if L.head == nil: L.head = n -proc append*[T](L: var TDoublyLinkedList[T], value: T) = +proc append*[T](L: var DoublyLinkedList[T], value: T) = ## appends a value to `L`. Efficiency: O(1). append(L, newDoublyLinkedNode(value)) -proc prepend*[T](L: var TDoublyLinkedList[T], n: PDoublyLinkedNode[T]) = +proc prepend*[T](L: var DoublyLinkedList[T], n: DoublyLinkedNode[T]) = ## prepends a node `n` to `L`. Efficiency: O(1). n.prev = nil n.next = L.head @@ -232,11 +239,11 @@ proc prepend*[T](L: var TDoublyLinkedList[T], n: PDoublyLinkedNode[T]) = L.head = n if L.tail == nil: L.tail = n -proc prepend*[T](L: var TDoublyLinkedList[T], value: T) = +proc prepend*[T](L: var DoublyLinkedList[T], value: T) = ## prepends a value to `L`. Efficiency: O(1). prepend(L, newDoublyLinkedNode(value)) -proc remove*[T](L: var TDoublyLinkedList[T], n: PDoublyLinkedNode[T]) = +proc remove*[T](L: var DoublyLinkedList[T], n: DoublyLinkedNode[T]) = ## removes `n` from `L`. Efficiency: O(1). if n == L.tail: L.tail = n.prev if n == L.head: L.head = n.next @@ -244,7 +251,7 @@ proc remove*[T](L: var TDoublyLinkedList[T], n: PDoublyLinkedNode[T]) = if n.prev != nil: n.prev.next = n.next -proc prepend*[T](L: var TSinglyLinkedRing[T], n: PSinglyLinkedNode[T]) = +proc prepend*[T](L: var SinglyLinkedRing[T], n: SinglyLinkedNode[T]) = ## prepends a node `n` to `L`. Efficiency: O(1). if L.head != nil: n.next = L.head @@ -253,11 +260,11 @@ proc prepend*[T](L: var TSinglyLinkedRing[T], n: PSinglyLinkedNode[T]) = n.next = n L.head = n -proc prepend*[T](L: var TSinglyLinkedRing[T], value: T) = +proc prepend*[T](L: var SinglyLinkedRing[T], value: T) = ## prepends a value to `L`. Efficiency: O(1). prepend(L, newSinglyLinkedNode(value)) -proc append*[T](L: var TDoublyLinkedRing[T], n: PDoublyLinkedNode[T]) = +proc append*[T](L: var DoublyLinkedRing[T], n: DoublyLinkedNode[T]) = ## appends a node `n` to `L`. Efficiency: O(1). if L.head != nil: n.next = L.head @@ -269,11 +276,11 @@ proc append*[T](L: var TDoublyLinkedRing[T], n: PDoublyLinkedNode[T]) = n.next = n L.head = n -proc append*[T](L: var TDoublyLinkedRing[T], value: T) = +proc append*[T](L: var DoublyLinkedRing[T], value: T) = ## appends a value to `L`. Efficiency: O(1). append(L, newDoublyLinkedNode(value)) -proc prepend*[T](L: var TDoublyLinkedRing[T], n: PDoublyLinkedNode[T]) = +proc prepend*[T](L: var DoublyLinkedRing[T], n: DoublyLinkedNode[T]) = ## prepends a node `n` to `L`. Efficiency: O(1). if L.head != nil: n.next = L.head @@ -285,11 +292,11 @@ proc prepend*[T](L: var TDoublyLinkedRing[T], n: PDoublyLinkedNode[T]) = n.next = n L.head = n -proc prepend*[T](L: var TDoublyLinkedRing[T], value: T) = +proc prepend*[T](L: var DoublyLinkedRing[T], value: T) = ## prepends a value to `L`. Efficiency: O(1). prepend(L, newDoublyLinkedNode(value)) -proc remove*[T](L: var TDoublyLinkedRing[T], n: PDoublyLinkedNode[T]) = +proc remove*[T](L: var DoublyLinkedRing[T], n: DoublyLinkedNode[T]) = ## removes `n` from `L`. Efficiency: O(1). n.next.prev = n.prev n.prev.next = n.next @@ -300,5 +307,3 @@ proc remove*[T](L: var TDoublyLinkedRing[T], n: PDoublyLinkedNode[T]) = L.head = nil else: L.head = L.head.prev - - diff --git a/lib/pure/collections/queues.nim b/lib/pure/collections/queues.nim index 5481272f0..d1c94868a 100644 --- a/lib/pure/collections/queues.nim +++ b/lib/pure/collections/queues.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -12,13 +12,15 @@ import math type - TQueue* {.pure, final.}[T] = object ## a queue + Queue*[T] = object ## a queue data: seq[T] rd, wr, count, mask: int - + +{.deprecated: [TQueue: Queue].} + proc initQueue*[T](initialSize=4): TQueue[T] = ## creates a new queue. `initialSize` needs to be a power of 2. - assert IsPowerOfTwo(initialSize) + assert isPowerOfTwo(initialSize) result.mask = initialSize-1 newSeq(result.data, initialSize) diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim index 2629e9f40..b824210a5 100644 --- a/lib/pure/collections/sequtils.nim +++ b/lib/pure/collections/sequtils.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2011 Alex Mitchell # # See the file "copying.txt", included in this @@ -31,7 +31,7 @@ proc concat*[T](seqs: varargs[seq[T]]): seq[T] = ## ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let ## s1 = @[1, 2, 3] ## s2 = @[4, 5] @@ -50,7 +50,7 @@ proc concat*[T](seqs: varargs[seq[T]]): seq[T] = proc deduplicate*[T](seq1: seq[T]): seq[T] = ## Returns a new sequence without duplicates. ## - ## .. code-block:: nimrod + ## .. code-block:: ## let ## dup1 = @[1, 1, 3, 4, 2, 2, 8, 1, 4] ## dup2 = @["a", "a", "c", "d", "d"] @@ -61,6 +61,8 @@ proc deduplicate*[T](seq1: seq[T]): seq[T] = result = @[] for itm in items(seq1): 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. @@ -69,7 +71,7 @@ proc zip*[S, T](seq1: seq[S], seq2: seq[T]): seq[tuple[a: S, b: T]] = ## fields `a` and `b`. If one sequence is shorter, the remaining items in the ## longer sequence are discarded. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let ## short = @[1, 2, 3] ## long = @[6, 5, 4, 3, 2, 1] @@ -104,7 +106,7 @@ proc distribute*[T](s: seq[T], num: int, spread = true): seq[seq[T]] = ## ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let numbers = @[1, 2, 3, 4, 5, 6, 7] ## assert numbers.distribute(3) == @[@[1, 2, 3], @[4, 5], @[6, 7]] ## assert numbers.distribute(3, false) == @[@[1, 2, 3], @[4, 5, 6], @[7]] @@ -155,7 +157,7 @@ iterator filter*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): T = ## ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let numbers = @[1, 4, 5, 8, 9, 7, 4] ## for n in filter(numbers, proc (x: int): bool = x mod 2 == 0): ## echo($n) @@ -169,7 +171,7 @@ proc filter*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): seq[T] = ## ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let ## colors = @["red", "yellow", "black"] ## f1 = filter(colors, proc(x: string): bool = x.len < 6) @@ -184,7 +186,7 @@ proc keepIf*[T](seq1: var seq[T], pred: proc(item: T): bool {.closure.}) = ## ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## 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] @@ -202,7 +204,7 @@ proc delete*[T](s: var seq[T], first=0, last=0) = ## ## Example: ## - ##.. code-block:: nimrod + ##.. code-block:: ## 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) @@ -223,7 +225,7 @@ proc insert*[T](dest: var seq[T], src: openArray[T], pos=0) = ## ## Example: ## - ##.. code-block:: nimrod + ##.. code-block:: ## var dest = @[1,1,1,1,1,1,1,1] ## let ## src = @[2,2,2,2,2,2] @@ -254,7 +256,7 @@ template filterIt*(seq1, pred: expr): expr {.immediate.} = ## the ``it`` variable for testing, like: ``filterIt("abcxyz", it == 'x')``. ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let ## temperatures = @[-272.15, -2.0, 24.5, 44.31, 99.9, -113.44] ## acceptable = filterIt(temperatures, it < 50 and it > -10) @@ -273,7 +275,7 @@ template keepItIf*(varSeq, pred: expr) = ## the ``it`` variable for testing, like: ``keepItIf("abcxyz", it == 'x')``. ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## var candidates = @["foo", "bar", "baz", "foobar"] ## keepItIf(candidates, it.len == 3 and it[0] == 'b') ## assert candidates == @["bar", "baz"] @@ -292,7 +294,7 @@ template toSeq*(iter: expr): expr {.immediate.} = ## ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let ## numeric = @[1, 2, 3, 4, 5, 6, 7, 8, 9] ## odd_numbers = toSeq(filter(numeric) do (x: int) -> bool: @@ -318,18 +320,18 @@ template foldl*(sequence, operation: expr): expr = ## the sequence of numbers 1, 2 and 3 will be parenthesized as (((1) - 2) - ## 3). Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let ## numbers = @[5, 9, 11] ## addition = foldl(numbers, a + b) ## substraction = foldl(numbers, a - b) ## multiplication = foldl(numbers, a * b) - ## words = @["nim", "rod", "is", "cool"] + ## words = @["nim", "is", "cool"] ## concatenation = foldl(words, a & b) ## assert addition == 25, "Addition is (((5)+9)+11)" ## assert substraction == -15, "Substraction is (((5)-9)-11)" ## assert multiplication == 495, "Multiplication is (((5)*9)*11)" - ## assert concatenation == "nimrodiscool" + ## assert concatenation == "nimiscool" assert sequence.len > 0, "Can't fold empty sequences" var result {.gensym.}: type(sequence[0]) result = sequence[0] @@ -354,18 +356,18 @@ template foldr*(sequence, operation: expr): expr = ## the sequence of numbers 1, 2 and 3 will be parenthesized as (1 - (2 - ## (3))). Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let ## numbers = @[5, 9, 11] ## addition = foldr(numbers, a + b) ## substraction = foldr(numbers, a - b) ## multiplication = foldr(numbers, a * b) - ## words = @["nim", "rod", "is", "cool"] + ## words = @["nim", "is", "cool"] ## concatenation = foldr(words, a & b) ## assert addition == 25, "Addition is (5+(9+(11)))" ## assert substraction == 7, "Substraction is (5-(9-(11)))" ## assert multiplication == 495, "Multiplication is (5*(9*(11)))" - ## assert concatenation == "nimrodiscool" + ## assert concatenation == "nimiscool" assert sequence.len > 0, "Can't fold empty sequences" var result {.gensym.}: type(sequence[0]) result = sequence[sequence.len - 1] @@ -384,7 +386,7 @@ template mapIt*(seq1, typ, pred: expr): expr = ## since the new returned sequence can have a different type than the ## original. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let ## nums = @[1, 2, 3, 4] ## strings = nums.mapIt(string, $(4 * it)) @@ -401,7 +403,7 @@ template mapIt*(varSeq, pred: expr) = ## expression. The expression has to return the same type as the sequence you ## are mutating. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## var nums = @[1, 2, 3, 4] ## nums.mapIt(it * 3) ## assert nums[0] + nums[3] == 15 @@ -412,7 +414,7 @@ template mapIt*(varSeq, pred: expr) = template newSeqWith*(len: int, init: expr): expr = ## creates a new sequence, calling `init` to initialize each value. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## var seq2D = newSeqWith(20, newSeq[bool](10)) ## seq2D[0][0] = true ## seq2D[1][0] = true @@ -503,12 +505,12 @@ when isMainModule: addition = foldl(numbers, a + b) substraction = foldl(numbers, a - b) multiplication = foldl(numbers, a * b) - words = @["nim", "rod", "is", "cool"] + words = @["nim", "is", "cool"] concatenation = foldl(words, a & b) assert addition == 25, "Addition is (((5)+9)+11)" assert substraction == -15, "Substraction is (((5)-9)-11)" assert multiplication == 495, "Multiplication is (((5)*9)*11)" - assert concatenation == "nimrodiscool" + assert concatenation == "nimiscool" block: # foldr tests let @@ -516,12 +518,12 @@ when isMainModule: addition = foldr(numbers, a + b) substraction = foldr(numbers, a - b) multiplication = foldr(numbers, a * b) - words = @["nim", "rod", "is", "cool"] + words = @["nim", "is", "cool"] concatenation = foldr(words, a & b) assert addition == 25, "Addition is (5+(9+(11)))" assert substraction == 7, "Substraction is (5-(9-(11)))" assert multiplication == 495, "Multiplication is (5*(9*(11)))" - assert concatenation == "nimrodiscool" + assert concatenation == "nimiscool" block: # delete tests let outcome = @[1,1,1,1,1,1,1,1] diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim index ce901963e..92ef3152d 100644 --- a/lib/pure/collections/sets.nim +++ b/lib/pure/collections/sets.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -24,18 +24,20 @@ when not defined(nimhygiene): {.pragma: dirty.} type - TSlotEnum = enum seEmpty, seFilled, seDeleted - TKeyValuePair[A] = tuple[slot: TSlotEnum, key: A] - TKeyValuePairSeq[A] = seq[TKeyValuePair[A]] - TSet* {.final, myShallow.}[A] = object ## \ + SlotEnum = enum seEmpty, seFilled, seDeleted + KeyValuePair[A] = tuple[slot: SlotEnum, key: A] + KeyValuePairSeq[A] = seq[KeyValuePair[A]] + HashSet* {.myShallow.}[A] = object ## \ ## A generic hash set. ## - ## Use `init() <#init,TSet[A],int>`_ or `initSet[type]() <#initSet>`_ + ## Use `init() <#init,HashSet[A],int>`_ or `initSet[type]() <#initSet>`_ ## before calling other procs on it. - data: TKeyValuePairSeq[A] + data: KeyValuePairSeq[A] counter: int -proc isValid*[A](s: TSet[A]): bool = +{.deprecated: [TSet: HashSet].} + +proc isValid*[A](s: HashSet[A]): bool = ## Returns `true` if the set has been initialized with `initSet <#initSet>`_. ## ## Most operations over an uninitialized set will crash at runtime and @@ -43,13 +45,13 @@ proc isValid*[A](s: TSet[A]): bool = ## your own procs to verify that sets passed to your procs are correctly ## initialized. Example: ## - ## .. code-block :: nimrod + ## .. code-block :: ## proc savePreferences(options: TSet[string]) = ## assert options.isValid, "Pass an initialized set!" ## # Do stuff here, may crash in release builds! result = not s.data.isNil -proc len*[A](s: TSet[A]): int = +proc len*[A](s: HashSet[A]): int = ## Returns the number of keys in `s`. ## ## Due to an implementation detail you can call this proc on variables which @@ -63,14 +65,14 @@ proc len*[A](s: TSet[A]): int = ## assert values.len == 0 result = s.counter -proc card*[A](s: TSet[A]): int = +proc card*[A](s: HashSet[A]): int = ## Alias for `len() <#len,TSet[A]>`_. ## ## Card stands for the `cardinality ## <http://en.wikipedia.org/wiki/Cardinality>`_ of a set. result = s.counter -iterator items*[A](s: TSet[A]): A = +iterator items*[A](s: HashSet[A]): A = ## Iterates over keys in the set `s`. ## ## If you need a sequence with the keys you can use `sequtils.toSeq() @@ -118,10 +120,10 @@ template rawInsertImpl() {.dirty.} = data[h].key = key data[h].slot = seFilled -proc rawGet[A](s: TSet[A], key: A): int = +proc rawGet[A](s: HashSet[A], key: A): int = rawGetImpl() -proc mget*[A](s: var TSet[A], key: A): var A = +proc mget*[A](s: var HashSet[A], key: A): var A = ## returns the element that is actually stored in 's' which has the same ## value as 'key' or raises the ``EInvalidKey`` exception. This is useful ## when one overloaded 'hash' and '==' but still needs reference semantics @@ -129,9 +131,9 @@ proc mget*[A](s: var TSet[A], key: A): var A = assert s.isValid, "The set needs to be initialized." var index = rawGet(s, key) if index >= 0: result = s.data[index].key - else: raise newException(EInvalidKey, "key not found: " & $key) + else: raise newException(KeyError, "key not found: " & $key) -proc contains*[A](s: TSet[A], key: A): bool = +proc contains*[A](s: HashSet[A], key: A): bool = ## Returns true iff `key` is in `s`. ## ## Example: @@ -147,11 +149,11 @@ proc contains*[A](s: TSet[A], key: A): bool = var index = rawGet(s, key) result = index >= 0 -proc rawInsert[A](s: var TSet[A], data: var TKeyValuePairSeq[A], key: A) = +proc rawInsert[A](s: var HashSet[A], data: var KeyValuePairSeq[A], key: A) = rawInsertImpl() -proc enlarge[A](s: var TSet[A]) = - var n: TKeyValuePairSeq[A] +proc enlarge[A](s: var HashSet[A]) = + var n: KeyValuePairSeq[A] newSeq(n, len(s.data) * growthFactor) for i in countup(0, high(s.data)): if s.data[i].slot == seFilled: rawInsert(s, n, s.data[i].key) @@ -173,7 +175,7 @@ template containsOrInclImpl() {.dirty.} = rawInsert(s, s.data, key) inc(s.counter) -proc incl*[A](s: var TSet[A], key: A) = +proc incl*[A](s: var HashSet[A], key: A) = ## Includes an element `key` in `s`. ## ## This doesn't do anything if `key` is already in `s`. Example: @@ -186,7 +188,7 @@ proc incl*[A](s: var TSet[A], key: A) = assert s.isValid, "The set needs to be initialized." inclImpl() -proc incl*[A](s: var TSet[A], other: TSet[A]) = +proc incl*[A](s: var HashSet[A], other: HashSet[A]) = ## Includes all elements from `other` into `s`. ## ## Example: @@ -201,7 +203,7 @@ proc incl*[A](s: var TSet[A], other: TSet[A]) = assert other.isValid, "The set `other` needs to be initialized." for item in other: incl(s, item) -proc excl*[A](s: var TSet[A], key: A) = +proc excl*[A](s: var HashSet[A], key: A) = ## Excludes `key` from the set `s`. ## ## This doesn't do anything if `key` is not found in `s`. Example: @@ -217,7 +219,7 @@ proc excl*[A](s: var TSet[A], key: A) = s.data[index].slot = seDeleted dec(s.counter) -proc excl*[A](s: var TSet[A], other: TSet[A]) = +proc excl*[A](s: var HashSet[A], other: HashSet[A]) = ## Excludes everything in `other` from `s`. ## ## Example: @@ -233,7 +235,7 @@ proc excl*[A](s: var TSet[A], other: TSet[A]) = assert other.isValid, "The set `other` needs to be initialized." for item in other: excl(s, item) -proc containsOrIncl*[A](s: var TSet[A], key: A): bool = +proc containsOrIncl*[A](s: var HashSet[A], key: A): bool = ## Includes `key` in the set `s` and tells if `key` was added to `s`. ## ## The difference with regards to the `incl() <#incl,TSet[A],A>`_ proc is @@ -248,7 +250,7 @@ proc containsOrIncl*[A](s: var TSet[A], key: A): bool = assert s.isValid, "The set needs to be initialized." containsOrInclImpl() -proc init*[A](s: var TSet[A], initialSize=64) = +proc init*[A](s: var HashSet[A], initialSize=64) = ## Initializes a hash set. ## ## The `initialSize` parameter needs to be a power of too. You can use @@ -271,7 +273,7 @@ proc init*[A](s: var TSet[A], initialSize=64) = s.counter = 0 newSeq(s.data, initialSize) -proc initSet*[A](initialSize=64): TSet[A] = +proc initSet*[A](initialSize=64): HashSet[A] = ## Wrapper around `init() <#init,TSet[A],int>`_ for initialization of hash ## sets. ## @@ -283,7 +285,7 @@ proc initSet*[A](initialSize=64): TSet[A] = ## a.incl(2) result.init(initialSize) -proc toSet*[A](keys: openArray[A]): TSet[A] = +proc toSet*[A](keys: openArray[A]): HashSet[A] = ## Creates a new hash set that contains the given `keys`. ## ## Example: @@ -302,7 +304,7 @@ template dollarImpl(): stmt {.dirty.} = result.add($key) result.add("}") -proc `$`*[A](s: TSet[A]): string = +proc `$`*[A](s: HashSet[A]): string = ## Converts the set `s` to a string, mostly for logging purposes. ## ## Don't use this proc for serialization, the representation may change at @@ -318,7 +320,7 @@ proc `$`*[A](s: TSet[A]): string = assert s.isValid, "The set needs to be initialized." dollarImpl() -proc union*[A](s1, s2: TSet[A]): TSet[A] = +proc union*[A](s1, s2: HashSet[A]): HashSet[A] = ## Returns the union of the sets `s1` and `s2`. ## ## The union of two sets is represented mathematically as *A ∪ B* and is the @@ -335,7 +337,7 @@ proc union*[A](s1, s2: TSet[A]): TSet[A] = result = s1 incl(result, s2) -proc intersection*[A](s1, s2: TSet[A]): TSet[A] = +proc intersection*[A](s1, s2: HashSet[A]): HashSet[A] = ## Returns the intersection of the sets `s1` and `s2`. ## ## The intersection of two sets is represented mathematically as *A ∩ B* and @@ -354,7 +356,7 @@ proc intersection*[A](s1, s2: TSet[A]): TSet[A] = for item in s1: if item in s2: incl(result, item) -proc difference*[A](s1, s2: TSet[A]): TSet[A] = +proc difference*[A](s1, s2: HashSet[A]): HashSet[A] = ## Returns the difference of the sets `s1` and `s2`. ## ## The difference of two sets is represented mathematically as *A \ B* and is @@ -374,7 +376,7 @@ proc difference*[A](s1, s2: TSet[A]): TSet[A] = if not contains(s2, item): incl(result, item) -proc symmetricDifference*[A](s1, s2: TSet[A]): TSet[A] = +proc symmetricDifference*[A](s1, s2: HashSet[A]): HashSet[A] = ## Returns the symmetric difference of the sets `s1` and `s2`. ## ## The symmetric difference of two sets is represented mathematically as *A â–³ @@ -393,23 +395,23 @@ proc symmetricDifference*[A](s1, s2: TSet[A]): TSet[A] = for item in s2: if containsOrIncl(result, item): excl(result, item) -proc `+`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} = +proc `+`*[A](s1, s2: HashSet[A]): HashSet[A] {.inline.} = ## Alias for `union(s1, s2) <#union>`_. result = union(s1, s2) -proc `*`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} = +proc `*`*[A](s1, s2: HashSet[A]): HashSet[A] {.inline.} = ## Alias for `intersection(s1, s2) <#intersection>`_. result = intersection(s1, s2) -proc `-`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} = +proc `-`*[A](s1, s2: HashSet[A]): HashSet[A] {.inline.} = ## Alias for `difference(s1, s2) <#difference>`_. result = difference(s1, s2) -proc `-+-`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} = +proc `-+-`*[A](s1, s2: HashSet[A]): HashSet[A] {.inline.} = ## Alias for `symmetricDifference(s1, s2) <#symmetricDifference>`_. result = symmetricDifference(s1, s2) -proc disjoint*[A](s1, s2: TSet[A]): bool = +proc disjoint*[A](s1, s2: HashSet[A]): bool = ## Returns true iff the sets `s1` and `s2` have no items in common. ## ## Example: @@ -426,7 +428,7 @@ proc disjoint*[A](s1, s2: TSet[A]): bool = if item in s2: return false return true -proc `<`*[A](s, t: TSet[A]): bool = +proc `<`*[A](s, t: HashSet[A]): bool = ## Returns true if `s` is a strict or proper subset of `t`. ## ## A strict or proper subset `s` has all of its members in `t` but `t` has @@ -441,7 +443,7 @@ proc `<`*[A](s, t: TSet[A]): bool = ## assert((a < a) == false) s.counter != t.counter and s <= t -proc `<=`*[A](s, t: TSet[A]): bool = +proc `<=`*[A](s, t: HashSet[A]): bool = ## Returns true if `s` is subset of `t`. ## ## A subset `s` has all of its members in `t` and `t` doesn't necessarily @@ -462,7 +464,7 @@ proc `<=`*[A](s, t: TSet[A]): bool = result = false return -proc `==`*[A](s, t: TSet[A]): bool = +proc `==`*[A](s, t: HashSet[A]): bool = ## Returns true if both `s` and `t` have the same members and set size. ## ## Example: @@ -475,7 +477,7 @@ proc `==`*[A](s, t: TSet[A]): bool = ## assert a == b s.counter == t.counter and s <= t -proc map*[A, B](data: TSet[A], op: proc (x: A): B {.closure.}): TSet[B] = +proc map*[A, B](data: HashSet[A], op: proc (x: A): B {.closure.}): HashSet[B] = ## Returns a new set after applying `op` on each of the elements of `data`. ## ## You can use this proc to transform the elements from a set. Example: @@ -490,19 +492,20 @@ proc map*[A, B](data: TSet[A], op: proc (x: A): B {.closure.}): TSet[B] = # ------------------------------ ordered set ------------------------------ type - TOrderedKeyValuePair[A] = tuple[ - slot: TSlotEnum, next: int, key: A] - TOrderedKeyValuePairSeq[A] = seq[TOrderedKeyValuePair[A]] - TOrderedSet* {. - final, myShallow.}[A] = object ## \ + OrderedKeyValuePair[A] = tuple[ + slot: SlotEnum, next: int, key: A] + OrderedKeyValuePairSeq[A] = seq[OrderedKeyValuePair[A]] + OrderedSet* {.myShallow.}[A] = object ## \ ## A generic hash set that remembers insertion order. ## - ## Use `init() <#init,TOrderedSet[A],int>`_ or `initOrderedSet[type]() + ## Use `init() <#init,OrderedSet[A],int>`_ or `initOrderedSet[type]() ## <#initOrderedSet>`_ before calling other procs on it. - data: TOrderedKeyValuePairSeq[A] + data: OrderedKeyValuePairSeq[A] counter, first, last: int -proc isValid*[A](s: TOrderedSet[A]): bool = +{.deprecated: [TOrderedSet: OrderedSet].} + +proc isValid*[A](s: OrderedSet[A]): bool = ## Returns `true` if the ordered set has been initialized with `initSet ## <#initOrderedSet>`_. ## @@ -511,13 +514,13 @@ proc isValid*[A](s: TOrderedSet[A]): bool = ## in your own procs to verify that ordered sets passed to your procs are ## correctly initialized. Example: ## - ## .. code-block :: nimrod + ## .. code-block:: ## proc saveTarotCards(cards: TOrderedSet[int]) = ## assert cards.isValid, "Pass an initialized set!" ## # Do stuff here, may crash in release builds! result = not s.data.isNil -proc len*[A](s: TOrderedSet[A]): int {.inline.} = +proc len*[A](s: OrderedSet[A]): int {.inline.} = ## Returns the number of keys in `s`. ## ## Due to an implementation detail you can call this proc on variables which @@ -531,7 +534,7 @@ proc len*[A](s: TOrderedSet[A]): int {.inline.} = ## assert values.len == 0 result = s.counter -proc card*[A](s: TOrderedSet[A]): int {.inline.} = +proc card*[A](s: OrderedSet[A]): int {.inline.} = ## Alias for `len() <#len,TOrderedSet[A]>`_. ## ## Card stands for the `cardinality @@ -545,7 +548,7 @@ template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} = if s.data[h].slot == seFilled: yieldStmt h = nxt -iterator items*[A](s: TOrderedSet[A]): A = +iterator items*[A](s: OrderedSet[A]): A = ## Iterates over keys in the ordered set `s` in insertion order. ## ## If you need a sequence with the keys you can use `sequtils.toSeq() @@ -567,10 +570,10 @@ iterator items*[A](s: TOrderedSet[A]): A = forAllOrderedPairs: yield s.data[h].key -proc rawGet[A](s: TOrderedSet[A], key: A): int = +proc rawGet[A](s: OrderedSet[A], key: A): int = rawGetImpl() -proc contains*[A](s: TOrderedSet[A], key: A): bool = +proc contains*[A](s: OrderedSet[A], key: A): bool = ## Returns true iff `key` is in `s`. ## ## Example: @@ -584,16 +587,16 @@ proc contains*[A](s: TOrderedSet[A], key: A): bool = var index = rawGet(s, key) result = index >= 0 -proc rawInsert[A](s: var TOrderedSet[A], - data: var TOrderedKeyValuePairSeq[A], key: A) = +proc rawInsert[A](s: var OrderedSet[A], + data: var OrderedKeyValuePairSeq[A], key: A) = rawInsertImpl() data[h].next = -1 if s.first < 0: s.first = h if s.last >= 0: data[s.last].next = h s.last = h -proc enlarge[A](s: var TOrderedSet[A]) = - var n: TOrderedKeyValuePairSeq[A] +proc enlarge[A](s: var OrderedSet[A]) = + var n: OrderedKeyValuePairSeq[A] newSeq(n, len(s.data) * growthFactor) var h = s.first s.first = -1 @@ -605,7 +608,7 @@ proc enlarge[A](s: var TOrderedSet[A]) = h = nxt swap(s.data, n) -proc incl*[A](s: var TOrderedSet[A], key: A) = +proc incl*[A](s: var OrderedSet[A], key: A) = ## Includes an element `key` in `s`. ## ## This doesn't do anything if `key` is already in `s`. Example: @@ -618,7 +621,7 @@ proc incl*[A](s: var TOrderedSet[A], key: A) = assert s.isValid, "The set needs to be initialized." inclImpl() -proc incl*[A](s: var TSet[A], other: TOrderedSet[A]) = +proc incl*[A](s: var HashSet[A], other: OrderedSet[A]) = ## Includes all elements from `other` into `s`. ## ## Example: @@ -633,7 +636,7 @@ proc incl*[A](s: var TSet[A], other: TOrderedSet[A]) = assert other.isValid, "The set `other` needs to be initialized." for item in other: incl(s, item) -proc containsOrIncl*[A](s: var TOrderedSet[A], key: A): bool = +proc containsOrIncl*[A](s: var OrderedSet[A], key: A): bool = ## Includes `key` in the set `s` and tells if `key` was added to `s`. ## ## The difference with regards to the `incl() <#incl,TOrderedSet[A],A>`_ proc @@ -648,7 +651,7 @@ proc containsOrIncl*[A](s: var TOrderedSet[A], key: A): bool = assert s.isValid, "The set needs to be initialized." containsOrInclImpl() -proc init*[A](s: var TOrderedSet[A], initialSize=64) = +proc init*[A](s: var OrderedSet[A], initialSize=64) = ## Initializes an ordered hash set. ## ## The `initialSize` parameter needs to be a power of too. You can use @@ -673,7 +676,7 @@ proc init*[A](s: var TOrderedSet[A], initialSize=64) = s.last = -1 newSeq(s.data, initialSize) -proc initOrderedSet*[A](initialSize=64): TOrderedSet[A] = +proc initOrderedSet*[A](initialSize=64): OrderedSet[A] = ## Wrapper around `init() <#init,TOrderedSet[A],int>`_ for initialization of ## ordered hash sets. ## @@ -685,7 +688,7 @@ proc initOrderedSet*[A](initialSize=64): TOrderedSet[A] = ## a.incl(2) result.init(initialSize) -proc toOrderedSet*[A](keys: openArray[A]): TOrderedSet[A] = +proc toOrderedSet*[A](keys: openArray[A]): OrderedSet[A] = ## Creates a new ordered hash set that contains the given `keys`. ## ## Example: @@ -697,7 +700,7 @@ proc toOrderedSet*[A](keys: openArray[A]): TOrderedSet[A] = result = initOrderedSet[A](nextPowerOfTwo(keys.len+10)) for key in items(keys): result.incl(key) -proc `$`*[A](s: TOrderedSet[A]): string = +proc `$`*[A](s: OrderedSet[A]): string = ## Converts the ordered hash set `s` to a string, mostly for logging purposes. ## ## Don't use this proc for serialization, the representation may change at @@ -713,7 +716,7 @@ proc `$`*[A](s: TOrderedSet[A]): string = assert s.isValid, "The set needs to be initialized." dollarImpl() -proc `==`*[A](s, t: TOrderedSet[A]): bool = +proc `==`*[A](s, t: OrderedSet[A]): bool = ## Equality for ordered sets. if s.counter != t.counter: return false var h = s.first @@ -734,14 +737,14 @@ proc `==`*[A](s, t: TOrderedSet[A]): bool = proc testModule() = ## Internal micro test to validate docstrings and such. block isValidTest: - var options: TSet[string] - proc savePreferences(options: TSet[string]) = + var options: HashSet[string] + proc savePreferences(options: HashSet[string]) = assert options.isValid, "Pass an initialized set!" options = initSet[string]() options.savePreferences block lenTest: - var values: TSet[int] + var values: HashSet[int] assert(not values.isValid) assert values.len == 0 assert values.card == 0 @@ -835,14 +838,14 @@ proc testModule() = assert b == toSet(["1", "2", "3"]) block isValidTest: - var cards: TOrderedSet[string] - proc saveTarotCards(cards: TOrderedSet[string]) = + var cards: OrderedSet[string] + proc saveTarotCards(cards: OrderedSet[string]) = assert cards.isValid, "Pass an initialized set!" cards = initOrderedSet[string]() cards.saveTarotCards block lenTest: - var values: TOrderedSet[int] + var values: OrderedSet[int] assert(not values.isValid) assert values.len == 0 assert values.card == 0 @@ -879,7 +882,7 @@ proc testModule() = assert(a == b) # https://github.com/Araq/Nimrod/issues/1413 block initBlocks: - var a: TOrderedSet[int] + var a: OrderedSet[int] a.init(4) a.incl(2) a.init @@ -888,7 +891,7 @@ proc testModule() = a.incl(2) assert a.len == 1 - var b: TSet[int] + var b: HashSet[int] b.init(4) b.incl(2) b.init diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index dcf2ab481..41dfdaca6 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -28,7 +28,7 @@ ## you add such a proc for your custom type everything will work. See this ## example: ## -## .. code-block:: nimrod +## .. code-block:: ## type ## Person = object ## firstName, lastName: string @@ -61,43 +61,45 @@ import {.pragma: myShallow.} type - TSlotEnum = enum seEmpty, seFilled, seDeleted - TKeyValuePair[A, B] = tuple[slot: TSlotEnum, key: A, val: B] - TKeyValuePairSeq[A, B] = seq[TKeyValuePair[A, B]] - TTable* {.final, myShallow.}[A, B] = object ## generic hash table - data: TKeyValuePairSeq[A, B] + SlotEnum = enum seEmpty, seFilled, seDeleted + KeyValuePair[A, B] = tuple[slot: SlotEnum, key: A, val: B] + KeyValuePairSeq[A, B] = seq[KeyValuePair[A, B]] + Table* {.myShallow.}[A, B] = object ## generic hash table + data: KeyValuePairSeq[A, B] counter: int - PTable*[A,B] = ref TTable[A, B] + TableRef*[A,B] = ref Table[A, B] + +{.deprecated: [TTable: Table, PTable: TableRef].} when not defined(nimhygiene): {.pragma: dirty.} -proc len*[A, B](t: TTable[A, B]): int = +proc len*[A, B](t: Table[A, B]): int = ## returns the number of keys in `t`. result = t.counter -iterator pairs*[A, B](t: TTable[A, B]): tuple[key: A, val: B] = +iterator pairs*[A, B](t: Table[A, B]): tuple[key: A, val: B] = ## iterates over any (key, value) pair in the table `t`. for h in 0..high(t.data): if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val) -iterator mpairs*[A, B](t: var TTable[A, B]): tuple[key: A, val: var B] = +iterator mpairs*[A, B](t: var Table[A, B]): tuple[key: A, val: var B] = ## iterates over any (key, value) pair in the table `t`. The values ## can be modified. for h in 0..high(t.data): if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val) -iterator keys*[A, B](t: TTable[A, B]): A = +iterator keys*[A, B](t: Table[A, B]): A = ## iterates over any key in the table `t`. for h in 0..high(t.data): if t.data[h].slot == seFilled: yield t.data[h].key -iterator values*[A, B](t: TTable[A, B]): B = +iterator values*[A, B](t: Table[A, B]): B = ## iterates over any value in the table `t`. for h in 0..high(t.data): if t.data[h].slot == seFilled: yield t.data[h].val -iterator mvalues*[A, B](t: var TTable[A, B]): var B = +iterator mvalues*[A, B](t: var Table[A, B]): var B = ## iterates over any value in the table `t`. The values can be modified. for h in 0..high(t.data): if t.data[h].slot == seFilled: yield t.data[h].val @@ -128,10 +130,10 @@ template rawInsertImpl() {.dirty.} = data[h].val = val data[h].slot = seFilled -proc rawGet[A, B](t: TTable[A, B], key: A): int = +proc rawGet[A, B](t: Table[A, B], key: A): int = rawGetImpl() -proc `[]`*[A, B](t: TTable[A, B], key: A): B = +proc `[]`*[A, B](t: Table[A, B], key: A): B = ## retrieves the value at ``t[key]``. If `key` is not in `t`, ## default empty value for the type `B` is returned ## and no exception is raised. One can check with ``hasKey`` whether the key @@ -139,14 +141,14 @@ proc `[]`*[A, B](t: TTable[A, B], key: A): B = var index = rawGet(t, key) if index >= 0: result = t.data[index].val -proc mget*[A, B](t: var TTable[A, B], key: A): var B = +proc mget*[A, B](t: var Table[A, B], key: A): var B = ## retrieves the value at ``t[key]``. The value can be modified. ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. var index = rawGet(t, key) if index >= 0: result = t.data[index].val - else: raise newException(EInvalidKey, "key not found: " & $key) + else: raise newException(KeyError, "key not found: " & $key) -iterator allValues*[A, B](t: TTable[A, B]; key: A): B = +iterator allValues*[A, B](t: Table[A, B]; key: A): B = ## iterates over any value in the table `t` that belongs to the given `key`. var h: THash = hash(key) and high(t.data) while t.data[h].slot != seEmpty: @@ -154,16 +156,16 @@ iterator allValues*[A, B](t: TTable[A, B]; key: A): B = yield t.data[h].val h = nextTry(h, high(t.data)) -proc hasKey*[A, B](t: TTable[A, B], key: A): bool = +proc hasKey*[A, B](t: Table[A, B], key: A): bool = ## returns true iff `key` is in the table `t`. result = rawGet(t, key) >= 0 -proc rawInsert[A, B](t: var TTable[A, B], data: var TKeyValuePairSeq[A, B], +proc rawInsert[A, B](t: var Table[A, B], data: var KeyValuePairSeq[A, B], key: A, val: B) = rawInsertImpl() -proc enlarge[A, B](t: var TTable[A, B]) = - var n: TKeyValuePairSeq[A, B] +proc enlarge[A, B](t: var Table[A, B]) = + var n: KeyValuePairSeq[A, B] newSeq(n, len(t.data) * growthFactor) for i in countup(0, high(t.data)): if t.data[i].slot == seFilled: rawInsert(t, n, t.data[i].key, t.data[i].val) @@ -194,22 +196,22 @@ when false: inc(t.counter) result = false -proc `[]=`*[A, B](t: var TTable[A, B], key: A, val: B) = +proc `[]=`*[A, B](t: var Table[A, B], key: A, val: B) = ## puts a (key, value)-pair into `t`. putImpl() -proc add*[A, B](t: var TTable[A, B], key: A, val: B) = +proc add*[A, B](t: var Table[A, B], key: A, val: B) = ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. addImpl() -proc del*[A, B](t: var TTable[A, B], key: A) = +proc del*[A, B](t: var Table[A, B], key: A) = ## deletes `key` from hash table `t`. let index = rawGet(t, key) if index >= 0: t.data[index].slot = seDeleted dec(t.counter) -proc initTable*[A, B](initialSize=64): TTable[A, B] = +proc initTable*[A, B](initialSize=64): Table[A, B] = ## creates a new hash table that is empty. ## ## `initialSize` needs to be a power of two. If you need to accept runtime @@ -220,7 +222,7 @@ proc initTable*[A, B](initialSize=64): TTable[A, B] = newSeq(result.data, initialSize) proc toTable*[A, B](pairs: openArray[tuple[key: A, - val: B]]): TTable[A, B] = + val: B]]): Table[A, B] = ## creates a new hash table that contains the given `pairs`. result = initTable[A, B](nextPowerOfTwo(pairs.len+10)) for key, val in items(pairs): result[key] = val @@ -237,7 +239,7 @@ template dollarImpl(): stmt {.dirty.} = result.add($val) result.add("}") -proc `$`*[A, B](t: TTable[A, B]): string = +proc `$`*[A, B](t: Table[A, B]): string = ## The `$` operator for hash tables. dollarImpl() @@ -251,93 +253,93 @@ template equalsImpl() = if t[key] != val: return false return true -proc `==`*[A, B](s, t: TTable[A, B]): bool = +proc `==`*[A, B](s, t: Table[A, B]): bool = equalsImpl() -proc indexBy*[A, B, C](collection: A, index: proc(x: B): C): TTable[C, B] = +proc indexBy*[A, B, C](collection: A, index: proc(x: B): C): Table[C, B] = ## Index the collection with the proc provided. # TODO: As soon as supported, change collection: A to collection: A[B] result = initTable[C, B]() for item in collection: result[index(item)] = item -proc len*[A, B](t: PTable[A, B]): int = +proc len*[A, B](t: TableRef[A, B]): int = ## returns the number of keys in `t`. result = t.counter -iterator pairs*[A, B](t: PTable[A, B]): tuple[key: A, val: B] = +iterator pairs*[A, B](t: TableRef[A, B]): tuple[key: A, val: B] = ## iterates over any (key, value) pair in the table `t`. for h in 0..high(t.data): if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val) -iterator mpairs*[A, B](t: PTable[A, B]): tuple[key: A, val: var B] = +iterator mpairs*[A, B](t: TableRef[A, B]): tuple[key: A, val: var B] = ## iterates over any (key, value) pair in the table `t`. The values ## can be modified. for h in 0..high(t.data): if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val) -iterator keys*[A, B](t: PTable[A, B]): A = +iterator keys*[A, B](t: TableRef[A, B]): A = ## iterates over any key in the table `t`. for h in 0..high(t.data): if t.data[h].slot == seFilled: yield t.data[h].key -iterator values*[A, B](t: PTable[A, B]): B = +iterator values*[A, B](t: TableRef[A, B]): B = ## iterates over any value in the table `t`. for h in 0..high(t.data): if t.data[h].slot == seFilled: yield t.data[h].val -iterator mvalues*[A, B](t: PTable[A, B]): var B = +iterator mvalues*[A, B](t: TableRef[A, B]): var B = ## iterates over any value in the table `t`. The values can be modified. for h in 0..high(t.data): if t.data[h].slot == seFilled: yield t.data[h].val -proc `[]`*[A, B](t: PTable[A, B], key: A): B = +proc `[]`*[A, B](t: TableRef[A, B], key: A): B = ## retrieves the value at ``t[key]``. If `key` is not in `t`, ## default empty value for the type `B` is returned ## and no exception is raised. One can check with ``hasKey`` whether the key ## exists. result = t[][key] -proc mget*[A, B](t: PTable[A, B], key: A): var B = +proc mget*[A, B](t: TableRef[A, B], key: A): var B = ## retrieves the value at ``t[key]``. The value can be modified. ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. t[].mget(key) -proc hasKey*[A, B](t: PTable[A, B], key: A): bool = +proc hasKey*[A, B](t: TableRef[A, B], key: A): bool = ## returns true iff `key` is in the table `t`. result = t[].hasKey(key) -proc `[]=`*[A, B](t: PTable[A, B], key: A, val: B) = +proc `[]=`*[A, B](t: TableRef[A, B], key: A, val: B) = ## puts a (key, value)-pair into `t`. t[][key] = val -proc add*[A, B](t: PTable[A, B], key: A, val: B) = +proc add*[A, B](t: TableRef[A, B], key: A, val: B) = ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. t[].add(key, val) -proc del*[A, B](t: PTable[A, B], key: A) = +proc del*[A, B](t: TableRef[A, B], key: A) = ## deletes `key` from hash table `t`. t[].del(key) -proc newTable*[A, B](initialSize=64): PTable[A, B] = +proc newTable*[A, B](initialSize=64): TableRef[A, B] = new(result) result[] = initTable[A, B](initialSize) -proc newTable*[A, B](pairs: openArray[tuple[key: A, val: B]]): PTable[A, B] = +proc newTable*[A, B](pairs: openArray[tuple[key: A, val: B]]): TableRef[A, B] = ## creates a new hash table that contains the given `pairs`. new(result) result[] = toTable[A, B](pairs) -proc `$`*[A, B](t: PTable[A, B]): string = +proc `$`*[A, B](t: TableRef[A, B]): string = ## The `$` operator for hash tables. dollarImpl() -proc `==`*[A, B](s, t: PTable[A, B]): bool = +proc `==`*[A, B](s, t: TableRef[A, B]): bool = if isNil(s): result = isNil(t) elif isNil(t): result = false else: result = equalsImpl() -proc newTableFrom*[A, B, C](collection: A, index: proc(x: B): C): PTable[C, B] = +proc newTableFrom*[A, B, C](collection: A, index: proc(x: B): C): TableRef[C, B] = ## Index the collection with the proc provided. # TODO: As soon as supported, change collection: A to collection: A[B] result = newTable[C, B]() @@ -347,16 +349,18 @@ proc newTableFrom*[A, B, C](collection: A, index: proc(x: B): C): PTable[C, B] = # ------------------------------ ordered table ------------------------------ type - TOrderedKeyValuePair[A, B] = tuple[ - slot: TSlotEnum, next: int, key: A, val: B] - TOrderedKeyValuePairSeq[A, B] = seq[TOrderedKeyValuePair[A, B]] - TOrderedTable* {. - final, myShallow.}[A, B] = object ## table that remembers insertion order - data: TOrderedKeyValuePairSeq[A, B] + OrderedKeyValuePair[A, B] = tuple[ + slot: SlotEnum, next: int, key: A, val: B] + OrderedKeyValuePairSeq[A, B] = seq[OrderedKeyValuePair[A, B]] + OrderedTable* {. + myShallow.}[A, B] = object ## table that remembers insertion order + data: OrderedKeyValuePairSeq[A, B] counter, first, last: int - POrderedTable*[A, B] = ref TOrderedTable[A, B] + OrderedTableRef*[A, B] = ref OrderedTable[A, B] + +{.deprecated: [TOrderedTable: OrderedTable, POrderedTable: OrderedTableRef].} -proc len*[A, B](t: TOrderedTable[A, B]): int {.inline.} = +proc len*[A, B](t: OrderedTable[A, B]): int {.inline.} = ## returns the number of keys in `t`. result = t.counter @@ -367,38 +371,38 @@ template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} = if t.data[h].slot == seFilled: yieldStmt h = nxt -iterator pairs*[A, B](t: TOrderedTable[A, B]): tuple[key: A, val: B] = +iterator pairs*[A, B](t: OrderedTable[A, B]): tuple[key: A, val: B] = ## iterates over any (key, value) pair in the table `t` in insertion ## order. forAllOrderedPairs: yield (t.data[h].key, t.data[h].val) -iterator mpairs*[A, B](t: var TOrderedTable[A, B]): tuple[key: A, val: var B] = +iterator mpairs*[A, B](t: var OrderedTable[A, B]): tuple[key: A, val: var B] = ## iterates over any (key, value) pair in the table `t` in insertion ## order. The values can be modified. forAllOrderedPairs: yield (t.data[h].key, t.data[h].val) -iterator keys*[A, B](t: TOrderedTable[A, B]): A = +iterator keys*[A, B](t: OrderedTable[A, B]): A = ## iterates over any key in the table `t` in insertion order. forAllOrderedPairs: yield t.data[h].key -iterator values*[A, B](t: TOrderedTable[A, B]): B = +iterator values*[A, B](t: OrderedTable[A, B]): B = ## iterates over any value in the table `t` in insertion order. forAllOrderedPairs: yield t.data[h].val -iterator mvalues*[A, B](t: var TOrderedTable[A, B]): var B = +iterator mvalues*[A, B](t: var OrderedTable[A, B]): var B = ## iterates over any value in the table `t` in insertion order. The values ## can be modified. forAllOrderedPairs: yield t.data[h].val -proc rawGet[A, B](t: TOrderedTable[A, B], key: A): int = +proc rawGet[A, B](t: OrderedTable[A, B], key: A): int = rawGetImpl() -proc `[]`*[A, B](t: TOrderedTable[A, B], key: A): B = +proc `[]`*[A, B](t: OrderedTable[A, B], key: A): B = ## retrieves the value at ``t[key]``. If `key` is not in `t`, ## default empty value for the type `B` is returned ## and no exception is raised. One can check with ``hasKey`` whether the key @@ -406,19 +410,19 @@ proc `[]`*[A, B](t: TOrderedTable[A, B], key: A): B = var index = rawGet(t, key) if index >= 0: result = t.data[index].val -proc mget*[A, B](t: var TOrderedTable[A, B], key: A): var B = +proc mget*[A, B](t: var OrderedTable[A, B], key: A): var B = ## retrieves the value at ``t[key]``. The value can be modified. ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. var index = rawGet(t, key) if index >= 0: result = t.data[index].val - else: raise newException(EInvalidKey, "key not found: " & $key) + else: raise newException(KeyError, "key not found: " & $key) -proc hasKey*[A, B](t: TOrderedTable[A, B], key: A): bool = +proc hasKey*[A, B](t: OrderedTable[A, B], key: A): bool = ## returns true iff `key` is in the table `t`. result = rawGet(t, key) >= 0 -proc rawInsert[A, B](t: var TOrderedTable[A, B], - data: var TOrderedKeyValuePairSeq[A, B], +proc rawInsert[A, B](t: var OrderedTable[A, B], + data: var OrderedKeyValuePairSeq[A, B], key: A, val: B) = rawInsertImpl() data[h].next = -1 @@ -426,8 +430,8 @@ proc rawInsert[A, B](t: var TOrderedTable[A, B], if t.last >= 0: data[t.last].next = h t.last = h -proc enlarge[A, B](t: var TOrderedTable[A, B]) = - var n: TOrderedKeyValuePairSeq[A, B] +proc enlarge[A, B](t: var OrderedTable[A, B]) = + var n: OrderedKeyValuePairSeq[A, B] newSeq(n, len(t.data) * growthFactor) var h = t.first t.first = -1 @@ -439,15 +443,15 @@ proc enlarge[A, B](t: var TOrderedTable[A, B]) = h = nxt swap(t.data, n) -proc `[]=`*[A, B](t: var TOrderedTable[A, B], key: A, val: B) = +proc `[]=`*[A, B](t: var OrderedTable[A, B], key: A, val: B) = ## puts a (key, value)-pair into `t`. putImpl() -proc add*[A, B](t: var TOrderedTable[A, B], key: A, val: B) = +proc add*[A, B](t: var OrderedTable[A, B], key: A, val: B) = ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. addImpl() -proc initOrderedTable*[A, B](initialSize=64): TOrderedTable[A, B] = +proc initOrderedTable*[A, B](initialSize=64): OrderedTable[A, B] = ## creates a new ordered hash table that is empty. ## ## `initialSize` needs to be a power of two. If you need to accept runtime @@ -460,16 +464,16 @@ proc initOrderedTable*[A, B](initialSize=64): TOrderedTable[A, B] = newSeq(result.data, initialSize) proc toOrderedTable*[A, B](pairs: openArray[tuple[key: A, - val: B]]): TOrderedTable[A, B] = + val: B]]): OrderedTable[A, B] = ## creates a new ordered hash table that contains the given `pairs`. result = initOrderedTable[A, B](nextPowerOfTwo(pairs.len+10)) for key, val in items(pairs): result[key] = val -proc `$`*[A, B](t: TOrderedTable[A, B]): string = +proc `$`*[A, B](t: OrderedTable[A, B]): string = ## The `$` operator for ordered hash tables. dollarImpl() -proc sort*[A, B](t: var TOrderedTable[A, B], +proc sort*[A, B](t: var OrderedTable[A, B], cmp: proc (x,y: tuple[key: A, val: B]): int) = ## sorts `t` according to `cmp`. This modifies the internal list ## that kept the insertion order, so insertion order is lost after this @@ -515,7 +519,7 @@ proc sort*[A, B](t: var TOrderedTable[A, B], t.first = list t.last = tail -proc len*[A, B](t: POrderedTable[A, B]): int {.inline.} = +proc len*[A, B](t: OrderedTableRef[A, B]): int {.inline.} = ## returns the number of keys in `t`. result = t.counter @@ -526,59 +530,59 @@ template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} = if t.data[h].slot == seFilled: yieldStmt h = nxt -iterator pairs*[A, B](t: POrderedTable[A, B]): tuple[key: A, val: B] = +iterator pairs*[A, B](t: OrderedTableRef[A, B]): tuple[key: A, val: B] = ## iterates over any (key, value) pair in the table `t` in insertion ## order. forAllOrderedPairs: yield (t.data[h].key, t.data[h].val) -iterator mpairs*[A, B](t: POrderedTable[A, B]): tuple[key: A, val: var B] = +iterator mpairs*[A, B](t: OrderedTableRef[A, B]): tuple[key: A, val: var B] = ## iterates over any (key, value) pair in the table `t` in insertion ## order. The values can be modified. forAllOrderedPairs: yield (t.data[h].key, t.data[h].val) -iterator keys*[A, B](t: POrderedTable[A, B]): A = +iterator keys*[A, B](t: OrderedTableRef[A, B]): A = ## iterates over any key in the table `t` in insertion order. forAllOrderedPairs: yield t.data[h].key -iterator values*[A, B](t: POrderedTable[A, B]): B = +iterator values*[A, B](t: OrderedTableRef[A, B]): B = ## iterates over any value in the table `t` in insertion order. forAllOrderedPairs: yield t.data[h].val -iterator mvalues*[A, B](t: POrderedTable[A, B]): var B = +iterator mvalues*[A, B](t: OrderedTableRef[A, B]): var B = ## iterates over any value in the table `t` in insertion order. The values ## can be modified. forAllOrderedPairs: yield t.data[h].val -proc `[]`*[A, B](t: POrderedTable[A, B], key: A): B = +proc `[]`*[A, B](t: OrderedTableRef[A, B], key: A): B = ## retrieves the value at ``t[key]``. If `key` is not in `t`, ## default empty value for the type `B` is returned ## and no exception is raised. One can check with ``hasKey`` whether the key ## exists. result = t[][key] -proc mget*[A, B](t: POrderedTable[A, B], key: A): var B = +proc mget*[A, B](t: OrderedTableRef[A, B], key: A): var B = ## retrieves the value at ``t[key]``. The value can be modified. ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. result = t[].mget(key) -proc hasKey*[A, B](t: POrderedTable[A, B], key: A): bool = +proc hasKey*[A, B](t: OrderedTableRef[A, B], key: A): bool = ## returns true iff `key` is in the table `t`. result = t[].hasKey(key) -proc `[]=`*[A, B](t: POrderedTable[A, B], key: A, val: B) = +proc `[]=`*[A, B](t: OrderedTableRef[A, B], key: A, val: B) = ## puts a (key, value)-pair into `t`. t[][key] = val -proc add*[A, B](t: POrderedTable[A, B], key: A, val: B) = +proc add*[A, B](t: OrderedTableRef[A, B], key: A, val: B) = ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. t[].add(key, val) -proc newOrderedTable*[A, B](initialSize=64): POrderedTable[A, B] = +proc newOrderedTable*[A, B](initialSize=64): OrderedTableRef[A, B] = ## creates a new ordered hash table that is empty. ## ## `initialSize` needs to be a power of two. If you need to accept runtime @@ -588,16 +592,16 @@ proc newOrderedTable*[A, B](initialSize=64): POrderedTable[A, B] = result[] = initOrderedTable[A, B]() proc newOrderedTable*[A, B](pairs: openArray[tuple[key: A, - val: B]]): POrderedTable[A, B] = + val: B]]): OrderedTableRef[A, B] = ## creates a new ordered hash table that contains the given `pairs`. result = newOrderedTable[A, B](nextPowerOfTwo(pairs.len+10)) for key, val in items(pairs): result[key] = val -proc `$`*[A, B](t: POrderedTable[A, B]): string = +proc `$`*[A, B](t: OrderedTableRef[A, B]): string = ## The `$` operator for ordered hash tables. dollarImpl() -proc sort*[A, B](t: POrderedTable[A, B], +proc sort*[A, B](t: OrderedTableRef[A, B], cmp: proc (x,y: tuple[key: A, val: B]): int) = ## sorts `t` according to `cmp`. This modifies the internal list ## that kept the insertion order, so insertion order is lost after this @@ -608,87 +612,89 @@ proc sort*[A, B](t: POrderedTable[A, B], # ------------------------------ count tables ------------------------------- type - TCountTable* {.final, myShallow.}[ + CountTable* {.myShallow.}[ A] = object ## table that counts the number of each key data: seq[tuple[key: A, val: int]] counter: int - PCountTable*[A] = ref TCountTable[A] + CountTableRef*[A] = ref CountTable[A] + +{.deprecated: [TCountTable: CountTable, PCountTable: CountTableRef].} -proc len*[A](t: TCountTable[A]): int = +proc len*[A](t: CountTable[A]): int = ## returns the number of keys in `t`. result = t.counter -iterator pairs*[A](t: TCountTable[A]): tuple[key: A, val: int] = +iterator pairs*[A](t: CountTable[A]): tuple[key: A, val: int] = ## iterates over any (key, value) pair in the table `t`. for h in 0..high(t.data): if t.data[h].val != 0: yield (t.data[h].key, t.data[h].val) -iterator mpairs*[A](t: var TCountTable[A]): tuple[key: A, val: var int] = +iterator mpairs*[A](t: var CountTable[A]): tuple[key: A, val: var int] = ## iterates over any (key, value) pair in the table `t`. The values can ## be modified. for h in 0..high(t.data): if t.data[h].val != 0: yield (t.data[h].key, t.data[h].val) -iterator keys*[A](t: TCountTable[A]): A = +iterator keys*[A](t: CountTable[A]): A = ## iterates over any key in the table `t`. for h in 0..high(t.data): if t.data[h].val != 0: yield t.data[h].key -iterator values*[A](t: TCountTable[A]): int = +iterator values*[A](t: CountTable[A]): int = ## iterates over any value in the table `t`. for h in 0..high(t.data): if t.data[h].val != 0: yield t.data[h].val -iterator mvalues*[A](t: TCountTable[A]): var int = +iterator mvalues*[A](t: CountTable[A]): var int = ## iterates over any value in the table `t`. The values can be modified. for h in 0..high(t.data): if t.data[h].val != 0: yield t.data[h].val -proc rawGet[A](t: TCountTable[A], key: A): int = +proc rawGet[A](t: CountTable[A], key: A): int = var h: THash = hash(key) and high(t.data) # start with real hash value while t.data[h].val != 0: if t.data[h].key == key: return h h = nextTry(h, high(t.data)) result = -1 -proc `[]`*[A](t: TCountTable[A], key: A): int = +proc `[]`*[A](t: CountTable[A], key: A): int = ## retrieves the value at ``t[key]``. If `key` is not in `t`, ## 0 is returned. One can check with ``hasKey`` whether the key ## exists. var index = rawGet(t, key) if index >= 0: result = t.data[index].val -proc mget*[A](t: var TCountTable[A], key: A): var int = +proc mget*[A](t: var CountTable[A], key: A): var int = ## retrieves the value at ``t[key]``. The value can be modified. ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. var index = rawGet(t, key) if index >= 0: result = t.data[index].val - else: raise newException(EInvalidKey, "key not found: " & $key) + else: raise newException(KeyError, "key not found: " & $key) -proc hasKey*[A](t: TCountTable[A], key: A): bool = +proc hasKey*[A](t: CountTable[A], key: A): bool = ## returns true iff `key` is in the table `t`. result = rawGet(t, key) >= 0 -proc rawInsert[A](t: TCountTable[A], data: var seq[tuple[key: A, val: int]], +proc rawInsert[A](t: CountTable[A], data: var seq[tuple[key: A, val: int]], key: A, val: int) = var h: THash = hash(key) and high(data) while data[h].val != 0: h = nextTry(h, high(data)) data[h].key = key data[h].val = val -proc enlarge[A](t: var TCountTable[A]) = +proc enlarge[A](t: var CountTable[A]) = var n: seq[tuple[key: A, val: int]] newSeq(n, len(t.data) * growthFactor) for i in countup(0, high(t.data)): if t.data[i].val != 0: rawInsert(t, n, t.data[i].key, t.data[i].val) swap(t.data, n) -proc `[]=`*[A](t: var TCountTable[A], key: A, val: int) = +proc `[]=`*[A](t: var CountTable[A], key: A, val: int) = ## puts a (key, value)-pair into `t`. `val` has to be positive. assert val > 0 putImpl() -proc initCountTable*[A](initialSize=64): TCountTable[A] = +proc initCountTable*[A](initialSize=64): CountTable[A] = ## creates a new count table that is empty. ## ## `initialSize` needs to be a power of two. If you need to accept runtime @@ -698,16 +704,16 @@ proc initCountTable*[A](initialSize=64): TCountTable[A] = result.counter = 0 newSeq(result.data, initialSize) -proc toCountTable*[A](keys: openArray[A]): TCountTable[A] = +proc toCountTable*[A](keys: openArray[A]): CountTable[A] = ## creates a new count table with every key in `keys` having a count of 1. result = initCountTable[A](nextPowerOfTwo(keys.len+10)) for key in items(keys): result[key] = 1 -proc `$`*[A](t: TCountTable[A]): string = +proc `$`*[A](t: CountTable[A]): string = ## The `$` operator for count tables. dollarImpl() -proc inc*[A](t: var TCountTable[A], key: A, val = 1) = +proc inc*[A](t: var CountTable[A], key: A, val = 1) = ## increments `t[key]` by `val`. var index = rawGet(t, key) if index >= 0: @@ -717,7 +723,7 @@ proc inc*[A](t: var TCountTable[A], key: A, val = 1) = rawInsert(t, t.data, key, val) inc(t.counter) -proc smallest*[A](t: TCountTable[A]): tuple[key: A, val: int] = +proc smallest*[A](t: CountTable[A]): tuple[key: A, val: int] = ## returns the largest (key,val)-pair. Efficiency: O(n) assert t.len > 0 var minIdx = 0 @@ -726,7 +732,7 @@ proc smallest*[A](t: TCountTable[A]): tuple[key: A, val: int] = result.key = t.data[minIdx].key result.val = t.data[minIdx].val -proc largest*[A](t: TCountTable[A]): tuple[key: A, val: int] = +proc largest*[A](t: CountTable[A]): tuple[key: A, val: int] = ## returns the (key,val)-pair with the largest `val`. Efficiency: O(n) assert t.len > 0 var maxIdx = 0 @@ -735,7 +741,7 @@ proc largest*[A](t: TCountTable[A]): tuple[key: A, val: int] = result.key = t.data[maxIdx].key result.val = t.data[maxIdx].val -proc sort*[A](t: var TCountTable[A]) = +proc sort*[A](t: var CountTable[A]) = ## sorts the count table so that the entry with the highest counter comes ## first. This is destructive! You must not modify `t` afterwards! ## You can use the iterators `pairs`, `keys`, and `values` to iterate over @@ -756,57 +762,57 @@ proc sort*[A](t: var TCountTable[A]) = if j < h: break if h == 1: break -proc len*[A](t: PCountTable[A]): int = +proc len*[A](t: CountTableRef[A]): int = ## returns the number of keys in `t`. result = t.counter -iterator pairs*[A](t: PCountTable[A]): tuple[key: A, val: int] = +iterator pairs*[A](t: CountTableRef[A]): tuple[key: A, val: int] = ## iterates over any (key, value) pair in the table `t`. for h in 0..high(t.data): if t.data[h].val != 0: yield (t.data[h].key, t.data[h].val) -iterator mpairs*[A](t: PCountTable[A]): tuple[key: A, val: var int] = +iterator mpairs*[A](t: CountTableRef[A]): tuple[key: A, val: var int] = ## iterates over any (key, value) pair in the table `t`. The values can ## be modified. for h in 0..high(t.data): if t.data[h].val != 0: yield (t.data[h].key, t.data[h].val) -iterator keys*[A](t: PCountTable[A]): A = +iterator keys*[A](t: CountTableRef[A]): A = ## iterates over any key in the table `t`. for h in 0..high(t.data): if t.data[h].val != 0: yield t.data[h].key -iterator values*[A](t: PCountTable[A]): int = +iterator values*[A](t: CountTableRef[A]): int = ## iterates over any value in the table `t`. for h in 0..high(t.data): if t.data[h].val != 0: yield t.data[h].val -iterator mvalues*[A](t: PCountTable[A]): var int = +iterator mvalues*[A](t: CountTableRef[A]): var int = ## iterates over any value in the table `t`. The values can be modified. for h in 0..high(t.data): if t.data[h].val != 0: yield t.data[h].val -proc `[]`*[A](t: PCountTable[A], key: A): int = +proc `[]`*[A](t: CountTableRef[A], key: A): int = ## retrieves the value at ``t[key]``. If `key` is not in `t`, ## 0 is returned. One can check with ``hasKey`` whether the key ## exists. result = t[][key] -proc mget*[A](t: PCountTable[A], key: A): var int = +proc mget*[A](t: CountTableRef[A], key: A): var int = ## retrieves the value at ``t[key]``. The value can be modified. ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. result = t[].mget(key) -proc hasKey*[A](t: PCountTable[A], key: A): bool = +proc hasKey*[A](t: CountTableRef[A], key: A): bool = ## returns true iff `key` is in the table `t`. result = t[].hasKey(key) -proc `[]=`*[A](t: PCountTable[A], key: A, val: int) = +proc `[]=`*[A](t: CountTableRef[A], key: A, val: int) = ## puts a (key, value)-pair into `t`. `val` has to be positive. assert val > 0 t[][key] = val -proc newCountTable*[A](initialSize=64): PCountTable[A] = +proc newCountTable*[A](initialSize=64): CountTableRef[A] = ## creates a new count table that is empty. ## ## `initialSize` needs to be a power of two. If you need to accept runtime @@ -815,28 +821,28 @@ proc newCountTable*[A](initialSize=64): PCountTable[A] = new(result) result[] = initCountTable[A](initialSize) -proc newCountTable*[A](keys: openArray[A]): PCountTable[A] = +proc newCountTable*[A](keys: openArray[A]): CountTableRef[A] = ## creates a new count table with every key in `keys` having a count of 1. result = newCountTable[A](nextPowerOfTwo(keys.len+10)) for key in items(keys): result[key] = 1 -proc `$`*[A](t: PCountTable[A]): string = +proc `$`*[A](t: CountTableRef[A]): string = ## The `$` operator for count tables. dollarImpl() -proc inc*[A](t: PCountTable[A], key: A, val = 1) = +proc inc*[A](t: CountTableRef[A], key: A, val = 1) = ## increments `t[key]` by `val`. t[].inc(key, val) -proc smallest*[A](t: PCountTable[A]): tuple[key: A, val: int] = +proc smallest*[A](t: CountTableRef[A]): tuple[key: A, val: int] = ## returns the largest (key,val)-pair. Efficiency: O(n) t[].smallest -proc largest*[A](t: PCountTable[A]): tuple[key: A, val: int] = +proc largest*[A](t: CountTableRef[A]): tuple[key: A, val: int] = ## returns the (key,val)-pair with the largest `val`. Efficiency: O(n) t[].largest -proc sort*[A](t: PCountTable[A]) = +proc sort*[A](t: CountTableRef[A]) = ## sorts the count table so that the entry with the highest counter comes ## first. This is destructive! You must not modify `t` afterwards! ## You can use the iterators `pairs`, `keys`, and `values` to iterate over diff --git a/lib/pure/colors.nim b/lib/pure/colors.nim index 9f824e5de..7942255cb 100644 --- a/lib/pure/colors.nim +++ b/lib/pure/colors.nim @@ -1,5 +1,5 @@ # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this @@ -12,18 +12,20 @@ import strutils type - TColor* = distinct int ## a color stored as RGB + Color* = distinct int ## a color stored as RGB -proc `==` *(a, b: TColor): bool {.borrow.} +{.deprecated: [TColor: Color].} + +proc `==` *(a, b: Color): bool {.borrow.} ## compares two colors. -template extract(a: TColor, r, g, b: expr) {.immediate.}= +template extract(a: Color, r, g, b: expr) {.immediate.}= var r = a.int shr 16 and 0xff var g = a.int shr 8 and 0xff var b = a.int and 0xff template rawRGB(r, g, b: int): expr = - TColor(r shl 16 or g shl 8 or b) + Color(r shl 16 or g shl 8 or b) template colorOp(op: expr) {.immediate.} = extract(a, ar, ag, ab) @@ -38,23 +40,23 @@ proc satMinus(a, b: int): int {.inline.} = result = a -% b if result < 0: result = 0 -proc `+`*(a, b: TColor): TColor = +proc `+`*(a, b: Color): Color = ## adds two colors: This uses saturated artithmetic, so that each color ## component cannot overflow (255 is used as a maximum). colorOp(satPlus) -proc `-`*(a, b: TColor): TColor = +proc `-`*(a, b: Color): Color = ## substracts two colors: This uses saturated artithmetic, so that each color ## component cannot overflow (255 is used as a maximum). colorOp(satMinus) -proc extractRGB*(a: TColor): tuple[r, g, b: range[0..255]] = +proc extractRGB*(a: Color): tuple[r, g, b: range[0..255]] = ## extracts the red/green/blue components of the color `a`. result.r = a.int shr 16 and 0xff result.g = a.int shr 8 and 0xff result.b = a.int and 0xff -proc intensity*(a: TColor, f: float): TColor = +proc intensity*(a: Color, f: float): Color = ## returns `a` with intensity `f`. `f` should be a float from 0.0 (completely ## dark) to 1.0 (full color intensity). var r = toInt(toFloat(a.int shr 16 and 0xff) * f) @@ -65,7 +67,7 @@ proc intensity*(a: TColor, f: float): TColor = if b >% 255: b = 255 result = rawRGB(r, g, b) -template mix*(a, b: TColor, fn: expr): expr = +template mix*(a, b: Color, fn: expr): expr = ## uses `fn` to mix the colors `a` and `b`. `fn` is invoked for each component ## R, G, and B. This is a template because `fn` should be inlined and the ## compiler cannot inline proc pointers yet. If `fn`'s result is not in the @@ -84,146 +86,146 @@ template mix*(a, b: TColor, fn: expr): expr = const - colAliceBlue* = TColor(0xF0F8FF) - colAntiqueWhite* = TColor(0xFAEBD7) - colAqua* = TColor(0x00FFFF) - colAquamarine* = TColor(0x7FFFD4) - colAzure* = TColor(0xF0FFFF) - colBeige* = TColor(0xF5F5DC) - colBisque* = TColor(0xFFE4C4) - colBlack* = TColor(0x000000) - colBlanchedAlmond* = TColor(0xFFEBCD) - colBlue* = TColor(0x0000FF) - colBlueViolet* = TColor(0x8A2BE2) - colBrown* = TColor(0xA52A2A) - colBurlyWood* = TColor(0xDEB887) - colCadetBlue* = TColor(0x5F9EA0) - colChartreuse* = TColor(0x7FFF00) - colChocolate* = TColor(0xD2691E) - colCoral* = TColor(0xFF7F50) - colCornflowerBlue* = TColor(0x6495ED) - colCornsilk* = TColor(0xFFF8DC) - colCrimson* = TColor(0xDC143C) - colCyan* = TColor(0x00FFFF) - colDarkBlue* = TColor(0x00008B) - colDarkCyan* = TColor(0x008B8B) - colDarkGoldenRod* = TColor(0xB8860B) - colDarkGray* = TColor(0xA9A9A9) - colDarkGreen* = TColor(0x006400) - colDarkKhaki* = TColor(0xBDB76B) - colDarkMagenta* = TColor(0x8B008B) - colDarkOliveGreen* = TColor(0x556B2F) - colDarkorange* = TColor(0xFF8C00) - colDarkOrchid* = TColor(0x9932CC) - colDarkRed* = TColor(0x8B0000) - colDarkSalmon* = TColor(0xE9967A) - colDarkSeaGreen* = TColor(0x8FBC8F) - colDarkSlateBlue* = TColor(0x483D8B) - colDarkSlateGray* = TColor(0x2F4F4F) - colDarkTurquoise* = TColor(0x00CED1) - colDarkViolet* = TColor(0x9400D3) - colDeepPink* = TColor(0xFF1493) - colDeepSkyBlue* = TColor(0x00BFFF) - colDimGray* = TColor(0x696969) - colDodgerBlue* = TColor(0x1E90FF) - colFireBrick* = TColor(0xB22222) - colFloralWhite* = TColor(0xFFFAF0) - colForestGreen* = TColor(0x228B22) - colFuchsia* = TColor(0xFF00FF) - colGainsboro* = TColor(0xDCDCDC) - colGhostWhite* = TColor(0xF8F8FF) - colGold* = TColor(0xFFD700) - colGoldenRod* = TColor(0xDAA520) - colGray* = TColor(0x808080) - colGreen* = TColor(0x008000) - colGreenYellow* = TColor(0xADFF2F) - colHoneyDew* = TColor(0xF0FFF0) - colHotPink* = TColor(0xFF69B4) - colIndianRed* = TColor(0xCD5C5C) - colIndigo* = TColor(0x4B0082) - colIvory* = TColor(0xFFFFF0) - colKhaki* = TColor(0xF0E68C) - colLavender* = TColor(0xE6E6FA) - colLavenderBlush* = TColor(0xFFF0F5) - colLawnGreen* = TColor(0x7CFC00) - colLemonChiffon* = TColor(0xFFFACD) - colLightBlue* = TColor(0xADD8E6) - colLightCoral* = TColor(0xF08080) - colLightCyan* = TColor(0xE0FFFF) - colLightGoldenRodYellow* = TColor(0xFAFAD2) - colLightGrey* = TColor(0xD3D3D3) - colLightGreen* = TColor(0x90EE90) - colLightPink* = TColor(0xFFB6C1) - colLightSalmon* = TColor(0xFFA07A) - colLightSeaGreen* = TColor(0x20B2AA) - colLightSkyBlue* = TColor(0x87CEFA) - colLightSlateGray* = TColor(0x778899) - colLightSteelBlue* = TColor(0xB0C4DE) - colLightYellow* = TColor(0xFFFFE0) - colLime* = TColor(0x00FF00) - colLimeGreen* = TColor(0x32CD32) - colLinen* = TColor(0xFAF0E6) - colMagenta* = TColor(0xFF00FF) - colMaroon* = TColor(0x800000) - colMediumAquaMarine* = TColor(0x66CDAA) - colMediumBlue* = TColor(0x0000CD) - colMediumOrchid* = TColor(0xBA55D3) - colMediumPurple* = TColor(0x9370D8) - colMediumSeaGreen* = TColor(0x3CB371) - colMediumSlateBlue* = TColor(0x7B68EE) - colMediumSpringGreen* = TColor(0x00FA9A) - colMediumTurquoise* = TColor(0x48D1CC) - colMediumVioletRed* = TColor(0xC71585) - colMidnightBlue* = TColor(0x191970) - colMintCream* = TColor(0xF5FFFA) - colMistyRose* = TColor(0xFFE4E1) - colMoccasin* = TColor(0xFFE4B5) - colNavajoWhite* = TColor(0xFFDEAD) - colNavy* = TColor(0x000080) - colOldLace* = TColor(0xFDF5E6) - colOlive* = TColor(0x808000) - colOliveDrab* = TColor(0x6B8E23) - colOrange* = TColor(0xFFA500) - colOrangeRed* = TColor(0xFF4500) - colOrchid* = TColor(0xDA70D6) - colPaleGoldenRod* = TColor(0xEEE8AA) - colPaleGreen* = TColor(0x98FB98) - colPaleTurquoise* = TColor(0xAFEEEE) - colPaleVioletRed* = TColor(0xD87093) - colPapayaWhip* = TColor(0xFFEFD5) - colPeachPuff* = TColor(0xFFDAB9) - colPeru* = TColor(0xCD853F) - colPink* = TColor(0xFFC0CB) - colPlum* = TColor(0xDDA0DD) - colPowderBlue* = TColor(0xB0E0E6) - colPurple* = TColor(0x800080) - colRed* = TColor(0xFF0000) - colRosyBrown* = TColor(0xBC8F8F) - colRoyalBlue* = TColor(0x4169E1) - colSaddleBrown* = TColor(0x8B4513) - colSalmon* = TColor(0xFA8072) - colSandyBrown* = TColor(0xF4A460) - colSeaGreen* = TColor(0x2E8B57) - colSeaShell* = TColor(0xFFF5EE) - colSienna* = TColor(0xA0522D) - colSilver* = TColor(0xC0C0C0) - colSkyBlue* = TColor(0x87CEEB) - colSlateBlue* = TColor(0x6A5ACD) - colSlateGray* = TColor(0x708090) - colSnow* = TColor(0xFFFAFA) - colSpringGreen* = TColor(0x00FF7F) - colSteelBlue* = TColor(0x4682B4) - colTan* = TColor(0xD2B48C) - colTeal* = TColor(0x008080) - colThistle* = TColor(0xD8BFD8) - colTomato* = TColor(0xFF6347) - colTurquoise* = TColor(0x40E0D0) - colViolet* = TColor(0xEE82EE) - colWheat* = TColor(0xF5DEB3) - colWhite* = TColor(0xFFFFFF) - colWhiteSmoke* = TColor(0xF5F5F5) - colYellow* = TColor(0xFFFF00) - colYellowGreen* = TColor(0x9ACD32) + colAliceBlue* = Color(0xF0F8FF) + colAntiqueWhite* = Color(0xFAEBD7) + colAqua* = Color(0x00FFFF) + colAquamarine* = Color(0x7FFFD4) + colAzure* = Color(0xF0FFFF) + colBeige* = Color(0xF5F5DC) + colBisque* = Color(0xFFE4C4) + colBlack* = Color(0x000000) + colBlanchedAlmond* = Color(0xFFEBCD) + colBlue* = Color(0x0000FF) + colBlueViolet* = Color(0x8A2BE2) + colBrown* = Color(0xA52A2A) + colBurlyWood* = Color(0xDEB887) + colCadetBlue* = Color(0x5F9EA0) + colChartreuse* = Color(0x7FFF00) + colChocolate* = Color(0xD2691E) + colCoral* = Color(0xFF7F50) + colCornflowerBlue* = Color(0x6495ED) + colCornsilk* = Color(0xFFF8DC) + colCrimson* = Color(0xDC143C) + colCyan* = Color(0x00FFFF) + colDarkBlue* = Color(0x00008B) + colDarkCyan* = Color(0x008B8B) + colDarkGoldenRod* = Color(0xB8860B) + colDarkGray* = Color(0xA9A9A9) + colDarkGreen* = Color(0x006400) + colDarkKhaki* = Color(0xBDB76B) + colDarkMagenta* = Color(0x8B008B) + colDarkOliveGreen* = Color(0x556B2F) + colDarkorange* = Color(0xFF8C00) + colDarkOrchid* = Color(0x9932CC) + colDarkRed* = Color(0x8B0000) + colDarkSalmon* = Color(0xE9967A) + colDarkSeaGreen* = Color(0x8FBC8F) + colDarkSlateBlue* = Color(0x483D8B) + colDarkSlateGray* = Color(0x2F4F4F) + colDarkTurquoise* = Color(0x00CED1) + colDarkViolet* = Color(0x9400D3) + colDeepPink* = Color(0xFF1493) + colDeepSkyBlue* = Color(0x00BFFF) + colDimGray* = Color(0x696969) + colDodgerBlue* = Color(0x1E90FF) + colFireBrick* = Color(0xB22222) + colFloralWhite* = Color(0xFFFAF0) + colForestGreen* = Color(0x228B22) + colFuchsia* = Color(0xFF00FF) + colGainsboro* = Color(0xDCDCDC) + colGhostWhite* = Color(0xF8F8FF) + colGold* = Color(0xFFD700) + colGoldenRod* = Color(0xDAA520) + colGray* = Color(0x808080) + colGreen* = Color(0x008000) + colGreenYellow* = Color(0xADFF2F) + colHoneyDew* = Color(0xF0FFF0) + colHotPink* = Color(0xFF69B4) + colIndianRed* = Color(0xCD5C5C) + colIndigo* = Color(0x4B0082) + colIvory* = Color(0xFFFFF0) + colKhaki* = Color(0xF0E68C) + colLavender* = Color(0xE6E6FA) + colLavenderBlush* = Color(0xFFF0F5) + colLawnGreen* = Color(0x7CFC00) + colLemonChiffon* = Color(0xFFFACD) + colLightBlue* = Color(0xADD8E6) + colLightCoral* = Color(0xF08080) + colLightCyan* = Color(0xE0FFFF) + colLightGoldenRodYellow* = Color(0xFAFAD2) + colLightGrey* = Color(0xD3D3D3) + colLightGreen* = Color(0x90EE90) + colLightPink* = Color(0xFFB6C1) + colLightSalmon* = Color(0xFFA07A) + colLightSeaGreen* = Color(0x20B2AA) + colLightSkyBlue* = Color(0x87CEFA) + colLightSlateGray* = Color(0x778899) + colLightSteelBlue* = Color(0xB0C4DE) + colLightYellow* = Color(0xFFFFE0) + colLime* = Color(0x00FF00) + colLimeGreen* = Color(0x32CD32) + colLinen* = Color(0xFAF0E6) + colMagenta* = Color(0xFF00FF) + colMaroon* = Color(0x800000) + colMediumAquaMarine* = Color(0x66CDAA) + colMediumBlue* = Color(0x0000CD) + colMediumOrchid* = Color(0xBA55D3) + colMediumPurple* = Color(0x9370D8) + colMediumSeaGreen* = Color(0x3CB371) + colMediumSlateBlue* = Color(0x7B68EE) + colMediumSpringGreen* = Color(0x00FA9A) + colMediumTurquoise* = Color(0x48D1CC) + colMediumVioletRed* = Color(0xC71585) + colMidnightBlue* = Color(0x191970) + colMintCream* = Color(0xF5FFFA) + colMistyRose* = Color(0xFFE4E1) + colMoccasin* = Color(0xFFE4B5) + colNavajoWhite* = Color(0xFFDEAD) + colNavy* = Color(0x000080) + colOldLace* = Color(0xFDF5E6) + colOlive* = Color(0x808000) + colOliveDrab* = Color(0x6B8E23) + colOrange* = Color(0xFFA500) + colOrangeRed* = Color(0xFF4500) + colOrchid* = Color(0xDA70D6) + colPaleGoldenRod* = Color(0xEEE8AA) + colPaleGreen* = Color(0x98FB98) + colPaleTurquoise* = Color(0xAFEEEE) + colPaleVioletRed* = Color(0xD87093) + colPapayaWhip* = Color(0xFFEFD5) + colPeachPuff* = Color(0xFFDAB9) + colPeru* = Color(0xCD853F) + colPink* = Color(0xFFC0CB) + colPlum* = Color(0xDDA0DD) + colPowderBlue* = Color(0xB0E0E6) + colPurple* = Color(0x800080) + colRed* = Color(0xFF0000) + colRosyBrown* = Color(0xBC8F8F) + colRoyalBlue* = Color(0x4169E1) + colSaddleBrown* = Color(0x8B4513) + colSalmon* = Color(0xFA8072) + colSandyBrown* = Color(0xF4A460) + colSeaGreen* = Color(0x2E8B57) + colSeaShell* = Color(0xFFF5EE) + colSienna* = Color(0xA0522D) + colSilver* = Color(0xC0C0C0) + colSkyBlue* = Color(0x87CEEB) + colSlateBlue* = Color(0x6A5ACD) + colSlateGray* = Color(0x708090) + colSnow* = Color(0xFFFAFA) + colSpringGreen* = Color(0x00FF7F) + colSteelBlue* = Color(0x4682B4) + colTan* = Color(0xD2B48C) + colTeal* = Color(0x008080) + colThistle* = Color(0xD8BFD8) + colTomato* = Color(0xFF6347) + colTurquoise* = Color(0x40E0D0) + colViolet* = Color(0xEE82EE) + colWheat* = Color(0xF5DEB3) + colWhite* = Color(0xFFFFFF) + colWhiteSmoke* = Color(0xF5F5F5) + colYellow* = Color(0xFFFF00) + colYellowGreen* = Color(0x9ACD32) colorNames = [ ("aliceblue", colAliceBlue), @@ -367,11 +369,11 @@ const ("yellow", colYellow), ("yellowgreen", colYellowGreen)] -proc `$`*(c: TColor): string = +proc `$`*(c: Color): string = ## converts a color into its textual representation. Example: ``#00FF00``. result = '#' & toHex(int(c), 6) -proc binaryStrSearch(x: openarray[tuple[name: string, col: TColor]], +proc binaryStrSearch(x: openArray[tuple[name: string, col: Color]], y: string): int = var a = 0 var b = len(x) - 1 @@ -383,14 +385,14 @@ proc binaryStrSearch(x: openarray[tuple[name: string, col: TColor]], else: return mid result = - 1 -proc parseColor*(name: string): TColor = +proc parseColor*(name: string): Color = ## parses `name` to a color value. If no valid color could be ## parsed ``EInvalidValue`` is raised. if name[0] == '#': - result = TColor(parseHexInt(name)) + result = Color(parseHexInt(name)) else: var idx = binaryStrSearch(colorNames, name) - if idx < 0: raise newException(EInvalidValue, "unkown color: " & name) + if idx < 0: raise newException(ValueError, "unkown color: " & name) result = colorNames[idx][1] proc isColor*(name: string): bool = @@ -403,7 +405,7 @@ proc isColor*(name: string): bool = else: result = binaryStrSearch(colorNames, name) >= 0 -proc rgb*(r, g, b: range[0..255]): TColor = +proc rgb*(r, g, b: range[0..255]): Color = ## constructs a color from RGB values. result = rawRGB(r, g, b) diff --git a/lib/pure/complex.nim b/lib/pure/complex.nim index 1392b73aa..a8709e098 100644 --- a/lib/pure/complex.nim +++ b/lib/pure/complex.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this @@ -25,53 +25,55 @@ const type - TComplex* = tuple[re, im: float] + Complex* = tuple[re, im: float] ## a complex number, consisting of a real and an imaginary part -proc `==` *(x, y: TComplex): bool = +{.deprecated: [TComplex: Complex].} + +proc `==` *(x, y: Complex): bool = ## Compare two complex numbers `x` and `y` for equality. result = x.re == y.re and x.im == y.im -proc `=~` *(x, y: TComplex): bool = +proc `=~` *(x, y: Complex): bool = ## Compare two complex numbers `x` and `y` approximately. result = abs(x.re-y.re)<EPS and abs(x.im-y.im)<EPS -proc `+` *(x, y: TComplex): TComplex = +proc `+` *(x, y: Complex): Complex = ## Add two complex numbers. result.re = x.re + y.re result.im = x.im + y.im -proc `+` *(x: TComplex, y: float): TComplex = +proc `+` *(x: Complex, y: float): Complex = ## Add complex `x` to float `y`. result.re = x.re + y result.im = x.im -proc `+` *(x: float, y: TComplex): TComplex = +proc `+` *(x: float, y: Complex): Complex = ## Add float `x` to complex `y`. result.re = x + y.re result.im = y.im -proc `-` *(z: TComplex): TComplex = +proc `-` *(z: Complex): Complex = ## Unary minus for complex numbers. result.re = -z.re result.im = -z.im -proc `-` *(x, y: TComplex): TComplex = +proc `-` *(x, y: Complex): Complex = ## Subtract two complex numbers. result.re = x.re - y.re result.im = x.im - y.im -proc `-` *(x: TComplex, y: float): TComplex = +proc `-` *(x: Complex, y: float): Complex = ## Subtracts float `y` from complex `x`. result = x + (-y) -proc `-` *(x: float, y: TComplex): TComplex = +proc `-` *(x: float, y: Complex): Complex = ## Subtracts complex `y` from float `x`. result = x + (-y) -proc `/` *(x, y: TComplex): TComplex = +proc `/` *(x, y: Complex): Complex = ## Divide `x` by `y`. var r, den: float @@ -86,73 +88,73 @@ proc `/` *(x, y: TComplex): TComplex = result.re = (x.re + r * x.im) / den result.im = (x.im - r * x.re) / den -proc `/` *(x : TComplex, y: float ): TComplex = +proc `/` *(x : Complex, y: float ): Complex = ## Divide complex `x` by float `y`. result.re = x.re/y result.im = x.im/y -proc `/` *(x : float, y: TComplex ): TComplex = +proc `/` *(x : float, y: Complex ): Complex = ## Divide float `x` by complex `y`. - var num : TComplex = (x, 0.0) + var num : Complex = (x, 0.0) result = num/y -proc `*` *(x, y: TComplex): TComplex = +proc `*` *(x, y: Complex): Complex = ## Multiply `x` with `y`. result.re = x.re * y.re - x.im * y.im result.im = x.im * y.re + x.re * y.im -proc `*` *(x: float, y: TComplex): TComplex = +proc `*` *(x: float, y: Complex): Complex = ## Multiply float `x` with complex `y`. result.re = x * y.re result.im = x * y.im -proc `*` *(x: TComplex, y: float): TComplex = +proc `*` *(x: Complex, y: float): Complex = ## Multiply complex `x` with float `y`. result.re = x.re * y result.im = x.im * y -proc `+=` *(x: var TComplex, y: TComplex) = +proc `+=` *(x: var Complex, y: Complex) = ## Add `y` to `x`. x.re += y.re x.im += y.im -proc `+=` *(x: var TComplex, y: float) = +proc `+=` *(x: var Complex, y: float) = ## Add `y` to the complex number `x`. x.re += y -proc `-=` *(x: var TComplex, y: TComplex) = +proc `-=` *(x: var Complex, y: Complex) = ## Subtract `y` from `x`. x.re -= y.re x.im -= y.im -proc `-=` *(x: var TComplex, y: float) = +proc `-=` *(x: var Complex, y: float) = ## Subtract `y` from the complex number `x`. x.re -= y -proc `*=` *(x: var TComplex, y: TComplex) = +proc `*=` *(x: var Complex, y: Complex) = ## Multiply `y` to `x`. let im = x.im * y.re + x.re * y.im x.re = x.re * y.re - x.im * y.im x.im = im -proc `*=` *(x: var TComplex, y: float) = +proc `*=` *(x: var Complex, y: float) = ## Multiply `y` to the complex number `x`. x.re *= y x.im *= y -proc `/=` *(x: var TComplex, y: TComplex) = +proc `/=` *(x: var Complex, y: Complex) = ## Divide `x` by `y` in place. x = x / y -proc `/=` *(x : var TComplex, y: float) = +proc `/=` *(x : var Complex, y: float) = ## Divide complex `x` by float `y` in place. x.re /= y x.im /= y -proc abs*(z: TComplex): float = +proc abs*(z: Complex): float = ## Return the distance from (0,0) to `z`. # optimized by checking special cases (sqrt is expensive) @@ -172,7 +174,7 @@ proc abs*(z: TComplex): float = result = y * sqrt(1.0 + temp * temp) -proc sqrt*(z: TComplex): TComplex = +proc sqrt*(z: Complex): Complex = ## Square root for a complex number `z`. var x, y, w, r: float @@ -196,7 +198,7 @@ proc sqrt*(z: TComplex): TComplex = result.re = z.im / (result.im + result.im) -proc exp*(z: TComplex): TComplex = +proc exp*(z: Complex): Complex = ## e raised to the power `z`. var rho = exp(z.re) var theta = z.im @@ -204,21 +206,21 @@ proc exp*(z: TComplex): TComplex = result.im = rho*sin(theta) -proc ln*(z: TComplex): TComplex = +proc ln*(z: Complex): Complex = ## Returns the natural log of `z`. result.re = ln(abs(z)) result.im = arctan2(z.im,z.re) -proc log10*(z: TComplex): TComplex = +proc log10*(z: Complex): Complex = ## Returns the log base 10 of `z`. result = ln(z)/ln(10.0) -proc log2*(z: TComplex): TComplex = +proc log2*(z: Complex): Complex = ## Returns the log base 2 of `z`. result = ln(z)/ln(2.0) -proc pow*(x, y: TComplex): TComplex = +proc pow*(x, y: Complex): Complex = ## `x` raised to the power `y`. if x.re == 0.0 and x.im == 0.0: if y.re == 0.0 and y.im == 0.0: @@ -240,53 +242,53 @@ proc pow*(x, y: TComplex): TComplex = result.im = s*sin(r) -proc sin*(z: TComplex): TComplex = +proc sin*(z: Complex): Complex = ## Returns the sine of `z`. result.re = sin(z.re)*cosh(z.im) result.im = cos(z.re)*sinh(z.im) -proc arcsin*(z: TComplex): TComplex = +proc arcsin*(z: Complex): Complex = ## Returns the inverse sine of `z`. - var i: TComplex = (0.0,1.0) + var i: Complex = (0.0,1.0) result = -i*ln(i*z + sqrt(1.0-z*z)) -proc cos*(z: TComplex): TComplex = +proc cos*(z: Complex): Complex = ## Returns the cosine of `z`. result.re = cos(z.re)*cosh(z.im) result.im = -sin(z.re)*sinh(z.im) -proc arccos*(z: TComplex): TComplex = +proc arccos*(z: Complex): Complex = ## Returns the inverse cosine of `z`. - var i: TComplex = (0.0,1.0) + var i: Complex = (0.0,1.0) result = -i*ln(z + sqrt(z*z-1.0)) -proc tan*(z: TComplex): TComplex = +proc tan*(z: Complex): Complex = ## Returns the tangent of `z`. result = sin(z)/cos(z) -proc cot*(z: TComplex): TComplex = +proc cot*(z: Complex): Complex = ## Returns the cotangent of `z`. result = cos(z)/sin(z) -proc sec*(z: TComplex): TComplex = +proc sec*(z: Complex): Complex = ## Returns the secant of `z`. result = 1.0/cos(z) -proc csc*(z: TComplex): TComplex = +proc csc*(z: Complex): Complex = ## Returns the cosecant of `z`. result = 1.0/sin(z) -proc sinh*(z: TComplex): TComplex = +proc sinh*(z: Complex): Complex = ## Returns the hyperbolic sine of `z`. result = 0.5*(exp(z)-exp(-z)) -proc cosh*(z: TComplex): TComplex = +proc cosh*(z: Complex): Complex = ## Returns the hyperbolic cosine of `z`. result = 0.5*(exp(z)+exp(-z)) -proc `$`*(z: TComplex): string = +proc `$`*(z: Complex): string = ## Returns `z`'s string representation as ``"(re, im)"``. result = "(" & $z.re & ", " & $z.im & ")" diff --git a/lib/pure/concurrency/cpuinfo.nim b/lib/pure/concurrency/cpuinfo.nim index 8d7f28f8e..ac5fa5dd9 100644 --- a/lib/pure/concurrency/cpuinfo.nim +++ b/lib/pure/concurrency/cpuinfo.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/pure/concurrency/cpuload.nim b/lib/pure/concurrency/cpuload.nim index 3cf6a7392..74a639be1 100644 --- a/lib/pure/concurrency/cpuload.nim +++ b/lib/pure/concurrency/cpuload.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/pure/concurrency/threadpool.nim b/lib/pure/concurrency/threadpool.nim index f46822d94..fbd344e4e 100644 --- a/lib/pure/concurrency/threadpool.nim +++ b/lib/pure/concurrency/threadpool.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## Implements Nimrod's 'spawn'. +## Implements Nim's 'spawn'. when not compileOption("threads"): {.error: "Threadpool requires --threads:on option.".} @@ -94,7 +94,7 @@ type idx: int FlowVarBase* = ref FlowVarBaseObj ## untyped base class for 'FlowVar[T]' - FlowVarBaseObj = object of TObject + FlowVarBaseObj = object of RootObj ready, usesCondVar, awaited: bool cv: CondVar #\ # for 'awaitAny' support @@ -164,7 +164,7 @@ proc cleanFlowVars(w: ptr Worker) = let q = addr(w.q) acquire(q.lock) for i in 0 .. <q.len: - GC_unref(cast[PObject](q.data[i])) + GC_unref(cast[RootRef](q.data[i])) q.len = 0 release(q.lock) signal(q.empty) @@ -185,11 +185,12 @@ proc nimFlowVarSignal(fv: FlowVarBase) {.compilerProc.} = inc fv.ai.cv.counter release(fv.ai.cv.L) signal(fv.ai.cv.c) - if fv.usesCondVar: signal(fv.cv) + if fv.usesCondVar: + signal(fv.cv) proc awaitAndThen*[T](fv: FlowVar[T]; action: proc (x: T) {.closure.}) = ## blocks until the ``fv`` is available and then passes its value - ## to ``action``. Note that due to Nimrod's parameter passing semantics this + ## to ``action``. Note that due to Nim's parameter passing semantics this ## means that ``T`` doesn't need to be copied and so ``awaitAndThen`` can ## sometimes be more efficient than ``^``. await(fv) diff --git a/lib/pure/cookies.nim b/lib/pure/cookies.nim index 49bf92980..6247efed2 100644 --- a/lib/pure/cookies.nim +++ b/lib/pure/cookies.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -11,7 +11,7 @@ import strtabs, times -proc parseCookies*(s: string): PStringTable = +proc parseCookies*(s: string): StringTableRef = ## parses cookies into a string table. result = newStringTable(modeCaseInsensitive) var i = 0 @@ -42,20 +42,19 @@ proc setCookie*(key, value: string, domain = "", path = "", if secure: result.add("; secure") if httpOnly: result.add("; HttpOnly") -proc setCookie*(key, value: string, expires: TTimeInfo, +proc setCookie*(key, value: string, expires: TimeInfo, domain = "", path = "", noName = false, secure = false, httpOnly = false): string = ## Creates a command in the format of ## ``Set-Cookie: key=value; Domain=...; ...`` ## - ## **Note:** UTC is assumed as the timezone for ``expires``. - + ## **Note:** UTC is assumed as the timezone for ``expires``. return setCookie(key, value, domain, path, format(expires, "ddd',' dd MMM yyyy HH:mm:ss 'UTC'"), noname, secure, httpOnly) - + when isMainModule: - var tim = TTime(int(getTime()) + 76 * (60 * 60 * 24)) + var tim = Time(int(getTime()) + 76 * (60 * 60 * 24)) echo(setCookie("test", "value", tim.getGMTime())) diff --git a/lib/pure/dynlib.nim b/lib/pure/dynlib.nim index 54a553173..c6794be67 100644 --- a/lib/pure/dynlib.nim +++ b/lib/pure/dynlib.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -12,31 +12,33 @@ ## Windows ``LoadLibrary``. type - TLibHandle* = pointer ## a handle to a dynamically loaded library + LibHandle* = pointer ## a handle to a dynamically loaded library -proc loadLib*(path: string, global_symbols=false): TLibHandle +{.deprecated: [TLibHandle: LibHandle].} + +proc loadLib*(path: string, global_symbols=false): LibHandle ## loads a library from `path`. Returns nil if the library could not ## be loaded. -proc loadLib*(): TLibHandle +proc loadLib*(): LibHandle ## gets the handle from the current executable. Returns nil if the ## library could not be loaded. -proc unloadLib*(lib: TLibHandle) +proc unloadLib*(lib: LibHandle) ## unloads the library `lib` proc raiseInvalidLibrary*(name: cstring) {.noinline, noreturn.} = ## raises an `EInvalidLibrary` exception. - var e: ref EInvalidLibrary + var e: ref LibraryError new(e) e.msg = "could not find symbol: " & $name raise e -proc symAddr*(lib: TLibHandle, name: cstring): pointer +proc symAddr*(lib: LibHandle, name: cstring): pointer ## retrieves the address of a procedure/variable from `lib`. Returns nil ## if the symbol could not be found. -proc checkedSymAddr*(lib: TLibHandle, name: cstring): pointer = +proc checkedSymAddr*(lib: LibHandle, name: cstring): pointer = ## retrieves the address of a procedure/variable from `lib`. Raises ## `EInvalidLibrary` if the symbol could not be found. result = symAddr(lib, name) @@ -55,19 +57,19 @@ when defined(posix): RTLD_NOW {.importc: "RTLD_NOW", header: "<dlfcn.h>".}: int RTLD_GLOBAL {.importc: "RTLD_GLOBAL", header: "<dlfcn.h>".}: int - proc dlclose(lib: TLibHandle) {.importc, header: "<dlfcn.h>".} - proc dlopen(path: CString, mode: int): TLibHandle {. + proc dlclose(lib: LibHandle) {.importc, header: "<dlfcn.h>".} + proc dlopen(path: cstring, mode: int): LibHandle {. importc, header: "<dlfcn.h>".} - proc dlsym(lib: TLibHandle, name: cstring): pointer {. + proc dlsym(lib: LibHandle, name: cstring): pointer {. importc, header: "<dlfcn.h>".} - proc loadLib(path: string, global_symbols=false): TLibHandle = + proc loadLib(path: string, global_symbols=false): LibHandle = var flags = RTLD_NOW if global_symbols: flags = flags or RTLD_GLOBAL return dlopen(path, flags) - proc loadLib(): TLibHandle = return dlopen(nil, RTLD_NOW) - proc unloadLib(lib: TLibHandle) = dlclose(lib) - proc symAddr(lib: TLibHandle, name: cstring): pointer = + proc loadLib(): LibHandle = return dlopen(nil, RTLD_NOW) + proc unloadLib(lib: LibHandle) = dlclose(lib) + proc symAddr(lib: LibHandle, name: cstring): pointer = return dlsym(lib, name) elif defined(windows) or defined(dos): @@ -85,13 +87,13 @@ elif defined(windows) or defined(dos): proc getProcAddress(lib: THINSTANCE, name: cstring): pointer {. importc: "GetProcAddress", header: "<windows.h>", stdcall.} - proc loadLib(path: string, global_symbols=false): TLibHandle = - result = cast[TLibHandle](winLoadLibrary(path)) - proc loadLib(): TLibHandle = - result = cast[TLibHandle](winLoadLibrary(nil)) - proc unloadLib(lib: TLibHandle) = FreeLibrary(cast[THINSTANCE](lib)) + proc loadLib(path: string, global_symbols=false): LibHandle = + result = cast[LibHandle](winLoadLibrary(path)) + proc loadLib(): LibHandle = + result = cast[LibHandle](winLoadLibrary(nil)) + proc unloadLib(lib: LibHandle) = FreeLibrary(cast[THINSTANCE](lib)) - proc symAddr(lib: TLibHandle, name: cstring): pointer = + proc symAddr(lib: LibHandle, name: cstring): pointer = result = getProcAddress(cast[THINSTANCE](lib), name) else: diff --git a/lib/pure/encodings.nim b/lib/pure/encodings.nim index 633ea6020..958a4133b 100644 --- a/lib/pure/encodings.nim +++ b/lib/pure/encodings.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -14,18 +14,20 @@ import os, parseutils, strutils when not defined(windows): type - TConverter = object - PConverter* = ptr TConverter ## can convert between two character sets + ConverterObj = object + EncodingConverter* = ptr ConverterObj ## can convert between two character sets else: type - TCodePage = distinct int32 - PConverter* = object - dest, src: TCodePage + CodePage = distinct int32 + EncodingConverter* = object + dest, src: CodePage type - EInvalidEncoding* = object of EInvalidValue ## exception that is raised - ## for encoding errors + EncodingError* = object of ValueError ## exception that is raised + ## for encoding errors + +{.deprecated: [EInvalidEncoding: EncodingError, PConverter: EncodingConverter].} when defined(windows): proc eqEncodingNames(a, b: string): bool = @@ -34,7 +36,7 @@ when defined(windows): while i < a.len and j < b.len: if a[i] in {'-', '_'}: inc i if b[j] in {'-', '_'}: inc j - if a[i].tolower != b[j].tolower: return false + if a[i].toLower != b[j].toLower: return false inc i inc j result = i == a.len and j == b.len @@ -214,26 +216,26 @@ when defined(windows): defaultChar: array[0..1, char] leadByte: array[0..12-1, char] - proc getCPInfo(codePage: TCodePage, lpCPInfo: var TCpInfo): int32 {. + proc getCPInfo(codePage: CodePage, lpCPInfo: var TCpInfo): int32 {. stdcall, importc: "GetCPInfo", dynlib: "kernel32".} - proc nameToCodePage(name: string): TCodePage = + proc nameToCodePage(name: string): CodePage = var nameAsInt: int if parseInt(name, nameAsInt) == 0: nameAsInt = -1 for no, na in items(winEncodings): - if no == nameAsInt or eqEncodingNames(na, name): return TCodePage(no) - result = TCodePage(-1) + if no == nameAsInt or eqEncodingNames(na, name): return CodePage(no) + result = CodePage(-1) - proc codePageToName(c: TCodePage): string = + proc codePageToName(c: CodePage): string = for no, na in items(winEncodings): if no == int(c): return if na.len != 0: na else: $no result = "" - proc getACP(): TCodePage {.stdcall, importc: "GetACP", dynlib: "kernel32".} + proc getACP(): CodePage {.stdcall, importc: "GetACP", dynlib: "kernel32".} proc multiByteToWideChar( - codePage: TCodePage, + codePage: CodePage, dwFlags: int32, lpMultiByteStr: cstring, cbMultiByte: cint, @@ -242,7 +244,7 @@ when defined(windows): stdcall, importc: "MultiByteToWideChar", dynlib: "kernel32".} proc wideCharToMultiByte( - codePage: TCodePage, + codePage: CodePage, dwFlags: int32, lpWideCharStr: cstring, cchWideChar: cint, @@ -260,7 +262,7 @@ else: else: const iconvDll = "(libc.so.6|libiconv.so)" - when defined(macosx) and defined(powerpc32): + when defined(macosx) and defined(powerpc): const prefix = "lib" else: const prefix = "" @@ -279,50 +281,50 @@ else: var errno {.importc, header: "<errno.h>".}: cint - proc iconvOpen(tocode, fromcode: cstring): PConverter {. + proc iconvOpen(tocode, fromcode: cstring): EncodingConverter {. importc: prefix & "iconv_open", cdecl, dynlib: iconvDll.} - proc iconvClose(c: PConverter) {. + proc iconvClose(c: EncodingConverter) {. importc: prefix & "iconv_close", cdecl, dynlib: iconvDll.} - proc iconv(c: PConverter, inbuf: var cstring, inbytesLeft: var int, + proc iconv(c: EncodingConverter, inbuf: var cstring, inbytesLeft: var int, outbuf: var cstring, outbytesLeft: var int): int {. importc: prefix & "iconv", cdecl, dynlib: iconvDll.} - proc iconv(c: PConverter, inbuf: pointer, inbytesLeft: pointer, + proc iconv(c: EncodingConverter, inbuf: pointer, inbytesLeft: pointer, outbuf: var cstring, outbytesLeft: var int): int {. importc: prefix & "iconv", cdecl, dynlib: iconvDll.} proc getCurrentEncoding*(): string = ## retrieves the current encoding. On Unix, always "UTF-8" is returned. when defined(windows): - result = codePageToName(GetACP()) + result = codePageToName(getACP()) else: result = "UTF-8" -proc open*(destEncoding = "UTF-8", srcEncoding = "CP1252"): PConverter = +proc open*(destEncoding = "UTF-8", srcEncoding = "CP1252"): EncodingConverter = ## opens a converter that can convert from `srcEncoding` to `destEncoding`. ## Raises `EIO` if it cannot fullfill the request. when not defined(windows): result = iconvOpen(destEncoding, srcEncoding) if result == nil: - raise newException(EInvalidEncoding, + raise newException(EncodingError, "cannot create encoding converter from " & srcEncoding & " to " & destEncoding) else: result.dest = nameToCodePage(destEncoding) result.src = nameToCodePage(srcEncoding) if int(result.dest) == -1: - raise newException(EInvalidEncoding, + raise newException(EncodingError, "cannot find encoding " & destEncoding) if int(result.src) == -1: - raise newException(EInvalidEncoding, + raise newException(EncodingError, "cannot find encoding " & srcEncoding) -proc close*(c: PConverter) = +proc close*(c: EncodingConverter) = ## frees the resources the converter `c` holds. when not defined(windows): iconvClose(c) when defined(windows): - proc convert*(c: PConverter, s: string): string = + proc convert*(c: EncodingConverter, s: string): string = ## converts `s` to `destEncoding` that was given to the converter `c`. It ## assumed that `s` is in `srcEncoding`. @@ -352,7 +354,7 @@ when defined(windows): cbMultiByte = cint(s.len), lpWideCharStr = cstring(result), cchWideChar = cint(cap)) - if m == 0: osError(osLastError()) + if m == 0: raiseOSError(osLastError()) setLen(result, m*2) elif m <= cap: setLen(result, m*2) @@ -389,7 +391,7 @@ when defined(windows): cchWideChar = cint(result.len div 2), lpMultiByteStr = cstring(res), cbMultiByte = cap.cint) - if m == 0: osError(osLastError()) + if m == 0: raiseOSError(osLastError()) setLen(res, m) result = res elif m <= cap: @@ -399,7 +401,7 @@ when defined(windows): assert(false) # cannot happen else: - proc convert*(c: PConverter, s: string): string = + proc convert*(c: EncodingConverter, s: string): string = result = newString(s.len) var inLen = len(s) var outLen = len(result) @@ -412,7 +414,7 @@ else: var lerr = errno if lerr == EILSEQ or lerr == EINVAL: # unknown char, skip - Dst[0] = Src[0] + dst[0] = src[0] src = cast[cstring](cast[int](src) + 1) dst = cast[cstring](cast[int](dst) + 1) dec(inLen) @@ -424,19 +426,19 @@ else: dst = cast[cstring](cast[int](cstring(result)) + offset) outLen = len(result) - offset else: - osError(lerr.TOSErrorCode) + raiseOSError(lerr.OSErrorCode) # iconv has a buffer that needs flushing, specially if the last char is # not '\0' - discard iconv(c, nil, nil, dst, outlen) + discard iconv(c, nil, nil, dst, outLen) if iconvres == cint(-1) and errno == E2BIG: var offset = cast[int](dst) - cast[int](cstring(result)) setLen(result, len(result)+inLen*2+5) # 5 is minimally one utf-8 char dst = cast[cstring](cast[int](cstring(result)) + offset) outLen = len(result) - offset - discard iconv(c, nil, nil, dst, outlen) + discard iconv(c, nil, nil, dst, outLen) # trim output buffer - setLen(result, len(result) - outlen) + setLen(result, len(result) - outLen) proc convert*(s: string, destEncoding = "UTF-8", srcEncoding = "CP1252"): string = diff --git a/lib/pure/endians.nim b/lib/pure/endians.nim index 73017464d..6e33d4624 100644 --- a/lib/pure/endians.nim +++ b/lib/pure/endians.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/pure/events.nim b/lib/pure/events.nim index 5830d9109..47dc6ba3f 100644 --- a/lib/pure/events.nim +++ b/lib/pure/events.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2011 Alex Mitchell # # See the file "copying.txt", included in this @@ -14,10 +14,10 @@ ## it was inspired by Python's PyEE module. There are two ways you can use ## events: one is a python-inspired way; the other is more of a C-style way. ## -## .. code-block:: Nimrod +## .. code-block:: Nim ## var ee = initEventEmitter() -## var genericargs: TEventArgs -## proc handleevent(e: TEventArgs) = +## var genericargs: EventArgs +## proc handleevent(e: EventArgs) = ## echo("Handled!") ## ## # Python way @@ -27,53 +27,56 @@ ## # C/Java way ## # Declare a type ## type -## TSomeObject = object of TObject -## SomeEvent: TEventHandler -## var myobj: TSomeObject +## SomeObject = object of RootObj +## SomeEvent: EventHandler +## var myobj: SomeObject ## myobj.SomeEvent = initEventHandler("SomeEvent") ## myobj.SomeEvent.addHandler(handleevent) ## ee.emit(myobj.SomeEvent, genericargs) type - TEventArgs* = object of TObject ## Base object for event arguments that are passed to callback functions. - TEventHandler* = tuple[name: string, handlers: seq[proc(e:TEventArgs) {.closure.}]] ## An eventhandler for an event. + EventArgs* = object of RootObj ## Base object for event arguments that are passed to callback functions. + EventHandler* = tuple[name: string, handlers: seq[proc(e: EventArgs) {.closure.}]] ## An eventhandler for an event. type - TEventEmitter* = object {.pure, final.} ## An object that fires events and holds event handlers for an object. - s: seq[TEventHandler] - EInvalidEvent* = object of EInvalidValue + EventEmitter* = object ## An object that fires events and holds event handlers for an object. + s: seq[EventHandler] + EventError* = object of ValueError + +{.deprecated: [TEventArgs: EventArgs, TEventHandler: EventHandler, + TEventEmitter: EventEmitter, EInvalidEvent: EventError].} -proc initEventHandler*(name: string): TEventHandler = +proc initEventHandler*(name: string): EventHandler = ## Initializes an EventHandler with the specified name and returns it. result.handlers = @[] result.name = name -proc addHandler*(handler: var TEventHandler, func: proc(e: TEventArgs) {.closure.}) = +proc addHandler*(handler: var EventHandler, func: proc(e: EventArgs) {.closure.}) = ## Adds the callback to the specified event handler. handler.handlers.add(func) -proc removeHandler*(handler: var TEventHandler, func: proc(e: TEventArgs) {.closure.}) = +proc removeHandler*(handler: var EventHandler, func: proc(e: EventArgs) {.closure.}) = ## Removes the callback from the specified event handler. for i in countup(0, len(handler.handlers) -1): if func == handler.handlers[i]: handler.handlers.del(i) break -proc containsHandler*(handler: var TEventHandler, func: proc(e: TEventArgs) {.closure.}): bool = +proc containsHandler*(handler: var EventHandler, func: proc(e: EventArgs) {.closure.}): bool = ## Checks if a callback is registered to this event handler. return handler.handlers.contains(func) -proc clearHandlers*(handler: var TEventHandler) = +proc clearHandlers*(handler: var EventHandler) = ## Clears all of the callbacks from the event handler. setLen(handler.handlers, 0) -proc getEventHandler(emitter: var TEventEmitter, event: string): int = +proc getEventHandler(emitter: var EventEmitter, event: string): int = for k in 0..high(emitter.s): if emitter.s[k].name == event: return k return -1 -proc on*(emitter: var TEventEmitter, event: string, func: proc(e: TEventArgs) {.closure.}) = +proc on*(emitter: var EventEmitter, event: string, func: proc(e: EventArgs) {.closure.}) = ## Assigns a event handler with the specified callback. If the event ## doesn't exist, it will be created. var i = getEventHandler(emitter, event) @@ -84,17 +87,17 @@ proc on*(emitter: var TEventEmitter, event: string, func: proc(e: TEventArgs) {. else: addHandler(emitter.s[i], func) -proc emit*(emitter: var TEventEmitter, eventhandler: var TEventHandler, - args: TEventArgs) = +proc emit*(emitter: var EventEmitter, eventhandler: var EventHandler, + args: EventArgs) = ## Fires an event handler with specified event arguments. for func in items(eventhandler.handlers): func(args) -proc emit*(emitter: var TEventEmitter, event: string, args: TEventArgs) = +proc emit*(emitter: var EventEmitter, event: string, args: EventArgs) = ## Fires an event handler with specified event arguments. var i = getEventHandler(emitter, event) if i >= 0: emit(emitter, emitter.s[i], args) -proc initEventEmitter*(): TEventEmitter = +proc initEventEmitter*(): EventEmitter = ## Creates and returns a new EventEmitter. result.s = @[] diff --git a/lib/pure/fsmonitor.nim b/lib/pure/fsmonitor.nim index b35466771..bf4aef61c 100644 --- a/lib/pure/fsmonitor.nim +++ b/lib/pure/fsmonitor.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Dominik Picheta # # See the file "copying.txt", included in this @@ -25,13 +25,13 @@ else: import inotify, os, asyncio, tables type - PFSMonitor* = ref TFSMonitor - TFSMonitor = object of TObject + FSMonitor* = ref FSMonitorObj + FSMonitorObj = object of RootObj fd: cint - handleEvent: proc (m: PFSMonitor, ev: TMonitorEvent) {.closure.} + handleEvent: proc (m: FSMonitor, ev: MonitorEvent) {.closure.} targets: TTable[cint, string] - TMonitorEventType* = enum ## Monitor event type + MonitorEventType* = enum ## Monitor event type MonitorAccess, ## File was accessed. MonitorAttrib, ## Metadata changed. MonitorCloseWrite, ## Writtable file was closed. @@ -45,8 +45,8 @@ type MonitorOpen, ## File was opened. MonitorAll ## Filter for all event types. - TMonitorEvent* = object - case kind*: TMonitorEventType ## Type of the event. + MonitorEvent* = object + case kind*: MonitorEventType ## Type of the event. of MonitorMoveSelf, MonitorMoved: oldPath*: string ## Old absolute location newPath*: string ## New absolute location @@ -58,6 +58,9 @@ type ## watched. wd*: cint ## Watch descriptor. +{.deprecated: [PFSMonitor: FSMonitor, TFSMonitor: FSMonitorObj, + TMonitorEventType: MonitorEventType, TMonitorEvent: MonitorEvent].} + const MaxEvents = 100 @@ -67,7 +70,7 @@ proc newMonitor*(): PFSMonitor = result.targets = initTable[cint, string]() result.fd = inotifyInit() if result.fd < 0: - OSError(OSLastError()) + raiseOSError(osLastError()) proc add*(monitor: PFSMonitor, target: string, filters = {MonitorAll}): cint {.discardable.} = @@ -93,7 +96,7 @@ proc add*(monitor: PFSMonitor, target: string, result = inotifyAddWatch(monitor.fd, target, INFilter.uint32) if result < 0: - OSError(OSLastError()) + raiseOSError(osLastError()) monitor.targets.add(result, target) proc del*(monitor: PFSMonitor, wd: cint) = @@ -101,7 +104,7 @@ proc del*(monitor: PFSMonitor, wd: cint) = ## ## If ``wd`` is not a part of ``monitor`` an EOS error is raised. if inotifyRmWatch(monitor.fd, wd) < 0: - OSError(OSLastError()) + raiseOSError(osLastError()) proc getEvent(m: PFSMonitor, fd: cint): seq[TMonitorEvent] = result = @[] @@ -110,8 +113,7 @@ proc getEvent(m: PFSMonitor, fd: cint): seq[TMonitorEvent] = let le = read(fd, addr(buffer[0]), size) - var movedFrom: TTable[cint, tuple[wd: cint, old: string]] = - initTable[cint, tuple[wd: cint, old: string]]() + var movedFrom = initTable[cint, tuple[wd: cint, old: string]]() var i = 0 while i < le: @@ -197,18 +199,19 @@ proc register*(d: PDispatcher, monitor: PFSMonitor, d.register(deleg) when isMainModule: - var disp = newDispatcher() - var monitor = newMonitor() - echo monitor.add("/home/dom/inotifytests/") - disp.register(monitor, - proc (m: PFSMonitor, ev: TMonitorEvent) = - echo("Got event: ", ev.kind) - if ev.kind == MonitorMoved: - echo("From ", ev.oldPath, " to ", ev.newPath) - echo("Name is ", ev.name) - else: - echo("Name ", ev.name, " fullname ", ev.fullName)) - - while true: - if not disp.poll(): break - + proc main = + var disp = newDispatcher() + var monitor = newMonitor() + echo monitor.add("/home/dom/inotifytests/") + disp.register(monitor, + proc (m: PFSMonitor, ev: TMonitorEvent) = + echo("Got event: ", ev.kind) + if ev.kind == MonitorMoved: + echo("From ", ev.oldPath, " to ", ev.newPath) + echo("Name is ", ev.name) + else: + echo("Name ", ev.name, " fullname ", ev.fullName)) + + while true: + if not disp.poll(): break + main() diff --git a/lib/pure/ftpclient.nim b/lib/pure/ftpclient.nim index e8d3f762e..975eae7e2 100644 --- a/lib/pure/ftpclient.nim +++ b/lib/pure/ftpclient.nim @@ -1,7 +1,7 @@ # # -# Nimrod's Runtime Library -# (c) Copyright 2012 Dominik Picheta +# Nim's Runtime Library +# (c) Copyright 2014 Dominik Picheta # See the file "copying.txt", included in this # distribution, for details about the copyright. # @@ -18,8 +18,8 @@ from asyncdispatch import PFuture ## by `RFC 959 <http://tools.ietf.org/html/rfc959>`_. ## ## This module provides both a synchronous and asynchronous implementation. -## The asynchronous implementation requires you to use the ``AsyncFTPClient`` -## function. You are then required to register the ``PAsyncFTPClient`` with a +## The asynchronous implementation requires you to use the ``asyncFTPClient`` +## function. You are then required to register the ``AsyncFTPClient`` with a ## asyncio dispatcher using the ``register`` function. Take a look at the ## asyncio module documentation for more information. ## @@ -28,65 +28,64 @@ from asyncdispatch import PFuture ## ## Here is some example usage of this module: ## -## .. code-block:: Nimrod -## var ftp = FTPClient("example.org", user = "user", pass = "pass") +## .. code-block:: Nim +## var ftp = ftpClient("example.org", user = "user", pass = "pass") ## ftp.connect() ## ftp.retrFile("file.ext", "file.ext") ## ## **Warning:** The API of this module is unstable, and therefore is subject ## to change. - type - PFtpBase*[SockType] = ref TFtpBase[SockType] - TFtpBase*[SockType] = object + FtpBase*[SockType] = ref FtpBaseObj[SockType] + FtpBaseObj*[SockType] = object csock*: SockType dsock*: SockType - when SockType is asyncio.PAsyncSocket: - handleEvent*: proc (ftp: PAsyncFTPClient, ev: TFTPEvent){.closure,gcsafe.} - disp: PDispatcher - asyncDSockID: PDelegate + when SockType is asyncio.AsyncSocket: + handleEvent*: proc (ftp: AsyncFTPClient, ev: FTPEvent){.closure,gcsafe.} + disp: Dispatcher + asyncDSockID: Delegate user*, pass*: string address*: string - when SockType is asyncnet.PAsyncSocket: - port*: rawsockets.TPort + when SockType is asyncnet.AsyncSocket: + port*: rawsockets.Port else: - port*: TPort + port*: Port jobInProgress*: bool - job*: PFTPJob[SockType] + job*: FTPJob[SockType] dsockConnected*: bool FTPJobType* = enum JRetrText, JRetr, JStore - PFtpJob[T] = ref TFtpJob[T] - TFTPJob[T] = object - prc: proc (ftp: PFTPBase[T], async: bool): bool {.nimcall, gcsafe.} + FtpJob[T] = ref FtpJobObj[T] + FTPJobObj[T] = object + prc: proc (ftp: FTPBase[T], async: bool): bool {.nimcall, gcsafe.} case typ*: FTPJobType of JRetrText: lines: string of JRetr, JStore: - file: TFile + file: File filename: string - total: biggestInt # In bytes. - progress: biggestInt # In bytes. - oneSecond: biggestInt # Bytes transferred in one second. + total: BiggestInt # In bytes. + progress: BiggestInt # In bytes. + oneSecond: BiggestInt # Bytes transferred in one second. lastProgressReport: float # Time toStore: string # Data left to upload (Only used with async) else: nil - TFtpClient* = TFtpBase[TSocket] - PFtpClient* = ref TFTPClient + FtpClientObj* = FtpBaseObj[Socket] + FtpClient* = ref FtpClientObj - PAsyncFTPClient* = ref TAsyncFTPClient ## Async alternative to TFTPClient. - TAsyncFTPClient* = TFtpBase[asyncio.PAsyncSocket] + AsyncFtpClient* = ref AsyncFtpClientObj ## Async alternative to TFTPClient. + AsyncFtpClientObj* = FtpBaseObj[asyncio.AsyncSocket] FTPEventType* = enum EvTransferProgress, EvLines, EvRetr, EvStore - TFTPEvent* = object ## Event + FTPEvent* = object ## Event filename*: string case typ*: FTPEventType of EvLines: @@ -94,17 +93,23 @@ type of EvRetr, EvStore: ## Retr/Store operation finished. nil of EvTransferProgress: - bytesTotal*: biggestInt ## Bytes total. - bytesFinished*: biggestInt ## Bytes transferred. - speed*: biggestInt ## Speed in bytes/s + bytesTotal*: BiggestInt ## Bytes total. + bytesFinished*: BiggestInt ## Bytes transferred. + speed*: BiggestInt ## Speed in bytes/s currentJob*: FTPJobType ## The current job being performed. - EInvalidReply* = object of ESynch - EFTP* = object of ESynch + ReplyError* = object of IOError + FTPError* = object of IOError + +{.deprecated: [ + TFTPClient: FTPClientObj, TFTPJob: FTPJob, PAsyncFTPClient: AsyncFTPClient, + TAsyncFTPClient: AsyncFTPClientObj, TFTPEvent: FTPEvent, + EInvalidReply: ReplyError, EFTP: FTPError +].} proc ftpClient*(address: string, port = TPort(21), - user, pass = ""): PFTPClient = - ## Create a ``PFTPClient`` object. + user, pass = ""): FtpClient = + ## Create a ``FtpClient`` object. new(result) result.user = user result.pass = pass @@ -113,13 +118,7 @@ proc ftpClient*(address: string, port = TPort(21), result.dsockConnected = false result.csock = socket() - if result.csock == InvalidSocket: osError(osLastError()) - -proc getDSock[T](ftp: PFTPBase[T]): TSocket = - return ftp.dsock - -proc getCSock[T](ftp: PFTPBase[T]): TSocket = - return ftp.csock + if result.csock == invalidSocket: raiseOSError(osLastError()) template blockingOperation(sock: TSocket, body: stmt) {.immediate.} = body @@ -129,16 +128,19 @@ template blockingOperation(sock: asyncio.PAsyncSocket, body: stmt) {.immediate.} body sock.setBlocking(false) -proc expectReply[T](ftp: PFtpBase[T]): TaintedString = +proc expectReply[T](ftp: FtpBase[T]): TaintedString = result = TaintedString"" - blockingOperation(ftp.getCSock()): - ftp.getCSock().readLine(result) + blockingOperation(ftp.csock): + when T is Socket: + ftp.csock.readLine(result) + else: + discard ftp.csock.readLine(result) -proc send*[T](ftp: PFtpBase[T], m: string): TaintedString = +proc send*[T](ftp: FtpBase[T], m: string): TaintedString = ## Send a message to the server, and wait for a primary reply. ## ``\c\L`` is added for you. - blockingOperation(ftp.getCSock()): - ftp.getCSock().send(m & "\c\L") + blockingOperation(ftp.csock): + ftp.csock.send(m & "\c\L") return ftp.expectReply() proc assertReply(received: TaintedString, expected: string) = @@ -154,8 +156,8 @@ proc assertReply(received: TaintedString, expected: varargs[string]) = "Expected reply '$1' got: $2" % [expected.join("' or '"), received.string]) -proc createJob[T](ftp: PFtpBase[T], - prc: proc (ftp: PFtpBase[T], async: bool): bool {. +proc createJob[T](ftp: FtpBase[T], + prc: proc (ftp: FtpBase[T], async: bool): bool {. nimcall,gcsafe.}, cmd: FTPJobType) = if ftp.jobInProgress: @@ -170,7 +172,7 @@ proc createJob[T](ftp: PFtpBase[T], of JRetr, JStore: ftp.job.toStore = "" -proc deleteJob[T](ftp: PFtpBase[T]) = +proc deleteJob[T](ftp: FtpBase[T]) = assert ftp.jobInProgress ftp.jobInProgress = false case ftp.job.typ @@ -215,13 +217,13 @@ proc handleRead(s: PAsyncSocket, ftp: PAsyncFTPClient) = # 226 from csock. assert(not ftp.job.prc(ftp, true)) -proc pasv[T](ftp: PFtpBase[T]) = +proc pasv[T](ftp: FtpBase[T]) = ## Negotiate a data connection. when T is TSocket: ftp.dsock = socket() - if ftp.dsock == InvalidSocket: osError(osLastError()) + if ftp.dsock == invalidSocket: raiseOSError(osLastError()) elif T is PAsyncSocket: - ftp.dsock = AsyncSocket() + ftp.dsock = asyncSocket() ftp.dsock.handleRead = proc (s: PAsyncSocket) = handleRead(s, ftp) @@ -244,14 +246,14 @@ proc pasv[T](ftp: PFtpBase[T]) = var properPort = port[0].parseInt()*256+port[1].parseInt() ftp.dsock.connect(ip.join("."), TPort(properPort.toU16)) when T is PAsyncSocket: - ftp.dsockConnected = False + ftp.dsockConnected = false else: - ftp.dsockConnected = True + ftp.dsockConnected = true proc normalizePathSep(path: string): string = return replace(path, '\\', '/') -proc connect*[T](ftp: PFtpBase[T]) = +proc connect*[T](ftp: FtpBase[T]) = ## Connect to the FTP server specified by ``ftp``. when T is PAsyncSocket: blockingOperation(ftp.csock): @@ -270,21 +272,21 @@ proc connect*[T](ftp: PFtpBase[T]) = if ftp.pass != "": assertReply ftp.send("PASS " & ftp.pass), "230" -proc pwd*(ftp: PFTPClient): string = +proc pwd*[T](ftp: FtpBase[T]): string = ## Returns the current working directory. var wd = ftp.send("PWD") assertReply wd, "257" return wd.string.captureBetween('"') # " -proc cd*(ftp: PFTPClient, dir: string) = +proc cd*[T](ftp: FtpBase[T], dir: string) = ## Changes the current directory on the remote FTP server to ``dir``. assertReply ftp.send("CWD " & dir.normalizePathSep), "250" -proc cdup*(ftp: PFTPClient) = +proc cdup*[T](ftp: FtpBase[T]) = ## Changes the current directory to the parent of the current directory. assertReply ftp.send("CDUP"), "200" -proc getLines[T](ftp: PFtpBase[T], async: bool = false): bool = +proc getLines[T](ftp: FtpBase[T], async: bool = false): bool = ## Downloads text data in ASCII mode ## Returns true if the download is complete. ## It doesn't if `async` is true, because it doesn't check for 226 then. @@ -307,14 +309,14 @@ proc getLines[T](ftp: PFtpBase[T], async: bool = false): bool = {.fatal: "Incorrect socket instantiation".} if not async: - var readSocks: seq[TSocket] = @[ftp.getCSock()] + var readSocks: seq[TSocket] = @[ftp.csock] # This is only needed here. Asyncio gets this socket... - blockingOperation(ftp.getCSock()): - if readSocks.select(1) != 0 and ftp.getCSock() in readSocks: + blockingOperation(ftp.csock): + if readSocks.select(1) != 0 and ftp.csock in readSocks: assertReply ftp.expectReply(), "226" return true -proc listDirs*[T](ftp: PFtpBase[T], dir: string = "", +proc listDirs*[T](ftp: FtpBase[T], dir: string = "", async = false): seq[string] = ## Returns a list of filenames in the given directory. If ``dir`` is "", ## the current directory is used. If ``async`` is true, this @@ -332,7 +334,7 @@ proc listDirs*[T](ftp: PFtpBase[T], dir: string = "", ftp.deleteJob() else: return @[] -proc fileExists*(ftp: PFTPClient, file: string): bool {.deprecated.} = +proc fileExists*(ftp: FtpClient, file: string): bool {.deprecated.} = ## **Deprecated since version 0.9.0:** Please use ``existsFile``. ## ## Determines whether ``file`` exists. @@ -343,7 +345,7 @@ proc fileExists*(ftp: PFTPClient, file: string): bool {.deprecated.} = for f in items(files): if f.normalizePathSep == file.normalizePathSep: return true -proc existsFile*(ftp: PFTPClient, file: string): bool = +proc existsFile*(ftp: FtpClient, file: string): bool = ## Determines whether ``file`` exists. ## ## Warning: This function may block. Especially on directories with many @@ -352,7 +354,7 @@ proc existsFile*(ftp: PFTPClient, file: string): bool = for f in items(files): if f.normalizePathSep == file.normalizePathSep: return true -proc createDir*(ftp: PFTPClient, dir: string, recursive: bool = false) = +proc createDir*[T](ftp: FtpBase[T], dir: string, recursive: bool = false) = ## Creates a directory ``dir``. If ``recursive`` is true, the topmost ## subdirectory of ``dir`` will be created first, following the secondmost... ## etc. this allows you to give a full path as the ``dir`` without worrying @@ -362,14 +364,14 @@ proc createDir*(ftp: PFTPClient, dir: string, recursive: bool = false) = else: var reply = TaintedString"" var previousDirs = "" - for p in split(dir, {os.dirSep, os.altSep}): + for p in split(dir, {os.DirSep, os.AltSep}): if p != "": previousDirs.add(p) reply = ftp.send("MKD " & previousDirs) previousDirs.add('/') assertReply reply, "257" -proc chmod*(ftp: PFTPClient, path: string, +proc chmod*[T](ftp: FtpBase[T], path: string, permissions: set[TFilePermission]) = ## Changes permission of ``path`` to ``permissions``. var userOctal = 0 @@ -391,7 +393,7 @@ proc chmod*(ftp: PFTPClient, path: string, assertReply ftp.send("SITE CHMOD " & perm & " " & path.normalizePathSep), "200" -proc list*[T](ftp: PFtpBase[T], dir: string = "", async = false): string = +proc list*[T](ftp: FtpBase[T], dir: string = "", async = false): string = ## Lists all files in ``dir``. If ``dir`` is ``""``, uses the current ## working directory. If ``async`` is true, this function will return ## immediately and it will be your job to call asyncio's @@ -408,7 +410,7 @@ proc list*[T](ftp: PFtpBase[T], dir: string = "", async = false): string = else: return "" -proc retrText*[T](ftp: PFtpBase[T], file: string, async = false): string = +proc retrText*[T](ftp: FtpBase[T], file: string, async = false): string = ## Retrieves ``file``. File must be ASCII text. ## If ``async`` is true, this function will return immediately and ## it will be your job to call asyncio's ``poll`` to progress this operation. @@ -423,7 +425,7 @@ proc retrText*[T](ftp: PFtpBase[T], file: string, async = false): string = else: return "" -proc getFile[T](ftp: PFtpBase[T], async = false): bool = +proc getFile[T](ftp: FtpBase[T], async = false): bool = if ftp.dsockConnected: var r = "".TaintedString var bytesRead = 0 @@ -435,7 +437,7 @@ proc getFile[T](ftp: PFtpBase[T], async = false): bool = bytesRead = ftp.dsock.recvAsync(r, BufferSize) returned = bytesRead != -1 else: - bytesRead = getDSock(ftp).recv(r, BufferSize) + bytesRead = ftp.dsock.recv(r, BufferSize) returned = true let r2 = r.string if r2 != "": @@ -443,16 +445,17 @@ proc getFile[T](ftp: PFtpBase[T], async = false): bool = ftp.job.oneSecond.inc(r2.len) ftp.job.file.write(r2) elif returned and r2 == "": - ftp.dsockConnected = False - - if not async: - var readSocks: seq[TSocket] = @[ftp.getCSock()] - blockingOperation(ftp.getCSock()): - if readSocks.select(1) != 0 and ftp.getCSock() in readSocks: - assertReply ftp.expectReply(), "226" - return true + ftp.dsockConnected = false + + when T is TSocket: + if not async: + var readSocks: seq[TSocket] = @[ftp.csock] + blockingOperation(ftp.csock): + if readSocks.select(1) != 0 and ftp.csock in readSocks: + assertReply ftp.expectReply(), "226" + return true -proc retrFile*[T](ftp: PFtpBase[T], file, dest: string, async = false) = +proc retrFile*[T](ftp: FtpBase[T], file, dest: string, async = false) = ## Downloads ``file`` and saves it to ``dest``. Usage of this function ## asynchronously is recommended to view the progress of the download. ## The ``EvRetr`` event is passed to the specified ``handleEvent`` function @@ -465,7 +468,7 @@ proc retrFile*[T](ftp: PFtpBase[T], file, dest: string, async = false) = assertReply reply, ["125", "150"] if {'(', ')'} notin reply.string: raise newException(EInvalidReply, "Reply has no file size.") - var fileSize: biggestInt + var fileSize: BiggestInt if reply.string.captureBetween('(', ')').parseBiggestInt(fileSize) == 0: raise newException(EInvalidReply, "Reply has no file size.") @@ -477,7 +480,7 @@ proc retrFile*[T](ftp: PFtpBase[T], file, dest: string, async = false) = while not ftp.job.prc(ftp, false): discard ftp.deleteJob() -proc doUpload[T](ftp: PFtpBase[T], async = false): bool = +proc doUpload[T](ftp: FtpBase[T], async = false): bool = if ftp.dsockConnected: if ftp.job.toStore.len() > 0: assert(async) @@ -503,7 +506,7 @@ proc doUpload[T](ftp: PFtpBase[T], async = false): bool = return false if not async: - getDSock(ftp).send(s) + ftp.dsock.send(s) else: let bytesSent = ftp.dsock.sendAsync(s) if bytesSent == 0: @@ -515,7 +518,7 @@ proc doUpload[T](ftp: PFtpBase[T], async = false): bool = ftp.job.progress.inc(len) ftp.job.oneSecond.inc(len) -proc store*[T](ftp: PFtpBase[T], file, dest: string, async = false) = +proc store*[T](ftp: FtpBase[T], file, dest: string, async = false) = ## Uploads ``file`` to ``dest`` on the remote FTP server. Usage of this ## function asynchronously is recommended to view the progress of ## the download. @@ -535,7 +538,7 @@ proc store*[T](ftp: PFtpBase[T], file, dest: string, async = false) = while not ftp.job.prc(ftp, false): discard ftp.deleteJob() -proc close*[T](ftp: PFTPBase[T]) = +proc close*[T](ftp: FtpBase[T]) = ## Terminates the connection to the server. assertReply ftp.send("QUIT"), "221" if ftp.jobInProgress: ftp.deleteJob() @@ -571,7 +574,7 @@ proc asyncFTPClient*(address: string, port = TPort(21), ## Create a ``PAsyncFTPClient`` object. ## ## Use this if you want to use asyncio's dispatcher. - var dres: PAsyncFTPClient + var dres: AsyncFtpClient new(dres) dres.user = user dres.pass = pass @@ -579,9 +582,9 @@ proc asyncFTPClient*(address: string, port = TPort(21), dres.port = port dres.dsockConnected = false dres.handleEvent = handleEvent - dres.csock = AsyncSocket() + dres.csock = asyncSocket() dres.csock.handleRead = - proc (s: PAsyncSocket) = + proc (s: AsyncSocket) = csockHandleRead(s, dres) result = dres @@ -594,7 +597,7 @@ when isMainModule: proc main = var d = newDispatcher() let hev = - proc (ftp: PAsyncFTPClient, event: TFTPEvent) = + proc (ftp: AsyncFTPClient, event: FTPEvent) = case event.typ of EvStore: echo("Upload finished!") diff --git a/lib/pure/future.nim b/lib/pure/future.nim index 480ee2b0d..34b76e41d 100644 --- a/lib/pure/future.nim +++ b/lib/pure/future.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Dominik Picheta # # See the file "copying.txt", included in this @@ -53,7 +53,7 @@ proc createProcType(p, b: PNimrodNode): PNimrodNode {.compileTime.} = macro `=>`*(p, b: expr): expr {.immediate.} = ## Syntax sugar for anonymous procedures. ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## proc passTwoAndTwo(f: (int, int) -> int): int = ## f(2, 2) @@ -104,7 +104,7 @@ macro `=>`*(p, b: expr): expr {.immediate.} = macro `->`*(p, b: expr): expr {.immediate.} = ## Syntax sugar for procedure types. ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## proc pass2(f: (float, float) -> float): float = ## f(2, 2) diff --git a/lib/pure/gentabs.nim b/lib/pure/gentabs.nim index 617473c14..a6128efc9 100644 --- a/lib/pure/gentabs.nim +++ b/lib/pure/gentabs.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -9,9 +9,11 @@ ## The ``gentabs`` module implements an efficient hash table that is a ## key-value mapping. The keys are required to be strings, but the values -## may be any Nimrod or user defined type. This module supports matching +## may be any Nim or user defined type. This module supports matching ## of keys in case-sensitive, case-insensitive and style-insensitive modes. +{.deprecated.} + import os, hashes, strutils @@ -23,7 +25,7 @@ type TGenKeyValuePair[T] = tuple[key: string, val: T] TGenKeyValuePairSeq[T] = seq[TGenKeyValuePair[T]] - TGenTable*[T] = object of TObject + TGenTable*[T] = object of RootObj counter: int data: TGenKeyValuePairSeq[T] mode: TGenTableMode @@ -72,16 +74,16 @@ proc newGenTable*[T](mode: TGenTableMode): PGenTable[T] = proc nextTry(h, maxHash: THash): THash {.inline.} = result = ((5 * h) + 1) and maxHash -proc RawGet[T](tbl: PGenTable[T], key: string): int = +proc rawGet[T](tbl: PGenTable[T], key: string): int = var h: THash h = myhash(tbl, key) and high(tbl.data) # start with real hash value while not isNil(tbl.data[h].key): - if mycmp(tbl, tbl.data[h].key, key): + if myCmp(tbl, tbl.data[h].key, key): return h h = nextTry(h, high(tbl.data)) result = - 1 -proc RawInsert[T](tbl: PGenTable[T], data: var TGenKeyValuePairSeq[T], +proc rawInsert[T](tbl: PGenTable[T], data: var TGenKeyValuePairSeq[T], key: string, val: T) = var h: THash h = myhash(tbl, key) and high(data) @@ -90,12 +92,12 @@ proc RawInsert[T](tbl: PGenTable[T], data: var TGenKeyValuePairSeq[T], data[h].key = key data[h].val = val -proc Enlarge[T](tbl: PGenTable[T]) = +proc enlarge[T](tbl: PGenTable[T]) = var n: TGenKeyValuePairSeq[T] newSeq(n, len(tbl.data) * growthFactor) for i in countup(0, high(tbl.data)): if not isNil(tbl.data[i].key): - RawInsert[T](tbl, n, tbl.data[i].key, tbl.data[i].val) + rawInsert[T](tbl, n, tbl.data[i].key, tbl.data[i].val) swap(tbl.data, n) proc hasKey*[T](tbl: PGenTable[T], key: string): bool = @@ -106,17 +108,17 @@ proc `[]`*[T](tbl: PGenTable[T], key: string): T = ## retrieves the value at ``tbl[key]``. If `key` is not in `tbl`, ## default(T) is returned and no exception is raised. One can check ## with ``hasKey`` whether the key exists. - var index = RawGet(tbl, key) + var index = rawGet(tbl, key) if index >= 0: result = tbl.data[index].val proc `[]=`*[T](tbl: PGenTable[T], key: string, val: T) = ## puts a (key, value)-pair into `tbl`. - var index = RawGet(tbl, key) + var index = rawGet(tbl, key) if index >= 0: tbl.data[index].val = val else: - if mustRehash(len(tbl.data), tbl.counter): Enlarge(tbl) - RawInsert(tbl, tbl.data, key, val) + if mustRehash(len(tbl.data), tbl.counter): enlarge(tbl) + rawInsert(tbl, tbl.data, key, val) inc(tbl.counter) diff --git a/lib/pure/hashes.nim b/lib/pure/hashes.nim index 740355e55..30daaf2dc 100644 --- a/lib/pure/hashes.nim +++ b/lib/pure/hashes.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -8,13 +8,13 @@ # ## This module implements efficient computations of hash values for diverse -## Nimrod types. All the procs are based on these two building blocks: the `!& +## Nim types. All the procs are based on these two building blocks: the `!& ## proc <#!&>`_ used to start or mix a hash value, and the `!$ proc <#!$>`_ ## used to *finish* the hash value. If you want to implement hash procs for ## your custom types you will end up writing the following kind of skeleton of ## code: ## -## .. code-block:: nimrod +## .. code-block:: Nim ## proc hash(x: Something): THash = ## ## Computes a THash from `x`. ## var h: THash = 0 @@ -29,7 +29,7 @@ ## like for example objects made up of ``strings``, you can simply hash ## together the hash value of the individual fields: ## -## .. code-block:: nimrod +## .. code-block:: Nim ## proc hash(x: Something): THash = ## ## Computes a THash from `x`. ## var h: THash = 0 diff --git a/lib/pure/htmlgen.nim b/lib/pure/htmlgen.nim index b9d6aec7b..a1440b6f4 100644 --- a/lib/pure/htmlgen.nim +++ b/lib/pure/htmlgen.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -18,13 +18,13 @@ ## ## Example: ## -## .. code-block:: nimrod -## var nim = "Nimrod" -## echo h1(a(href="http://nimrod-lang.org", nim)) +## .. code-block:: Nim +## var nim = "Nim" +## echo h1(a(href="http://nim-lang.org", nim)) ## ## Writes the string:: ## -## <h1><a href="http://nimrod-lang.org">Nimrod</a></h1> +## <h1><a href="http://nim-lang.org">Nim</a></h1> ## import @@ -53,8 +53,7 @@ proc delete[T](s: var seq[T], attr: T): bool = setLen(s, L-1) result = true -proc xmlCheckedTag*(e: PNimrodNode, tag: string, - optAttr = "", reqAttr = "", +proc xmlCheckedTag*(e: PNimrodNode, tag: string, optAttr = "", reqAttr = "", isLeaf = false): PNimrodNode {.compileTime.} = ## use this procedure to define a new XML tag @@ -484,7 +483,7 @@ macro `var`*(e: expr): expr {.immediate.} = result = xmlCheckedTag(e, "var", commonAttr) when isMainModule: - var nim = "Nimrod" - echo h1(a(href="http://nimrod-code.org", nim)) + var nim = "Nim" + echo h1(a(href="http://nim-lang.org", nim)) echo form(action="test", `accept-charset` = "Content-Type") diff --git a/lib/pure/htmlparser.nim b/lib/pure/htmlparser.nim index c38eb7063..e2cbb4949 100644 --- a/lib/pure/htmlparser.nim +++ b/lib/pure/htmlparser.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -13,7 +13,7 @@ ## It can be used to parse a wild HTML document and output it as valid XHTML ## document (well, if you are lucky): ## -## .. code-block:: nimrod +## .. code-block:: Nim ## ## echo loadHtml("mydirty.html") ## @@ -29,7 +29,7 @@ ## and write back the modified version. In this case we look for hyperlinks ## ending with the extension ``.rst`` and convert them to ``.html``. ## -## .. code-block:: nimrod +## .. code-block:: Nim ## ## import htmlparser ## import xmltree # To use '$' for PXmlNode @@ -422,7 +422,7 @@ proc toHtmlTag(s: string): THtmlTag = of "wbr": tagWbr else: tagUnknown -proc htmlTag*(n: PXmlNode): THtmlTag = +proc htmlTag*(n: XmlNode): THtmlTag = ## gets `n`'s tag as a ``THtmlTag``. if n.clientData == 0: n.clientData = toHtmlTag(n.tag).ord @@ -438,24 +438,24 @@ proc entityToUtf8*(entity: string): string = ## converts an HTML entity name like ``Ü`` to its UTF-8 equivalent. ## "" is returned if the entity name is unknown. The HTML parser ## already converts entities to UTF-8. - for name, val in items(entities): - if name == entity: return toUTF8(TRune(val)) + for name, val in items(Entities): + if name == entity: return toUTF8(Rune(val)) result = "" -proc addNode(father, son: PXmlNode) = +proc addNode(father, son: XmlNode) = if son != nil: add(father, son) -proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode +proc parse(x: var XmlParser, errors: var seq[string]): XmlNode -proc expected(x: var TXmlParser, n: PXmlNode): string = +proc expected(x: var XmlParser, n: XmlNode): string = result = errorMsg(x, "</" & n.tag & "> expected") template elemName(x: expr): expr = rawData(x) -proc untilElementEnd(x: var TXmlParser, result: PXmlNode, +proc untilElementEnd(x: var XmlParser, result: XmlNode, errors: var seq[string]) = # we parsed e.g. ``<br>`` and don't really expect a ``</br>``: - if result.htmlTag in singleTags: + if result.htmlTag in SingleTags: if x.kind != xmlElementEnd or cmpIgnoreCase(x.elemName, result.tag) != 0: return while true: @@ -496,7 +496,7 @@ proc untilElementEnd(x: var TXmlParser, result: PXmlNode, else: result.addNode(parse(x, errors)) -proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode = +proc parse(x: var XmlParser, errors: var seq[string]): XmlNode = case x.kind of xmlComment: result = newComment(x.rawData) @@ -549,11 +549,11 @@ proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode = next(x) of xmlEof: discard -proc parseHtml*(s: PStream, filename: string, - errors: var seq[string]): PXmlNode = +proc parseHtml*(s: Stream, filename: string, + errors: var seq[string]): XmlNode = ## parses the XML from stream `s` and returns a ``PXmlNode``. Every ## occured parsing error is added to the `errors` sequence. - var x: TXmlParser + var x: XmlParser open(x, s, filename, {reportComments, reportWhitespace}) next(x) # skip the DOCTYPE: @@ -573,21 +573,21 @@ proc parseHtml*(s: PStream, filename: string, if result.len == 1: result = result[0] -proc parseHtml*(s: PStream): PXmlNode = +proc parseHtml*(s: Stream): XmlNode = ## parses the XTML from stream `s` and returns a ``PXmlNode``. All parsing ## errors are ignored. var errors: seq[string] = @[] result = parseHtml(s, "unknown_html_doc", errors) -proc loadHtml*(path: string, errors: var seq[string]): PXmlNode = +proc loadHtml*(path: string, errors: var seq[string]): XmlNode = ## Loads and parses HTML from file specified by ``path``, and returns ## a ``PXmlNode``. Every occured parsing error is added to ## the `errors` sequence. var s = newFileStream(path, fmRead) - if s == nil: raise newException(EIO, "Unable to read file: " & path) + if s == nil: raise newException(IOError, "Unable to read file: " & path) result = parseHtml(s, path, errors) -proc loadHtml*(path: string): PXmlNode = +proc loadHtml*(path: string): XmlNode = ## Loads and parses HTML from file specified by ``path``, and returns ## a ``PXmlNode``. All parsing errors are ignored. var errors: seq[string] = @[] @@ -600,7 +600,7 @@ when isMainModule: var x = loadHtml(paramStr(1), errors) for e in items(errors): echo e - var f: TFile + var f: File if open(f, "test.txt", fmWrite): f.write($x) f.close() diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index 4db6ac6ed..892ddac40 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Dominik Picheta, Andreas Rumpf # # See the file "copying.txt", included in this @@ -21,7 +21,7 @@ ## This example uses HTTP GET to retrieve ## ``http://google.com`` ## -## .. code-block:: nimrod +## .. code-block:: Nim ## echo(getContent("http://google.com")) ## ## Using HTTP POST @@ -31,7 +31,7 @@ ## uses ``multipart/form-data`` as the ``Content-Type`` to send the HTML to ## the server. ## -## .. code-block:: nimrod +## .. code-block:: Nim ## var headers: string = "Content-Type: multipart/form-data; boundary=xyz\c\L" ## var body: string = "--xyz\c\L" ## # soap 1.2 output @@ -48,13 +48,26 @@ ## ## echo(postContent("http://validator.w3.org/check", headers, body)) ## +## Asynchronous HTTP requests +## ========================== +## +## You simply have to create a new instance of the ``AsyncHttpClient`` object. +## You may then use ``await`` on the functions defined for that object. +## Keep in mind that the following code needs to be inside an asynchronous +## procedure. +## +## .. code-block::nim +## +## var client = newAsyncHttpClient() +## var resp = await client.request("http://google.com") +## ## SSL/TLS support ## =============== ## This requires the OpenSSL library, fortunately it's widely used and installed ## on many operating systems. httpclient will use SSL automatically if you give ## any of the functions a url with the ``https`` schema, for example: ## ``https://github.com/``, you also have to compile with ``ssl`` defined like so: -## ``nimrod c -d:ssl ...``. +## ``nim c -d:ssl ...``. ## ## Timeouts ## ======== @@ -78,36 +91,41 @@ import sockets, strutils, parseurl, parseutils, strtabs, base64, os import asyncnet, asyncdispatch import rawsockets +from net import nil type - TResponse* = tuple[ + Response* = tuple[ version: string, status: string, - headers: PStringTable, + headers: StringTableRef, body: string] - PProxy* = ref object + Proxy* = ref object url*: TUrl auth*: string - EInvalidProtocol* = object of ESynch ## exception that is raised when server + ProtocolError* = object of IOError ## exception that is raised when server ## does not conform to the implemented ## protocol - EHttpRequestErr* = object of ESynch ## Thrown in the ``getContent`` proc - ## and ``postContent`` proc, - ## when the server returns an error + HttpRequestError* = object of IOError ## Thrown in the ``getContent`` proc + ## and ``postContent`` proc, + ## when the server returns an error -const defUserAgent* = "Nimrod httpclient/0.1" +{.deprecated: [TResponse: Response, PProxy: Proxy, + EInvalidProtocol: ProtocolError, EHttpRequestErr: HttpRequestError +].} + +const defUserAgent* = "Nim httpclient/0.1" proc httpError(msg: string) = - var e: ref EInvalidProtocol + var e: ref ProtocolError new(e) e.msg = msg raise e proc fileError(msg: string) = - var e: ref EIO + var e: ref IOError new(e) e.msg = msg raise e @@ -160,16 +178,17 @@ proc parseBody(s: TSocket, headers: PStringTable, timeout: int): string = var contentLengthHeader = headers["Content-Length"] if contentLengthHeader != "": var length = contentLengthHeader.parseint() - result = newString(length) - var received = 0 - while true: - if received >= length: break - let r = s.recv(addr(result[received]), length-received, timeout) - if r == 0: break - received += r - if received != length: - httpError("Got invalid content length. Expected: " & $length & - " got: " & $received) + if length > 0: + result = newString(length) + var received = 0 + while true: + if received >= length: break + let r = s.recv(addr(result[received]), length-received, timeout) + if r == 0: break + received += r + if received != length: + httpError("Got invalid content length. Expected: " & $length & + " got: " & $received) else: # (http://tools.ietf.org/html/rfc2616#section-4.4) NR.4 TODO @@ -177,7 +196,7 @@ proc parseBody(s: TSocket, headers: PStringTable, timeout: int): string = # (http://tools.ietf.org/html/rfc2616#section-4.4) NR.5 if headers["Connection"] == "close": var buf = "" - while True: + while true: buf = newString(4000) let r = s.recv(addr(buf[0]), 4000, timeout) if r == 0: break @@ -190,7 +209,7 @@ proc parseResponse(s: TSocket, getBody: bool, timeout: int): TResponse = var fullyRead = false var line = "" result.headers = newStringTable(modeCaseInsensitive) - while True: + while true: line = "" linei = 0 s.readLine(line, timeout) @@ -232,7 +251,7 @@ proc parseResponse(s: TSocket, getBody: bool, timeout: int): TResponse = result.body = "" type - THttpMethod* = enum ## the requested HttpMethod + HttpMethod* = enum ## the requested HttpMethod httpHEAD, ## Asks for the response identical to the one that would ## correspond to a GET request, but without the response ## body. @@ -250,6 +269,8 @@ type httpCONNECT ## Converts the request connection to a transparent ## TCP/IP tunnel, usually used for proxies. +{.deprecated: [THttpMethod: HttpMethod].} + when not defined(ssl): type PSSLContext = ref object let defaultSSLContext: PSSLContext = nil @@ -288,7 +309,7 @@ proc request*(url: string, httpMethod = httpGET, extraHeaders = "", add(headers, "\c\L") var s = socket() - if s == InvalidSocket: osError(osLastError()) + if s == invalidSocket: raiseOSError(osLastError()) var port = sockets.TPort(80) if r.scheme == "https": when defined(ssl): @@ -315,7 +336,7 @@ proc redirection(status: string): bool = const redirectionNRs = ["301", "302", "303", "307"] for i in items(redirectionNRs): if status.startsWith(i): - return True + return true proc getNewLocation(lastUrl: string, headers: PStringTable): string = result = headers["Location"] @@ -431,16 +452,20 @@ proc generateHeaders(r: TURL, httpMethod: THttpMethod, add(result, "\c\L") type - PAsyncHttpClient* = ref object - socket: PAsyncSocket + AsyncHttpClient* = ref object + socket: AsyncSocket connected: bool currentURL: TURL ## Where we are currently connected. - headers: PStringTable + headers: StringTableRef maxRedirects: int userAgent: string + when defined(ssl): + sslContext: net.SslContext + +{.deprecated: [PAsyncHttpClient: AsyncHttpClient].} proc newAsyncHttpClient*(userAgent = defUserAgent, - maxRedirects = 5): PAsyncHttpClient = + maxRedirects = 5, sslContext = defaultSslContext): AsyncHttpClient = ## Creates a new PAsyncHttpClient instance. ## ## ``userAgent`` specifies the user agent that will be used when making @@ -448,18 +473,22 @@ proc newAsyncHttpClient*(userAgent = defUserAgent, ## ## ``maxRedirects`` specifies the maximum amount of redirects to follow, ## default is 5. + ## + ## ``sslContext`` specifies the SSL context to use for HTTPS requests. new result result.headers = newStringTable(modeCaseInsensitive) result.userAgent = defUserAgent result.maxRedirects = maxRedirects + when defined(ssl): + result.sslContext = net.SslContext(sslContext) -proc close*(client: PAsyncHttpClient) = +proc close*(client: AsyncHttpClient) = ## Closes any connections held by the HTTP client. if client.connected: client.socket.close() client.connected = false -proc recvFull(socket: PAsyncSocket, size: int): PFuture[string] {.async.} = +proc recvFull(socket: PAsyncSocket, size: int): Future[string] {.async.} = ## Ensures that all the data requested is read and returned. result = "" while true: @@ -468,7 +497,7 @@ proc recvFull(socket: PAsyncSocket, size: int): PFuture[string] {.async.} = if data == "": break # We've been disconnected. result.add data -proc parseChunks(client: PAsyncHttpClient): PFuture[string] {.async.} = +proc parseChunks(client: PAsyncHttpClient): Future[string] {.async.} = result = "" var ri = 0 while true: @@ -501,7 +530,7 @@ proc parseChunks(client: PAsyncHttpClient): PFuture[string] {.async.} = # them: http://tools.ietf.org/html/rfc2616#section-3.6.1 proc parseBody(client: PAsyncHttpClient, - headers: PStringTable): PFuture[string] {.async.} = + headers: PStringTable): Future[string] {.async.} = result = "" if headers["Transfer-Encoding"] == "chunked": result = await parseChunks(client) @@ -511,12 +540,13 @@ proc parseBody(client: PAsyncHttpClient, var contentLengthHeader = headers["Content-Length"] if contentLengthHeader != "": var length = contentLengthHeader.parseint() - result = await client.socket.recvFull(length) - if result == "": - httpError("Got disconnected while trying to read body.") - if result.len != length: - httpError("Received length doesn't match expected length. Wanted " & - $length & " got " & $result.len) + if length > 0: + result = await client.socket.recvFull(length) + if result == "": + httpError("Got disconnected while trying to read body.") + if result.len != length: + httpError("Received length doesn't match expected length. Wanted " & + $length & " got " & $result.len) else: # (http://tools.ietf.org/html/rfc2616#section-4.4) NR.4 TODO @@ -524,19 +554,19 @@ proc parseBody(client: PAsyncHttpClient, # (http://tools.ietf.org/html/rfc2616#section-4.4) NR.5 if headers["Connection"] == "close": var buf = "" - while True: + while true: buf = await client.socket.recvFull(4000) if buf == "": break result.add(buf) proc parseResponse(client: PAsyncHttpClient, - getBody: bool): PFuture[TResponse] {.async.} = + getBody: bool): Future[TResponse] {.async.} = var parsedStatus = false var linei = 0 var fullyRead = false var line = "" result.headers = newStringTable(modeCaseInsensitive) - while True: + while true: linei = 0 line = await client.socket.recvLine() if line == "": break # We've been disconnected. @@ -582,20 +612,29 @@ proc newConnection(client: PAsyncHttpClient, url: TURL) {.async.} = client.currentURL.scheme != url.scheme: if client.connected: client.close() client.socket = newAsyncSocket() - if url.scheme == "https": - assert false, "TODO SSL" # TODO: I should be able to write 'net.TPort' here... let port = - if url.port == "": rawsockets.TPort(80) + if url.port == "": + if url.scheme.toLower() == "https": + rawsockets.TPort(443) + else: + rawsockets.TPort(80) else: rawsockets.TPort(url.port.parseInt) + if url.scheme.toLower() == "https": + when defined(ssl): + client.sslContext.wrapSocket(client.socket) + else: + raise newException(EHttpRequestErr, + "SSL support is not available. Cannot connect over SSL.") + await client.socket.connect(url.hostname, port) client.currentURL = url client.connected = true proc request*(client: PAsyncHttpClient, url: string, httpMethod = httpGET, - body = ""): PFuture[TResponse] {.async.} = + body = ""): Future[TResponse] {.async.} = ## Connects to the hostname specified by the URL and performs a request ## using the method specified. ## @@ -618,7 +657,7 @@ proc request*(client: PAsyncHttpClient, url: string, httpMethod = httpGET, result = await parseResponse(client, httpMethod != httpHEAD) -proc get*(client: PAsyncHttpClient, url: string): PFuture[TResponse] {.async.} = +proc get*(client: PAsyncHttpClient, url: string): Future[TResponse] {.async.} = ## Connects to the hostname specified by the URL and performs a GET request. ## ## This procedure will follow redirects up to a maximum number of redirects @@ -648,16 +687,16 @@ when isMainModule: resp = await client.request("http://picheta.me/aboutme.html") echo("Got response: ", resp.status) - resp = await client.request("http://nimrod-lang.org/") + resp = await client.request("http://nim-lang.org/") echo("Got response: ", resp.status) - resp = await client.request("http://nimrod-lang.org/download.html") + resp = await client.request("http://nim-lang.org/download.html") echo("Got response: ", resp.status) waitFor main() else: - #downloadFile("http://force7.de/nimrod/index.html", "nimrodindex.html") + #downloadFile("http://force7.de/nim/index.html", "nimindex.html") #downloadFile("http://www.httpwatch.com/", "ChunkTest.html") #downloadFile("http://validator.w3.org/check?uri=http%3A%2F%2Fgoogle.com", # "validator.html") diff --git a/lib/pure/httpserver.nim b/lib/pure/httpserver.nim index 885742b64..dc6db4738 100644 --- a/lib/pure/httpserver.nim +++ b/lib/pure/httpserver.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf, Dominik Picheta # # See the file "copying.txt", included in this @@ -11,7 +11,7 @@ ## ## Example: ## -## .. code-block:: nimrod +## .. code-block:: nim ## import strutils, sockets, httpserver ## ## var counter = 0 @@ -22,8 +22,6 @@ ## ## run(handleRequest, TPort(80)) ## -## **Warning:** The API of this module is unstable, and therefore is subject -## to change. import parseutils, strutils, os, osproc, strtabs, streams, sockets, asyncio @@ -90,14 +88,14 @@ proc serveFile*(client: TSocket, filename: string) = headers(client, filename) const bufSize = 8000 # != 8K might be good for memory manager var buf = alloc(bufsize) - while True: + while true: var bytesread = readBuffer(f, buf, bufsize) if bytesread > 0: var byteswritten = send(client, buf, bytesread) if bytesread != bytesWritten: dealloc(buf) close(f) - OSError(OSLastError()) + raiseOSError(osLastError()) if bytesread != bufSize: break dealloc(buf) close(f) @@ -145,7 +143,7 @@ when false: var buf = alloc(contentLength) if recv(client, buf, contentLength) != contentLength: dealloc(buf) - OSError() + raiseOSError() var inp = process.inputStream inp.writeData(buf, contentLength) dealloc(buf) @@ -228,9 +226,9 @@ proc open*(s: var TServer, port = TPort(80), reuseAddr = false) = ## creates a new server at port `port`. If ``port == 0`` a free port is ## acquired that can be accessed later by the ``port`` proc. s.socket = socket(AF_INET) - if s.socket == InvalidSocket: OSError(OSLastError()) + if s.socket == invalidSocket: raiseOSError(osLastError()) if reuseAddr: - s.socket.setSockOpt(OptReuseAddr, True) + s.socket.setSockOpt(OptReuseAddr, true) bindAddr(s.socket, port) listen(s.socket) @@ -238,7 +236,7 @@ proc open*(s: var TServer, port = TPort(80), reuseAddr = false) = s.port = getSockName(s.socket) else: s.port = port - s.client = InvalidSocket + s.client = invalidSocket s.reqMethod = "" s.body = "" s.path = "" @@ -346,7 +344,7 @@ proc next*(s: var TServer) = # XXX we ignore "HTTP/1.1" etc. for now here var query = 0 var last = i - while last < data.len and data[last] notin whitespace: + while last < data.len and data[last] notin Whitespace: if data[last] == '?' and query == 0: query = last inc(last) if query > 0: @@ -466,7 +464,7 @@ proc nextAsync(s: PAsyncHTTPServer) = # XXX we ignore "HTTP/1.1" etc. for now here var query = 0 var last = i - while last < data.len and data[last] notin whitespace: + while last < data.len and data[last] notin Whitespace: if data[last] == '?' and query == 0: query = last inc(last) if query > 0: @@ -483,7 +481,7 @@ proc asyncHTTPServer*(handleRequest: proc (server: PAsyncHTTPServer, client: TSo ## Creates an Asynchronous HTTP server at ``port``. var capturedRet: PAsyncHTTPServer new(capturedRet) - capturedRet.asyncSocket = AsyncSocket() + capturedRet.asyncSocket = asyncSocket() capturedRet.asyncSocket.handleAccept = proc (s: PAsyncSocket) = nextAsync(capturedRet) @@ -491,7 +489,7 @@ proc asyncHTTPServer*(handleRequest: proc (server: PAsyncHTTPServer, client: TSo capturedRet.query) if quit: capturedRet.asyncSocket.close() if reuseAddr: - capturedRet.asyncSocket.setSockOpt(OptReuseAddr, True) + capturedRet.asyncSocket.setSockOpt(OptReuseAddr, true) capturedRet.asyncSocket.bindAddr(port, address) capturedRet.asyncSocket.listen() @@ -500,7 +498,7 @@ proc asyncHTTPServer*(handleRequest: proc (server: PAsyncHTTPServer, client: TSo else: capturedRet.port = port - capturedRet.client = InvalidSocket + capturedRet.client = invalidSocket capturedRet.reqMethod = "" capturedRet.body = "" capturedRet.path = "" diff --git a/lib/pure/json.nim b/lib/pure/json.nim index 5d51c2d87..385787d6c 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -1,77 +1,53 @@ # # -# Nimrod's Runtime Library -# (c) Copyright 2012 Andreas Rumpf, Dominik Picheta +# Nim's Runtime Library +# (c) Copyright 2014 Andreas Rumpf, Dominik Picheta # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## This module implements a simple high performance `JSON`:idx: parser. `JSON -## (JavaScript Object Notation) <http://www.json.org>`_ is a lightweight -## data-interchange format that is easy for humans to read and write (unlike -## XML). It is easy for machines to parse and generate. JSON is based on a -## subset of the JavaScript Programming Language, `Standard ECMA-262 3rd -## Edition - December 1999 -## <http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf>`_. +## This module implements a simple high performance `JSON`:idx: +## parser. JSON (JavaScript Object Notation) is a lightweight +## data-interchange format that is easy for humans to read and write +## (unlike XML). It is easy for machines to parse and generate. +## JSON is based on a subset of the JavaScript Programming Language, +## Standard ECMA-262 3rd Edition - December 1999. ## -## Parsing small values quickly can be done with the convenience `parseJson() -## <#parseJson,string>`_ proc which returns the whole JSON tree. If you are -## parsing very big JSON inputs or want to skip most of the items in them you -## can initialize your own `TJsonParser <#TJsonParser>`_ with the `open() -## <#open>`_ proc and call `next() <#next>`_ in a loop to process the -## individual parsing events. +## Usage example: ## -## If you need to create JSON objects from your Nimrod types you can call procs -## like `newJObject() <#newJObject>`_ (or their equivalent `%() -## <#%,openArray[tuple[string,PJsonNode]]>`_ generic constructor). For -## consistency you can provide your own ``%`` operators for custom object -## types: +## .. code-block:: nim +## let +## small_json = """{"test": 1.3, "key2": true}""" +## jobj = parseJson(small_json) +## assert (jobj.kind == JObject) +## echo($jobj["test"].fnum) +## echo($jobj["key2"].bval) ## -## .. code-block:: nimrod -## type -## Person = object ## Generic person record. -## age: int ## The age of the person. -## name: string ## The name of the person. +## Results in: ## -## proc `%`(p: Person): PJsonNode = -## ## Converts a Person into a PJsonNode. -## result = %[("age", %p.age), ("name", %p.name)] +## .. code-block:: nim ## -## proc test() = -## # Tests making some jsons. -## var p: Person -## p.age = 24 -## p.name = "Minah" -## echo(%p) # { "age": 24, "name": "Minah"} -## -## p.age = 33 -## p.name = "Sojin" -## echo(%p) # { "age": 33, "name": "Sojin"} -## -## If you don't need special logic in your Nimrod objects' serialization code -## you can also use the `marshal module <marshal.html>`_ which converts objects -## directly to JSON. +## 1.3000000000000000e+00 +## true import hashes, strutils, lexbase, streams, unicode type - TJsonEventKind* = enum ## Events that may occur when parsing. \ - ## - ## You compare these values agains the result of the `kind() proc <#kind>`_. - jsonError, ## An error ocurred during parsing. - jsonEof, ## End of file reached. - jsonString, ## A string literal. - jsonInt, ## An integer literal. - jsonFloat, ## A float literal. - jsonTrue, ## The value ``true``. - jsonFalse, ## The value ``false``. - jsonNull, ## The value ``null``. - jsonObjectStart, ## Start of an object: the ``{`` token. - jsonObjectEnd, ## End of an object: the ``}`` token. - jsonArrayStart, ## Start of an array: the ``[`` token. - jsonArrayEnd ## Start of an array: the ``]`` token. + JsonEventKind* = enum ## enumeration of all events that may occur when parsing + jsonError, ## an error ocurred during parsing + jsonEof, ## end of file reached + jsonString, ## a string literal + jsonInt, ## an integer literal + jsonFloat, ## a float literal + jsonTrue, ## the value ``true`` + jsonFalse, ## the value ``false`` + jsonNull, ## the value ``null`` + jsonObjectStart, ## start of an object: the ``{`` token + jsonObjectEnd, ## end of an object: the ``}`` token + jsonArrayStart, ## start of an array: the ``[`` token + jsonArrayEnd ## start of an array: the ``]`` token TTokKind = enum # must be synchronized with TJsonEventKind! tkError, @@ -89,7 +65,7 @@ type tkColon, tkComma - TJsonError = enum ## enumeration that lists all errors that can occur + JsonError* = enum ## enumeration that lists all errors that can occur errNone, ## no error errInvalidToken, ## invalid token errStringExpected, ## string expected @@ -102,22 +78,23 @@ type errEofExpected, ## EOF expected errExprExpected ## expr expected - TParserState = enum + ParserState = enum stateEof, stateStart, stateObject, stateArray, stateExpectArrayComma, stateExpectObjectComma, stateExpectColon, stateExpectValue - TJsonParser* = object of TBaseLexer ## The JSON parser object. \ - ## - ## Create a variable of this type and use `open() <#open>`_ on it. + JsonParser* = object of BaseLexer ## the parser object. a: string tok: TTokKind - kind: TJsonEventKind - err: TJsonError - state: seq[TParserState] + kind: JsonEventKind + err: JsonError + state: seq[ParserState] filename: string + +{.deprecated: [TJsonEventKind: JsonEventKind, TJsonError: JsonError, + TJsonParser: JsonParser].} const - errorMessages: array [TJsonError, string] = [ + errorMessages: array [JsonError, string] = [ "no error", "invalid token", "string expected", @@ -142,130 +119,60 @@ const "{", "}", "[", "]", ":", "," ] -proc open*(my: var TJsonParser, input: PStream, filename: string) = - ## Initializes the JSON parser with an `input stream <streams.html>`_. - ## - ## The `filename` parameter is not strictly required and is used only for - ## nice error messages. You can pass ``nil`` as long as you never use procs - ## like `errorMsg() <#errorMsg>`_ or `errorMsgExpected() - ## <#errorMsgExpected>`_ but passing a dummy filename like ``<input string>`` - ## is safer and more user friendly. Example: - ## - ## .. code-block:: nimrod - ## import json, streams - ## - ## var - ## s = newStringStream("some valid json") - ## p: TJsonParser - ## p.open(s, "<input string>") - ## - ## Once opened, you can process JSON parsing events with the `next() - ## <#next>`_ proc. +proc open*(my: var JsonParser, input: Stream, filename: string) = + ## initializes the parser with an input stream. `Filename` is only used + ## for nice error messages. + lexbase.open(my, input) my.filename = filename my.state = @[stateStart] my.kind = jsonError my.a = "" -proc close*(my: var TJsonParser) {.inline.} = - ## Closes the parser `my` and its associated input stream. - ## - ## Example: - ## - ## .. code-block:: nimrod - ## var - ## s = newStringStream("some valid json") - ## p: TJsonParser - ## p.open(s, "<input string>") - ## finally: p.close - ## # write here parsing of input +proc close*(my: var JsonParser) {.inline.} = + ## closes the parser `my` and its associated input stream. lexbase.close(my) -proc str*(my: TJsonParser): string {.inline.} = - ## Returns the character data for the `events <#TJsonEventKind>`_ - ## ``jsonInt``, ``jsonFloat`` and ``jsonString``. - ## - ## This proc will `assert <system.html#assert>`_ in debug builds when used - ## with other event types. See `next() <#next>`_ for an usage example. +proc str*(my: JsonParser): string {.inline.} = + ## returns the character data for the events: ``jsonInt``, ``jsonFloat``, + ## ``jsonString`` assert(my.kind in {jsonInt, jsonFloat, jsonString}) return my.a -proc getInt*(my: TJsonParser): BiggestInt {.inline.} = - ## Returns the number for the `jsonInt <#TJsonEventKind>`_ event. - ## - ## This proc will `assert <system.html#assert>`_ in debug builds when used - ## with other event types. See `next() <#next>`_ for an usage example. +proc getInt*(my: JsonParser): BiggestInt {.inline.} = + ## returns the number for the event: ``jsonInt`` assert(my.kind == jsonInt) return parseBiggestInt(my.a) -proc getFloat*(my: TJsonParser): float {.inline.} = - ## Returns the number for the `jsonFloat <#TJsonEventKind>`_ event. - ## - ## This proc will `assert <system.html#assert>`_ in debug builds when used - ## with other event types. See `next() <#next>`_ for an usage example. +proc getFloat*(my: JsonParser): float {.inline.} = + ## returns the number for the event: ``jsonFloat`` assert(my.kind == jsonFloat) return parseFloat(my.a) -proc kind*(my: TJsonParser): TJsonEventKind {.inline.} = - ## Returns the current event type for the `JSON parser <#TJsonParser>`_. - ## - ## Call this proc just after `next() <#next>`_ to act on the new event. +proc kind*(my: JsonParser): JsonEventKind {.inline.} = + ## returns the current event type for the JSON parser return my.kind -proc getColumn*(my: TJsonParser): int {.inline.} = - ## Get the current column the parser has arrived at. - ## - ## While this is mostly used by procs like `errorMsg() <#errorMsg>`_ you can - ## use it as well to show user warnings if you are validating JSON values - ## during parsing. See `next() <#next>`_ for the full example: - ## - ## .. code-block:: nimrod - ## case parser.kind - ## ... - ## of jsonString: - ## let inputValue = parser.str - ## if previousValues.contains(inputValue): - ## echo "$1($2, $3) Warning: repeated value '$4'" % [ - ## parser.getFilename, $parser.getLine, $parser.getColumn, - ## inputValue] - ## ... +proc getColumn*(my: JsonParser): int {.inline.} = + ## get the current column the parser has arrived at. result = getColNumber(my, my.bufpos) -proc getLine*(my: TJsonParser): int {.inline.} = - ## Get the current line the parser has arrived at. - ## - ## While this is mostly used by procs like `errorMsg() <#errorMsg>`_ you can - ## use it as well to indicate user warnings if you are validating JSON values - ## during parsing. See `next() <#next>`_ and `getColumn() <#getColumn>`_ for - ## examples. +proc getLine*(my: JsonParser): int {.inline.} = + ## get the current line the parser has arrived at. result = my.lineNumber -proc getFilename*(my: TJsonParser): string {.inline.} = - ## Get the filename of the file that the parser is processing. - ## - ## This is the value you pass to the `open() <#open>`_ proc. While this is - ## mostly used by procs like `errorMsg() <#errorMsg>`_ you can use it as well - ## to indicate user warnings if you are validating JSON values during - ## parsing. See `next() <#next>`_ and `getColumn() <#getColumn>`_ for - ## examples. +proc getFilename*(my: JsonParser): string {.inline.} = + ## get the filename of the file that the parser processes. result = my.filename -proc errorMsg*(my: TJsonParser): string = - ## Returns a helpful error message for the `jsonError <#TJsonEventKind>`_ - ## event. - ## - ## This proc will `assert <system.html#assert>`_ in debug builds when used - ## with other event types. See `next() <#next>`_ for an usage example. +proc errorMsg*(my: JsonParser): string = + ## returns a helpful error message for the event ``jsonError`` assert(my.kind == jsonError) result = "$1($2, $3) Error: $4" % [ my.filename, $getLine(my), $getColumn(my), errorMessages[my.err]] -proc errorMsgExpected*(my: TJsonParser, e: string): string = - ## Returns an error message "`e` expected". - ## - ## The message is in the same format as the other error messages which - ## include the parser filename, line and column values. This is used by - ## `raiseParseErr() <#raiseParseErr>`_ to raise an `EJsonParsingError - ## <#EJsonParsingError>`_. +proc errorMsgExpected*(my: JsonParser, e: string): string = + ## returns an error message "`e` expected" in the same format as the + ## other error messages result = "$1($2, $3) Error: $4" % [ my.filename, $getLine(my), $getColumn(my), e & " expected"] @@ -277,7 +184,7 @@ proc handleHexChar(c: char, x: var int): bool = of 'A'..'F': x = (x shl 4) or (ord(c) - ord('A') + 10) else: result = false # error -proc parseString(my: var TJsonParser): TTokKind = +proc parseString(my: var JsonParser): TTokKind = result = tkString var pos = my.bufpos + 1 var buf = my.buf @@ -317,7 +224,7 @@ proc parseString(my: var TJsonParser): TTokKind = if handleHexChar(buf[pos], r): inc(pos) if handleHexChar(buf[pos], r): inc(pos) if handleHexChar(buf[pos], r): inc(pos) - add(my.a, toUTF8(TRune(r))) + add(my.a, toUTF8(Rune(r))) else: # don't bother with the error add(my.a, buf[pos]) @@ -335,7 +242,7 @@ proc parseString(my: var TJsonParser): TTokKind = inc(pos) my.bufpos = pos # store back -proc skip(my: var TJsonParser) = +proc skip(my: var JsonParser) = var pos = my.bufpos var buf = my.buf while true: @@ -393,7 +300,7 @@ proc skip(my: var TJsonParser) = break my.bufpos = pos -proc parseNumber(my: var TJsonParser) = +proc parseNumber(my: var JsonParser) = var pos = my.bufpos var buf = my.buf if buf[pos] == '-': @@ -424,7 +331,7 @@ proc parseNumber(my: var TJsonParser) = inc(pos) my.bufpos = pos -proc parseName(my: var TJsonParser) = +proc parseName(my: var JsonParser) = var pos = my.bufpos var buf = my.buf if buf[pos] in IdentStartChars: @@ -433,7 +340,7 @@ proc parseName(my: var TJsonParser) = inc(pos) my.bufpos = pos -proc getTok(my: var TJsonParser): TTokKind = +proc getTok(my: var JsonParser): TTokKind = setLen(my.a, 0) skip(my) # skip whitespace, comments case my.buf[my.bufpos] @@ -477,33 +384,8 @@ proc getTok(my: var TJsonParser): TTokKind = result = tkError my.tok = result -proc next*(my: var TJsonParser) = - ## Retrieves the first/next event for the `JSON parser <#TJsonParser>`_. - ## - ## You are meant to call this method inside an infinite loop. After each - ## call, check the result of the `kind() <#kind>`_ proc to know what has to - ## be done next (eg. break out due to end of file). Here is a basic example - ## which simply echoes all found elements by the parser: - ## - ## .. code-block:: nimrod - ## parser.open(stream, "<input string>") - ## while true: - ## parser.next - ## case parser.kind - ## of jsonError: - ## echo parser.errorMsg - ## break - ## of jsonEof: break - ## of jsonString: echo parser.str - ## of jsonInt: echo parser.getInt - ## of jsonFloat: echo parser.getFloat - ## of jsonTrue: echo "true" - ## of jsonFalse: echo "false" - ## of jsonNull: echo "null" - ## of jsonObjectStart: echo "{" - ## of jsonObjectEnd: echo "}" - ## of jsonArrayStart: echo "[" - ## of jsonArrayEnd: echo "]" +proc next*(my: var JsonParser) = + ## retrieves the first/next event. This controls the parser. var tk = getTok(my) var i = my.state.len-1 # the following code is a state machine. If we had proper coroutines, @@ -520,7 +402,7 @@ proc next*(my: var TJsonParser) = case tk of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull: my.state[i] = stateEof # expect EOF next! - my.kind = TJsonEventKind(ord(tk)) + my.kind = JsonEventKind(ord(tk)) of tkBracketLe: my.state.add(stateArray) # we expect any my.kind = jsonArrayStart @@ -536,7 +418,7 @@ proc next*(my: var TJsonParser) = case tk of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull: my.state.add(stateExpectColon) - my.kind = TJsonEventKind(ord(tk)) + my.kind = JsonEventKind(ord(tk)) of tkBracketLe: my.state.add(stateExpectColon) my.state.add(stateArray) @@ -555,7 +437,7 @@ proc next*(my: var TJsonParser) = case tk of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull: my.state.add(stateExpectArrayComma) # expect value next! - my.kind = TJsonEventKind(ord(tk)) + my.kind = JsonEventKind(ord(tk)) of tkBracketLe: my.state.add(stateExpectArrayComma) my.state.add(stateArray) @@ -606,7 +488,7 @@ proc next*(my: var TJsonParser) = case tk of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull: my.state[i] = stateExpectObjectComma - my.kind = TJsonEventKind(ord(tk)) + my.kind = JsonEventKind(ord(tk)) of tkBracketLe: my.state[i] = stateExpectObjectComma my.state.add(stateArray) @@ -623,16 +505,7 @@ proc next*(my: var TJsonParser) = # ------------- higher level interface --------------------------------------- type - TJsonNodeKind* = enum ## Possible `JSON node <#TJsonNodeKind>`_ types. \ - ## - ## To build nodes use the helper procs - ## `newJNull() <#newJNull>`_, - ## `newJBool() <#newJBool>`_, - ## `newJInt() <#newJInt>`_, - ## `newJFloat() <#newJFloat>`_, - ## `newJString() <#newJString>`_, - ## `newJObject() <#newJObject>`_ and - ## `newJArray() <#newJArray>`_. + JsonNodeKind* = enum ## possible JSON node types JNull, JBool, JInt, @@ -641,10 +514,9 @@ type JObject, JArray - PJsonNode* = ref TJsonNode ## Reference to a `JSON node <#TJsonNode>`_. - TJsonNode* {.final, pure, acyclic.} = object ## `Object variant \ - ## <manual.html#object-variants>`_ wrapping all possible JSON types. - case kind*: TJsonNodeKind + JsonNode* = ref JsonNodeObj ## JSON node + JsonNodeObj* {.acyclic.} = object + case kind*: JsonNodeKind of JString: str*: string of JInt: @@ -656,250 +528,105 @@ type of JNull: nil of JObject: - fields*: seq[tuple[key: string, val: PJsonNode]] + fields*: seq[tuple[key: string, val: JsonNode]] of JArray: - elems*: seq[PJsonNode] - - EJsonParsingError* = object of EInvalidValue ## Raised during JSON parsing. \ - ## - ## Example: - ## - ## .. code-block:: nimrod - ## let smallJson = """{"test: 1.3, "key2": true}""" - ## try: - ## discard parseJson(smallJson) - ## # --> Bad JSON! input(1, 18) Error: : expected - ## except EJsonParsingError: - ## echo "Bad JSON! " & getCurrentExceptionMsg() - -proc raiseParseErr*(p: TJsonParser, msg: string) {.noinline, noreturn.} = - ## Raises an `EJsonParsingError <#EJsonParsingError>`_ exception. - ## - ## The message for the exception will be built passing the `msg` parameter to - ## the `errorMsgExpected() <#errorMsgExpected>`_ proc. - raise newException(EJsonParsingError, errorMsgExpected(p, msg)) - -proc newJString*(s: string): PJsonNode = - ## Creates a new `JString PJsonNode <#TJsonNodeKind>`_. - ## - ## Example: - ## - ## .. code-block:: nimrod - ## var node = newJString("A string") - ## echo node - ## # --> "A string" - ## - ## Or you can use the shorter `%() proc <#%,string>`_. + elems*: seq[JsonNode] + + JsonParsingError* = object of ValueError ## is raised for a JSON error + +{.deprecated: [EJsonParsingError: JsonParsingError, TJsonNode: JsonNodeObj, + PJsonNode: JsonNode, TJsonNodeKind: JsonNodeKind].} + +proc raiseParseErr*(p: JsonParser, msg: string) {.noinline, noreturn.} = + ## raises an `EJsonParsingError` exception. + raise newException(JsonParsingError, errorMsgExpected(p, msg)) + +proc newJString*(s: string): JsonNode = + ## Creates a new `JString JsonNode`. new(result) result.kind = JString result.str = s -proc newJStringMove(s: string): PJsonNode = +proc newJStringMove(s: string): JsonNode = new(result) result.kind = JString shallowCopy(result.str, s) -proc newJInt*(n: BiggestInt): PJsonNode = - ## Creates a new `JInt PJsonNode <#TJsonNodeKind>`_. - ## - ## Example: - ## - ## .. code-block:: nimrod - ## var node = newJInt(900_100_200_300) - ## echo node - ## # --> 900100200300 - ## - ## Or you can use the shorter `%() proc <#%,BiggestInt>`_. +proc newJInt*(n: BiggestInt): JsonNode = + ## Creates a new `JInt JsonNode`. new(result) result.kind = JInt result.num = n -proc newJFloat*(n: float): PJsonNode = - ## Creates a new `JFloat PJsonNode <#TJsonNodeKind>`_. - ## - ## Example: - ## - ## .. code-block:: nimrod - ## var node = newJFloat(3.14) - ## echo node - ## # --> 3.14 - ## - ## Or you can use the shorter `%() proc <#%,float>`_. +proc newJFloat*(n: float): JsonNode = + ## Creates a new `JFloat JsonNode`. new(result) result.kind = JFloat result.fnum = n -proc newJBool*(b: bool): PJsonNode = - ## Creates a new `JBool PJsonNode <#TJsonNodeKind>`_. - ## - ## Example: - ## - ## .. code-block:: nimrod - ## var node = newJBool(true) - ## echo node - ## # --> true - ## - ## Or you can use the shorter `%() proc <#%,bool>`_. +proc newJBool*(b: bool): JsonNode = + ## Creates a new `JBool JsonNode`. new(result) result.kind = JBool result.bval = b -proc newJNull*(): PJsonNode = - ## Creates a new `JNull PJsonNode <#TJsonNodeKind>`_. - ## - ## Example: - ## - ## .. code-block:: nimrod - ## var node = newJNull() - ## echo node - ## # --> null +proc newJNull*(): JsonNode = + ## Creates a new `JNull JsonNode`. new(result) -proc newJObject*(): PJsonNode = - ## Creates a new `JObject PJsonNode <#TJsonNodeKind>`_. - ## - ## The `PJsonNode <#PJsonNode>`_ will be initialized with an empty ``fields`` - ## sequence to which you can add new elements. Example: - ## - ## .. code-block:: nimrod - ## var node = newJObject() - ## node.add("age", newJInt(24)) - ## node.add("name", newJString("Minah")) - ## echo node - ## # --> { "age": 24, "name": "Minah"} - ## - ## Or you can use the shorter `%() proc - ## <#%,openArray[tuple[string,PJsonNode]]>`_. +proc newJObject*(): JsonNode = + ## Creates a new `JObject JsonNode` new(result) result.kind = JObject result.fields = @[] -proc newJArray*(): PJsonNode = - ## Creates a new `JArray PJsonNode <#TJsonNodeKind>`_. - ## - ## The `PJsonNode <#PJsonNode>`_ will be initialized with an empty ``elems`` - ## sequence to which you can add new elements. Example: - ## - ## .. code-block:: nimrod - ## var node = newJArray() - ## node.add(newJString("Mixing types")) - ## node.add(newJInt(42)) - ## node.add(newJString("is madness")) - ## node.add(newJFloat(3.14)) - ## echo node - ## # --> [ "Mixing types", 42, "is madness", 3.14] - ## - ## Or you can use the shorter `%() proc <#%,openArray[PJsonNode]>`_. +proc newJArray*(): JsonNode = + ## Creates a new `JArray JsonNode` new(result) result.kind = JArray result.elems = @[] -proc `%`*(s: string): PJsonNode = - ## Creates a new `JString PJsonNode <#TJsonNodeKind>`_. - ## - ## Example: - ## - ## .. code-block:: nimrod - ## var node = %"A string" - ## echo node - ## # --> "A string" - ## - ## This generic constructor is equivalent to the `newJString() - ## <#newJString>`_ proc. +proc `%`*(s: string): JsonNode = + ## Generic constructor for JSON data. Creates a new `JString JsonNode`. new(result) result.kind = JString result.str = s -proc `%`*(n: BiggestInt): PJsonNode = - ## Creates a new `JInt PJsonNode <#TJsonNodeKind>`_. - ## - ## Example: - ## - ## .. code-block:: nimrod - ## var node = %900_100_200_300 - ## echo node - ## # --> 900100200300 - ## - ## This generic constructor is equivalent to the `newJInt() <#newJInt>`_ - ## proc. +proc `%`*(n: BiggestInt): JsonNode = + ## Generic constructor for JSON data. Creates a new `JInt JsonNode`. new(result) result.kind = JInt result.num = n -proc `%`*(n: float): PJsonNode = - ## Creates a new `JFloat PJsonNode <#TJsonNodeKind>`_. - ## - ## Example: - ## - ## .. code-block:: nimrod - ## var node = %3.14 - ## echo node - ## # --> 3.14 - ## - ## This generic constructor is equivalent to the `newJFloat() <#newJFloat>`_ - ## proc. +proc `%`*(n: float): JsonNode = + ## Generic constructor for JSON data. Creates a new `JFloat JsonNode`. new(result) result.kind = JFloat result.fnum = n -proc `%`*(b: bool): PJsonNode = - ## Creates a new `JBool PJsonNode <#TJsonNodeKind>`_. - ## - ## Example: - ## - ## .. code-block:: nimrod - ## var node = %true - ## echo node - ## # --> true - ## - ## This generic constructor is equivalent to the `newJBool() <#newJBool>`_ - ## proc. +proc `%`*(b: bool): JsonNode = + ## Generic constructor for JSON data. Creates a new `JBool JsonNode`. new(result) result.kind = JBool result.bval = b -proc `%`*(keyVals: openArray[tuple[key: string, val: PJsonNode]]): PJsonNode = - ## Creates a new `JObject PJsonNode <#TJsonNodeKind>`_. - ## - ## Unlike the `newJObject() <#newJObject>`_ proc, which returns an object - ## that has to be further manipulated, you can use this generic constructor - ## to create JSON objects with all their fields in one go. Example: - ## - ## .. code-block:: nimrod - ## let node = %[("age", %24), ("name", %"Minah")] - ## echo node - ## # --> { "age": 24, "name": "Minah"} +proc `%`*(keyVals: openArray[tuple[key: string, val: JsonNode]]): JsonNode = + ## Generic constructor for JSON data. Creates a new `JObject JsonNode` new(result) result.kind = JObject newSeq(result.fields, keyVals.len) for i, p in pairs(keyVals): result.fields[i] = p -proc `%`*(elements: openArray[PJsonNode]): PJsonNode = - ## Creates a new `JArray PJsonNode <#TJsonNodeKind>`_. - ## - ## Unlike the `newJArray() <#newJArray>`_ proc, which returns an object - ## that has to be further manipulated, you can use this generic constructor - ## to create JSON arrays with all their values in one go. Example: - ## - ## .. code-block:: nimrod - ## let node = %[%"Mixing types", %42, - ## %"is madness", %3.14,] - ## echo node - ## # --> [ "Mixing types", 42, "is madness", 3.14] +proc `%`*(elements: openArray[JsonNode]): JsonNode = + ## Generic constructor for JSON data. Creates a new `JArray JsonNode` new(result) result.kind = JArray newSeq(result.elems, elements.len) for i, p in pairs(elements): result.elems[i] = p -proc `==`* (a,b: PJsonNode): bool = - ## Check two `PJsonNode <#PJsonNode>`_ nodes for equality. - ## - ## Example: - ## - ## .. code-block:: nimrod - ## assert(%1 == %1) - ## assert(%1 != %2) +proc `==`* (a,b: JsonNode): bool = + ## Check two nodes for equality if a.isNil: if b.isNil: return true return false @@ -922,22 +649,8 @@ proc `==`* (a,b: PJsonNode): bool = of JObject: a.fields == b.fields -proc hash* (n:PJsonNode): THash = - ## Computes the hash for a JSON node. - ## - ## The `THash <hashes.html#THash>`_ allows JSON nodes to be used as keys for - ## `sets <sets.html>`_ or `tables <tables.html>`_. Example: - ## - ## .. code-block:: nimrod - ## import json, sets - ## - ## var - ## uniqueValues = initSet[PJsonNode]() - ## values = %[%1, %2, %1, %2, %3] - ## for value in values.elems: - ## discard uniqueValues.containsOrIncl(value) - ## echo uniqueValues - ## # --> {1, 2, 3} +proc hash* (n:JsonNode): THash = + ## Compute the hash for a JSON node case n.kind of JArray: result = hash(n.elems) @@ -954,41 +667,18 @@ proc hash* (n:PJsonNode): THash = of JNull: result = hash(0) -proc len*(n: PJsonNode): int = - ## Returns the number of children items for this `PJsonNode <#PJsonNode>`_. - ## - ## If `n` is a `JArray <#TJsonNodeKind>`_, it will return the number of - ## elements. If `n` is a `JObject <#TJsonNodeKind>`_, it will return the - ## number of key-value pairs. For all other types this proc returns zero. - ## Example: - ## - ## .. code-block:: nimrod - ## let - ## n1 = %[("age", %33), ("name", %"Sojin")] - ## n2 = %[%1, %2, %3, %4, %5, %6, %7] - ## n3 = %"Some odd string we have here" - ## echo n1.len # --> 2 - ## echo n2.len # --> 7 - ## echo n3.len # --> 0 - ## +proc len*(n: JsonNode): int = + ## If `n` is a `JArray`, it returns the number of elements. + ## If `n` is a `JObject`, it returns the number of pairs. + ## Else it returns 0. case n.kind of JArray: result = n.elems.len of JObject: result = n.fields.len else: discard -proc `[]`*(node: PJsonNode, name: string): PJsonNode = - ## Gets a named field from a `JObject <#TJsonNodeKind>`_ `PJsonNode - ## <#PJsonNode>`_. - ## - ## Returns the value for `name` or nil if `node` doesn't contain such a - ## field. This proc will `assert <system.html#assert>`_ in debug builds if - ## `name` is ``nil`` or `node` is not a ``JObject``. On release builds it - ## will likely crash. Example: - ## - ## .. code-block:: nimrod - ## let node = %[("age", %40), ("name", %"Britney")] - ## echo node["name"] - ## # --> "Britney" +proc `[]`*(node: JsonNode, name: string): JsonNode = + ## Gets a field from a `JObject`, which must not be nil. + ## If the value at `name` does not exist, returns nil assert(not isNil(node)) assert(node.kind == JObject) for key, item in items(node.fields): @@ -996,93 +686,36 @@ proc `[]`*(node: PJsonNode, name: string): PJsonNode = return item return nil -proc `[]`*(node: PJsonNode, index: int): PJsonNode = - ## Gets the `index` item from a `JArray <#TJsonNodeKind>`_ `PJsonNode - ## <#PJsonNode>`_. - ## - ## Returns the specified item. Result is undefined if `index` is out of - ## bounds. This proc will `assert <system.html#assert>`_ in debug builds if - ## `node` is ``nil`` or not a ``JArray``. Example: - ## - ## .. code-block:: nimrod - ## let node = %[%"Mixing types", %42, - ## %"is madness", %3.14,] - ## echo node[2] - ## # --> "is madness" +proc `[]`*(node: JsonNode, index: int): JsonNode = + ## Gets the node at `index` in an Array. Result is undefined if `index` + ## is out of bounds assert(not isNil(node)) assert(node.kind == JArray) return node.elems[index] -proc hasKey*(node: PJsonNode, key: string): bool = - ## Returns `true` if `key` exists in a `JObject <#TJsonNodeKind>`_ `PJsonNode - ## <#PJsonNode>`_. - ## - ## This proc will `assert <system.html#assert>`_ in debug builds if `node` is - ## not a ``JObject``. On release builds it will likely crash. Example: - ## - ## .. code-block:: nimrod - ## let node = %[("age", %40), ("name", %"Britney")] - ## echo node.hasKey("email") - ## # --> false +proc hasKey*(node: JsonNode, key: string): bool = + ## Checks if `key` exists in `node`. assert(node.kind == JObject) for k, item in items(node.fields): if k == key: return true -proc existsKey*(node: PJsonNode, key: string): bool {.deprecated.} = node.hasKey(key) - ## Deprecated for `hasKey() <#hasKey>`_. - -proc add*(father, child: PJsonNode) = - ## Adds `child` to a `JArray <#TJsonNodeKind>`_ `PJsonNode <#PJsonNode>`_ - ## `father` node. - ## - ## This proc will `assert <system.html#assert>`_ in debug builds if `node` is - ## not a ``JArray``. On release builds it will likely crash. Example: - ## - ## .. code-block:: nimrod - ## var node = %[%"Mixing types", %42] - ## node.add(%"is madness") - ## echo node - ## # --> false +proc existsKey*(node: JsonNode, key: string): bool {.deprecated.} = node.hasKey(key) + ## Deprecated for `hasKey` + +proc add*(father, child: JsonNode) = + ## Adds `child` to a JArray node `father`. assert father.kind == JArray father.elems.add(child) -proc add*(obj: PJsonNode, key: string, val: PJsonNode) = - ## Adds ``(key, val)`` pair to a `JObject <#TJsonNodeKind>`_ `PJsonNode - ## <#PJsonNode>`_ `obj` node. - ## - ## For speed reasons no check for duplicate keys is performed! But ``[]=`` - ## performs the check. - ## - ## This proc will `assert <system.html#assert>`_ in debug builds if `node` is - ## not a ``JObject``. On release builds it will likely crash. Example: - ## - ## .. code-block:: nimrod - ## var node = newJObject() - ## node.add("age", newJInt(12)) - ## # This is wrong! But we need speed… - ## node.add("age", newJInt(24)) - ## echo node - ## # --> { "age": 12, "age": 24} +proc add*(obj: JsonNode, key: string, val: JsonNode) = + ## Adds ``(key, val)`` pair to the JObject node `obj`. For speed + ## reasons no check for duplicate keys is performed! + ## But ``[]=`` performs the check. assert obj.kind == JObject obj.fields.add((key, val)) -proc `[]=`*(obj: PJsonNode, key: string, val: PJsonNode) = - ## Sets a field from a `JObject <#TJsonNodeKind>`_ `PJsonNode - ## <#PJsonNode>`_ `obj` node. - ## - ## Unlike the `add() <#add,PJsonNode,string,PJsonNode>`_ proc this will - ## perform a check for duplicate keys and replace existing values. - ## - ## This proc will `assert <system.html#assert>`_ in debug builds if `node` is - ## not a ``JObject``. On release builds it will likely crash. Example: - ## - ## .. code-block:: nimrod - ## var node = newJObject() - ## node["age"] = %12 - ## # The new value replaces the previous one. - ## node["age"] = %24 - ## echo node - ## # --> { "age": 24} +proc `[]=`*(obj: JsonNode, key: string, val: JsonNode) = + ## Sets a field from a `JObject`. Performs a check for duplicate keys. assert(obj.kind == JObject) for i in 0..obj.fields.len-1: if obj.fields[i].key == key: @@ -1090,14 +723,14 @@ proc `[]=`*(obj: PJsonNode, key: string, val: PJsonNode) = return obj.fields.add((key, val)) -proc `{}`*(node: PJsonNode, key: string): PJsonNode = +proc `{}`*(node: JsonNode, key: string): JsonNode = ## Transverses the node and gets the given value. If any of the ## names does not exist, returns nil result = node if isNil(node): return nil result = result[key] -proc `{}=`*(node: PJsonNode, names: varargs[string], value: PJsonNode) = +proc `{}=`*(node: JsonNode, names: varargs[string], value: JsonNode) = ## Transverses the node and tries to set the value at the given location ## to `value` If any of the names are missing, they are added var node = node @@ -1107,31 +740,17 @@ proc `{}=`*(node: PJsonNode, names: varargs[string], value: PJsonNode) = node = node[names[i]] node[names[names.len-1]] = value -proc delete*(obj: PJsonNode, key: string) = +proc delete*(obj: JsonNode, key: string) = ## Deletes ``obj[key]`` preserving the order of the other (key, value)-pairs. - ## - ## If `key` doesn't exist in `obj` ``EInvalidIndex`` will be raised. This - ## proc will `assert <system.html#assert>`_ in debug builds if `node` is not - ## a ``JObject``. On release builds it will likely crash. Example: - ## - ## .. code-block:: nimrod - ## var node = %[("age", %37), ("name", %"Chris"), ("male", %false)] - ## echo node - ## # --> { "age": 37, "name": "Chris", "male": false} - ## node.delete("age") - ## echo node - ## # --> { "name": "Chris", "male": false} assert(obj.kind == JObject) for i in 0..obj.fields.len-1: if obj.fields[i].key == key: obj.fields.delete(i) return - raise newException(EInvalidIndex, "key not in object") + raise newException(IndexError, "key not in object") -proc copy*(p: PJsonNode): PJsonNode = - ## Performs a deep copy of `p`. - ## - ## Modifications to the copy won't affect the original. +proc copy*(p: JsonNode): JsonNode = + ## Performs a deep copy of `a`. case p.kind of JString: result = newJString(p.str) @@ -1166,12 +785,6 @@ proc nl(s: var string, ml: bool) = proc escapeJson*(s: string): string = ## Converts a string `s` to its JSON representation. - ## - ## Example: - ## - ## .. code-block:: nimrod - ## echo """name: "Torbjørn"""".escapeJson - ## # --> "name: \"Torbj\u00F8rn\"" result = newStringOfCap(s.len + s.len shr 3) result.add("\"") for x in runes(s): @@ -1187,7 +800,7 @@ proc escapeJson*(s: string): string = result.add(toHex(r, 4)) result.add("\"") -proc toPretty(result: var string, node: PJsonNode, indent = 2, ml = true, +proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true, lstArr = false, currIndent = 0) = case node.kind of JObject: @@ -1242,68 +855,34 @@ proc toPretty(result: var string, node: PJsonNode, indent = 2, ml = true, if lstArr: result.indent(currIndent) result.add("null") -proc pretty*(node: PJsonNode, indent = 2): string = - ## Converts `node` to a pretty JSON representation. - ## - ## The representation will have indentation use multiple lines. Example: - ## - ## .. code-block:: nimrod - ## let node = %[("age", %33), ("name", %"Sojin")] - ## echo node - ## # --> { "age": 33, "name": "Sojin"} - ## echo node.pretty - ## # --> { - ## # "age": 33, - ## # "name": "Sojin" - ## # } +proc pretty*(node: JsonNode, indent = 2): string = + ## Converts `node` to its JSON Representation, with indentation and + ## on multiple lines. result = "" toPretty(result, node, indent) -proc `$`*(node: PJsonNode): string = - ## Converts `node` to its JSON representation on one line. +proc `$`*(node: JsonNode): string = + ## Converts `node` to its JSON Representation on one line. result = "" toPretty(result, node, 1, false) -iterator items*(node: PJsonNode): PJsonNode = - ## Iterator for the items of `node`. - ## - ## This proc will `assert <system.html#assert>`_ in debug builds if `node` is - ## not a `JArray <#TJsonNodeKind>`_. On release builds it will likely crash. - ## Example: - ## - ## .. code-block:: nimrod - ## let numbers = %[%1, %2, %3] - ## for n in numbers.items: - ## echo "Number ", n - ## ## --> Number 1 - ## ## Number 2 - ## ## Number 3 +iterator items*(node: JsonNode): JsonNode = + ## Iterator for the items of `node`. `node` has to be a JArray. assert node.kind == JArray for i in items(node.elems): yield i -iterator pairs*(node: PJsonNode): tuple[key: string, val: PJsonNode] = - ## Iterator for the child elements of `node`. - ## - ## This proc will `assert <system.html#assert>`_ in debug builds if `node` is - ## not a `JObject <#TJsonNodeKind>`_. On release builds it will likely crash. - ## Example: - ## - ## .. code-block:: nimrod - ## var node = %[("age", %37), ("name", %"Chris")] - ## for key, value in node.pairs: - ## echo "Key: ", key, ", value: ", value - ## # --> Key: age, value: 37 - ## # Key: name, value: "Chris" +iterator pairs*(node: JsonNode): tuple[key: string, val: JsonNode] = + ## Iterator for the child elements of `node`. `node` has to be a JObject. assert node.kind == JObject for key, val in items(node.fields): yield (key, val) -proc eat(p: var TJsonParser, tok: TTokKind) = +proc eat(p: var JsonParser, tok: TTokKind) = if p.tok == tok: discard getTok(p) else: raiseParseErr(p, tokToStr[tok]) -proc parseJson(p: var TJsonParser): PJsonNode = +proc parseJson(p: var JsonParser): JsonNode = ## Parses JSON from a JSON Parser `p`. case p.tok of tkString: @@ -1352,46 +931,24 @@ proc parseJson(p: var TJsonParser): PJsonNode = raiseParseErr(p, "{") when not defined(js): - proc parseJson*(s: PStream, filename: string): PJsonNode = - ## Generic convenience proc to parse stream `s` into a `PJsonNode`. - ## - ## This wraps around `open() <#open>`_ and `next() <#next>`_ to return the - ## full JSON DOM. Errors will be raised as exceptions, this requires the - ## `filename` parameter to not be ``nil`` to avoid crashes. - assert(not isNil(filename)) - var p: TJsonParser + proc parseJson*(s: Stream, filename: string): JsonNode = + ## Parses from a stream `s` into a `JsonNode`. `filename` is only needed + ## for nice error messages. + var p: JsonParser p.open(s, filename) discard getTok(p) # read first token result = p.parseJson() p.close() - proc parseJson*(buffer: string): PJsonNode = + proc parseJson*(buffer: string): JsonNode = ## Parses JSON from `buffer`. - ## - ## Specialized version around `parseJson(PStream, string) - ## <#parseJson,PStream,string>`_. Example: - ## - ## .. code-block:: nimrod - ## let - ## smallJson = """{"test": 1.3, "key2": true}""" - ## jobj = parseJson(smallJson) - ## assert jobj.kind == JObject - ## - ## assert jobj["test"].kind == JFloat - ## echo jobj["test"].fnum # --> 1.3 - ## - ## assert jobj["key2"].kind == JBool - ## echo jobj["key2"].bval # --> true result = parseJson(newStringStream(buffer), "input") - proc parseFile*(filename: string): PJsonNode = - ## Parses `file` into a `PJsonNode`. - ## - ## Specialized version around `parseJson(PStream, string) - ## <#parseJson,PStream,string>`_. + proc parseFile*(filename: string): JsonNode = + ## Parses `file` into a `JsonNode`. var stream = newFileStream(filename, fmRead) if stream == nil: - raise newException(EIO, "cannot read from file: " & filename) + raise newException(IOError, "cannot read from file: " & filename) result = parseJson(stream, filename) else: from math import `mod` @@ -1399,7 +956,7 @@ else: TJSObject = object proc parseNativeJson(x: cstring): TJSObject {.importc: "JSON.parse".} - proc getVarType(x): TJsonNodeKind = + proc getVarType(x): JsonNodeKind = result = JNull proc getProtoName(y): cstring {.importc: "Object.prototype.toString.call".} @@ -1434,7 +991,7 @@ else: return `x`[`y`]; """ - proc convertObject(x: TJSObject): PJsonNode = + proc convertObject(x: TJSObject): JsonNode = case getVarType(x) of JArray: result = newJArray() @@ -1461,15 +1018,15 @@ else: of JNull: result = newJNull() - proc parseJson*(buffer: string): PJsonNode = + proc parseJson*(buffer: string): JsonNode = return parseNativeJson(buffer).convertObject() when false: import os - var s = newFileStream(ParamStr(1), fmRead) - if s == nil: quit("cannot open the file" & ParamStr(1)) - var x: TJsonParser - open(x, s, ParamStr(1)) + var s = newFileStream(paramStr(1), fmRead) + if s == nil: quit("cannot open the file" & paramStr(1)) + var x: JsonParser + open(x, s, paramStr(1)) while true: next(x) case x.kind @@ -1478,13 +1035,13 @@ when false: break of jsonEof: break of jsonString, jsonInt, jsonFloat: echo(x.str) - of jsonTrue: Echo("!TRUE") - of jsonFalse: Echo("!FALSE") - of jsonNull: Echo("!NULL") - of jsonObjectStart: Echo("{") - of jsonObjectEnd: Echo("}") - of jsonArrayStart: Echo("[") - of jsonArrayEnd: Echo("]") + of jsonTrue: echo("!TRUE") + of jsonFalse: echo("!FALSE") + of jsonNull: echo("!NULL") + of jsonObjectStart: echo("{") + of jsonObjectEnd: echo("}") + of jsonArrayStart: echo("[") + of jsonArrayEnd: echo("]") close(x) @@ -1505,8 +1062,8 @@ when isMainModule: echo(pretty(parsed2)) try: echo(parsed["key2"][12123]) - raise newException(EInvalidValue, "That line was expected to fail") - except EInvalidIndex: echo() + raise newException(ValueError, "That line was expected to fail") + except IndexError: echo() let testJson = parseJson"""{ "a": [1, 2, 3, 4], "b": "asd" }""" # nil passthrough @@ -1518,12 +1075,12 @@ when isMainModule: try: let a = testJson["a"][9] assert(false, "EInvalidIndex not thrown") - except EInvalidIndex: + except IndexError: discard try: let a = testJson["a"][-1] assert(false, "EInvalidIndex not thrown") - except EInvalidIndex: + except IndexError: discard try: assert(testJson["a"][0].num == 1, "Index doesn't correspond to its value") diff --git a/lib/pure/lexbase.nim b/lib/pure/lexbase.nim index eee95e2e6..a3a3d7b5c 100644 --- a/lib/pure/lexbase.nim +++ b/lib/pure/lexbase.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2009 Andreas Rumpf # # See the file "copying.txt", included in this @@ -25,34 +25,36 @@ const # type - TBaseLexer* = object of TObject ## the base lexer. Inherit your lexer from - ## this object. + BaseLexer* = object of RootObj ## the base lexer. Inherit your lexer from + ## this object. bufpos*: int ## the current position within the buffer buf*: cstring ## the buffer itself bufLen*: int ## length of buffer in characters - input: PStream ## the input stream + input: Stream ## the input stream lineNumber*: int ## the current line number sentinel: int lineStart: int # index of last line start in buffer fileOpened: bool -proc open*(L: var TBaseLexer, input: PStream, bufLen: int = 8192) +{.deprecated: [TBaseLexer: BaseLexer].} + +proc open*(L: var BaseLexer, input: Stream, bufLen: int = 8192) ## inits the TBaseLexer with a stream to read from -proc close*(L: var TBaseLexer) +proc close*(L: var BaseLexer) ## closes the base lexer. This closes `L`'s associated stream too. -proc getCurrentLine*(L: TBaseLexer, marker: bool = true): string +proc getCurrentLine*(L: BaseLexer, marker: bool = true): string ## retrieves the current line. -proc getColNumber*(L: TBaseLexer, pos: int): int +proc getColNumber*(L: BaseLexer, pos: int): int ## retrieves the current column. -proc handleCR*(L: var TBaseLexer, pos: int): int +proc handleCR*(L: var BaseLexer, pos: int): int ## Call this if you scanned over '\c' in the buffer; it returns the the ## position to continue the scanning from. `pos` must be the position ## of the '\c'. -proc handleLF*(L: var TBaseLexer, pos: int): int +proc handleLF*(L: var BaseLexer, pos: int): int ## Call this if you scanned over '\L' in the buffer; it returns the the ## position to continue the scanning from. `pos` must be the position ## of the '\L'. @@ -62,11 +64,11 @@ proc handleLF*(L: var TBaseLexer, pos: int): int const chrSize = sizeof(char) -proc close(L: var TBaseLexer) = +proc close(L: var BaseLexer) = dealloc(L.buf) close(L.input) -proc fillBuffer(L: var TBaseLexer) = +proc fillBuffer(L: var BaseLexer) = var charsRead, toCopy, s: int # all are in characters, # not bytes (in case this @@ -111,7 +113,7 @@ proc fillBuffer(L: var TBaseLexer) = break s = L.bufLen - 1 -proc fillBaseLexer(L: var TBaseLexer, pos: int): int = +proc fillBaseLexer(L: var BaseLexer, pos: int): int = assert(pos <= L.sentinel) if pos < L.sentinel: result = pos + 1 # nothing to do @@ -121,24 +123,24 @@ proc fillBaseLexer(L: var TBaseLexer, pos: int): int = result = 0 L.lineStart = result -proc handleCR(L: var TBaseLexer, pos: int): int = +proc handleCR(L: var BaseLexer, pos: int): int = assert(L.buf[pos] == '\c') inc(L.lineNumber) result = fillBaseLexer(L, pos) if L.buf[result] == '\L': result = fillBaseLexer(L, result) -proc handleLF(L: var TBaseLexer, pos: int): int = +proc handleLF(L: var BaseLexer, pos: int): int = assert(L.buf[pos] == '\L') inc(L.lineNumber) result = fillBaseLexer(L, pos) #L.lastNL := result-1; // BUGFIX: was: result; -proc skipUtf8Bom(L: var TBaseLexer) = +proc skipUtf8Bom(L: var BaseLexer) = if (L.buf[0] == '\xEF') and (L.buf[1] == '\xBB') and (L.buf[2] == '\xBF'): inc(L.bufpos, 3) inc(L.lineStart, 3) -proc open(L: var TBaseLexer, input: PStream, bufLen: int = 8192) = +proc open(L: var BaseLexer, input: Stream, bufLen: int = 8192) = assert(bufLen > 0) assert(input != nil) L.input = input @@ -151,10 +153,10 @@ proc open(L: var TBaseLexer, input: PStream, bufLen: int = 8192) = fillBuffer(L) skipUtf8Bom(L) -proc getColNumber(L: TBaseLexer, pos: int): int = +proc getColNumber(L: BaseLexer, pos: int): int = result = abs(pos - L.lineStart) -proc getCurrentLine(L: TBaseLexer, marker: bool = true): string = +proc getCurrentLine(L: BaseLexer, marker: bool = true): string = var i: int result = "" i = L.lineStart diff --git a/lib/pure/logging.nim b/lib/pure/logging.nim index 284384b37..9247f69c5 100644 --- a/lib/pure/logging.nim +++ b/lib/pure/logging.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf, Dominik Picheta # # See the file "copying.txt", included in this @@ -26,7 +26,7 @@ ## The following example demonstrates logging to three different handlers ## simultaneously: ## -## .. code-block:: nimrod +## .. code-block:: nim ## ## var L = newConsoleLogger() ## var fL = newFileLogger("test.log", fmtStr = verboseFmtStr) @@ -42,7 +42,7 @@ import strutils, os, times type - TLevel* = enum ## logging level + Level* = enum ## logging level lvlAll, ## all levels active lvlDebug, ## debug level (and any above) active lvlInfo, ## info level (and any above) active @@ -52,7 +52,7 @@ type lvlNone ## no levels active const - LevelNames*: array [TLevel, string] = [ + LevelNames*: array [Level, string] = [ "DEBUG", "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "NONE" ] @@ -60,26 +60,29 @@ const verboseFmtStr* = "$date $time " type - PLogger* = ref object of PObject ## abstract logger; the base type of all loggers - levelThreshold*: TLevel ## only messages of level >= levelThreshold - ## should be processed + Logger* = ref object of RootObj ## abstract logger; the base type of all loggers + levelThreshold*: Level ## only messages of level >= levelThreshold + ## should be processed fmtStr: string ## = defaultFmtStr by default, see substituteLog for $date etc. - PConsoleLogger* = ref object of PLogger ## logger that writes the messages to the - ## console + ConsoleLogger* = ref object of Logger ## logger that writes the messages to the + ## console - PFileLogger* = ref object of PLogger ## logger that writes the messages to a file - f: TFile + FileLogger* = ref object of Logger ## logger that writes the messages to a file + f: File - PRollingFileLogger* = ref object of PFileLogger ## logger that writes the - ## messages to a file and - ## performs log rotation + RollingFileLogger* = ref object of FileLogger ## logger that writes the + ## messages to a file and + ## performs log rotation maxLines: int # maximum number of lines curLine : int baseName: string # initial filename - baseMode: TFileMode # initial file mode + baseMode: FileMode # initial file mode logFiles: int # how many log files already created, e.g. basename.1, basename.2... +{.deprecated: [TLevel: Level, PLogger: Logger, PConsoleLogger: ConsoleLogger, + PFileLogger: FileLogger, PRollingFileLogger: RollingFileLogger].} + proc substituteLog(frmt: string): string = ## converts $date to the current date ## converts $time to the current time @@ -104,21 +107,24 @@ proc substituteLog(frmt: string): string = of "app": result.add(app) of "appdir": result.add(app.splitFile.dir) of "appname": result.add(app.splitFile.name) + else: discard -method log*(logger: PLogger, level: TLevel, - frmt: string, args: varargs[string, `$`]) {.raises: [EBase], tags: [FTime, FWriteIO, FReadIO].} = +method log*(logger: Logger, level: Level, + frmt: string, args: varargs[string, `$`]) {. + raises: [Exception], + tags: [TimeEffect, WriteIOEffect, ReadIOEffect].} = ## Override this method in custom loggers. Default implementation does ## nothing. discard -method log*(logger: PConsoleLogger, level: TLevel, +method log*(logger: ConsoleLogger, level: Level, frmt: string, args: varargs[string, `$`]) = ## Logs to the console using ``logger`` only. if level >= logger.levelThreshold: writeln(stdout, LevelNames[level], " ", substituteLog(logger.fmtStr), frmt % args) -method log*(logger: PFileLogger, level: TLevel, +method log*(logger: FileLogger, level: Level, frmt: string, args: varargs[string, `$`]) = ## Logs to a file using ``logger`` only. if level >= logger.levelThreshold: @@ -130,16 +136,16 @@ proc defaultFilename*(): string = var (path, name, ext) = splitFile(getAppFilename()) result = changeFileExt(path / name, "log") -proc newConsoleLogger*(levelThreshold = lvlAll, fmtStr = defaultFmtStr): PConsoleLogger = +proc newConsoleLogger*(levelThreshold = lvlAll, fmtStr = defaultFmtStr): ConsoleLogger = ## Creates a new console logger. This logger logs to the console. new result result.fmtStr = fmtStr result.levelThreshold = levelThreshold proc newFileLogger*(filename = defaultFilename(), - mode: TFileMode = fmAppend, + mode: FileMode = fmAppend, levelThreshold = lvlAll, - fmtStr = defaultFmtStr): PFileLogger = + fmtStr = defaultFmtStr): FileLogger = ## Creates a new file logger. This logger logs to a file. new(result) result.levelThreshold = levelThreshold @@ -148,7 +154,7 @@ proc newFileLogger*(filename = defaultFilename(), # ------ -proc countLogLines(logger: PRollingFileLogger): int = +proc countLogLines(logger: RollingFileLogger): int = result = 0 for line in logger.f.lines(): result.inc() @@ -166,13 +172,13 @@ proc countFiles(filename: string): int = let num = parseInt(numS) if num > result: result = num - except EInvalidValue: discard + except ValueError: discard proc newRollingFileLogger*(filename = defaultFilename(), - mode: TFileMode = fmReadWrite, + mode: FileMode = fmReadWrite, levelThreshold = lvlAll, fmtStr = defaultFmtStr, - maxLines = 1000): PRollingFileLogger = + maxLines = 1000): RollingFileLogger = ## Creates a new rolling file logger. Once a file reaches ``maxLines`` lines ## a new log file will be started and the old will be renamed. new(result) @@ -190,14 +196,14 @@ proc newRollingFileLogger*(filename = defaultFilename(), # We need to get a line count because we will be appending to the file. result.curLine = countLogLines(result) -proc rotate(logger: PRollingFileLogger) = +proc rotate(logger: RollingFileLogger) = let (dir, name, ext) = splitFile(logger.baseName) for i in countdown(logger.logFiles, 0): let srcSuff = if i != 0: ExtSep & $i else: "" moveFile(dir / (name & ext & srcSuff), dir / (name & ext & ExtSep & $(i+1))) -method log*(logger: PRollingFileLogger, level: TLevel, +method log*(logger: RollingFileLogger, level: Level, frmt: string, args: varargs[string, `$`]) = ## Logs to a file using rolling ``logger`` only. if level >= logger.levelThreshold: @@ -215,20 +221,20 @@ method log*(logger: PRollingFileLogger, level: TLevel, var level* = lvlAll ## global log filter - handlers*: seq[PLogger] = @[] ## handlers with their own log levels + handlers*: seq[Logger] = @[] ## handlers with their own log levels -proc logLoop(level: TLevel, frmt: string, args: varargs[string, `$`]) = +proc logLoop(level: Level, frmt: string, args: varargs[string, `$`]) = for logger in items(handlers): if level >= logger.levelThreshold: log(logger, level, frmt, args) -template log*(level: TLevel, frmt: string, args: varargs[string, `$`]) = +template log*(level: Level, frmt: string, args: varargs[string, `$`]) = ## Logs a message to all registered handlers at the given level. bind logLoop bind `%` - bind logging.Level + bind logging.level - if level >= logging.Level: + if level >= logging.level: logLoop(level, frmt, args) template debug*(frmt: string, args: varargs[string, `$`]) = diff --git a/lib/pure/marshal.nim b/lib/pure/marshal.nim index 789f6ad76..fc63605a9 100644 --- a/lib/pure/marshal.nim +++ b/lib/pure/marshal.nim @@ -1,319 +1,319 @@ -# -# -# Nimrod's Runtime Library -# (c) Copyright 2013 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## This module contains procs for serialization and deseralization of -## arbitrary Nimrod data structures. The serialization format uses JSON. -## -## **Restriction**: For objects their type is **not** serialized. This means -## essentially that it does not work if the object has some other runtime -## type than its compiletime type: -## -## .. code-block:: nimrod -## -## type -## TA = object -## TB = object of TA -## f: int -## -## var -## a: ref TA -## b: ref TB -## -## new(b) -## a = b -## echo($$a[]) # produces "{}", not "{f: 0}" - -import streams, typeinfo, json, intsets, tables - -proc ptrToInt(x: pointer): int {.inline.} = - result = cast[int](x) # don't skip alignment - -proc storeAny(s: PStream, a: TAny, stored: var TIntSet) = - case a.kind - of akNone: assert false - of akBool: s.write($getBool(a)) - of akChar: s.write(escapeJson($getChar(a))) - of akArray, akSequence: - if a.kind == akSequence and isNil(a): s.write("null") - else: - s.write("[") - for i in 0 .. a.len-1: - if i > 0: s.write(", ") - storeAny(s, a[i], stored) - s.write("]") - of akObject, akTuple: - s.write("{") - var i = 0 - for key, val in fields(a): - if i > 0: s.write(", ") - s.write(escapeJson(key)) - s.write(": ") - storeAny(s, val, stored) - inc(i) - s.write("}") - of akSet: - s.write("[") - var i = 0 - for e in elements(a): - if i > 0: s.write(", ") - s.write($e) - inc(i) - s.write("]") - of akRange: storeAny(s, skipRange(a), stored) - of akEnum: s.write(getEnumField(a).escapeJson) - of akPtr, akRef: - var x = a.getPointer - if isNil(x): s.write("null") - elif stored.containsOrIncl(x.ptrToInt): - # already stored, so we simply write out the pointer as an int: - s.write($x.ptrToInt) - else: - # else as a [value, key] pair: - # (reversed order for convenient x[0] access!) - s.write("[") - s.write($x.ptrToInt) - s.write(", ") - storeAny(s, a[], stored) - s.write("]") - of akProc, akPointer, akCString: s.write($a.getPointer.ptrToInt) - of akString: - var x = getString(a) - if IsNil(x): s.write("null") - else: s.write(escapeJson(x)) - of akInt..akInt64, akUInt..akUInt64: s.write($getBiggestInt(a)) - of akFloat..akFloat128: s.write($getBiggestFloat(a)) - -proc loadAny(p: var TJsonParser, a: TAny, t: var TTable[biggestInt, pointer]) = - case a.kind - of akNone: assert false - of akBool: - case p.kind - of jsonFalse: setBiggestInt(a, 0) - of jsonTrue: setBiggestInt(a, 1) - else: raiseParseErr(p, "'true' or 'false' expected for a bool") - next(p) - of akChar: - if p.kind == jsonString: - var x = p.str - if x.len == 1: - setBiggestInt(a, ord(x[0])) - next(p) - return - raiseParseErr(p, "string of length 1 expected for a char") - of akEnum: - if p.kind == jsonString: - setBiggestInt(a, getEnumOrdinal(a, p.str)) - next(p) - return - raiseParseErr(p, "string expected for an enum") - of akArray: - if p.kind != jsonArrayStart: raiseParseErr(p, "'[' expected for an array") - next(p) - var i = 0 - while p.kind != jsonArrayEnd and p.kind != jsonEof: - loadAny(p, a[i], t) - inc(i) - if p.kind == jsonArrayEnd: next(p) - else: raiseParseErr(p, "']' end of array expected") - of akSequence: - case p.kind - of jsonNull: - setPointer(a, nil) - next(p) - of jsonArrayStart: - next(p) - invokeNewSeq(a, 0) - var i = 0 - while p.kind != jsonArrayEnd and p.kind != jsonEof: - extendSeq(a) - loadAny(p, a[i], t) - inc(i) - if p.kind == jsonArrayEnd: next(p) - else: raiseParseErr(p, "") - else: - raiseParseErr(p, "'[' expected for a seq") - of akObject, akTuple: - if a.kind == akObject: setObjectRuntimeType(a) - if p.kind != jsonObjectStart: raiseParseErr(p, "'{' expected for an object") - next(p) - while p.kind != jsonObjectEnd and p.kind != jsonEof: - if p.kind != jsonString: - raiseParseErr(p, "string expected for a field name") - var fieldName = p.str - next(p) - loadAny(p, a[fieldName], t) - if p.kind == jsonObjectEnd: next(p) - else: raiseParseErr(p, "'}' end of object expected") - of akSet: - if p.kind != jsonArrayStart: raiseParseErr(p, "'[' expected for a set") - next(p) - while p.kind != jsonArrayEnd and p.kind != jsonEof: - if p.kind != jsonInt: raiseParseErr(p, "int expected for a set") - inclSetElement(a, p.getInt.int) - next(p) - if p.kind == jsonArrayEnd: next(p) - else: raiseParseErr(p, "']' end of array expected") - of akPtr, akRef: - case p.kind - of jsonNull: - setPointer(a, nil) - next(p) - of jsonInt: - setPointer(a, t[p.getInt]) - next(p) - of jsonArrayStart: - next(p) - if a.kind == akRef: invokeNew(a) - else: setPointer(a, alloc0(a.baseTypeSize)) - if p.kind == jsonInt: - t[p.getInt] = getPointer(a) - next(p) - else: raiseParseErr(p, "index for ref type expected") - loadAny(p, a[], t) - if p.kind == jsonArrayEnd: next(p) - else: raiseParseErr(p, "']' end of ref-address pair expected") - else: raiseParseErr(p, "int for pointer type expected") - of akProc, akPointer, akCString: - case p.kind - of jsonNull: - setPointer(a, nil) - next(p) - of jsonInt: - setPointer(a, cast[pointer](p.getInt.int)) - next(p) - else: raiseParseErr(p, "int for pointer type expected") - of akString: - case p.kind - of jsonNull: - setPointer(a, nil) - next(p) - of jsonString: - setString(a, p.str) - next(p) - else: raiseParseErr(p, "string expected") - of akInt..akInt64, akUInt..akUInt64: - if p.kind == jsonInt: - setBiggestInt(a, getInt(p)) - next(p) - return - raiseParseErr(p, "int expected") - of akFloat..akFloat128: - if p.kind == jsonFloat: - setBiggestFloat(a, getFloat(p)) - next(p) - return - raiseParseErr(p, "float expected") - of akRange: loadAny(p, a.skipRange, t) - -proc loadAny(s: PStream, a: TAny, t: var TTable[biggestInt, pointer]) = - var p: TJsonParser - open(p, s, "unknown file") - next(p) - loadAny(p, a, t) - close(p) - -proc load*[T](s: PStream, data: var T) = - ## loads `data` from the stream `s`. Raises `EIO` in case of an error. - var tab = initTable[biggestInt, pointer]() - loadAny(s, toAny(data), tab) - -proc store*[T](s: PStream, data: T) = - ## stores `data` into the stream `s`. Raises `EIO` in case of an error. - var stored = initIntSet() - var d: T - shallowCopy(d, data) - storeAny(s, toAny(d), stored) - -proc `$$`*[T](x: T): string = - ## returns a string representation of `x`. - var stored = initIntSet() - var d: T - shallowCopy(d, x) - var s = newStringStream() - storeAny(s, toAny(d), stored) - result = s.data - -proc to*[T](data: string): T = - ## reads data and transforms it to a ``T``. - var tab = initTable[biggestInt, pointer]() - loadAny(newStringStream(data), toAny(result), tab) - -when isMainModule: - template testit(x: expr) = echo($$to[type(x)]($$x)) - - var x: array[0..4, array[0..4, string]] = [ - ["test", "1", "2", "3", "4"], ["test", "1", "2", "3", "4"], - ["test", "1", "2", "3", "4"], ["test", "1", "2", "3", "4"], - ["test", "1", "2", "3", "4"]] - testit(x) - var test2: tuple[name: string, s: uint] = ("tuple test", 56u) - testit(test2) - - type - TE = enum - blah, blah2 - - TestObj = object - test, asd: int - case test2: TE - of blah: - help: string - else: - nil - - PNode = ref TNode - TNode = object - next, prev: PNode - data: string - - proc buildList(): PNode = - new(result) - new(result.next) - new(result.prev) - result.data = "middle" - result.next.data = "next" - result.prev.data = "prev" - result.next.next = result.prev - result.next.prev = result - result.prev.next = result - result.prev.prev = result.next - - var test3: TestObj - test3.test = 42 - test3.test2 = blah - testit(test3) - - var test4: ref tuple[a, b: string] - new(test4) - test4.a = "ref string test: A" - test4.b = "ref string test: B" - testit(test4) - - var test5 = @[(0,1),(2,3),(4,5)] - testit(test5) - - var test6: set[char] = {'A'..'Z', '_'} - testit(test6) - - var test7 = buildList() - echo($$test7) - testit(test7) - - type - TA {.inheritable.} = object - TB = object of TA - f: int - - var - a: ref TA - b: ref TB - new(b) - a = b - echo($$a[]) # produces "{}", not "{f: 0}" - +# +# +# Nim's Runtime Library +# (c) Copyright 2014 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This module contains procs for serialization and deseralization of +## arbitrary Nim data structures. The serialization format uses JSON. +## +## **Restriction**: For objects their type is **not** serialized. This means +## essentially that it does not work if the object has some other runtime +## type than its compiletime type: +## +## .. code-block:: nim +## +## type +## TA = object +## TB = object of TA +## f: int +## +## var +## a: ref TA +## b: ref TB +## +## new(b) +## a = b +## echo($$a[]) # produces "{}", not "{f: 0}" + +import streams, typeinfo, json, intsets, tables + +proc ptrToInt(x: pointer): int {.inline.} = + result = cast[int](x) # don't skip alignment + +proc storeAny(s: Stream, a: TAny, stored: var IntSet) = + case a.kind + of akNone: assert false + of akBool: s.write($getBool(a)) + of akChar: s.write(escapeJson($getChar(a))) + of akArray, akSequence: + if a.kind == akSequence and isNil(a): s.write("null") + else: + s.write("[") + for i in 0 .. a.len-1: + if i > 0: s.write(", ") + storeAny(s, a[i], stored) + s.write("]") + of akObject, akTuple: + s.write("{") + var i = 0 + for key, val in fields(a): + if i > 0: s.write(", ") + s.write(escapeJson(key)) + s.write(": ") + storeAny(s, val, stored) + inc(i) + s.write("}") + of akSet: + s.write("[") + var i = 0 + for e in elements(a): + if i > 0: s.write(", ") + s.write($e) + inc(i) + s.write("]") + of akRange: storeAny(s, skipRange(a), stored) + of akEnum: s.write(getEnumField(a).escapeJson) + of akPtr, akRef: + var x = a.getPointer + if isNil(x): s.write("null") + elif stored.containsOrIncl(x.ptrToInt): + # already stored, so we simply write out the pointer as an int: + s.write($x.ptrToInt) + else: + # else as a [value, key] pair: + # (reversed order for convenient x[0] access!) + s.write("[") + s.write($x.ptrToInt) + s.write(", ") + storeAny(s, a[], stored) + s.write("]") + of akProc, akPointer, akCString: s.write($a.getPointer.ptrToInt) + of akString: + var x = getString(a) + if isNil(x): s.write("null") + else: s.write(escapeJson(x)) + of akInt..akInt64, akUInt..akUInt64: s.write($getBiggestInt(a)) + of akFloat..akFloat128: s.write($getBiggestFloat(a)) + +proc loadAny(p: var JsonParser, a: TAny, t: var Table[BiggestInt, pointer]) = + case a.kind + of akNone: assert false + of akBool: + case p.kind + of jsonFalse: setBiggestInt(a, 0) + of jsonTrue: setBiggestInt(a, 1) + else: raiseParseErr(p, "'true' or 'false' expected for a bool") + next(p) + of akChar: + if p.kind == jsonString: + var x = p.str + if x.len == 1: + setBiggestInt(a, ord(x[0])) + next(p) + return + raiseParseErr(p, "string of length 1 expected for a char") + of akEnum: + if p.kind == jsonString: + setBiggestInt(a, getEnumOrdinal(a, p.str)) + next(p) + return + raiseParseErr(p, "string expected for an enum") + of akArray: + if p.kind != jsonArrayStart: raiseParseErr(p, "'[' expected for an array") + next(p) + var i = 0 + while p.kind != jsonArrayEnd and p.kind != jsonEof: + loadAny(p, a[i], t) + inc(i) + if p.kind == jsonArrayEnd: next(p) + else: raiseParseErr(p, "']' end of array expected") + of akSequence: + case p.kind + of jsonNull: + setPointer(a, nil) + next(p) + of jsonArrayStart: + next(p) + invokeNewSeq(a, 0) + var i = 0 + while p.kind != jsonArrayEnd and p.kind != jsonEof: + extendSeq(a) + loadAny(p, a[i], t) + inc(i) + if p.kind == jsonArrayEnd: next(p) + else: raiseParseErr(p, "") + else: + raiseParseErr(p, "'[' expected for a seq") + of akObject, akTuple: + if a.kind == akObject: setObjectRuntimeType(a) + if p.kind != jsonObjectStart: raiseParseErr(p, "'{' expected for an object") + next(p) + while p.kind != jsonObjectEnd and p.kind != jsonEof: + if p.kind != jsonString: + raiseParseErr(p, "string expected for a field name") + var fieldName = p.str + next(p) + loadAny(p, a[fieldName], t) + if p.kind == jsonObjectEnd: next(p) + else: raiseParseErr(p, "'}' end of object expected") + of akSet: + if p.kind != jsonArrayStart: raiseParseErr(p, "'[' expected for a set") + next(p) + while p.kind != jsonArrayEnd and p.kind != jsonEof: + if p.kind != jsonInt: raiseParseErr(p, "int expected for a set") + inclSetElement(a, p.getInt.int) + next(p) + if p.kind == jsonArrayEnd: next(p) + else: raiseParseErr(p, "']' end of array expected") + of akPtr, akRef: + case p.kind + of jsonNull: + setPointer(a, nil) + next(p) + of jsonInt: + setPointer(a, t[p.getInt]) + next(p) + of jsonArrayStart: + next(p) + if a.kind == akRef: invokeNew(a) + else: setPointer(a, alloc0(a.baseTypeSize)) + if p.kind == jsonInt: + t[p.getInt] = getPointer(a) + next(p) + else: raiseParseErr(p, "index for ref type expected") + loadAny(p, a[], t) + if p.kind == jsonArrayEnd: next(p) + else: raiseParseErr(p, "']' end of ref-address pair expected") + else: raiseParseErr(p, "int for pointer type expected") + of akProc, akPointer, akCString: + case p.kind + of jsonNull: + setPointer(a, nil) + next(p) + of jsonInt: + setPointer(a, cast[pointer](p.getInt.int)) + next(p) + else: raiseParseErr(p, "int for pointer type expected") + of akString: + case p.kind + of jsonNull: + setPointer(a, nil) + next(p) + of jsonString: + setString(a, p.str) + next(p) + else: raiseParseErr(p, "string expected") + of akInt..akInt64, akUInt..akUInt64: + if p.kind == jsonInt: + setBiggestInt(a, getInt(p)) + next(p) + return + raiseParseErr(p, "int expected") + of akFloat..akFloat128: + if p.kind == jsonFloat: + setBiggestFloat(a, getFloat(p)) + next(p) + return + raiseParseErr(p, "float expected") + of akRange: loadAny(p, a.skipRange, t) + +proc loadAny(s: Stream, a: TAny, t: var Table[BiggestInt, pointer]) = + var p: JsonParser + open(p, s, "unknown file") + next(p) + loadAny(p, a, t) + close(p) + +proc load*[T](s: Stream, data: var T) = + ## loads `data` from the stream `s`. Raises `EIO` in case of an error. + var tab = initTable[BiggestInt, pointer]() + loadAny(s, toAny(data), tab) + +proc store*[T](s: Stream, data: T) = + ## stores `data` into the stream `s`. Raises `EIO` in case of an error. + var stored = initIntSet() + var d: T + shallowCopy(d, data) + storeAny(s, toAny(d), stored) + +proc `$$`*[T](x: T): string = + ## returns a string representation of `x`. + var stored = initIntSet() + var d: T + shallowCopy(d, x) + var s = newStringStream() + storeAny(s, toAny(d), stored) + result = s.data + +proc to*[T](data: string): T = + ## reads data and transforms it to a ``T``. + var tab = initTable[BiggestInt, pointer]() + loadAny(newStringStream(data), toAny(result), tab) + +when isMainModule: + template testit(x: expr) = echo($$to[type(x)]($$x)) + + var x: array[0..4, array[0..4, string]] = [ + ["test", "1", "2", "3", "4"], ["test", "1", "2", "3", "4"], + ["test", "1", "2", "3", "4"], ["test", "1", "2", "3", "4"], + ["test", "1", "2", "3", "4"]] + testit(x) + var test2: tuple[name: string, s: uint] = ("tuple test", 56u) + testit(test2) + + type + TE = enum + blah, blah2 + + TestObj = object + test, asd: int + case test2: TE + of blah: + help: string + else: + nil + + PNode = ref TNode + TNode = object + next, prev: PNode + data: string + + proc buildList(): PNode = + new(result) + new(result.next) + new(result.prev) + result.data = "middle" + result.next.data = "next" + result.prev.data = "prev" + result.next.next = result.prev + result.next.prev = result + result.prev.next = result + result.prev.prev = result.next + + var test3: TestObj + test3.test = 42 + test3.test2 = blah + testit(test3) + + var test4: ref tuple[a, b: string] + new(test4) + test4.a = "ref string test: A" + test4.b = "ref string test: B" + testit(test4) + + var test5 = @[(0,1),(2,3),(4,5)] + testit(test5) + + var test6: set[char] = {'A'..'Z', '_'} + testit(test6) + + var test7 = buildList() + echo($$test7) + testit(test7) + + type + TA {.inheritable.} = object + TB = object of TA + f: int + + var + a: ref TA + b: ref TB + new(b) + a = b + echo($$a[]) # produces "{}", not "{f: 0}" + diff --git a/lib/pure/matchers.nim b/lib/pure/matchers.nim index 2db7fa660..46fc9985c 100644 --- a/lib/pure/matchers.nim +++ b/lib/pure/matchers.nim @@ -1,7 +1,7 @@ # # -# Nimrod's Runtime Library -# (c) Copyright 2012 Andreas Rumpf +# Nim's Runtime Library +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -31,8 +31,8 @@ proc validEmailAddress*(s: string): bool {.noSideEffect, inc(i) if s[i] != '@': return false var j = len(s)-1 - if s[j] notin letters: return false - while j >= i and s[j] in letters: dec(j) + if s[j] notin Letters: return false + while j >= i and s[j] in Letters: dec(j) inc(i) # skip '@' while s[i] in {'0'..'9', 'a'..'z', '-', '.'}: inc(i) if s[i] != '\0': return false @@ -44,7 +44,7 @@ proc validEmailAddress*(s: string): bool {.noSideEffect, "aero", "jobs", "museum": return true return false -proc parseInt*(s: string, value: var int, validRange: TSlice[int]) {. +proc parseInt*(s: string, value: var int, validRange: Slice[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 @@ -53,7 +53,7 @@ proc parseInt*(s: string, value: var int, validRange: TSlice[int]) {. var x = value try: discard parseutils.parseInt(s, x, 0) - except EOverflow: + except OverflowError: discard if x in validRange: value = x diff --git a/lib/pure/math.nim b/lib/pure/math.nim index 0f6a07f13..1b6572d53 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -1,7 +1,7 @@ # # -# Nimrod's Runtime Library -# (c) Copyright 2012 Andreas Rumpf +# Nim's Runtime Library +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -9,12 +9,11 @@ ## Constructive mathematics is naturally typed. -- Simon Thompson ## -## Basic math routines for Nimrod. +## Basic math routines for Nim. ## This module is available for the `JavaScript target ## <backends.html#the-javascript-target>`_. include "system/inclrtl" -import "impure/fenv" {.push debugger:off .} # the user does not want to trace a part # of the standard library! @@ -30,20 +29,31 @@ const E* = 2.71828182845904523536028747 ## Euler's number MaxFloat64Precision* = 16 ## maximum number of meaningful digits - ## after the decimal point for Nimrod's + ## after the decimal point for Nim's ## ``float64`` type. MaxFloat32Precision* = 8 ## maximum number of meaningful digits - ## after the decimal point for Nimrod's + ## after the decimal point for Nim's ## ``float32`` type. MaxFloatPrecision* = MaxFloat64Precision ## maximum number of ## meaningful digits ## after the decimal point - ## for Nimrod's ``float`` type. + ## for Nim's ``float`` type. -proc classify*(x: float): TFloatClass = +type + FloatClass* = enum ## describes the class a floating point value belongs to. + ## This is the type that is returned by `classify`. + fcNormal, ## value is an ordinary nonzero floating point value + fcSubnormal, ## value is a subnormal (a very small) floating point value + fcZero, ## value is zero + fcNegZero, ## value is the negative zero + fcNan, ## value is Not-A-Number (NAN) + fcInf, ## value is positive infinity + fcNegInf ## value is negative infinity + +proc classify*(x: float): FloatClass = ## classifies a floating point value. Returns `x`'s class as specified by - ## `TFloatClass`. - + ## `FloatClass`. + # JavaScript and most C compilers have no classify: if x == 0.0: if 1.0/x == Inf: @@ -267,21 +277,23 @@ else: proc `mod`*(x, y: float): float = result = if y == 0.0: x else: x - y * (x/y).floor -proc random*[T](x: TSlice[T]): T = +proc random*[T](x: Slice[T]): T = ## For a slice `a .. b` returns a value in the range `a .. b-1`. result = random(x.b - x.a) + x.a -proc random[T](a: openarray[T]): T = +proc random[T](a: openArray[T]): T = ## returns a random element from the openarray `a`. result = a[random(a.low..a.len)] type - TRunningStat* {.pure,final.} = object ## an accumulator for statistical data - n*: int ## number of pushed data - sum*, min*, max*, mean*: float ## self-explaining + RunningStat* = object ## an accumulator for statistical data + n*: int ## number of pushed data + sum*, min*, max*, mean*: float ## self-explaining oldM, oldS, newS: float -proc push*(s: var TRunningStat, x: float) = +{.deprecated: [TFloatClass: FloatClass, TRunningStat: RunningStat].} + +proc push*(s: var RunningStat, x: float) = ## pushes a value `x` for processing inc(s.n) # See Knuth TAOCP vol 2, 3rd edition, page 232 @@ -302,16 +314,16 @@ proc push*(s: var TRunningStat, x: float) = s.oldS = s.newS s.sum = s.sum + x -proc push*(s: var TRunningStat, x: int) = +proc push*(s: var RunningStat, x: int) = ## pushes a value `x` for processing. `x` is simply converted to ``float`` ## and the other push operation is called. push(s, toFloat(x)) -proc variance*(s: TRunningStat): float = +proc variance*(s: RunningStat): float = ## computes the current variance of `s` if s.n > 1: result = s.newS / (toFloat(s.n - 1)) -proc standardDeviation*(s: TRunningStat): float = +proc standardDeviation*(s: RunningStat): float = ## computes the current standard deviation of `s` result = sqrt(variance(s)) diff --git a/lib/pure/md5.nim b/lib/pure/md5.nim index 0328932fd..3b5453957 100644 --- a/lib/pure/md5.nim +++ b/lib/pure/md5.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this @@ -84,14 +84,14 @@ proc decode(dest: var openArray[int8], src: openArray[int32]) = dest[i+3] = toU8(src[j] shr 24'i32 and 0xff'i32) inc(i, 4) -proc transform(Buffer: pointer, State: var MD5State) = +proc transform(buffer: pointer, state: var MD5State) = var myBlock: MD5Block - encode(myBlock, cast[cstring](Buffer)) - var a = State[0] - var b = State[1] - var c = State[2] - var d = State[3] + encode(myBlock, cast[cstring](buffer)) + var a = state[0] + var b = state[1] + var c = state[2] + var d = state[3] FF(a, b, c, d, myBlock[0], 7'i8, 0xD76AA478'i32) FF(d, a, b, c, myBlock[1], 12'i8, 0xE8C7B756'i32) FF(c, d, a, b, myBlock[2], 17'i8, 0x242070DB'i32) @@ -156,52 +156,52 @@ proc transform(Buffer: pointer, State: var MD5State) = II(d, a, b, c, myBlock[11], 10'i8, 0xBD3AF235'i32) II(c, d, a, b, myBlock[2], 15'i8, 0x2AD7D2BB'i32) II(b, c, d, a, myBlock[9], 21'i8, 0xEB86D391'i32) - State[0] = State[0] +% a - State[1] = State[1] +% b - State[2] = State[2] +% c - State[3] = State[3] +% d + state[0] = state[0] +% a + state[1] = state[1] +% b + state[2] = state[2] +% c + state[3] = state[3] +% d proc md5Init*(c: var MD5Context) = ## initializes a MD5Context - c.State[0] = 0x67452301'i32 - c.State[1] = 0xEFCDAB89'i32 - c.State[2] = 0x98BADCFE'i32 - c.State[3] = 0x10325476'i32 - c.Count[0] = 0'i32 - c.Count[1] = 0'i32 - zeroMem(addr(c.Buffer), sizeof(MD5Buffer)) + c.state[0] = 0x67452301'i32 + c.state[1] = 0xEFCDAB89'i32 + c.state[2] = 0x98BADCFE'i32 + c.state[3] = 0x10325476'i32 + c.count[0] = 0'i32 + c.count[1] = 0'i32 + zeroMem(addr(c.buffer), sizeof(MD5buffer)) proc md5Update*(c: var MD5Context, input: cstring, len: int) = ## updates the MD5Context with the `input` data of length `len` var input = input var Index = (c.count[0] shr 3) and 0x3F - c.Count[0] = c.count[0] +% toU32(len shl 3) - if c.Count[0] < (len shl 3): c.Count[1] = c.count[1] +% 1'i32 - c.Count[1] = c.count[1] +% toU32(len shr 29) + c.count[0] = c.count[0] +% toU32(len shl 3) + if c.count[0] < (len shl 3): c.count[1] = c.count[1] +% 1'i32 + c.count[1] = c.count[1] +% toU32(len shr 29) var PartLen = 64 - Index if len >= PartLen: - copyMem(addr(c.Buffer[Index]), input, PartLen) - transform(addr(c.Buffer), c.State) + copyMem(addr(c.buffer[Index]), input, PartLen) + transform(addr(c.buffer), c.state) var i = PartLen while i + 63 < len: - transform(addr(input[i]), c.State) + transform(addr(input[i]), c.state) inc(i, 64) - copyMem(addr(c.Buffer[0]), addr(input[i]), len-i) + copyMem(addr(c.buffer[0]), addr(input[i]), len-i) else: - copyMem(addr(c.Buffer[Index]), addr(input[0]), len) + copyMem(addr(c.buffer[Index]), addr(input[0]), len) proc md5Final*(c: var MD5Context, digest: var MD5Digest) = ## finishes the MD5Context and stores the result in `digest` var Bits: MD5CBits PadLen: int - decode(Bits, c.Count) - var Index = (c.Count[0] shr 3) and 0x3F + decode(Bits, c.count) + var Index = (c.count[0] shr 3) and 0x3F if Index < 56: PadLen = 56 - Index else: PadLen = 120 - Index md5Update(c, padding, PadLen) md5Update(c, cast[cstring](addr(Bits)), 8) - decode(digest, c.State) + decode(digest, c.state) zeroMem(addr(c), sizeof(MD5Context)) proc toMD5*(s: string): MD5Digest = @@ -216,8 +216,8 @@ proc `$`*(D: MD5Digest): string = const digits = "0123456789abcdef" result = "" for i in 0..15: - add(result, Digits[(D[i] shr 4) and 0xF]) - add(result, Digits[D[i] and 0xF]) + add(result, digits[(D[i] shr 4) and 0xF]) + add(result, digits[D[i] and 0xF]) proc getMD5*(s: string): string = ## computes an MD5 value of `s` and returns its string representation diff --git a/lib/pure/memfiles.nim b/lib/pure/memfiles.nim index ffeb0beff..24dbfb6d3 100644 --- a/lib/pure/memfiles.nim +++ b/lib/pure/memfiles.nim @@ -1,7 +1,7 @@ # # -# Nimrod's Runtime Library -# (c) Copyright 2014 Nimrod Contributors +# Nim's Runtime Library +# (c) Copyright 2014 Nim Contributors # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -22,7 +22,7 @@ else: import os type - TMemFile* = object {.pure.} ## represents a memory mapped file + MemFile* = object ## represents a memory mapped file mem*: pointer ## a pointer to the memory mapped file. The pointer ## can be used directly to change the contents of the ## file, if it was opened with write access. @@ -34,8 +34,9 @@ type else: handle: cint +{.deprecated: [TMemFile: MemFile].} -proc mapMem*(m: var TMemFile, mode: TFileMode = fmRead, +proc mapMem*(m: var MemFile, mode: FileMode = fmRead, mappedSize = -1, offset = 0): pointer = var readonly = mode == fmRead when defined(windows): @@ -47,7 +48,7 @@ proc mapMem*(m: var TMemFile, mode: TFileMode = fmRead, if mappedSize == -1: 0 else: mappedSize, nil) if result == nil: - osError(osLastError()) + raiseOSError(osLastError()) else: assert mappedSize > 0 result = mmap( @@ -57,30 +58,30 @@ proc mapMem*(m: var TMemFile, mode: TFileMode = fmRead, if readonly: (MAP_PRIVATE or MAP_POPULATE) else: (MAP_SHARED or MAP_POPULATE), m.handle, offset) if result == cast[pointer](MAP_FAILED): - osError(osLastError()) + raiseOSError(osLastError()) -proc unmapMem*(f: var TMemFile, p: pointer, size: int) = +proc unmapMem*(f: var MemFile, p: pointer, size: int) = ## unmaps the memory region ``(p, <p+size)`` of the mapped file `f`. ## All changes are written back to the file system, if `f` was opened ## with write access. ``size`` must be of exactly the size that was requested ## via ``mapMem``. when defined(windows): - if unmapViewOfFile(p) == 0: osError(osLastError()) + if unmapViewOfFile(p) == 0: raiseOSError(osLastError()) else: - if munmap(p, size) != 0: osError(osLastError()) + if munmap(p, size) != 0: raiseOSError(osLastError()) -proc open*(filename: string, mode: TFileMode = fmRead, - mappedSize = -1, offset = 0, newFileSize = -1): TMemFile = +proc open*(filename: string, mode: FileMode = fmRead, + mappedSize = -1, offset = 0, newFileSize = -1): MemFile = ## opens a memory mapped file. If this fails, ``EOS`` is raised. ## `newFileSize` can only be set if the file does not exist and is opened ## with write access (e.g., with fmReadWrite). `mappedSize` and `offset` ## can be used to map only a slice of the file. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var - ## mm, mm_full, mm_half: TMemFile + ## mm, mm_full, mm_half: MemFile ## ## mm = memfiles.open("/tmp/test.mmap", mode = fmWrite, newFileSize = 1024) # Create a new file ## mm.close() @@ -100,11 +101,11 @@ proc open*(filename: string, mode: TFileMode = fmRead, result.size = 0 when defined(windows): - template fail(errCode: TOSErrorCode, msg: expr) = + template fail(errCode: OSErrorCode, msg: expr) = rollback() if result.fHandle != 0: discard closeHandle(result.fHandle) if result.mapHandle != 0: discard closeHandle(result.mapHandle) - osError(errCode) + raiseOSError(errCode) # return false #raise newException(EIO, msg) @@ -169,10 +170,10 @@ proc open*(filename: string, mode: TFileMode = fmRead, else: result.size = fileSize.int else: - template fail(errCode: TOSErrorCode, msg: expr) = + template fail(errCode: OSErrorCode, msg: expr) = rollback() if result.handle != 0: discard close(result.handle) - osError(errCode) + raiseOSError(errCode) var flags = if readonly: O_RDONLY else: O_RDWR @@ -214,12 +215,12 @@ proc open*(filename: string, mode: TFileMode = fmRead, if result.mem == cast[pointer](MAP_FAILED): fail(osLastError(), "file mapping failed") -proc close*(f: var TMemFile) = +proc close*(f: var MemFile) = ## closes the memory mapped file `f`. All changes are written back to the ## file system, if `f` was opened with write access. var error = false - var lastErr: TOSErrorCode + var lastErr: OSErrorCode when defined(windows): if f.fHandle != INVALID_HANDLE_VALUE: @@ -242,5 +243,5 @@ proc close*(f: var TMemFile) = else: f.handle = 0 - if error: osError(lastErr) + if error: raiseOSError(lastErr) diff --git a/lib/pure/mersenne.nim b/lib/pure/mersenne.nim index 2b12cce73..a6a781cb8 100644 --- a/lib/pure/mersenne.nim +++ b/lib/pure/mersenne.nim @@ -1,24 +1,26 @@ import unsigned type - TMersenneTwister* = object + MersenneTwister* = object mt: array[0..623, uint32] index: int -proc newMersenneTwister*(seed: int): TMersenneTwister = +{.deprecated: [TMersenneTwister: MersenneTwister].} + +proc newMersenneTwister*(seed: int): MersenneTwister = result.index = 0 result.mt[0]= uint32(seed) for i in 1..623'u32: result.mt[i]= (0x6c078965'u32 * (result.mt[i-1] xor (result.mt[i-1] shr 30'u32)) + i) -proc generateNumbers(m: var TMersenneTwister) = +proc generateNumbers(m: var MersenneTwister) = for i in 0..623: var y = (m.mt[i] and 0x80000000'u32) + (m.mt[(i+1) mod 624] and 0x7fffffff'u32) m.mt[i] = m.mt[(i+397) mod 624] xor uint32(y shr 1'u32) if (y mod 2'u32) != 0: m.mt[i] = m.mt[i] xor 0x9908b0df'u32 -proc getNum*(m: var TMersenneTwister): int = +proc getNum*(m: var MersenneTwister): int = if m.index == 0: generateNumbers(m) var y = m.mt[m.index] @@ -29,11 +31,9 @@ proc getNum*(m: var TMersenneTwister): int = m.index = (m.index+1) mod 624 return int(y) - - # Test when isMainModule: var mt = newMersenneTwister(2525) for i in 0..99: - echo mt.getNum \ No newline at end of file + echo mt.getNum diff --git a/lib/pure/mimetypes.nim b/lib/pure/mimetypes.nim index 92baf0549..a52ba4ebe 100644 --- a/lib/pure/mimetypes.nim +++ b/lib/pure/mimetypes.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Dominik Picheta # # See the file "copying.txt", included in this @@ -10,8 +10,10 @@ ## This module implements a mimetypes database import strtabs type - TMimeDB* = object - mimes: PStringTable + MimeDB* = object + mimes: StringTableRef + +{.deprecated: [TMimeDB: MimeDB].} const mimes* = { "ez": "application/andrew-inset", @@ -489,20 +491,19 @@ const mimes* = { "vrml": "x-world/x-vrml", "wrl": "x-world/x-vrml"} -proc newMimetypes*(): TMimeDB = +proc newMimetypes*(): MimeDB = ## Creates a new Mimetypes database. The database will contain the most ## common mimetypes. - result.mimes = mimes.newStringTable() -proc getMimetype*(mimedb: TMimeDB, ext: string, default = "text/plain"): string = +proc getMimetype*(mimedb: MimeDB, ext: string, default = "text/plain"): string = ## Gets mimetype which corresponds to ``ext``. Returns ``default`` if ``ext`` ## could not be found. result = mimedb.mimes[ext] if result == "": return default -proc getExt*(mimedb: TMimeDB, mimetype: string, default = "txt"): string = +proc getExt*(mimedb: MimeDB, mimetype: string, default = "txt"): string = ## Gets extension which corresponds to ``mimetype``. Returns ``default`` if ## ``mimetype`` could not be found. Extensions are returned without the ## leading dot. @@ -511,11 +512,11 @@ proc getExt*(mimedb: TMimeDB, mimetype: string, default = "txt"): string = if m == mimetype: result = e -proc register*(mimedb: var TMimeDB, ext: string, mimetype: string) = +proc register*(mimedb: var MimeDB, ext: string, mimetype: string) = ## Adds ``mimetype`` to the ``mimedb``. mimedb.mimes[ext] = mimetype when isMainModule: var m = newMimetypes() echo m.getMimetype("mp4") - echo m.getExt("text/html") \ No newline at end of file + echo m.getExt("text/html") diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 696527467..f63f5fff8 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Dominik Picheta # # See the file "copying.txt", included in this @@ -11,7 +11,7 @@ {.deadCodeElim: on.} import rawsockets, os, strutils, unsigned, parseutils, times -export TPort, `$`, `==` +export Port, `$`, `==` const useWinVersion = defined(Windows) or defined(nimdoc) @@ -22,25 +22,29 @@ when defined(ssl): when defined(ssl): type - ESSL* = object of ESynch + SslError* = object of Exception - TSSLCVerifyMode* = enum + SslCVerifyMode* = enum CVerifyNone, CVerifyPeer - TSSLProtVersion* = enum + SslProtVersion* = enum protSSLv2, protSSLv3, protTLSv1, protSSLv23 - PSSLContext* = distinct PSSLCTX + SslContext* = distinct SslCtx - TSSLAcceptResult* = enum + SslAcceptResult* = enum AcceptNoClient = 0, AcceptNoHandshake, AcceptSuccess + {.deprecated: [ESSL: SSLError, TSSLCVerifyMode: SSLCVerifyMode, + TSSLProtVersion: SSLProtVersion, PSSLContext: SSLContext, + TSSLAcceptResult: SSLAcceptResult].} + const BufferSize*: int = 4000 ## size of a buffered socket's buffer type - TSocketImpl* = object ## socket type - fd*: TSocketHandle + SocketImpl* = object ## socket type + fd*: SocketHandle case isBuffered*: bool # determines whether this socket is buffered. of true: buffer*: array[0..BufferSize, char] @@ -57,42 +61,46 @@ type sslPeekChar*: char of false: nil - PSocket* = ref TSocketImpl + Socket* = ref SocketImpl - TSOBool* = enum ## Boolean socket options. + SOBool* = enum ## Boolean socket options. OptAcceptConn, OptBroadcast, OptDebug, OptDontRoute, OptKeepAlive, OptOOBInline, OptReuseAddr - TReadLineResult* = enum ## result for readLineAsync + ReadLineResult* = enum ## result for readLineAsync ReadFullLine, ReadPartialLine, ReadDisconnected, ReadNone - ETimeout* = object of ESynch + TimeoutError* = object of Exception - TSocketFlags* {.pure.} = enum + SocketFlag* {.pure.} = enum Peek, SafeDisconn ## Ensures disconnection exceptions (ECONNRESET, EPIPE etc) are not thrown. -proc isDisconnectionError*(flags: set[TSocketFlags], - lastError: TOSErrorCode): bool = +{.deprecated: [TSocketFlags: SocketFlag, ETimeout: TimeoutError, + TReadLineResult: ReadLineResult, TSOBool: SOBool, PSocket: Socket, + TSocketImpl: SocketImpl].} + +proc isDisconnectionError*(flags: set[SocketFlag], + lastError: OSErrorCode): bool = ## Determines whether ``lastError`` is a disconnection error. Only does this ## if flags contains ``SafeDisconn``. when useWinVersion: - TSocketFlags.SafeDisconn in flags and + SocketFlag.SafeDisconn in flags and lastError.int32 in {WSAECONNRESET, WSAECONNABORTED, WSAENETRESET, WSAEDISCON, ERROR_NETNAME_DELETED} else: - TSocketFlags.SafeDisconn in flags and + SocketFlag.SafeDisconn in flags and lastError.int32 in {ECONNRESET, EPIPE, ENETRESET} -proc toOSFlags*(socketFlags: set[TSocketFlags]): cint = +proc toOSFlags*(socketFlags: set[SocketFlag]): cint = ## Converts the flags into the underlying OS representation. for f in socketFlags: case f - of TSocketFlags.Peek: + of SocketFlag.Peek: result = result or MSG_PEEK - of TSocketFlags.SafeDisconn: continue + of SocketFlag.SafeDisconn: continue -proc createSocket(fd: TSocketHandle, isBuff: bool): PSocket = +proc createSocket(fd: SocketHandle, isBuff: bool): Socket = assert fd != osInvalidSocket new(result) result.fd = fd @@ -100,14 +108,23 @@ proc createSocket(fd: TSocketHandle, isBuff: bool): PSocket = if isBuff: result.currPos = 0 -proc newSocket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, - protocol: TProtocol = IPPROTO_TCP, buffered = true): PSocket = +proc newSocket*(domain, typ, protocol: cint, buffered = true): Socket = + ## Creates a new socket. + ## + ## If an error occurs EOS will be raised. + let fd = newRawSocket(domain, typ, protocol) + if fd == osInvalidSocket: + raiseOSError(osLastError()) + result = createSocket(fd, buffered) + +proc newSocket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM, + protocol: Protocol = IPPROTO_TCP, buffered = true): Socket = ## Creates a new socket. ## ## If an error occurs EOS will be raised. let fd = newRawSocket(domain, typ, protocol) if fd == osInvalidSocket: - osError(osLastError()) + raiseOSError(osLastError()) result = createSocket(fd, buffered) when defined(ssl): @@ -117,16 +134,17 @@ when defined(ssl): ErrLoadBioStrings() OpenSSL_add_all_algorithms() - proc SSLError(s = "") = + proc raiseSSLError*(s = "") = + ## Raises a new SSL error. if s != "": - raise newException(ESSL, s) + raise newException(SSLError, s) let err = ErrPeekLastError() if err == 0: - raise newException(ESSL, "No error reported.") + raise newException(SSLError, "No error reported.") if err == -1: - OSError(OSLastError()) + raiseOSError(osLastError()) var errStr = ErrErrorString(err, nil) - raise newException(ESSL, $errStr) + raise newException(SSLError, $errStr) # http://simplestcodings.blogspot.co.uk/2010/08/secure-server-client-using-openssl-in-c.html proc loadCertificates(ctx: PSSL_CTX, certFile, keyFile: string) = @@ -138,23 +156,23 @@ when defined(ssl): if certFile != "": var ret = SSLCTXUseCertificateChainFile(ctx, certFile) if ret != 1: - SSLError() + raiseSSLError() # TODO: Password? www.rtfm.com/openssl-examples/part1.pdf if keyFile != "": if SSL_CTX_use_PrivateKey_file(ctx, keyFile, SSL_FILETYPE_PEM) != 1: - SSLError() + raiseSSLError() if SSL_CTX_check_private_key(ctx) != 1: - SSLError("Verification of private key file failed.") + raiseSSLError("Verification of private key file failed.") - proc newContext*(protVersion = ProtSSLv23, verifyMode = CVerifyPeer, + proc newContext*(protVersion = protSSLv23, verifyMode = CVerifyPeer, certFile = "", keyFile = ""): PSSLContext = ## Creates an SSL context. ## - ## Protocol version specifies the protocol to use. SSLv2, SSLv3, TLSv1 are - ## are available with the addition of ``ProtSSLv23`` which allows for + ## Protocol version specifies the protocol to use. SSLv2, SSLv3, TLSv1 + ## are available with the addition of ``protSSLv23`` which allows for ## compatibility with all of them. ## ## There are currently only two options for verify mode; @@ -174,21 +192,21 @@ when defined(ssl): when not defined(linux): newCTX = SSL_CTX_new(SSLv2_method()) else: - SSLError() + raiseSslError() of protSSLv3: newCTX = SSL_CTX_new(SSLv3_method()) of protTLSv1: newCTX = SSL_CTX_new(TLSv1_method()) if newCTX.SSLCTXSetCipherList("ALL") != 1: - SSLError() + raiseSSLError() case verifyMode of CVerifyPeer: newCTX.SSLCTXSetVerify(SSLVerifyPeer, nil) of CVerifyNone: newCTX.SSLCTXSetVerify(SSLVerifyNone, nil) if newCTX == nil: - SSLError() + raiseSSLError() discard newCTX.SSLCTXSetMode(SSL_MODE_AUTO_RETRY) newCTX.loadCertificates(certFile, keyFile) @@ -207,17 +225,17 @@ when defined(ssl): socket.sslNoHandshake = false socket.sslHasPeekChar = false if socket.sslHandle == nil: - SSLError() + raiseSSLError() if SSLSetFd(socket.sslHandle, socket.fd) != 1: - SSLError() + raiseSSLError() -proc socketError*(socket: PSocket, err: int = -1, async = false, - lastError = (-1).TOSErrorCode) = - ## Raises an EOS error based on the error code returned by ``SSLGetError`` +proc socketError*(socket: Socket, err: int = -1, async = false, + lastError = (-1).OSErrorCode) = + ## Raises an OSError based on the error code returned by ``SSLGetError`` ## (for SSL sockets) and ``osLastError`` otherwise. ## - ## If ``async`` is ``True`` no error will be thrown in the case when the + ## If ``async`` is ``true`` no error will be thrown in the case when the ## error was caused by no data being available to be read. ## ## If ``err`` is not lower than 0 no exception will be raised. @@ -227,20 +245,20 @@ proc socketError*(socket: PSocket, err: int = -1, async = false, var ret = SSLGetError(socket.sslHandle, err.cint) case ret of SSL_ERROR_ZERO_RETURN: - SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") + raiseSSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: if async: return - else: SSLError("Not enough data on socket.") + else: raiseSSLError("Not enough data on socket.") of SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_READ: if async: return - else: SSLError("Not enough data on socket.") + else: raiseSSLError("Not enough data on socket.") of SSL_ERROR_WANT_X509_LOOKUP: - SSLError("Function for x509 lookup has been called.") + raiseSSLError("Function for x509 lookup has been called.") of SSL_ERROR_SYSCALL, SSL_ERROR_SSL: - SSLError() - else: SSLError("Unknown Error") + raiseSSLError() + else: raiseSSLError("Unknown Error") if err == -1 and not (when defined(ssl): socket.isSSL else: false): let lastE = if lastError.int == -1: osLastError() else: lastError @@ -248,47 +266,47 @@ proc socketError*(socket: PSocket, err: int = -1, async = false, when useWinVersion: if lastE.int32 == WSAEWOULDBLOCK: return - else: osError(lastE) + else: raiseOSError(lastE) else: if lastE.int32 == EAGAIN or lastE.int32 == EWOULDBLOCK: return - else: osError(lastE) - else: osError(lastE) + else: raiseOSError(lastE) + else: raiseOSError(lastE) -proc listen*(socket: PSocket, backlog = SOMAXCONN) {.tags: [FReadIO].} = +proc listen*(socket: Socket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} = ## Marks ``socket`` as accepting connections. ## ``Backlog`` specifies the maximum length of the ## queue of pending connections. ## ## Raises an EOS error upon failure. - if listen(socket.fd, backlog) < 0'i32: osError(osLastError()) + if listen(socket.fd, backlog) < 0'i32: raiseOSError(osLastError()) -proc bindAddr*(socket: PSocket, port = TPort(0), address = "") {. - tags: [FReadIO].} = +proc bindAddr*(socket: Socket, port = Port(0), address = "") {. + tags: [ReadIOEffect].} = ## Binds ``address``:``port`` to the socket. ## ## If ``address`` is "" then ADDR_ANY will be bound. if address == "": - var name: TSockaddr_in + var name: Sockaddr_in when useWinVersion: name.sin_family = toInt(AF_INET).int16 else: name.sin_family = toInt(AF_INET) name.sin_port = htons(int16(port)) name.sin_addr.s_addr = htonl(INADDR_ANY) - if bindAddr(socket.fd, cast[ptr TSockAddr](addr(name)), - sizeof(name).TSocklen) < 0'i32: - osError(osLastError()) + if bindAddr(socket.fd, cast[ptr SockAddr](addr(name)), + sizeof(name).SockLen) < 0'i32: + raiseOSError(osLastError()) else: var aiList = getAddrInfo(address, port, AF_INET) - if bindAddr(socket.fd, aiList.ai_addr, aiList.ai_addrlen.TSocklen) < 0'i32: + if bindAddr(socket.fd, aiList.ai_addr, aiList.ai_addrlen.SockLen) < 0'i32: dealloc(aiList) - osError(osLastError()) + raiseOSError(osLastError()) dealloc(aiList) -proc acceptAddr*(server: PSocket, client: var PSocket, address: var string, - flags = {TSocketFlags.SafeDisconn}) {.tags: [FReadIO].} = +proc acceptAddr*(server: Socket, client: var Socket, address: var string, + flags = {SocketFlag.SafeDisconn}) {.tags: [ReadIOEffect].} = ## Blocks until a connection is being made from a client. When a connection ## is made sets ``client`` to the client socket and ``address`` to the address ## of the connecting client. @@ -305,16 +323,16 @@ proc acceptAddr*(server: PSocket, client: var PSocket, address: var string, ## flag is specified then this error will not be raised and instead ## accept will be called again. assert(client != nil) - var sockAddress: Tsockaddr_in - var addrLen = sizeof(sockAddress).TSocklen - var sock = accept(server.fd, cast[ptr TSockAddr](addr(sockAddress)), + var sockAddress: Sockaddr_in + var addrLen = sizeof(sockAddress).SockLen + var sock = accept(server.fd, cast[ptr SockAddr](addr(sockAddress)), addr(addrLen)) if sock == osInvalidSocket: let err = osLastError() if flags.isDisconnectionError(err): acceptAddr(server, client, address, flags) - osError(err) + raiseOSError(err) else: client.fd = sock client.isBuffered = server.isBuffered @@ -363,17 +381,17 @@ when false: #defined(ssl): if err != SSL_ERROR_WANT_ACCEPT: case err of SSL_ERROR_ZERO_RETURN: - SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") + raiseSSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") of SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: client.sslNoHandshake = true return AcceptNoHandshake of SSL_ERROR_WANT_X509_LOOKUP: - SSLError("Function for x509 lookup has been called.") + raiseSSLError("Function for x509 lookup has been called.") of SSL_ERROR_SYSCALL, SSL_ERROR_SSL: - SSLError() + raiseSSLError() else: - SSLError("Unknown error") + raiseSSLError("Unknown error") client.sslNoHandshake = false if client.isSSL and client.sslNoHandshake: @@ -383,8 +401,8 @@ when false: #defined(ssl): acceptAddrPlain(AcceptNoClient, AcceptSuccess): doHandshake() -proc accept*(server: PSocket, client: var PSocket, - flags = {TSocketFlags.SafeDisconn}) {.tags: [FReadIO].} = +proc accept*(server: Socket, client: var Socket, + flags = {SocketFlag.SafeDisconn}) {.tags: [ReadIOEffect].} = ## Equivalent to ``acceptAddr`` but doesn't return the address, only the ## socket. ## @@ -398,7 +416,7 @@ proc accept*(server: PSocket, client: var PSocket, var addrDummy = "" acceptAddr(server, client, addrDummy, flags) -proc close*(socket: PSocket) = +proc close*(socket: Socket) = ## Closes a socket. socket.fd.close() when defined(ssl): @@ -410,7 +428,7 @@ proc close*(socket: PSocket) = elif res != 1: socketError(socket) -proc toCInt(opt: TSOBool): cint = +proc toCInt(opt: SOBool): cint = case opt of OptAcceptConn: SO_ACCEPTCONN of OptBroadcast: SO_BROADCAST @@ -420,20 +438,20 @@ proc toCInt(opt: TSOBool): cint = of OptOOBInline: SO_OOBINLINE of OptReuseAddr: SO_REUSEADDR -proc getSockOpt*(socket: PSocket, opt: TSOBool, level = SOL_SOCKET): bool {. - tags: [FReadIO].} = +proc getSockOpt*(socket: Socket, opt: SOBool, level = SOL_SOCKET): bool {. + tags: [ReadIOEffect].} = ## Retrieves option ``opt`` as a boolean value. - var res = getsockoptint(socket.fd, cint(level), toCInt(opt)) + var res = getSockOptInt(socket.fd, cint(level), toCInt(opt)) result = res != 0 -proc setSockOpt*(socket: PSocket, opt: TSOBool, value: bool, level = SOL_SOCKET) {. - tags: [FWriteIO].} = +proc setSockOpt*(socket: Socket, opt: SOBool, value: bool, level = SOL_SOCKET) {. + tags: [WriteIOEffect].} = ## Sets option ``opt`` to a boolean value specified by ``value``. var valuei = cint(if value: 1 else: 0) - setsockoptint(socket.fd, cint(level), toCInt(opt), valuei) + setSockOptInt(socket.fd, cint(level), toCInt(opt), valuei) -proc connect*(socket: PSocket, address: string, port = TPort(0), - af: TDomain = AF_INET) {.tags: [FReadIO].} = +proc connect*(socket: Socket, address: string, port = Port(0), + af: Domain = AF_INET) {.tags: [ReadIOEffect].} = ## Connects socket to ``address``:``port``. ``Address`` can be an IP address or a ## host name. If ``address`` is a host name, this function will try each IP ## of that host name. ``htons`` is already performed on ``port`` so you must @@ -443,17 +461,17 @@ proc connect*(socket: PSocket, address: string, port = TPort(0), var aiList = getAddrInfo(address, port, af) # try all possibilities: var success = false - var lastError: TOSErrorCode + var lastError: OSErrorCode var it = aiList while it != nil: - if connect(socket.fd, it.ai_addr, it.ai_addrlen.TSocklen) == 0'i32: + if connect(socket.fd, it.ai_addr, it.ai_addrlen.SockLen) == 0'i32: success = true break else: lastError = osLastError() it = it.ai_next dealloc(aiList) - if not success: osError(lastError) + if not success: raiseOSError(lastError) when defined(ssl): if socket.isSSL: @@ -477,19 +495,19 @@ when defined(ssl): var errret = SSLGetError(socket.sslHandle, ret) case errret of SSL_ERROR_ZERO_RETURN: - SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") + raiseSSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT, SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE: return false of SSL_ERROR_WANT_X509_LOOKUP: - SSLError("Function for x509 lookup has been called.") + raiseSSLError("Function for x509 lookup has been called.") of SSL_ERROR_SYSCALL, SSL_ERROR_SSL: - SSLError() + raiseSSLError() else: - SSLError("Unknown Error") + raiseSSLError("Unknown Error") socket.sslNoHandshake = false else: - SSLError("Socket is not an SSL socket.") + raiseSSLError("Socket is not an SSL socket.") proc gotHandshake*(socket: PSocket): bool = ## Determines whether a handshake has occurred between a client (``socket``) @@ -499,9 +517,9 @@ when defined(ssl): if socket.isSSL: return not socket.sslNoHandshake else: - SSLError("Socket is not an SSL socket.") + raiseSSLError("Socket is not an SSL socket.") -proc hasDataBuffered*(s: PSocket): bool = +proc hasDataBuffered*(s: Socket): bool = ## Determines whether a socket has data buffered. result = false if s.isBuffered: @@ -511,15 +529,15 @@ proc hasDataBuffered*(s: PSocket): bool = if s.isSSL and not result: result = s.sslHasPeekChar -proc select(readfd: PSocket, timeout = 500): int = +proc select(readfd: Socket, timeout = 500): int = ## Used for socket operation timeouts. if readfd.hasDataBuffered: return 1 - var fds = @[readFd.fd] + var fds = @[readfd.fd] result = select(fds, timeout) -proc readIntoBuf(socket: PSocket, flags: int32): int = +proc readIntoBuf(socket: Socket, flags: int32): int = result = 0 when defined(ssl): if socket.isSSL: @@ -543,7 +561,7 @@ template retRead(flags, readBytes: int) {.dirty.} = else: return res -proc recv*(socket: PSocket, data: pointer, size: int): int {.tags: [FReadIO].} = +proc recv*(socket: Socket, data: pointer, size: int): int {.tags: [ReadIOEffect].} = ## Receives data from a socket. ## ## **Note**: This is a low-level function, you may be interested in the higher @@ -584,8 +602,8 @@ proc recv*(socket: PSocket, data: pointer, size: int): int {.tags: [FReadIO].} = else: result = recv(socket.fd, data, size.cint, 0'i32) -proc waitFor(socket: PSocket, waited: var float, timeout, size: int, - funcName: string): int {.tags: [FTime].} = +proc waitFor(socket: Socket, waited: var float, timeout, size: int, + funcName: string): int {.tags: [TimeEffect].} = ## determines the amount of characters that can be read. Result will never ## be larger than ``size``. For unbuffered sockets this will be ``1``. ## For buffered sockets it can be as big as ``BufferSize``. @@ -600,7 +618,7 @@ proc waitFor(socket: PSocket, waited: var float, timeout, size: int, result = min(result, size) else: if timeout - int(waited * 1000.0) < 1: - raise newException(ETimeout, "Call to '" & funcName & "' timed out.") + raise newException(TimeoutError, "Call to '" & funcName & "' timed out.") when defined(ssl): if socket.isSSL: @@ -613,13 +631,13 @@ proc waitFor(socket: PSocket, waited: var float, timeout, size: int, var startTime = epochTime() let selRet = select(socket, timeout - int(waited * 1000.0)) - if selRet < 0: osError(osLastError()) + if selRet < 0: raiseOSError(osLastError()) if selRet != 1: - raise newException(ETimeout, "Call to '" & funcName & "' timed out.") + raise newException(TimeoutError, "Call to '" & funcName & "' timed out.") waited += (epochTime() - startTime) -proc recv*(socket: PSocket, data: pointer, size: int, timeout: int): int {. - tags: [FReadIO, FTime].} = +proc recv*(socket: Socket, data: pointer, size: int, timeout: int): int {. + tags: [ReadIOEffect, TimeEffect].} = ## overload with a ``timeout`` parameter in miliseconds. var waited = 0.0 # number of seconds already waited @@ -636,8 +654,8 @@ proc recv*(socket: PSocket, data: pointer, size: int, timeout: int): int {. result = read -proc recv*(socket: PSocket, data: var string, size: int, timeout = -1, - flags = {TSocketFlags.SafeDisconn}): int = +proc recv*(socket: Socket, data: var string, size: int, timeout = -1, + flags = {SocketFlag.SafeDisconn}): int = ## Higher-level version of ``recv``. ## ## When 0 is returned the socket's connection has been closed. @@ -660,7 +678,7 @@ proc recv*(socket: PSocket, data: var string, size: int, timeout = -1, socket.socketError(result, lastError = lastError) data.setLen(result) -proc peekChar(socket: PSocket, c: var char): int {.tags: [FReadIO].} = +proc peekChar(socket: Socket, c: var char): int {.tags: [ReadIOEffect].} = if socket.isBuffered: result = 1 if socket.bufLen == 0 or socket.currPos > socket.bufLen-1: @@ -680,9 +698,9 @@ proc peekChar(socket: PSocket, c: var char): int {.tags: [FReadIO].} = return result = recv(socket.fd, addr(c), 1, MSG_PEEK) -proc readLine*(socket: PSocket, line: var TaintedString, timeout = -1, - flags = {TSocketFlags.SafeDisconn}) {. - tags: [FReadIO, FTime].} = +proc readLine*(socket: Socket, line: var TaintedString, timeout = -1, + flags = {SocketFlag.SafeDisconn}) {. + tags: [ReadIOEffect, TimeEffect].} = ## Reads a line of data from ``socket``. ## ## If a full line is read ``\r\L`` is not @@ -729,9 +747,9 @@ proc readLine*(socket: PSocket, line: var TaintedString, timeout = -1, return add(line.string, c) -proc recvFrom*(socket: PSocket, data: var string, length: int, - address: var string, port: var TPort, flags = 0'i32): int {. - tags: [FReadIO].} = +proc recvFrom*(socket: Socket, data: var string, length: int, + address: var string, port: var Port, flags = 0'i32): int {. + tags: [ReadIOEffect].} = ## Receives data from ``socket``. This function should normally be used with ## connection-less sockets (UDP sockets). ## @@ -745,19 +763,19 @@ proc recvFrom*(socket: PSocket, data: var string, length: int, # TODO: Buffered sockets data.setLen(length) - var sockAddress: Tsockaddr_in - var addrLen = sizeof(sockAddress).TSocklen + var sockAddress: Sockaddr_in + var addrLen = sizeof(sockAddress).SockLen result = recvfrom(socket.fd, cstring(data), length.cint, flags.cint, - cast[ptr TSockAddr](addr(sockAddress)), addr(addrLen)) + cast[ptr SockAddr](addr(sockAddress)), addr(addrLen)) if result != -1: data.setLen(result) address = $inet_ntoa(sockAddress.sin_addr) - port = ntohs(sockAddress.sin_port).TPort + port = ntohs(sockAddress.sin_port).Port else: - osError(osLastError()) + raiseOSError(osLastError()) -proc skip*(socket: PSocket, size: int, timeout = -1) = +proc skip*(socket: Socket, size: int, timeout = -1) = ## Skips ``size`` amount of bytes. ## ## An optional timeout can be specified in miliseconds, if skipping the @@ -772,8 +790,8 @@ proc skip*(socket: PSocket, size: int, timeout = -1) = bytesSkipped += recv(socket, dummy, avail) dealloc(dummy) -proc send*(socket: PSocket, data: pointer, size: int): int {. - tags: [FWriteIO].} = +proc send*(socket: Socket, data: pointer, size: int): int {. + tags: [WriteIOEffect].} = ## Sends data to a socket. ## ## **Note**: This is a low-level version of ``send``. You likely should use @@ -789,8 +807,8 @@ proc send*(socket: PSocket, data: pointer, size: int): int {. const MSG_NOSIGNAL = 0 result = send(socket.fd, data, size, int32(MSG_NOSIGNAL)) -proc send*(socket: PSocket, data: string, - flags = {TSocketFlags.SafeDisconn}) {.tags: [FWriteIO].} = +proc send*(socket: Socket, data: string, + flags = {SocketFlag.SafeDisconn}) {.tags: [WriteIOEffect].} = ## sends data to a socket. let sent = send(socket, cstring(data), data.len) if sent < 0: @@ -799,16 +817,16 @@ proc send*(socket: PSocket, data: string, socketError(socket, lastError = lastError) if sent != data.len: - raise newException(EOS, "Could not send all data.") + raise newException(OSError, "Could not send all data.") -proc trySend*(socket: PSocket, data: string): bool {.tags: [FWriteIO].} = +proc trySend*(socket: Socket, data: string): bool {.tags: [WriteIOEffect].} = ## Safe alternative to ``send``. Does not raise an EOS when an error occurs, ## and instead returns ``false`` on failure. result = send(socket, cstring(data), data.len) == data.len -proc sendTo*(socket: PSocket, address: string, port: TPort, data: pointer, - size: int, af: TDomain = AF_INET, flags = 0'i32): int {. - tags: [FWriteIO].} = +proc sendTo*(socket: Socket, address: string, port: Port, data: pointer, + size: int, af: Domain = AF_INET, flags = 0'i32): int {. + tags: [WriteIOEffect].} = ## This proc sends ``data`` to the specified ``address``, ## which may be an IP address or a hostname, if a hostname is specified ## this function will try each IP of that hostname. @@ -825,7 +843,7 @@ proc sendTo*(socket: PSocket, address: string, port: TPort, data: pointer, var it = aiList while it != nil: result = sendto(socket.fd, data, size.cint, flags.cint, it.ai_addr, - it.ai_addrlen.TSocklen) + it.ai_addrlen.SockLen) if result != -1'i32: success = true break @@ -833,8 +851,8 @@ proc sendTo*(socket: PSocket, address: string, port: TPort, data: pointer, dealloc(aiList) -proc sendTo*(socket: PSocket, address: string, port: TPort, - data: string): int {.tags: [FWriteIO].} = +proc sendTo*(socket: Socket, address: string, port: Port, + data: string): int {.tags: [WriteIOEffect].} = ## This proc sends ``data`` to the specified ``address``, ## which may be an IP address or a hostname, if a hostname is specified ## this function will try each IP of that hostname. @@ -842,8 +860,8 @@ proc sendTo*(socket: PSocket, address: string, port: TPort, ## This is the high-level version of the above ``sendTo`` function. result = socket.sendTo(address, port, cstring(data), data.len) -proc connectAsync(socket: PSocket, name: string, port = TPort(0), - af: TDomain = AF_INET) {.tags: [FReadIO].} = +proc connectAsync(socket: Socket, name: string, port = Port(0), + af: Domain = AF_INET) {.tags: [ReadIOEffect].} = ## A variant of ``connect`` for non-blocking sockets. ## ## This procedure will immediatelly return, it will not block until a connection @@ -855,10 +873,10 @@ proc connectAsync(socket: PSocket, name: string, port = TPort(0), var aiList = getAddrInfo(name, port, af) # try all possibilities: var success = false - var lastError: TOSErrorCode + var lastError: OSErrorCode var it = aiList while it != nil: - var ret = connect(socket.fd, it.ai_addr, it.ai_addrlen.TSocklen) + var ret = connect(socket.fd, it.ai_addr, it.ai_addrlen.SockLen) if ret == 0'i32: success = true break @@ -877,10 +895,10 @@ proc connectAsync(socket: PSocket, name: string, port = TPort(0), it = it.ai_next dealloc(aiList) - if not success: osError(lastError) + if not success: raiseOSError(lastError) -proc connect*(socket: PSocket, address: string, port = TPort(0), timeout: int, - af: TDomain = AF_INET) {.tags: [FReadIO, FWriteIO].} = +proc connect*(socket: Socket, address: string, port = Port(0), timeout: int, + af: Domain = AF_INET) {.tags: [ReadIOEffect, WriteIOEffect].} = ## Connects to server as specified by ``address`` on port specified by ``port``. ## ## The ``timeout`` paremeter specifies the time in miliseconds to allow for @@ -890,7 +908,7 @@ proc connect*(socket: PSocket, address: string, port = TPort(0), timeout: int, socket.connectAsync(address, port, af) var s = @[socket.fd] if selectWrite(s, timeout) != 1: - raise newException(ETimeout, "Call to 'connect' timed out.") + raise newException(TimeoutError, "Call to 'connect' timed out.") else: when defined(ssl): if socket.isSSL: @@ -898,10 +916,10 @@ proc connect*(socket: PSocket, address: string, port = TPort(0), timeout: int, doAssert socket.handshake() socket.fd.setBlocking(true) -proc isSSL*(socket: PSocket): bool = return socket.isSSL +proc isSSL*(socket: Socket): bool = return socket.isSSL ## Determines whether ``socket`` is a SSL socket. -proc getFD*(socket: PSocket): TSocketHandle = return socket.fd +proc getFD*(socket: Socket): SocketHandle = return socket.fd ## Returns the socket's file descriptor type @@ -1036,23 +1054,23 @@ proc parseIPv4Address(address_str: string): TIpAddress = currentByte = currentByte * 10 + cast[uint16](ord(address_str[i]) - ord('0')) if currentByte > 255'u16: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. Value is out of range") seperatorValid = true elif address_str[i] == '.': # IPv4 address separator if not seperatorValid or byteCount >= 3: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. The address consists of too many groups") result.address_v4[byteCount] = cast[uint8](currentByte) currentByte = 0 byteCount.inc seperatorValid = false else: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. Address contains an invalid character") if byteCount != 3 or not seperatorValid: - raise newException(EInvalidValue, "Invalid IP Address") + raise newException(ValueError, "Invalid IP Address") result.address_v4[byteCount] = cast[uint8](currentByte) proc parseIPv6Address(address_str: string): TIpAddress = @@ -1060,7 +1078,7 @@ proc parseIPv6Address(address_str: string): TIpAddress = ## Raises EInvalidValue on errors result.family = IpAddressFamily.IPv6 if address_str.len < 2: - raise newException(EInvalidValue, "Invalid IP Address") + raise newException(ValueError, "Invalid IP Address") var groupCount = 0 @@ -1075,17 +1093,17 @@ proc parseIPv6Address(address_str: string): TIpAddress = for i,c in address_str: if c == ':': if not seperatorValid: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. Address contains an invalid seperator") if lastWasColon: if dualColonGroup != -1: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. Address contains more than one \"::\" seperator") dualColonGroup = groupCount seperatorValid = false elif i != 0 and i != high(address_str): if groupCount >= 8: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. The address consists of too many groups") result.address_v6[groupCount*2] = cast[uint8](currentShort shr 8) result.address_v6[groupCount*2+1] = cast[uint8](currentShort and 0xFF) @@ -1094,17 +1112,17 @@ proc parseIPv6Address(address_str: string): TIpAddress = if dualColonGroup != -1: seperatorValid = false elif i == 0: # only valid if address starts with :: if address_str[1] != ':': - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. Address may not start with \":\"") else: # i == high(address_str) - only valid if address ends with :: if address_str[high(address_str)-1] != ':': - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. Address may not end with \":\"") lastWasColon = true currentGroupStart = i + 1 elif c == '.': # Switch to parse IPv4 mode if i < 3 or not seperatorValid or groupCount >= 7: - raise newException(EInvalidValue, "Invalid IP Address") + raise newException(ValueError, "Invalid IP Address") v4StartPos = currentGroupStart currentShort = 0 seperatorValid = false @@ -1117,19 +1135,19 @@ proc parseIPv6Address(address_str: string): TIpAddress = else: # Upper case hex currentShort = (currentShort shl 4) + cast[uint32](ord(c) - ord('A')) + 10 if currentShort > 65535'u32: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. Value is out of range") lastWasColon = false seperatorValid = true else: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. Address contains an invalid character") if v4StartPos == -1: # Don't parse v4. Copy the remaining v6 stuff if seperatorValid: # Copy remaining data if groupCount >= 8: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. The address consists of too many groups") result.address_v6[groupCount*2] = cast[uint8](currentShort shr 8) result.address_v6[groupCount*2+1] = cast[uint8](currentShort and 0xFF) @@ -1139,32 +1157,32 @@ proc parseIPv6Address(address_str: string): TIpAddress = if c in strutils.Digits: # Character is a number currentShort = currentShort * 10 + cast[uint32](ord(c) - ord('0')) if currentShort > 255'u32: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. Value is out of range") seperatorValid = true elif c == '.': # IPv4 address separator if not seperatorValid or byteCount >= 3: - raise newException(EInvalidValue, "Invalid IP Address") + raise newException(ValueError, "Invalid IP Address") result.address_v6[groupCount*2 + byteCount] = cast[uint8](currentShort) currentShort = 0 byteCount.inc() seperatorValid = false else: # Invalid character - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. Address contains an invalid character") if byteCount != 3 or not seperatorValid: - raise newException(EInvalidValue, "Invalid IP Address") + raise newException(ValueError, "Invalid IP Address") result.address_v6[groupCount*2 + byteCount] = cast[uint8](currentShort) groupCount += 2 # Shift and fill zeros in case of :: if groupCount > 8: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. The address consists of too many groups") elif groupCount < 8: # must fill if dualColonGroup == -1: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. The address consists of too few groups") var toFill = 8 - groupCount # The number of groups to fill var toShift = groupCount - dualColonGroup # Nr of known groups after :: @@ -1173,14 +1191,14 @@ proc parseIPv6Address(address_str: string): TIpAddress = for i in 0..2*toFill-1: # fill with 0s result.address_v6[dualColonGroup*2+i] = 0 elif dualColonGroup != -1: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. The address consists of too many groups") proc parseIpAddress*(address_str: string): TIpAddress = ## Parses an IP address ## Raises EInvalidValue on error if address_str == nil: - raise newException(EInvalidValue, "IP Address string is nil") + raise newException(ValueError, "IP Address string is nil") if address_str.contains(':'): return parseIPv6Address(address_str) else: diff --git a/lib/pure/nimprof.nim b/lib/pure/nimprof.nim index 6f94d0656..3598cdd3a 100644 --- a/lib/pure/nimprof.nim +++ b/lib/pure/nimprof.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## Profiling support for Nimrod. This is an embedded profiler that requires +## Profiling support for Nim. This is an embedded profiler that requires ## ``--profiler:on``. You only need to import this module to get a profiling ## report at program exit. @@ -64,7 +64,7 @@ when withThreads: var profilingLock: TLock - InitLock profilingLock + initLock profilingLock proc hookAux(st: TStackTrace, costs: int) = # this is quite performance sensitive! @@ -132,9 +132,9 @@ else: proc hook(st: TStackTrace) {.nimcall.} = if interval == 0: hookAux(st, 1) - elif getticks() - t0 > interval: + elif getTicks() - t0 > interval: hookAux(st, 1) - t0 = getticks() + t0 = getTicks() proc getTotal(x: ptr TProfileEntry): int = result = if isNil(x): 0 else: x.total @@ -150,7 +150,7 @@ proc writeProfile() {.noconv.} = system.profilerHook = nil const filename = "profile_results.txt" echo "writing " & filename & "..." - var f: TFile + var f: File if open(f, filename, fmWrite): sort(profileData, cmpEntries) writeln(f, "total executions of each stack trace:") diff --git a/lib/pure/numeric.nim b/lib/pure/numeric.nim index 8ef5fabda..9b298c0a0 100644 --- a/lib/pure/numeric.nim +++ b/lib/pure/numeric.nim @@ -1,16 +1,17 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Robert Persson # # See the file "copying.txt", included in this # distribution, for details about the copyright. # +type OneVarFunction* = proc (x: float): float -type TOneVarFunction* =proc (x:float):float +{.deprecated: [TOneVarFunction: OneVarFunction].} -proc brent*(xmin,xmax:float ,function:TOneVarFunction, tol:float,maxiter=1000): +proc brent*(xmin,xmax:float, function:OneVarFunction, tol:float,maxiter=1000): tuple[rootx, rooty: float, success: bool]= ## Searches `function` for a root between `xmin` and `xmax` ## using brents method. If the function value at `xmin`and `xmax` has the diff --git a/lib/pure/oids.nim b/lib/pure/oids.nim index 2843e6c65..0dc8e3c15 100644 --- a/lib/pure/oids.nim +++ b/lib/pure/oids.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## Nimrod OID support. An OID is a global ID that consists of a timestamp, +## Nim OID support. An OID is a global ID that consists of a timestamp, ## a unique counter and a random value. This combination should suffice to ## produce a globally distributed unique ID. This implementation was extracted ## from the Mongodb interface and it thus binary compatible with a Mongo OID. @@ -18,11 +18,13 @@ import times, endians type - Toid* {.pure, final.} = object ## an OID + Oid* = object ## an OID time: int32 ## fuzz: int32 ## count: int32 ## +{.deprecated: [Toid: Oid].} + proc hexbyte*(hex: char): int = case hex of '0'..'9': result = (ord(hex) - ord('0')) @@ -30,7 +32,7 @@ proc hexbyte*(hex: char): int = of 'A'..'F': result = (ord(hex) - ord('A') + 10) else: discard -proc parseOid*(str: cstring): TOid = +proc parseOid*(str: cstring): Oid = ## parses an OID. var bytes = cast[cstring](addr(result.time)) var i = 0 @@ -38,7 +40,7 @@ proc parseOid*(str: cstring): TOid = bytes[i] = chr((hexbyte(str[2 * i]) shl 4) or hexbyte(str[2 * i + 1])) inc(i) -proc oidToString*(oid: TOid, str: cstring) = +proc oidToString*(oid: Oid, str: cstring) = const hex = "0123456789abcdef" # work around a compiler bug: var str = str @@ -52,15 +54,15 @@ proc oidToString*(oid: TOid, str: cstring) = inc(i) str[24] = '\0' -proc `$`*(oid: TOid): string = - result = newString(25) +proc `$`*(oid: Oid): string = + result = newString(24) oidToString(oid, result) var incr: int fuzz: int32 -proc genOid*(): TOid = +proc genOid*(): Oid = ## generates a new OID. proc rand(): cint {.importc: "rand", header: "<stdlib.h>", nodecl.} proc gettime(dummy: ptr cint): cint {.importc: "time", header: "<time.h>".} @@ -79,13 +81,13 @@ proc genOid*(): TOid = result.fuzz = fuzz bigEndian32(addr result.count, addr(i)) -proc generatedTime*(oid: TOid): TTime = +proc generatedTime*(oid: Oid): Time = ## returns the generated timestamp of the OID. var tmp: int32 var dummy = oid.time bigEndian32(addr(tmp), addr(dummy)) - result = TTime(tmp) + result = Time(tmp) when isMainModule: - let xo = genOID() + let xo = genOid() echo xo.generatedTime diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 71089494f..3a6930654 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -29,18 +29,23 @@ else: include "system/ansi_c" type - FReadEnv* = object of FReadIO ## effect that denotes a read - ## from an environment variable - FWriteEnv* = object of FWriteIO ## effect that denotes a write - ## to an environment variable - - FReadDir* = object of FReadIO ## effect that denotes a write operation to - ## the directory structure - FWriteDir* = object of FWriteIO ## effect that denotes a write operation to - ## the directory structure - - TOSErrorCode* = distinct int32 ## Specifies an OS Error Code. - + ReadEnvEffect* = object of ReadIOEffect ## effect that denotes a read + ## from an environment variable + WriteEnvEffect* = object of WriteIOEffect ## effect that denotes a write + ## to an environment variable + + ReadDirEffect* = object of ReadIOEffect ## effect that denotes a write + ## operation to the directory structure + WriteDirEffect* = object of WriteIOEffect ## effect that denotes a write operation to + ## the directory structure + + OSErrorCode* = distinct int32 ## Specifies an OS Error Code. + +{.deprecated: [FReadEnv: ReadEnvEffect, FWriteEnv: WriteEnvEffect, + FReadDir: ReadDirEffect, + FWriteDir: WriteDirEffect, + TOSErrorCode: OSErrorCode +].} const doslike = defined(windows) or defined(OS2) or defined(DOS) # DOS-like filesystem @@ -75,7 +80,7 @@ when defined(Nimdoc): # only for proper documentation: ## search patch components (as in PATH), such as ':' for POSIX or ';' for ## Windows. - FileSystemCaseSensitive* = True + FileSystemCaseSensitive* = true ## True if the file system is case sensitive, false otherwise. Used by ## `cmpPaths` to compare filenames properly. @@ -182,7 +187,7 @@ proc osErrorMsg*(): string {.rtl, extern: "nos$1", deprecated.} = ## On Windows ``GetLastError`` is checked before ``errno``. ## Returns "" if no error occured. ## - ## **Deprecated since version 0.9.4**: use the other ``OSErrorMsg`` proc. + ## **Deprecated since version 0.9.4**: use the other ``osErrorMsg`` proc. result = "" when defined(Windows): @@ -204,7 +209,8 @@ proc osErrorMsg*(): string {.rtl, extern: "nos$1", deprecated.} = result = $os.strerror(errno) {.push warning[deprecated]: off.} -proc osError*(msg: string = "") {.noinline, rtl, extern: "nos$1", deprecated.} = +proc raiseOSError*(msg: string = "") {.noinline, rtl, extern: "nos$1", + deprecated.} = ## raises an EOS exception with the given message ``msg``. ## If ``msg == ""``, the operating system's error flag ## (``errno``) is converted to a readable error message. On Windows @@ -214,15 +220,18 @@ proc osError*(msg: string = "") {.noinline, rtl, extern: "nos$1", deprecated.} = ## **Deprecated since version 0.9.4**: use the other ``OSError`` proc. if len(msg) == 0: var m = osErrorMsg() - raise newException(EOS, if m.len > 0: m else: "unknown OS error") + raise newException(OSError, if m.len > 0: m else: "unknown OS error") else: - raise newException(EOS, msg) + raise newException(OSError, msg) {.pop.} -proc `==`*(err1, err2: TOSErrorCode): bool {.borrow.} -proc `$`*(err: TOSErrorCode): string {.borrow.} +when not defined(nimfix): + {.deprecated: [osError: raiseOSError].} -proc osErrorMsg*(errorCode: TOSErrorCode): string = +proc `==`*(err1, err2: OSErrorCode): bool {.borrow.} +proc `$`*(err: OSErrorCode): string {.borrow.} + +proc osErrorMsg*(errorCode: OSErrorCode): string = ## Converts an OS error code into a human readable string. ## ## The error code can be retrieved using the ``OSLastError`` proc. @@ -235,7 +244,7 @@ proc osErrorMsg*(errorCode: TOSErrorCode): string = ## message. result = "" when defined(Windows): - if errorCode != TOSErrorCode(0'i32): + if errorCode != OSErrorCode(0'i32): when useWinUnicode: var msgbuf: WideCString if formatMessageW(0x00000100 or 0x00001000 or 0x00000200, @@ -249,10 +258,10 @@ proc osErrorMsg*(errorCode: TOSErrorCode): string = result = $msgbuf if msgbuf != nil: localFree(msgbuf) else: - if errorCode != TOSErrorCode(0'i32): + if errorCode != OSErrorCode(0'i32): result = $os.strerror(errorCode.int32) -proc osError*(errorCode: TOSErrorCode) = +proc raiseOSError*(errorCode: OSErrorCode) = ## Raises an ``EOS`` exception. The ``errorCode`` will determine the ## message, ``OSErrorMsg`` will be used to get this message. ## @@ -260,7 +269,7 @@ proc osError*(errorCode: TOSErrorCode) = ## ## If the error code is ``0`` or an error message could not be retrieved, ## the message ``unknown OS error`` will be used. - var e: ref EOS; new(e) + var e: ref OSError; new(e) e.errorCode = errorCode.int32 e.msg = osErrorMsg(errorCode) if e.msg == "": @@ -268,7 +277,7 @@ proc osError*(errorCode: TOSErrorCode) = raise e {.push stackTrace:off.} -proc osLastError*(): TOSErrorCode = +proc osLastError*(): OSErrorCode = ## Retrieves the last operating system error code. ## ## This procedure is useful in the event when an OS call fails. In that case @@ -283,9 +292,9 @@ proc osLastError*(): TOSErrorCode = ## immediately after an OS call fails. On POSIX systems this is not a problem. when defined(windows): - result = TOSErrorCode(getLastError()) + result = OSErrorCode(getLastError()) else: - result = TOSErrorCode(errno) + result = OSErrorCode(errno) {.pop.} proc unixToNativePath*(path: string, drive=""): string {. @@ -371,7 +380,7 @@ when defined(windows): f.cFileName[1].int == dot and f.cFileName[2].int == 0) proc existsFile*(filename: string): bool {.rtl, extern: "nos$1", - tags: [FReadDir].} = + tags: [ReadDirEffect].} = ## Returns true if the file exists, false otherwise. when defined(windows): when useWinUnicode: @@ -384,7 +393,7 @@ proc existsFile*(filename: string): bool {.rtl, extern: "nos$1", var res: TStat return stat(filename, res) >= 0'i32 and S_ISREG(res.st_mode) -proc existsDir*(dir: string): bool {.rtl, extern: "nos$1", tags: [FReadDir].} = +proc existsDir*(dir: string): bool {.rtl, extern: "nos$1", tags: [ReadDirEffect].} = ## Returns true iff the directory `dir` exists. If `dir` is a file, false ## is returned. when defined(windows): @@ -399,7 +408,7 @@ proc existsDir*(dir: string): bool {.rtl, extern: "nos$1", tags: [FReadDir].} = return stat(dir, res) >= 0'i32 and S_ISDIR(res.st_mode) proc symlinkExists*(link: string): bool {.rtl, extern: "nos$1", - tags: [FReadDir].} = + tags: [ReadDirEffect].} = ## Returns true iff the symlink `link` exists. Will return true ## regardless of whether the link points to a directory or file. when defined(windows): @@ -421,44 +430,44 @@ proc dirExists*(dir: string): bool {.inline.} = ## Synonym for existsDir existsDir(dir) -proc getLastModificationTime*(file: string): TTime {.rtl, extern: "nos$1".} = +proc getLastModificationTime*(file: string): Time {.rtl, extern: "nos$1".} = ## Returns the `file`'s last modification time. when defined(posix): var res: TStat - if stat(file, res) < 0'i32: osError(osLastError()) + if stat(file, res) < 0'i32: raiseOSError(osLastError()) return res.st_mtime else: var f: TWIN32_FIND_DATA var h = findFirstFile(file, f) - if h == -1'i32: osError(osLastError()) + if h == -1'i32: raiseOSError(osLastError()) result = winTimeToUnixTime(rdFileTime(f.ftLastWriteTime)) findClose(h) -proc getLastAccessTime*(file: string): TTime {.rtl, extern: "nos$1".} = +proc getLastAccessTime*(file: string): Time {.rtl, extern: "nos$1".} = ## Returns the `file`'s last read or write access time. when defined(posix): var res: TStat - if stat(file, res) < 0'i32: osError(osLastError()) + if stat(file, res) < 0'i32: raiseOSError(osLastError()) return res.st_atime else: var f: TWIN32_FIND_DATA var h = findFirstFile(file, f) - if h == -1'i32: osError(osLastError()) + if h == -1'i32: raiseOSError(osLastError()) result = winTimeToUnixTime(rdFileTime(f.ftLastAccessTime)) findClose(h) -proc getCreationTime*(file: string): TTime {.rtl, extern: "nos$1".} = +proc getCreationTime*(file: string): Time {.rtl, extern: "nos$1".} = ## Returns the `file`'s creation time. ## Note that under posix OS's, the returned time may actually be the time at ## which the file's attribute's were last modified. when defined(posix): var res: TStat - if stat(file, res) < 0'i32: osError(osLastError()) + if stat(file, res) < 0'i32: raiseOSError(osLastError()) return res.st_ctime else: var f: TWIN32_FIND_DATA var h = findFirstFile(file, f) - if h == -1'i32: osError(osLastError()) + if h == -1'i32: raiseOSError(osLastError()) result = winTimeToUnixTime(rdFileTime(f.ftCreationTime)) findClose(h) @@ -474,19 +483,19 @@ proc getCurrentDir*(): string {.rtl, extern: "nos$1", tags: [].} = when useWinUnicode: var res = newWideCString("", bufsize) var L = getCurrentDirectoryW(bufsize, res) - if L == 0'i32: osError(osLastError()) + if L == 0'i32: raiseOSError(osLastError()) result = res$L else: result = newString(bufsize) var L = getCurrentDirectoryA(bufsize, result) - if L == 0'i32: osError(osLastError()) + if L == 0'i32: raiseOSError(osLastError()) setLen(result, L) else: result = newString(bufsize) if getcwd(result, bufsize) != nil: setLen(result, c_strlen(result)) else: - osError(osLastError()) + raiseOSError(osLastError()) proc setCurrentDir*(newDir: string) {.inline, tags: [].} = ## Sets the `current working directory`:idx:; `EOS` is raised if @@ -494,11 +503,11 @@ proc setCurrentDir*(newDir: string) {.inline, tags: [].} = when defined(Windows): when useWinUnicode: if setCurrentDirectoryW(newWideCString(newDir)) == 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) else: - if setCurrentDirectoryA(newDir) == 0'i32: osError(osLastError()) + if setCurrentDirectoryA(newDir) == 0'i32: raiseOSError(osLastError()) else: - if chdir(newDir) != 0'i32: osError(osLastError()) + if chdir(newDir) != 0'i32: raiseOSError(osLastError()) proc joinPath*(head, tail: string): string {. noSideEffect, rtl, extern: "nos$1".} = @@ -506,12 +515,12 @@ proc joinPath*(head, tail: string): string {. ## ## For example on Unix: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## joinPath("usr", "lib") ## ## results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "usr/lib" ## ## If head is the empty string, tail is returned. If tail is the empty @@ -520,7 +529,7 @@ proc joinPath*(head, tail: string): string {. ## path separators not located on boundaries won't be modified. More ## examples on Unix: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## assert joinPath("usr", "") == "usr/" ## assert joinPath("", "lib") == "lib" ## assert joinPath("", "/lib") == "/lib" @@ -552,7 +561,7 @@ proc `/` * (head, tail: string): string {.noSideEffect.} = ## ## Here are some examples for Unix: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## assert "usr" / "" == "usr/" ## assert "" / "lib" == "lib" ## assert "" / "/lib" == "/lib" @@ -566,7 +575,7 @@ proc splitPath*(path: string): tuple[head, tail: string] {. ## ## Examples: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## splitPath("usr/local/bin") -> ("usr/local", "bin") ## splitPath("usr/local/bin/") -> ("usr/local/bin", "") ## splitPath("bin") -> ("", "bin") @@ -666,10 +675,10 @@ proc splitFile*(path: string): tuple[dir, name, ext: string] {. ## ## Example: ## - ## .. code-block:: nimrod - ## var (dir, name, ext) = splitFile("usr/local/nimrodc.html") + ## .. code-block:: nim + ## var (dir, name, ext) = splitFile("usr/local/nimc.html") ## assert dir == "usr/local" - ## assert name == "nimrodc" + ## assert name == "nimc" ## assert ext == ".html" ## ## If `path` has no extension, `ext` is the empty string. @@ -701,7 +710,7 @@ proc extractFilename*(path: string): string {. result = splitPath(path).tail proc expandFilename*(filename: string): string {.rtl, extern: "nos$1", - tags: [FReadDir].} = + tags: [ReadDirEffect].} = ## Returns the full path of `filename`, raises EOS in case of an error. when defined(windows): const bufsize = 3072'i32 @@ -710,19 +719,19 @@ proc expandFilename*(filename: string): string {.rtl, extern: "nos$1", var res = newWideCString("", bufsize div 2) var L = getFullPathNameW(newWideCString(filename), bufsize, res, unused) if L <= 0'i32 or L >= bufsize: - osError(osLastError()) + raiseOSError(osLastError()) result = res$L else: var unused: cstring result = newString(bufsize) var L = getFullPathNameA(filename, bufsize, result, unused) - if L <= 0'i32 or L >= bufsize: osError(osLastError()) + if L <= 0'i32 or L >= bufsize: raiseOSError(osLastError()) setLen(result, L) else: # careful, realpath needs to take an allocated buffer according to Posix: result = newString(pathMax) var r = realpath(filename, result) - if r.isNil: osError(osLastError()) + if r.isNil: raiseOSError(osLastError()) setLen(result, c_strlen(result)) proc changeFileExt*(filename, ext: string): string {. @@ -800,7 +809,7 @@ when defined(Windows): ) proc sameFile*(path1, path2: string): bool {.rtl, extern: "nos$1", - tags: [FReadDir].} = + tags: [ReadDirEffect].} = ## Returns True if both pathname arguments refer to the same physical ## file or directory. Raises an exception if any of the files does not ## exist or information about it can not be obtained. @@ -812,7 +821,7 @@ proc sameFile*(path1, path2: string): bool {.rtl, extern: "nos$1", var f1 = openHandle(path1) var f2 = openHandle(path2) - var lastErr: TOSErrorCode + var lastErr: OSErrorCode if f1 != INVALID_HANDLE_VALUE and f2 != INVALID_HANDLE_VALUE: var fi1, fi2: TBY_HANDLE_FILE_INFORMATION @@ -831,22 +840,22 @@ proc sameFile*(path1, path2: string): bool {.rtl, extern: "nos$1", discard closeHandle(f1) discard closeHandle(f2) - if not success: osError(lastErr) + if not success: raiseOSError(lastErr) else: var a, b: TStat if stat(path1, a) < 0'i32 or stat(path2, b) < 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) else: result = a.st_dev == b.st_dev and a.st_ino == b.st_ino proc sameFileContent*(path1, path2: string): bool {.rtl, extern: "nos$1", - tags: [FReadIO].} = + tags: [ReadIOEffect].} = ## Returns True if both pathname arguments refer to files with identical ## binary content. const bufSize = 8192 # 8K buffer var - a, b: TFile + a, b: File if not open(a, path1): return false if not open(b, path2): close(a) @@ -883,13 +892,13 @@ type fpOthersRead ## read access for others proc getFilePermissions*(filename: string): set[TFilePermission] {. - rtl, extern: "nos$1", tags: [FReadDir].} = + rtl, extern: "nos$1", tags: [ReadDirEffect].} = ## retrieves file permissions for `filename`. `OSError` is raised in case of ## an error. On Windows, only the ``readonly`` flag is checked, every other ## permission is available in any case. when defined(posix): var a: TStat - if stat(filename, a) < 0'i32: osError(osLastError()) + if stat(filename, a) < 0'i32: raiseOSError(osLastError()) result = {} if (a.st_mode and S_IRUSR) != 0'i32: result.incl(fpUserRead) if (a.st_mode and S_IWUSR) != 0'i32: result.incl(fpUserWrite) @@ -907,7 +916,7 @@ proc getFilePermissions*(filename: string): set[TFilePermission] {. wrapUnary(res, getFileAttributesW, filename) else: var res = getFileAttributesA(filename) - if res == -1'i32: osError(osLastError()) + if res == -1'i32: raiseOSError(osLastError()) if (res and FILE_ATTRIBUTE_READONLY) != 0'i32: result = {fpUserExec, fpUserRead, fpGroupExec, fpGroupRead, fpOthersExec, fpOthersRead} @@ -915,7 +924,7 @@ proc getFilePermissions*(filename: string): set[TFilePermission] {. result = {fpUserExec..fpOthersRead} proc setFilePermissions*(filename: string, permissions: set[TFilePermission]) {. - rtl, extern: "nos$1", tags: [FWriteDir].} = + rtl, extern: "nos$1", tags: [WriteDirEffect].} = ## sets the file permissions for `filename`. `OSError` is raised in case of ## an error. On Windows, only the ``readonly`` flag is changed, depending on ## ``fpUserWrite``. @@ -933,13 +942,13 @@ proc setFilePermissions*(filename: string, permissions: set[TFilePermission]) {. if fpOthersWrite in permissions: p = p or S_IWOTH if fpOthersExec in permissions: p = p or S_IXOTH - if chmod(filename, p) != 0: osError(osLastError()) + if chmod(filename, p) != 0: raiseOSError(osLastError()) else: when useWinUnicode: wrapUnary(res, getFileAttributesW, filename) else: var res = getFileAttributesA(filename) - if res == -1'i32: osError(osLastError()) + if res == -1'i32: raiseOSError(osLastError()) if fpUserWrite in permissions: res = res and not FILE_ATTRIBUTE_READONLY else: @@ -948,10 +957,10 @@ proc setFilePermissions*(filename: string, permissions: set[TFilePermission]) {. wrapBinary(res2, setFileAttributesW, filename, res) else: var res2 = setFileAttributesA(filename, res) - if res2 == - 1'i32: osError(osLastError()) + if res2 == - 1'i32: raiseOSError(osLastError()) proc copyFile*(source, dest: string) {.rtl, extern: "nos$1", - tags: [FReadIO, FWriteIO].} = + tags: [ReadIOEffect, WriteIOEffect].} = ## Copies a file from `source` to `dest`. ## ## If this fails, `EOS` is raised. On the Windows platform this proc will @@ -966,17 +975,17 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1", when useWinUnicode: let s = newWideCString(source) let d = newWideCString(dest) - if copyFileW(s, d, 0'i32) == 0'i32: osError(osLastError()) + if copyFileW(s, d, 0'i32) == 0'i32: raiseOSError(osLastError()) else: - if copyFileA(source, dest, 0'i32) == 0'i32: osError(osLastError()) + if copyFileA(source, dest, 0'i32) == 0'i32: raiseOSError(osLastError()) else: # generic version of copyFile which works for any platform: const bufSize = 8000 # better for memory manager - var d, s: TFile - if not open(s, source): osError(osLastError()) + var d, s: File + if not open(s, source): raiseOSError(osLastError()) if not open(d, dest, fmWrite): close(s) - osError(osLastError()) + raiseOSError(osLastError()) var buf = alloc(bufSize) while true: var bytesread = readBuffer(s, buf, bufSize) @@ -986,17 +995,17 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1", dealloc(buf) close(s) close(d) - osError(osLastError()) + raiseOSError(osLastError()) if bytesread != bufSize: break dealloc(buf) close(s) close(d) proc moveFile*(source, dest: string) {.rtl, extern: "nos$1", - tags: [FReadIO, FWriteIO].} = + tags: [ReadIOEffect, WriteIOEffect].} = ## Moves a file from `source` to `dest`. If this fails, `EOS` is raised. if c_rename(source, dest) != 0'i32: - raise newException(EOS, $strerror(errno)) + raise newException(OSError, $strerror(errno)) when not declared(ENOENT) and not defined(Windows): when NoFakeVars: @@ -1014,7 +1023,7 @@ when defined(Windows): template setFileAttributes(file, attrs: expr): expr {.immediate.} = setFileAttributesA(file, attrs) -proc removeFile*(file: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} = +proc removeFile*(file: string) {.rtl, extern: "nos$1", tags: [WriteDirEffect].} = ## Removes the `file`. If this fails, `EOS` is raised. This does not fail ## if the file never existed in the first place. ## On Windows, ignores the read-only attribute. @@ -1026,15 +1035,15 @@ proc removeFile*(file: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} = if deleteFile(f) == 0: if getLastError() == ERROR_ACCESS_DENIED: if setFileAttributes(f, FILE_ATTRIBUTE_NORMAL) == 0: - osError(osLastError()) + raiseOSError(osLastError()) if deleteFile(f) == 0: - osError(osLastError()) + raiseOSError(osLastError()) else: if c_remove(file) != 0'i32 and errno != ENOENT: - raise newException(EOS, $strerror(errno)) + raise newException(OSError, $strerror(errno)) proc execShellCmd*(command: string): int {.rtl, extern: "nos$1", - tags: [FExecIO].} = + tags: [ExecIOEffect].} = ## Executes a `shell command`:idx:. ## ## Command has the form 'program args' where args are the command @@ -1076,7 +1085,7 @@ when defined(windows): while true: var eend = strEnd(e) add(environment, $e) - e = cast[WideCString](cast[TAddress](eend)+2) + e = cast[WideCString](cast[ByteAddress](eend)+2) if eend[1].int == 0: break discard freeEnvironmentStringsW(env) else: @@ -1087,7 +1096,7 @@ when defined(windows): while true: var eend = strEnd(e) add(environment, $e) - e = cast[cstring](cast[TAddress](eend)+1) + e = cast[cstring](cast[ByteAddress](eend)+1) if eend[1] == '\0': break discard freeEnvironmentStringsA(env) envComputed = true @@ -1130,7 +1139,7 @@ proc findEnvVar(key: string): int = if startsWith(environment[i], temp): return i return -1 -proc getEnv*(key: string): TaintedString {.tags: [FReadEnv].} = +proc getEnv*(key: string): TaintedString {.tags: [ReadEnvEffect].} = ## Returns the value of the `environment variable`:idx: named `key`. ## ## If the variable does not exist, "" is returned. To distinguish @@ -1144,13 +1153,13 @@ proc getEnv*(key: string): TaintedString {.tags: [FReadEnv].} = if env == nil: return TaintedString("") result = TaintedString($env) -proc existsEnv*(key: string): bool {.tags: [FReadEnv].} = +proc existsEnv*(key: string): bool {.tags: [ReadEnvEffect].} = ## Checks whether the environment variable named `key` exists. ## Returns true if it exists, false otherwise. if c_getenv(key) != nil: return true else: return findEnvVar(key) >= 0 -proc putEnv*(key, val: string) {.tags: [FWriteEnv].} = +proc putEnv*(key, val: string) {.tags: [WriteEnvEffect].} = ## Sets the value of the `environment variable`:idx: named `key` to `val`. ## If an error occurs, `EInvalidEnvVar` is raised. @@ -1166,16 +1175,16 @@ proc putEnv*(key, val: string) {.tags: [FWriteEnv].} = indx = high(environment) when defined(unix): if c_putenv(environment[indx]) != 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) else: when useWinUnicode: var k = newWideCString(key) var v = newWideCString(val) - if setEnvironmentVariableW(k, v) == 0'i32: osError(osLastError()) + if setEnvironmentVariableW(k, v) == 0'i32: raiseOSError(osLastError()) else: - if setEnvironmentVariableA(key, val) == 0'i32: osError(osLastError()) + if setEnvironmentVariableA(key, val) == 0'i32: raiseOSError(osLastError()) -iterator envPairs*(): tuple[key, value: TaintedString] {.tags: [FReadEnv].} = +iterator envPairs*(): tuple[key, value: TaintedString] {.tags: [ReadEnvEffect].} = ## Iterate over all `environments variables`:idx:. In the first component ## of the tuple is the name of the current variable stored, in the second ## its value. @@ -1185,7 +1194,7 @@ iterator envPairs*(): tuple[key, value: TaintedString] {.tags: [FReadEnv].} = yield (TaintedString(substr(environment[i], 0, p-1)), TaintedString(substr(environment[i], p+1))) -iterator walkFiles*(pattern: string): string {.tags: [FReadDir].} = +iterator walkFiles*(pattern: string): string {.tags: [ReadDirEffect].} = ## Iterate over all the files that match the `pattern`. On POSIX this uses ## the `glob`:idx: call. ## @@ -1225,7 +1234,7 @@ type pcLinkToDir ## path refers to a symbolic link to a directory iterator walkDir*(dir: string): tuple[kind: TPathComponent, path: string] {. - tags: [FReadDir].} = + tags: [ReadDirEffect].} = ## walks over the directory `dir` and yields for each directory or file in ## `dir`. The component type and full path for each item is returned. ## Walking is not recursive. @@ -1237,7 +1246,7 @@ iterator walkDir*(dir: string): tuple[kind: TPathComponent, path: string] {. ## ## and this code: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## for kind, path in walkDir("dirA"): ## echo(path) ## @@ -1278,7 +1287,7 @@ iterator walkDir*(dir: string): tuple[kind: TPathComponent, path: string] {. discard closedir(d) iterator walkDirRec*(dir: string, filter={pcFile, pcDir}): string {. - tags: [FReadDir].} = + tags: [ReadDirEffect].} = ## walks over the directory `dir` and yields for each file in `dir`. The ## full path for each file is returned. ## **Warning**: @@ -1313,12 +1322,12 @@ proc rawRemoveDir(dir: string) = let lastError = osLastError() if res == 0'i32 and lastError.int32 != 3'i32 and lastError.int32 != 18'i32 and lastError.int32 != 2'i32: - osError(lastError) + raiseOSError(lastError) else: - if rmdir(dir) != 0'i32 and errno != ENOENT: osError(osLastError()) + if rmdir(dir) != 0'i32 and errno != ENOENT: raiseOSError(osLastError()) proc removeDir*(dir: string) {.rtl, extern: "nos$1", tags: [ - FWriteDir, FReadDir].} = + WriteDirEffect, ReadDirEffect].} = ## Removes the directory `dir` including all subdirectories and files ## in `dir` (recursively). ## @@ -1333,19 +1342,19 @@ proc removeDir*(dir: string) {.rtl, extern: "nos$1", tags: [ proc rawCreateDir(dir: string) = when defined(solaris): if mkdir(dir, 0o777) != 0'i32 and errno != EEXIST and errno != ENOSYS: - osError(osLastError()) + raiseOSError(osLastError()) elif defined(unix): if mkdir(dir, 0o777) != 0'i32 and errno != EEXIST: - osError(osLastError()) + raiseOSError(osLastError()) else: when useWinUnicode: wrapUnary(res, createDirectoryW, dir) else: var res = createDirectoryA(dir) if res == 0'i32 and getLastError() != 183'i32: - osError(osLastError()) + raiseOSError(osLastError()) -proc createDir*(dir: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} = +proc createDir*(dir: string) {.rtl, extern: "nos$1", tags: [WriteDirEffect].} = ## Creates the `directory`:idx: `dir`. ## ## The directory may contain several subdirectories that do not exist yet. @@ -1364,7 +1373,7 @@ proc createDir*(dir: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} = rawCreateDir(dir) proc copyDir*(source, dest: string) {.rtl, extern: "nos$1", - tags: [FWriteIO, FReadIO].} = + tags: [WriteIOEffect, ReadIOEffect].} = ## Copies a directory from `source` to `dest`. ## ## If this fails, `EOS` is raised. On the Windows platform this proc will @@ -1395,13 +1404,13 @@ proc createSymlink*(src, dest: string) = var wSrc = newWideCString(src) var wDst = newWideCString(dest) if createSymbolicLinkW(wDst, wSrc, flag) == 0 or getLastError() != 0: - osError(osLastError()) + raiseOSError(osLastError()) else: if createSymbolicLinkA(dest, src, flag) == 0 or getLastError() != 0: - osError(osLastError()) + raiseOSError(osLastError()) else: if symlink(src, dest) != 0: - osError(osLastError()) + raiseOSError(osLastError()) proc createHardlink*(src, dest: string) = ## Create a hard link at `dest` which points to the item specified @@ -1414,13 +1423,13 @@ proc createHardlink*(src, dest: string) = var wSrc = newWideCString(src) var wDst = newWideCString(dest) if createHardLinkW(wDst, wSrc, nil) == 0: - osError(osLastError()) + raiseOSError(osLastError()) else: if createHardLinkA(dest, src, nil) == 0: - osError(osLastError()) + raiseOSError(osLastError()) else: if link(src, dest) != 0: - osError(osLastError()) + raiseOSError(osLastError()) proc parseCmdLine*(c: string): seq[string] {. noSideEffect, rtl, extern: "nos$1".} = @@ -1537,7 +1546,7 @@ proc copyFileWithPermissions*(source, dest: string, proc copyDirWithPermissions*(source, dest: string, ignorePermissionErrors = true) {.rtl, extern: "nos$1", - tags: [FWriteIO, FReadIO].} = + tags: [WriteIOEffect, ReadIOEffect].} = ## Copies a directory from `source` to `dest` preserving file permissions. ## ## If this fails, `EOS` is raised. This is a wrapper proc around `copyDir() @@ -1568,23 +1577,23 @@ proc copyDirWithPermissions*(source, dest: string, proc inclFilePermissions*(filename: string, permissions: set[TFilePermission]) {. - rtl, extern: "nos$1", tags: [FReadDir, FWriteDir].} = + rtl, extern: "nos$1", tags: [ReadDirEffect, WriteDirEffect].} = ## a convenience procedure for: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## setFilePermissions(filename, getFilePermissions(filename)+permissions) setFilePermissions(filename, getFilePermissions(filename)+permissions) proc exclFilePermissions*(filename: string, permissions: set[TFilePermission]) {. - rtl, extern: "nos$1", tags: [FReadDir, FWriteDir].} = + rtl, extern: "nos$1", tags: [ReadDirEffect, WriteDirEffect].} = ## a convenience procedure for: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## setFilePermissions(filename, getFilePermissions(filename)-permissions) setFilePermissions(filename, getFilePermissions(filename)-permissions) -proc getHomeDir*(): string {.rtl, extern: "nos$1", tags: [FReadEnv].} = +proc getHomeDir*(): string {.rtl, extern: "nos$1", tags: [ReadEnvEffect].} = ## Returns the home directory of the current user. ## ## This proc is wrapped by the expandTilde proc for the convenience of @@ -1592,12 +1601,12 @@ proc getHomeDir*(): string {.rtl, extern: "nos$1", tags: [FReadEnv].} = when defined(windows): return string(getEnv("USERPROFILE")) & "\\" else: return string(getEnv("HOME")) & "/" -proc getConfigDir*(): string {.rtl, extern: "nos$1", tags: [FReadEnv].} = +proc getConfigDir*(): string {.rtl, extern: "nos$1", tags: [ReadEnvEffect].} = ## Returns the config directory of the current user for applications. when defined(windows): return string(getEnv("APPDATA")) & "\\" else: return string(getEnv("HOME")) & "/.config/" -proc getTempDir*(): string {.rtl, extern: "nos$1", tags: [FReadEnv].} = +proc getTempDir*(): string {.rtl, extern: "nos$1", tags: [ReadEnvEffect].} = ## Returns the temporary directory of the current user for applications to ## save temporary files in. when defined(windows): return string(getEnv("TEMP")) & "\\" @@ -1605,7 +1614,7 @@ proc getTempDir*(): string {.rtl, extern: "nos$1", tags: [FReadEnv].} = when defined(nimdoc): # Common forward declaration docstring block for parameter retrieval procs. - proc paramCount*(): int {.tags: [FReadIO].} = + proc paramCount*(): int {.tags: [ReadIOEffect].} = ## Returns the number of `command line arguments`:idx: given to the ## application. ## @@ -1619,13 +1628,13 @@ when defined(nimdoc): ## can test for its availability with `declared() <system.html#declared>`_. ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## when declared(paramCount): ## # Use paramCount() here ## else: ## # Do something else! - proc paramStr*(i: int): TaintedString {.tags: [FReadIO].} = + proc paramStr*(i: int): TaintedString {.tags: [ReadIOEffect].} = ## Returns the `i`-th `command line argument`:idx: given to the application. ## ## `i` should be in the range `1..paramCount()`, the `EInvalidIndex` @@ -1642,14 +1651,14 @@ when defined(nimdoc): ## can test for its availability with `declared() <system.html#declared>`_. ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## when declared(paramStr): ## # Use paramStr() here ## else: ## # Do something else! elif defined(windows): - # Since we support GUI applications with Nimrod, we sometimes generate + # Since we support GUI applications with Nim, we sometimes generate # a WinMain entry proc. But a WinMain proc has no access to the parsed # command line arguments. The way to get them differs. Thus we parse them # ourselves. This has the additional benefit that the program's behaviour @@ -1657,13 +1666,13 @@ elif defined(windows): var ownArgv {.threadvar.}: seq[string] - proc paramCount*(): int {.rtl, extern: "nos$1", tags: [FReadIO].} = + proc paramCount*(): int {.rtl, extern: "nos$1", tags: [ReadIOEffect].} = # Docstring in nimdoc block. if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLine()) result = ownArgv.len-1 proc paramStr*(i: int): TaintedString {.rtl, extern: "nos$1", - tags: [FReadIO].} = + tags: [ReadIOEffect].} = # Docstring in nimdoc block. if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLine()) return TaintedString(ownArgv[i]) @@ -1674,12 +1683,12 @@ elif not defined(createNimRtl): cmdCount {.importc: "cmdCount".}: cint cmdLine {.importc: "cmdLine".}: cstringArray - proc paramStr*(i: int): TaintedString {.tags: [FReadIO].} = + proc paramStr*(i: int): TaintedString {.tags: [ReadIOEffect].} = # Docstring in nimdoc block. if i < cmdCount and i >= 0: return TaintedString($cmdLine[i]) - raise newException(EInvalidIndex, "invalid index") + raise newException(IndexError, "invalid index") - proc paramCount*(): int {.tags: [FReadIO].} = + proc paramCount*(): int {.tags: [ReadIOEffect].} = # Docstring in nimdoc block. result = cmdCount-1 @@ -1695,7 +1704,7 @@ when declared(paramCount) or defined(nimdoc): ## can test for its availability with `declared() <system.html#declared>`_. ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## when declared(commandLineParams): ## # Use commandLineParams() here ## else: @@ -1739,7 +1748,7 @@ when defined(macosx): proc getExecPath2(c: cstring, size: var cuint32): bool {. importc: "_NSGetExecutablePath", header: "<mach-o/dyld.h>".} -proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [FReadIO].} = +proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [ReadIOEffect].} = ## Returns the filename of the application's executable. ## ## This procedure will resolve symlinks. @@ -1795,38 +1804,38 @@ proc getApplicationDir*(): string {.rtl, extern: "nos$1", deprecated.} = ## instead. result = splitFile(getAppFilename()).dir -proc getAppDir*(): string {.rtl, extern: "nos$1", tags: [FReadIO].} = +proc getAppDir*(): string {.rtl, extern: "nos$1", tags: [ReadIOEffect].} = ## Returns the directory of the application's executable. ## **Note**: This does not work reliably on BSD. result = splitFile(getAppFilename()).dir -proc sleep*(milsecs: int) {.rtl, extern: "nos$1", tags: [FTime].} = +proc sleep*(milsecs: int) {.rtl, extern: "nos$1", tags: [TimeEffect].} = ## sleeps `milsecs` milliseconds. when defined(windows): winlean.sleep(int32(milsecs)) else: var a, b: Ttimespec - a.tv_sec = TTime(milsecs div 1000) + a.tv_sec = Time(milsecs div 1000) a.tv_nsec = (milsecs mod 1000) * 1000 * 1000 discard posix.nanosleep(a, b) proc getFileSize*(file: string): BiggestInt {.rtl, extern: "nos$1", - tags: [FReadIO].} = + tags: [ReadIOEffect].} = ## returns the file size of `file`. Can raise ``EOS``. when defined(windows): var a: TWIN32_FIND_DATA var resA = findFirstFile(file, a) - if resA == -1: osError(osLastError()) + if resA == -1: raiseOSError(osLastError()) result = rdFileSize(a) findClose(resA) else: - var f: TFile + var f: File if open(f, file): result = getFileSize(f) close(f) - else: osError(osLastError()) + else: raiseOSError(osLastError()) -proc findExe*(exe: string): string {.tags: [FReadDir, FReadEnv].} = +proc findExe*(exe: string): string {.tags: [ReadDirEffect, ReadEnvEffect].} = ## Searches for `exe` in the current working directory and then ## in directories listed in the ``PATH`` environment variable. ## Returns "" if the `exe` cannot be found. On DOS-like platforms, `exe` @@ -1850,11 +1859,10 @@ proc expandTilde*(path: string): string = ## The behaviour of this proc is the same on the Windows platform despite not ## having this convention. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## let configFile = expandTilde("~" / "appname.cfg") ## echo configFile ## # --> C:\Users\amber\appname.cfg - if len(path) > 1 and path[0] == '~' and (path[1] == '/' or path[1] == '\\'): result = getHomeDir() / path[2..len(path)-1] else: @@ -1867,7 +1875,7 @@ when defined(Windows): else: type DeviceId* = TDev - FileId* = TIno + FileId* = Tino type FileInfo* = object @@ -1877,12 +1885,12 @@ type size*: BiggestInt # Size of file. permissions*: set[TFilePermission] # File permissions linkCount*: BiggestInt # Number of hard links the file object has. - lastAccessTime*: TTime # Time file was last accessed. - lastWriteTime*: TTime # Time file was last modified/written to. - creationTime*: TTime # Time file was created. Not supported on all systems! + lastAccessTime*: Time # Time file was last accessed. + lastWriteTime*: Time # Time file was last modified/written to. + creationTime*: Time # Time file was created. Not supported on all systems! template rawToFormalFileInfo(rawInfo, formalInfo): expr = - ## Transforms the native file info structure into the one nimrod uses. + ## Transforms the native file info structure into the one nim uses. ## 'rawInfo' is either a 'TBY_HANDLE_FILE_INFORMATION' structure on Windows, ## or a 'TStat' structure on posix when defined(Windows): @@ -1939,7 +1947,7 @@ template rawToFormalFileInfo(rawInfo, formalInfo): expr = if S_ISDIR(rawInfo.st_mode): formalInfo.kind = pcDir if S_ISLNK(rawInfo.st_mode): formalInfo.kind.inc() -proc getFileInfo*(handle: TFileHandle): FileInfo = +proc getFileInfo*(handle: FileHandle): FileInfo = ## Retrieves file information for the file object represented by the given ## handle. ## @@ -1952,16 +1960,16 @@ proc getFileInfo*(handle: TFileHandle): FileInfo = # To transform the C file descripter to a native file handle. var realHandle = get_osfhandle(handle) if getFileInformationByHandle(realHandle, addr rawInfo) == 0: - osError(osLastError()) + raiseOSError(osLastError()) rawToFormalFileInfo(rawInfo, result) else: var rawInfo: TStat if fstat(handle, rawInfo) < 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) rawToFormalFileInfo(rawInfo, result) -proc getFileInfo*(file: TFile): FileInfo = - result = getFileInfo(file.fileHandle()) +proc getFileInfo*(file: File): FileInfo = + result = getFileInfo(file.getFileHandle()) proc getFileInfo*(path: string, followSymlink = true): FileInfo = ## Retrieves file information for the file object pointed to by `path`. @@ -1982,19 +1990,19 @@ proc getFileInfo*(path: string, followSymlink = true): FileInfo = handle = openHandle(path, followSymlink) rawInfo: TBY_HANDLE_FILE_INFORMATION if handle == INVALID_HANDLE_VALUE: - osError(osLastError()) + raiseOSError(osLastError()) if getFileInformationByHandle(handle, addr rawInfo) == 0: - osError(osLastError()) + raiseOSError(osLastError()) rawToFormalFileInfo(rawInfo, result) discard closeHandle(handle) else: var rawInfo: TStat if followSymlink: if lstat(path, rawInfo) < 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) else: if stat(path, rawInfo) < 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) rawToFormalFileInfo(rawInfo, result) proc isHidden*(path: string): bool = @@ -2006,7 +2014,10 @@ proc isHidden*(path: string): bool = ## On Unix-like systems, a file is hidden if it starts with a '.' (period) ## and is not *just* '.' or '..' ' ." when defined(Windows): - wrapUnary(attributes, getFileAttributesW, path) + when useWinUnicode: + wrapUnary(attributes, getFileAttributesW, path) + else: + var attributes = getFileAttributesA(path) if attributes != -1'i32: result = (attributes and FILE_ATTRIBUTE_HIDDEN) != 0'i32 else: diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 4384cd7d2..3963497fd 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -24,20 +24,20 @@ when defined(linux): import linux type - TProcess = object of TObject + ProcessObj = object of RootObj when defined(windows): fProcessHandle: THandle - inHandle, outHandle, errHandle: TFileHandle + inHandle, outHandle, errHandle: FileHandle id: THandle else: - inHandle, outHandle, errHandle: TFileHandle - inStream, outStream, errStream: PStream + inHandle, outHandle, errHandle: FileHandle + inStream, outStream, errStream: Stream id: TPid exitCode: cint - PProcess* = ref TProcess ## represents an operating system process + Process* = ref ProcessObj ## represents an operating system process - TProcessOption* = enum ## options that can be passed `startProcess` + ProcessOption* = enum ## options that can be passed `startProcess` poEchoCmd, ## echo the command before execution poUsePath, ## Asks system to search for executable using PATH environment ## variable. @@ -47,6 +47,9 @@ type poStdErrToStdOut, ## merge stdout and stderr to the stdout stream poParentStreams ## use the parent's streams +{.deprecated: [TProcess: ProcessObj, PProcess: Process, + TProcessOption: ProcessOption].} + const poUseShell* {.deprecated.} = poUsePath ## Deprecated alias for poUsePath. @@ -103,19 +106,19 @@ proc quoteShell*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".} = {.error:"quoteShell is not supported on your system".} proc execProcess*(command: string, - args: openarray[string] = [], - env: PStringTable = nil, - options: set[TProcessOption] = {poStdErrToStdOut, + args: openArray[string] = [], + env: StringTableRef = nil, + options: set[ProcessOption] = {poStdErrToStdOut, poUsePath, poEvalCommand}): TaintedString {. rtl, extern: "nosp$1", - tags: [FExecIO, FReadIO].} + tags: [ExecIOEffect, ReadIOEffect].} ## A convenience procedure that executes ``command`` with ``startProcess`` ## and returns its output as a string. ## WARNING: this function uses poEvalCommand by default for backward compatibility. ## Make sure to pass options explicitly. -proc execCmd*(command: string): int {.rtl, extern: "nosp$1", tags: [FExecIO].} +proc execCmd*(command: string): int {.rtl, extern: "nosp$1", tags: [ExecIOEffect].} ## Executes ``command`` and returns its error code. Standard input, output, ## error streams are inherited from the calling process. This operation ## is also often called `system`:idx:. @@ -123,9 +126,9 @@ proc execCmd*(command: string): int {.rtl, extern: "nosp$1", tags: [FExecIO].} proc startProcess*(command: string, workingDir: string = "", args: openArray[string] = [], - env: PStringTable = nil, - options: set[TProcessOption] = {poStdErrToStdOut}): - PProcess {.rtl, extern: "nosp$1", tags: [FExecIO, FReadEnv].} + env: StringTableRef = nil, + options: set[ProcessOption] = {poStdErrToStdOut}): + Process {.rtl, extern: "nosp$1", tags: [ExecIOEffect, ReadEnvEffect].} ## Starts a process. `Command` is the executable file, `workingDir` is the ## process's working directory. If ``workingDir == ""`` the current directory ## is used. `args` are the command line arguments that are passed to the @@ -148,63 +151,66 @@ proc startProcess*(command: string, ## Return value: The newly created process object. Nil is never returned, ## but ``EOS`` is raised in case of an error. -proc startCmd*(command: string, options: set[TProcessOption] = { - poStdErrToStdOut, poUsePath}): PProcess {. - tags: [FExecIO, FReadEnv], deprecated.} = +proc startCmd*(command: string, options: set[ProcessOption] = { + poStdErrToStdOut, poUsePath}): Process {. + tags: [ExecIOEffect, ReadEnvEffect], deprecated.} = ## Deprecated - use `startProcess` directly. result = startProcess(command=command, options=options + {poEvalCommand}) -proc close*(p: PProcess) {.rtl, extern: "nosp$1", tags: [].} +proc close*(p: Process) {.rtl, extern: "nosp$1", tags: [].} ## When the process has finished executing, cleanup related handles -proc suspend*(p: PProcess) {.rtl, extern: "nosp$1", tags: [].} +proc suspend*(p: Process) {.rtl, extern: "nosp$1", tags: [].} ## Suspends the process `p`. -proc resume*(p: PProcess) {.rtl, extern: "nosp$1", tags: [].} +proc resume*(p: Process) {.rtl, extern: "nosp$1", tags: [].} ## Resumes the process `p`. -proc terminate*(p: PProcess) {.rtl, extern: "nosp$1", tags: [].} - ## Stop the process `p`. On Posix OSs the procedure sends SIGTERM to the process. On Windows the Win32 API function TerminateProcess() is called to stop the process. +proc terminate*(p: Process) {.rtl, extern: "nosp$1", tags: [].} + ## Stop the process `p`. On Posix OSes the procedure sends ``SIGTERM`` + ## to the process. On Windows the Win32 API function ``TerminateProcess()`` + ## is called to stop the process. -proc kill*(p: PProcess) {.rtl, extern: "nosp$1", tags: [].} - ## Kill the process `p`. On Posix OSs the procedure sends SIGKILL to the process. On Windows kill() is an alias for terminate(). +proc kill*(p: Process) {.rtl, extern: "nosp$1", tags: [].} + ## Kill the process `p`. On Posix OSes the procedure sends ``SIGKILL`` to + ## the process. On Windows ``kill()`` is simply an alias for ``terminate()``. -proc running*(p: PProcess): bool {.rtl, extern: "nosp$1", tags: [].} +proc running*(p: Process): bool {.rtl, extern: "nosp$1", tags: [].} ## Returns true iff the process `p` is still running. Returns immediately. -proc processID*(p: PProcess): int {.rtl, extern: "nosp$1".} = +proc processID*(p: Process): int {.rtl, extern: "nosp$1".} = ## returns `p`'s process ID. return p.id -proc waitForExit*(p: PProcess, timeout: int = -1): int {.rtl, +proc waitForExit*(p: Process, timeout: int = -1): int {.rtl, extern: "nosp$1", tags: [].} ## waits for the process to finish and returns `p`'s error code. ## ## **Warning**: Be careful when using waitForExit for processes created without ## poParentStreams because they may fill output buffers, causing deadlock. -proc peekExitCode*(p: PProcess): int {.tags: [].} +proc peekExitCode*(p: Process): int {.tags: [].} ## return -1 if the process is still running. Otherwise the process' exit code -proc inputStream*(p: PProcess): PStream {.rtl, extern: "nosp$1", tags: [].} +proc inputStream*(p: Process): Stream {.rtl, extern: "nosp$1", tags: [].} ## returns ``p``'s input stream for writing to. ## ## **Warning**: The returned `PStream` should not be closed manually as it ## is closed when closing the PProcess ``p``. -proc outputStream*(p: PProcess): PStream {.rtl, extern: "nosp$1", tags: [].} +proc outputStream*(p: Process): Stream {.rtl, extern: "nosp$1", tags: [].} ## returns ``p``'s output stream for reading from. ## ## **Warning**: The returned `PStream` should not be closed manually as it ## is closed when closing the PProcess ``p``. -proc errorStream*(p: PProcess): PStream {.rtl, extern: "nosp$1", tags: [].} +proc errorStream*(p: Process): Stream {.rtl, extern: "nosp$1", tags: [].} ## returns ``p``'s error stream for reading from. ## ## **Warning**: The returned `PStream` should not be closed manually as it ## is closed when closing the PProcess ``p``. -proc inputHandle*(p: PProcess): TFileHandle {.rtl, extern: "nosp$1", +proc inputHandle*(p: Process): FileHandle {.rtl, extern: "nosp$1", tags: [].} = ## returns ``p``'s input file handle for writing to. ## @@ -212,7 +218,7 @@ proc inputHandle*(p: PProcess): TFileHandle {.rtl, extern: "nosp$1", ## it is closed when closing the PProcess ``p``. result = p.inHandle -proc outputHandle*(p: PProcess): TFileHandle {.rtl, extern: "nosp$1", +proc outputHandle*(p: Process): FileHandle {.rtl, extern: "nosp$1", tags: [].} = ## returns ``p``'s output file handle for reading from. ## @@ -220,7 +226,7 @@ proc outputHandle*(p: PProcess): TFileHandle {.rtl, extern: "nosp$1", ## it is closed when closing the PProcess ``p``. result = p.outHandle -proc errorHandle*(p: PProcess): TFileHandle {.rtl, extern: "nosp$1", +proc errorHandle*(p: Process): FileHandle {.rtl, extern: "nosp$1", tags: [].} = ## returns ``p``'s error file handle for reading from. ## @@ -235,21 +241,25 @@ proc countProcessors*(): int {.rtl, extern: "nosp$1".} = proc execProcesses*(cmds: openArray[string], options = {poStdErrToStdOut, poParentStreams}, - n = countProcessors()): int {.rtl, extern: "nosp$1", - tags: [FExecIO, FTime, FReadEnv]} = + n = countProcessors(), + beforeRunEvent: proc(idx: int) = nil): int + {.rtl, extern: "nosp$1", + tags: [ExecIOEffect, TimeEffect, ReadEnvEffect, RootEffect]} = ## executes the commands `cmds` in parallel. Creates `n` processes ## that execute in parallel. The highest return value of all processes - ## is returned. + ## is returned. Runs `beforeRunEvent` before running each command. when defined(posix): # poParentStreams causes problems on Posix, so we simply disable it: var options = options - {poParentStreams} assert n > 0 if n > 1: - var q: seq[PProcess] + var q: seq[Process] newSeq(q, n) var m = min(n, cmds.len) for i in 0..m-1: + if beforeRunEvent != nil: + beforeRunEvent(i) q[i] = startCmd(cmds[i], options=options) when defined(noBusyWaiting): var r = 0 @@ -263,6 +273,8 @@ proc execProcesses*(cmds: openArray[string], echo(err) result = max(waitForExit(q[r]), result) if q[r] != nil: close(q[r]) + if beforeRunEvent != nil: + beforeRunEvent(i) q[r] = startCmd(cmds[i], options=options) r = (r + 1) mod n else: @@ -274,6 +286,8 @@ proc execProcesses*(cmds: openArray[string], #echo(outputStream(q[r]).readLine()) result = max(waitForExit(q[r]), result) if q[r] != nil: close(q[r]) + if beforeRunEvent != nil: + beforeRunEvent(i) q[r] = startCmd(cmds[i], options=options) inc(i) if i > high(cmds): break @@ -282,12 +296,14 @@ proc execProcesses*(cmds: openArray[string], if q[j] != nil: close(q[j]) else: for i in 0..high(cmds): + if beforeRunEvent != nil: + beforeRunEvent(i) var p = startCmd(cmds[i], options=options) result = max(waitForExit(p), result) close(p) -proc select*(readfds: var seq[PProcess], timeout = 500): int - ## `select` with a sensible Nimrod interface. `timeout` is in miliseconds. +proc select*(readfds: var seq[Process], timeout = 500): int + ## `select` with a sensible Nim interface. `timeout` is in miliseconds. ## Specify -1 for no timeout. Returns the number of processes that are ## ready to read from. The processes that are ready to be read from are ## removed from `readfds`. @@ -297,9 +313,9 @@ proc select*(readfds: var seq[PProcess], timeout = 500): int when not defined(useNimRtl): proc execProcess(command: string, - args: openarray[string] = [], - env: PStringTable = nil, - options: set[TProcessOption] = {poStdErrToStdOut, + args: openArray[string] = [], + env: StringTableRef = nil, + options: set[ProcessOption] = {poStdErrToStdOut, poUsePath, poEvalCommand}): TaintedString = var p = startProcess(command, args=args, env=env, options=options) @@ -319,30 +335,31 @@ when defined(Windows) and not defined(useNimRtl): # We need to implement a handle stream for Windows: type PFileHandleStream = ref TFileHandleStream - TFileHandleStream = object of TStream + TFileHandleStream = object of StreamObj handle: THandle atTheEnd: bool - proc hsClose(s: PStream) = discard # nothing to do here - proc hsAtEnd(s: PStream): bool = return PFileHandleStream(s).atTheEnd + proc hsClose(s: Stream) = discard # nothing to do here + proc hsAtEnd(s: Stream): bool = return PFileHandleStream(s).atTheEnd - proc hsReadData(s: PStream, buffer: pointer, bufLen: int): int = + proc hsReadData(s: Stream, buffer: pointer, bufLen: int): int = var s = PFileHandleStream(s) if s.atTheEnd: return 0 var br: int32 - var a = winlean.readFile(s.handle, buffer, bufLen.cint, br, nil) + var a = winlean.readFile(s.handle, buffer, bufLen.cint, addr br, nil) # TRUE and zero bytes returned (EOF). # TRUE and n (>0) bytes returned (good data). # FALSE and bytes returned undefined (system error). - if a == 0 and br != 0: osError(osLastError()) + if a == 0 and br != 0: raiseOSError(osLastError()) s.atTheEnd = br < bufLen result = br - proc hsWriteData(s: PStream, buffer: pointer, bufLen: int) = + proc hsWriteData(s: Stream, buffer: pointer, bufLen: int) = var s = PFileHandleStream(s) var bytesWritten: int32 - var a = winlean.writeFile(s.handle, buffer, bufLen.cint, bytesWritten, nil) - if a == 0: osError(osLastError()) + var a = winlean.writeFile(s.handle, buffer, bufLen.cint, + addr bytesWritten, nil) + if a == 0: raiseOSError(osLastError()) proc newFileHandleStream(handle: THandle): PFileHandleStream = new(result) @@ -360,7 +377,7 @@ when defined(Windows) and not defined(useNimRtl): result = cast[cstring](alloc0(res.len+1)) copyMem(result, cstring(res), res.len) - proc buildEnv(env: PStringTable): cstring = + proc buildEnv(env: StringTableRef): cstring = var L = 0 for key, val in pairs(env): inc(L, key.len + val.len + 2) result = cast[cstring](alloc0(L+2)) @@ -383,7 +400,7 @@ when defined(Windows) and not defined(useNimRtl): piInheritablePipe.lpSecurityDescriptor = nil piInheritablePipe.bInheritHandle = 1 if createPipe(rdHandle, wrHandle, piInheritablePipe, 1024) == 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) proc fileClose(h: THandle) {.inline.} = if h > 4: discard closeHandle(h) @@ -391,8 +408,8 @@ when defined(Windows) and not defined(useNimRtl): proc startProcess(command: string, workingDir: string = "", args: openArray[string] = [], - env: PStringTable = nil, - options: set[TProcessOption] = {poStdErrToStdOut}): PProcess = + env: StringTableRef = nil, + options: set[ProcessOption] = {poStdErrToStdOut}): Process = var si: TSTARTUPINFO procInfo: TPROCESS_INFORMATION @@ -409,16 +426,16 @@ when defined(Windows) and not defined(useNimRtl): he = ho else: createPipeHandles(he, si.hStdError) - result.inHandle = TFileHandle(hi) - result.outHandle = TFileHandle(ho) - result.errHandle = TFileHandle(he) + result.inHandle = FileHandle(hi) + result.outHandle = FileHandle(ho) + result.errHandle = FileHandle(he) else: si.hStdError = getStdHandle(STD_ERROR_HANDLE) si.hStdInput = getStdHandle(STD_INPUT_HANDLE) si.hStdOutput = getStdHandle(STD_OUTPUT_HANDLE) - result.inHandle = TFileHandle(si.hStdInput) - result.outHandle = TFileHandle(si.hStdOutput) - result.errHandle = TFileHandle(si.hStdError) + result.inHandle = FileHandle(si.hStdInput) + result.outHandle = FileHandle(si.hStdOutput) + result.errHandle = FileHandle(si.hStdError) var cmdl: cstring if poEvalCommand in options: @@ -450,13 +467,13 @@ when defined(Windows) and not defined(useNimRtl): fileClose(si.hStdError) if e != nil: dealloc(e) - if success == 0: osError(lastError) + if success == 0: raiseOSError(lastError) # Close the handle now so anyone waiting is woken: discard closeHandle(procInfo.hThread) result.fProcessHandle = procInfo.hProcess result.id = procInfo.dwProcessId - proc close(p: PProcess) = + proc close(p: Process) = when false: # somehow this does not work on Windows: discard closeHandle(p.inHandle) @@ -464,17 +481,17 @@ when defined(Windows) and not defined(useNimRtl): discard closeHandle(p.errHandle) discard closeHandle(p.FProcessHandle) - proc suspend(p: PProcess) = + proc suspend(p: Process) = discard suspendThread(p.fProcessHandle) - proc resume(p: PProcess) = + proc resume(p: Process) = discard resumeThread(p.fProcessHandle) - proc running(p: PProcess): bool = + proc running(p: Process): bool = var x = waitForSingleObject(p.fProcessHandle, 50) return x == WAIT_TIMEOUT - proc terminate(p: PProcess) = + proc terminate(p: Process) = if running(p): discard terminateProcess(p.fProcessHandle, 0) @@ -489,7 +506,7 @@ when defined(Windows) and not defined(useNimRtl): result = res discard closeHandle(p.fProcessHandle) - proc peekExitCode(p: PProcess): int = + proc peekExitCode(p: Process): int = var b = waitForSingleObject(p.fProcessHandle, 50) == WAIT_TIMEOUT if b: result = -1 else: @@ -497,13 +514,13 @@ when defined(Windows) and not defined(useNimRtl): discard getExitCodeProcess(p.fProcessHandle, res) return res - proc inputStream(p: PProcess): PStream = + proc inputStream(p: Process): Stream = result = newFileHandleStream(p.inHandle) - proc outputStream(p: PProcess): PStream = + proc outputStream(p: Process): Stream = result = newFileHandleStream(p.outHandle) - proc errorStream(p: PProcess): PStream = + proc errorStream(p: Process): Stream = result = newFileHandleStream(p.errHandle) proc execCmd(command: string): int = @@ -524,7 +541,7 @@ when defined(Windows) and not defined(useNimRtl): var res = winlean.createProcessA(nil, command, nil, nil, 0, NORMAL_PRIORITY_CLASS, nil, nil, si, procInfo) if res == 0: - osError(osLastError()) + raiseOSError(osLastError()) else: process = procInfo.hProcess discard closeHandle(procInfo.hThread) @@ -535,7 +552,7 @@ when defined(Windows) and not defined(useNimRtl): result = -1 discard closeHandle(process) - proc select(readfds: var seq[PProcess], timeout = 500): int = + proc select(readfds: var seq[Process], timeout = 500): int = assert readfds.len <= MAXIMUM_WAIT_OBJECTS var rfds: TWOHandleArray for i in 0..readfds.len()-1: @@ -547,7 +564,7 @@ when defined(Windows) and not defined(useNimRtl): of WAIT_TIMEOUT: return 0 of WAIT_FAILED: - osError(osLastError()) + raiseOSError(osLastError()) else: var i = ret - WAIT_OBJECT_0 readfds.del(i) @@ -558,7 +575,7 @@ elif not defined(useNimRtl): readIdx = 0 writeIdx = 1 - proc envToCStringArray(t: PStringTable): cstringArray = + proc envToCStringArray(t: StringTableRef): cstringArray = result = cast[cstringArray](alloc0((t.len + 1) * sizeof(cstring))) var i = 0 for key, val in pairs(t): @@ -590,19 +607,19 @@ elif not defined(useNimRtl): when not defined(useFork): proc startProcessAuxSpawn(data: TStartProcessData): TPid {. - tags: [FExecIO, FReadEnv], gcsafe.} + tags: [ExecIOEffect, ReadEnvEffect], gcsafe.} proc startProcessAuxFork(data: TStartProcessData): TPid {. - tags: [FExecIO, FReadEnv], gcsafe.} + tags: [ExecIOEffect, ReadEnvEffect], gcsafe.} {.push stacktrace: off, profiler: off.} proc startProcessAfterFork(data: ptr TStartProcessData) {. - tags: [FExecIO, FReadEnv], cdecl, gcsafe.} + tags: [ExecIOEffect, ReadEnvEffect], cdecl, gcsafe.} {.pop.} proc startProcess(command: string, workingDir: string = "", args: openArray[string] = [], - env: PStringTable = nil, - options: set[TProcessOption] = {poStdErrToStdOut}): PProcess = + env: StringTableRef = nil, + options: set[ProcessOption] = {poStdErrToStdOut}): Process = var pStdin, pStdout, pStderr: array [0..1, cint] new(result) @@ -610,7 +627,7 @@ elif not defined(useNimRtl): if poParentStreams notin options: if pipe(pStdin) != 0'i32 or pipe(pStdout) != 0'i32 or pipe(pStderr) != 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) var sysCommand: string var sysArgsRaw: seq[string] @@ -686,7 +703,7 @@ elif not defined(useNimRtl): var fops: Tposix_spawn_file_actions template chck(e: expr) = - if e != 0'i32: osError(osLastError()) + if e != 0'i32: raiseOSError(osLastError()) chck posix_spawn_file_actions_init(fops) chck posix_spawnattr_init(attr) @@ -729,7 +746,7 @@ elif not defined(useNimRtl): proc startProcessAuxFork(data: TStartProcessData): TPid = if pipe(data.pErrorPipe) != 0: - osError(osLastError()) + raiseOSError(osLastError()) finally: discard close(data.pErrorPipe[readIdx]) @@ -754,12 +771,12 @@ elif not defined(useNimRtl): exitnow(1) discard close(data.pErrorPipe[writeIdx]) - if pid < 0: osError(osLastError()) + if pid < 0: raiseOSError(osLastError()) var error: cint let sizeRead = read(data.pErrorPipe[readIdx], addr error, sizeof(error)) if sizeRead == sizeof(error): - osError($strerror(error)) + raiseOSError($strerror(error)) return pid @@ -774,7 +791,7 @@ elif not defined(useNimRtl): proc startProcessAfterFork(data: ptr TStartProcessData) = # Warning: no GC here! - # Or anything that touches global structures - all called nimrod procs + # Or anything that touches global structures - all called nim procs # must be marked with stackTrace:off. Inspect C code after making changes. if not data.optionPoParentStreams: discard close(data.pStdin[writeIdx]) @@ -812,7 +829,7 @@ elif not defined(useNimRtl): startProcessFail(data) {.pop} - proc close(p: PProcess) = + proc close(p: Process) = if p.inStream != nil: close(p.inStream) if p.outStream != nil: close(p.outStream) if p.errStream != nil: close(p.errStream) @@ -820,26 +837,26 @@ elif not defined(useNimRtl): discard close(p.outHandle) discard close(p.errHandle) - proc suspend(p: PProcess) = - if kill(p.id, SIGSTOP) != 0'i32: osError(osLastError()) + proc suspend(p: Process) = + if kill(p.id, SIGSTOP) != 0'i32: raiseOsError(osLastError()) - proc resume(p: PProcess) = - if kill(p.id, SIGCONT) != 0'i32: osError(osLastError()) + proc resume(p: Process) = + if kill(p.id, SIGCONT) != 0'i32: raiseOsError(osLastError()) - proc running(p: PProcess): bool = + proc running(p: Process): bool = var ret = waitpid(p.id, p.exitCode, WNOHANG) if ret == 0: return true # Can't establish status. Assume running. result = ret == int(p.id) - proc terminate(p: PProcess) = + proc terminate(p: Process) = if kill(p.id, SIGTERM) != 0'i32: - osError(osLastError()) + raiseOsError(osLastError()) - proc kill(p: PProcess) = + proc kill(p: Process) = if kill(p.id, SIGKILL) != 0'i32: - osError(osLastError()) + raiseOsError(osLastError()) - proc waitForExit(p: PProcess, timeout: int = -1): int = + proc waitForExit(p: Process, timeout: int = -1): int = #if waitPid(p.id, p.exitCode, 0) == int(p.id): # ``waitPid`` fails if the process is not running anymore. But then # ``running`` probably set ``p.exitCode`` for us. Since ``p.exitCode`` is @@ -847,10 +864,10 @@ elif not defined(useNimRtl): if p.exitCode != -3: return p.exitCode if waitpid(p.id, p.exitCode, 0) < 0: p.exitCode = -3 - osError(osLastError()) + raiseOSError(osLastError()) result = int(p.exitCode) shr 8 - proc peekExitCode(p: PProcess): int = + proc peekExitCode(p: Process): int = if p.exitCode != -3: return p.exitCode var ret = waitpid(p.id, p.exitCode, WNOHANG) var b = ret == int(p.id) @@ -858,28 +875,29 @@ elif not defined(useNimRtl): if p.exitCode == -3: result = -1 else: result = p.exitCode.int shr 8 - proc createStream(stream: var PStream, handle: var TFileHandle, - fileMode: TFileMode) = - var f: TFile - if not open(f, handle, fileMode): osError(osLastError()) + proc createStream(stream: var Stream, handle: var FileHandle, + fileMode: FileMode) = + var f: File + if not open(f, handle, fileMode): raiseOSError(osLastError()) stream = newFileStream(f) - proc inputStream(p: PProcess): PStream = + proc inputStream(p: Process): Stream = if p.inStream == nil: createStream(p.inStream, p.inHandle, fmWrite) return p.inStream - proc outputStream(p: PProcess): PStream = + proc outputStream(p: Process): Stream = if p.outStream == nil: createStream(p.outStream, p.outHandle, fmRead) return p.outStream - proc errorStream(p: PProcess): PStream = + proc errorStream(p: Process): Stream = if p.errStream == nil: createStream(p.errStream, p.errHandle, fmRead) return p.errStream - proc csystem(cmd: cstring): cint {.nodecl, importc: "system", header: "<stdlib.h>".} + proc csystem(cmd: cstring): cint {.nodecl, importc: "system", + header: "<stdlib.h>".} proc execCmd(command: string): int = when defined(linux): @@ -887,13 +905,13 @@ elif not defined(useNimRtl): else: result = csystem(command) - proc createFdSet(fd: var TFdSet, s: seq[PProcess], m: var int) = + proc createFdSet(fd: var TFdSet, s: seq[Process], m: var int) = FD_ZERO(fd) for i in items(s): m = max(m, int(i.outHandle)) FD_SET(cint(i.outHandle), fd) - proc pruneProcessSet(s: var seq[PProcess], fd: var TFdSet) = + proc pruneProcessSet(s: var seq[Process], fd: var TFdSet) = var i = 0 var L = s.len while i < L: @@ -904,8 +922,8 @@ elif not defined(useNimRtl): inc(i) setLen(s, L) - proc select(readfds: var seq[PProcess], timeout = 500): int = - var tv: TTimeVal + proc select(readfds: var seq[Process], timeout = 500): int = + var tv: Timeval tv.tv_sec = 0 tv.tv_usec = timeout * 1000 @@ -921,10 +939,10 @@ elif not defined(useNimRtl): pruneProcessSet(readfds, (rd)) -proc execCmdEx*(command: string, options: set[TProcessOption] = { +proc execCmdEx*(command: string, options: set[ProcessOption] = { poStdErrToStdOut, poUsePath}): tuple[ output: TaintedString, - exitCode: int] {.tags: [FExecIO, FReadIO], gcsafe.} = + exitCode: int] {.tags: [ExecIOEffect, ReadIOEffect], gcsafe.} = ## a convenience proc that runs the `command`, grabs all its output and ## exit code and returns both. var p = startCmd(command, options) diff --git a/lib/pure/parsecfg.nim b/lib/pure/parsecfg.nim index 1d61a967b..bb9d2aed2 100644 --- a/lib/pure/parsecfg.nim +++ b/lib/pure/parsecfg.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this @@ -11,7 +11,7 @@ ## parser. The configuration file's syntax is similar to the Windows ``.ini`` ## format, but much more powerful, as it is not a line based parser. String ## literals, raw string literals and triple quoted string literals are supported -## as in the Nimrod programming language. +## as in the Nim programming language. ## This is an example of how a configuration file may look like: ## @@ -20,25 +20,25 @@ ## The file ``examples/parsecfgex.nim`` demonstrates how to use the ## configuration file parser: ## -## .. code-block:: nimrod +## .. code-block:: nim ## :file: examples/parsecfgex.nim -import +import hashes, strutils, lexbase, streams include "system/inclrtl" -type - TCfgEventKind* = enum ## enumeration of all events that may occur when parsing +type + CfgEventKind* = enum ## enumeration of all events that may occur when parsing cfgEof, ## end of file reached cfgSectionStart, ## a ``[section]`` has been parsed cfgKeyValuePair, ## a ``key=value`` pair has been detected cfgOption, ## a ``--key=value`` command line option cfgError ## an error ocurred during parsing - TCfgEvent* = object of TObject ## describes a parsing event - case kind*: TCfgEventKind ## the kind of the event + CfgEvent* = object of RootObj ## describes a parsing event + case kind*: CfgEventKind ## the kind of the event of cfgEof: nil of cfgSectionStart: section*: string ## `section` contains the name of the @@ -53,28 +53,29 @@ type msg*: string ## contains the error message. No exceptions ## are thrown if a parse error occurs. - TTokKind = enum + TokKind = enum tkInvalid, tkEof, tkSymbol, tkEquals, tkColon, tkBracketLe, tkBracketRi, tkDashDash - TToken {.final.} = object # a token - kind: TTokKind # the type of the token + Token = object # a token + kind: TokKind # the type of the token literal: string # the parsed (string) literal - TCfgParser* = object of TBaseLexer ## the parser object. - tok: TToken + CfgParser* = object of BaseLexer ## the parser object. + tok: Token filename: string +{.deprecated: [TCfgEventKind: CfgEventKind, TCfgEvent: CfgEvent, + TTokKind: TokKind, TToken: Token, TCfgParser: CfgParser].} + # implementation const - SymChars: TCharSet = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\x80'..'\xFF', '.', - '/', '\\'} + SymChars = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\x80'..'\xFF', '.', '/', '\\'} -proc rawGetTok(c: var TCfgParser, tok: var TToken) {.gcsafe.} +proc rawGetTok(c: var CfgParser, tok: var Token) {.gcsafe.} -proc open*(c: var TCfgParser, input: PStream, filename: string, - lineOffset = 0) {. - rtl, extern: "npc$1".} = +proc open*(c: var CfgParser, input: Stream, filename: string, + lineOffset = 0) {.rtl, extern: "npc$1".} = ## initializes the parser with an input stream. `Filename` is only used ## for nice error messages. `lineOffset` can be used to influence the line ## number information in the generated error messages. @@ -85,23 +86,23 @@ proc open*(c: var TCfgParser, input: PStream, filename: string, inc(c.lineNumber, lineOffset) rawGetTok(c, c.tok) -proc close*(c: var TCfgParser) {.rtl, extern: "npc$1".} = +proc close*(c: var CfgParser) {.rtl, extern: "npc$1".} = ## closes the parser `c` and its associated input stream. lexbase.close(c) -proc getColumn*(c: TCfgParser): int {.rtl, extern: "npc$1".} = +proc getColumn*(c: CfgParser): int {.rtl, extern: "npc$1".} = ## get the current column the parser has arrived at. result = getColNumber(c, c.bufpos) -proc getLine*(c: TCfgParser): int {.rtl, extern: "npc$1".} = +proc getLine*(c: CfgParser): int {.rtl, extern: "npc$1".} = ## get the current line the parser has arrived at. result = c.lineNumber -proc getFilename*(c: TCfgParser): string {.rtl, extern: "npc$1".} = +proc getFilename*(c: CfgParser): string {.rtl, extern: "npc$1".} = ## get the filename of the file that the parser processes. result = c.filename -proc handleHexChar(c: var TCfgParser, xi: var int) = +proc handleHexChar(c: var CfgParser, xi: var int) = case c.buf[c.bufpos] of '0'..'9': xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('0')) @@ -115,12 +116,12 @@ proc handleHexChar(c: var TCfgParser, xi: var int) = else: discard -proc handleDecChars(c: var TCfgParser, xi: var int) = +proc handleDecChars(c: var CfgParser, xi: var int) = while c.buf[c.bufpos] in {'0'..'9'}: xi = (xi * 10) + (ord(c.buf[c.bufpos]) - ord('0')) inc(c.bufpos) -proc getEscapedChar(c: var TCfgParser, tok: var TToken) = +proc getEscapedChar(c: var CfgParser, tok: var Token) = inc(c.bufpos) # skip '\' case c.buf[c.bufpos] of 'n', 'N': @@ -169,13 +170,13 @@ proc getEscapedChar(c: var TCfgParser, tok: var TToken) = else: tok.kind = tkInvalid else: tok.kind = tkInvalid -proc handleCRLF(c: var TCfgParser, pos: int): int = +proc handleCRLF(c: var CfgParser, pos: int): int = case c.buf[pos] of '\c': result = lexbase.handleCR(c, pos) of '\L': result = lexbase.handleLF(c, pos) else: result = pos -proc getString(c: var TCfgParser, tok: var TToken, rawMode: bool) = +proc getString(c: var CfgParser, tok: var Token, rawMode: bool) = var pos = c.bufpos + 1 # skip " var buf = c.buf # put `buf` in a register tok.kind = tkSymbol @@ -221,7 +222,7 @@ proc getString(c: var TCfgParser, tok: var TToken, rawMode: bool) = inc(pos) c.bufpos = pos -proc getSymbol(c: var TCfgParser, tok: var TToken) = +proc getSymbol(c: var CfgParser, tok: var Token) = var pos = c.bufpos var buf = c.buf while true: @@ -231,7 +232,7 @@ proc getSymbol(c: var TCfgParser, tok: var TToken) = c.bufpos = pos tok.kind = tkSymbol -proc skip(c: var TCfgParser) = +proc skip(c: var CfgParser) = var pos = c.bufpos var buf = c.buf while true: @@ -247,7 +248,7 @@ proc skip(c: var TCfgParser) = break # EndOfFile also leaves the loop c.bufpos = pos -proc rawGetTok(c: var TCfgParser, tok: var TToken) = +proc rawGetTok(c: var CfgParser, tok: var Token) = tok.kind = tkInvalid setLen(tok.literal, 0) skip(c) @@ -286,19 +287,19 @@ proc rawGetTok(c: var TCfgParser, tok: var TToken) = tok.literal = "[EOF]" else: getSymbol(c, tok) -proc errorStr*(c: TCfgParser, msg: string): string {.rtl, extern: "npc$1".} = +proc errorStr*(c: CfgParser, msg: string): string {.rtl, extern: "npc$1".} = ## returns a properly formated error message containing current line and ## column information. result = `%`("$1($2, $3) Error: $4", [c.filename, $getLine(c), $getColumn(c), msg]) -proc warningStr*(c: TCfgParser, msg: string): string {.rtl, extern: "npc$1".} = +proc warningStr*(c: CfgParser, msg: string): string {.rtl, extern: "npc$1".} = ## returns a properly formated warning message containing current line and ## column information. result = `%`("$1($2, $3) Warning: $4", [c.filename, $getLine(c), $getColumn(c), msg]) -proc ignoreMsg*(c: TCfgParser, e: TCfgEvent): string {.rtl, extern: "npc$1".} = +proc ignoreMsg*(c: CfgParser, e: CfgEvent): string {.rtl, extern: "npc$1".} = ## returns a properly formated warning message containing that ## an entry is ignored. case e.kind @@ -309,7 +310,7 @@ proc ignoreMsg*(c: TCfgParser, e: TCfgEvent): string {.rtl, extern: "npc$1".} = of cfgError: result = e.msg of cfgEof: result = "" -proc getKeyValPair(c: var TCfgParser, kind: TCfgEventKind): TCfgEvent = +proc getKeyValPair(c: var CfgParser, kind: CfgEventKind): CfgEvent = if c.tok.kind == tkSymbol: result.kind = kind result.key = c.tok.literal @@ -329,7 +330,7 @@ proc getKeyValPair(c: var TCfgParser, kind: TCfgEventKind): TCfgEvent = result.msg = errorStr(c, "symbol expected, but found: " & c.tok.literal) rawGetTok(c, c.tok) -proc next*(c: var TCfgParser): TCfgEvent {.rtl, extern: "npc$1".} = +proc next*(c: var CfgParser): CfgEvent {.rtl, extern: "npc$1".} = ## retrieves the first/next event. This controls the parser. case c.tok.kind of tkEof: diff --git a/lib/pure/parsecsv.nim b/lib/pure/parsecsv.nim index 4b25babec..f4943ed89 100644 --- a/lib/pure/parsecsv.nim +++ b/lib/pure/parsecsv.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2009 Andreas Rumpf # # See the file "copying.txt", included in this @@ -13,16 +13,16 @@ ## Example: How to use the parser ## ============================== ## -## .. code-block:: nimrod +## .. code-block:: nim ## import os, parsecsv, streams -## var s = newFileStream(ParamStr(1), fmRead) -## if s == nil: quit("cannot open the file" & ParamStr(1)) -## var x: TCsvParser -## open(x, s, ParamStr(1)) +## var s = newFileStream(paramStr(1), fmRead) +## if s == nil: quit("cannot open the file" & paramStr(1)) +## var x: CsvParser +## open(x, s, paramStr(1)) ## while readRow(x): -## Echo "new row: " +## echo "new row: " ## for val in items(x.row): -## Echo "##", val, "##" +## echo "##", val, "##" ## close(x) ## @@ -30,28 +30,30 @@ import lexbase, streams type - TCsvRow* = seq[string] ## a row in a CSV file - TCsvParser* = object of TBaseLexer ## the parser object. - row*: TCsvRow ## the current row + CsvRow* = seq[string] ## a row in a CSV file + CsvParser* = object of BaseLexer ## the parser object. + row*: CsvRow ## the current row filename: string sep, quote, esc: char skipWhite: bool currRow: int - EInvalidCsv* = object of EIO ## exception that is raised if - ## a parsing error occurs + CsvError* = object of IOError ## exception that is raised if + ## a parsing error occurs + +{.deprecated: [TCsvRow: CsvRow, TCsvParser: CsvParser, EInvalidCsv: CsvError].} proc raiseEInvalidCsv(filename: string, line, col: int, msg: string) {.noreturn.} = - var e: ref EInvalidCsv + var e: ref CsvError new(e) e.msg = filename & "(" & $line & ", " & $col & ") Error: " & msg raise e -proc error(my: TCsvParser, pos: int, msg: string) = - raiseEInvalidCsv(my.filename, my.LineNumber, getColNumber(my, pos), msg) +proc error(my: CsvParser, pos: int, msg: string) = + raiseEInvalidCsv(my.filename, my.lineNumber, getColNumber(my, pos), msg) -proc open*(my: var TCsvParser, input: PStream, filename: string, +proc open*(my: var CsvParser, input: Stream, filename: string, separator = ',', quote = '"', escape = '\0', skipInitialSpace = false) = ## initializes the parser with an input stream. `Filename` is only used @@ -75,7 +77,7 @@ proc open*(my: var TCsvParser, input: PStream, filename: string, my.row = @[] my.currRow = 0 -proc parseField(my: var TCsvParser, a: var string) = +proc parseField(my: var CsvParser, a: var string) = var pos = my.bufpos var buf = my.buf if my.skipWhite: @@ -83,7 +85,7 @@ proc parseField(my: var TCsvParser, a: var string) = setLen(a, 0) # reuse memory if buf[pos] == my.quote and my.quote != '\0': inc(pos) - while true: + while true: var c = buf[pos] if c == '\0': my.bufpos = pos # can continue after exception? @@ -121,11 +123,11 @@ proc parseField(my: var TCsvParser, a: var string) = inc(pos) my.bufpos = pos -proc processedRows*(my: var TCsvParser): int = +proc processedRows*(my: var CsvParser): int = ## returns number of the processed rows return my.currRow -proc readRow*(my: var TCsvParser, columns = 0): bool = +proc readRow*(my: var CsvParser, columns = 0): bool = ## reads the next row; if `columns` > 0, it expects the row to have ## exactly this many columns. Returns false if the end of the file ## has been encountered else true. @@ -153,26 +155,26 @@ proc readRow*(my: var TCsvParser, columns = 0): bool = else: error(my, my.bufpos, my.sep & " expected") break - setlen(my.row, col) + setLen(my.row, col) result = col > 0 if result and col != columns and columns > 0: error(my, oldpos+1, $columns & " columns expected, but found " & $col & " columns") inc(my.currRow) -proc close*(my: var TCsvParser) {.inline.} = +proc close*(my: var CsvParser) {.inline.} = ## closes the parser `my` and its associated input stream. lexbase.close(my) when isMainModule: import os - var s = newFileStream(ParamStr(1), fmRead) - if s == nil: quit("cannot open the file" & ParamStr(1)) - var x: TCsvParser - open(x, s, ParamStr(1)) + var s = newFileStream(paramStr(1), fmRead) + if s == nil: quit("cannot open the file" & paramStr(1)) + var x: CsvParser + open(x, s, paramStr(1)) while readRow(x): - Echo "new row: " + echo "new row: " for val in items(x.row): - Echo "##", val, "##" + echo "##", val, "##" close(x) diff --git a/lib/pure/parseopt.nim b/lib/pure/parseopt.nim index f43853fe6..8af6920c1 100644 --- a/lib/pure/parseopt.nim +++ b/lib/pure/parseopt.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library -# (c) Copyright 2012 Andreas Rumpf +# Nim's Runtime Library +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## This module provides the standard Nimrod command line parser. +## This module provides the standard Nim command line parser. ## It supports one convenience iterator over all command line options and some ## lower-level features. ## @@ -22,26 +22,28 @@ import os, strutils type - TCmdLineKind* = enum ## the detected command line token + CmdLineKind* = enum ## the detected command line token cmdEnd, ## end of command line reached cmdArgument, ## argument detected - cmdLongoption, ## a long option ``--option`` detected + cmdLongOption, ## a long option ``--option`` detected cmdShortOption ## a short option ``-c`` detected - TOptParser* = - object of TObject ## this object implements the command line parser + OptParser* = + object of RootObj ## this object implements the command line parser cmd: string pos: int inShortState: bool - kind*: TCmdLineKind ## the dected command line token + kind*: CmdLineKind ## the dected 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 +{.deprecated: [TCmdLineKind: CmdLineKind, TOptParser: OptParser].} + when declared(os.paramCount): # we cannot provide this for NimRtl creation on Posix, because we can't # access the command line arguments then! - proc initOptParser*(cmdline = ""): TOptParser = + proc initOptParser*(cmdline = ""): OptParser = ## inits the option parser. If ``cmdline == ""``, the real command line ## (as provided by the ``OS`` module) is taken. result.pos = 0 @@ -57,7 +59,7 @@ when declared(os.paramCount): result.val = TaintedString"" proc parseWord(s: string, i: int, w: var string, - delim: TCharSet = {'\x09', ' ', '\0'}): int = + delim: set[char] = {'\x09', ' ', '\0'}): int = result = i if s[result] == '\"': inc(result) @@ -70,7 +72,7 @@ proc parseWord(s: string, i: int, w: var string, add(w, s[result]) inc(result) -proc handleShortOption(p: var TOptParser) = +proc handleShortOption(p: var OptParser) = var i = p.pos p.kind = cmdShortOption add(p.key.string, p.cmd[i]) @@ -87,8 +89,7 @@ proc handleShortOption(p: var TOptParser) = if p.cmd[i] == '\0': p.inShortState = false p.pos = i -proc next*(p: var TOptParser) {. - rtl, extern: "npo$1".} = +proc next*(p: var OptParser) {.rtl, extern: "npo$1".} = ## parses the first or next option; ``p.kind`` describes what token has been ## parsed. ``p.key`` and ``p.val`` are set accordingly. var i = p.pos @@ -122,18 +123,16 @@ proc next*(p: var TOptParser) {. p.kind = cmdArgument p.pos = parseWord(p.cmd, i, p.key.string) -proc cmdLineRest*(p: TOptParser): TaintedString {. - rtl, extern: "npo$1".} = +proc cmdLineRest*(p: OptParser): TaintedString {.rtl, extern: "npo$1".} = ## retrieves the rest of the command line that has not been parsed yet. result = strip(substr(p.cmd, p.pos, len(p.cmd) - 1)).TaintedString when declared(initOptParser): - - iterator getopt*(): tuple[kind: TCmdLineKind, key, val: TaintedString] = + iterator getopt*(): tuple[kind: CmdLineKind, key, val: TaintedString] = ## This is an convenience iterator for iterating over the command line. ## This uses the TOptParser object. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var ## filename = "" ## for kind, key, val in getopt(): diff --git a/lib/pure/parseopt2.nim b/lib/pure/parseopt2.nim index 7638171d1..5b1f50958 100644 --- a/lib/pure/parseopt2.nim +++ b/lib/pure/parseopt2.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library -# (c) Copyright 2012 Andreas Rumpf +# Nim's Runtime Library +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## This module provides the standard Nimrod command line parser. +## This module provides the standard Nim command line parser. ## It supports one convenience iterator over all command line options and some ## lower-level features. ## @@ -25,22 +25,24 @@ import os, strutils type - TCmdLineKind* = enum ## the detected command line token + CmdLineKind* = enum ## the detected command line token cmdEnd, ## end of command line reached cmdArgument, ## argument detected cmdLongOption, ## a long option ``--option`` detected cmdShortOption ## a short option ``-c`` detected - TOptParser* = - object of TObject ## this object implements the command line parser + OptParser* = + object of RootObj ## this object implements the command line parser cmd: seq[string] pos: int remainingShortOptions: string - kind*: TCmdLineKind ## the dected command line token + kind*: CmdLineKind ## the dected 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 -proc initOptParser*(cmdline: seq[string]): TOptParser {.rtl.} = +{.deprecated: [TCmdLineKind: CmdLineKind, TOptParser: OptParser].} + +proc initOptParser*(cmdline: seq[string]): OptParser {.rtl.} = ## Initalizes option parses with cmdline. cmdline should not contain ## argument 0 - program name. ## If cmdline == nil default to current command line arguments. @@ -54,7 +56,7 @@ proc initOptParser*(cmdline: seq[string]): TOptParser {.rtl.} = result.cmd = @cmdline -proc initOptParser*(cmdline: string): TOptParser {.rtl, deprecated.} = +proc initOptParser*(cmdline: string): OptParser {.rtl, deprecated.} = ## Initalizes option parses with cmdline. Splits cmdline in on spaces ## and calls initOptParser(openarray[string]) ## Do not use. @@ -64,13 +66,13 @@ proc initOptParser*(cmdline: string): TOptParser {.rtl, deprecated.} = return initOptParser(cmdline.split) when not defined(createNimRtl): - proc initOptParser*(): TOptParser = + proc initOptParser*(): OptParser = ## Initializes option parser from current command line arguments. return initOptParser(commandLineParams()) -proc next*(p: var TOptParser) {.rtl, extern: "npo$1".} +proc next*(p: var OptParser) {.rtl, extern: "npo$1".} -proc nextOption(p: var TOptParser, token: string, allowEmpty: bool) = +proc nextOption(p: var OptParser, token: string, allowEmpty: bool) = for splitchar in [':', '=']: if splitchar in token: let pos = token.find(splitchar) @@ -85,7 +87,7 @@ proc nextOption(p: var TOptParser, token: string, allowEmpty: bool) = p.remainingShortOptions = token[0..token.len-1] p.next() -proc next(p: var TOptParser) = +proc next(p: var OptParser) = if p.remainingShortOptions.len != 0: p.kind = cmdShortOption p.key = TaintedString(p.remainingShortOptions[0..0]) @@ -100,10 +102,10 @@ proc next(p: var TOptParser) = let token = p.cmd[p.pos] p.pos += 1 - if token.startswith("--"): + if token.startsWith("--"): p.kind = cmdLongOption nextOption(p, token[2..token.len-1], allowEmpty=true) - elif token.startswith("-"): + elif token.startsWith("-"): p.kind = cmdShortOption nextOption(p, token[1..token.len-1], allowEmpty=true) else: @@ -111,20 +113,22 @@ proc next(p: var TOptParser) = p.key = token p.val = "" -proc cmdLineRest*(p: TOptParser): TaintedString {.rtl, extern: "npo$1", deprecated.} = +proc cmdLineRest*(p: OptParser): TaintedString {.rtl, extern: "npo$1", deprecated.} = ## Returns part of command line string that has not been parsed yet. ## Do not use - does not correctly handle whitespace. return p.cmd[p.pos..p.cmd.len-1].join(" ") type - TGetoptResult* = tuple[kind: TCmdLineKind, key, val: TaintedString] + GetoptResult* = tuple[kind: CmdLineKind, key, val: TaintedString] + +{.deprecated: [TGetoptResult: GetoptResult].} when declared(paramCount): - iterator getopt*(): TGetoptResult = + iterator getopt*(): GetoptResult = ## This is an convenience iterator for iterating over the command line. - ## This uses the TOptParser object. Example: + ## This uses the OptParser object. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var ## filename = "" ## for kind, key, val in getopt(): diff --git a/lib/pure/parsesql.nim b/lib/pure/parsesql.nim index bd8836f7c..bb4ede779 100644 --- a/lib/pure/parsesql.nim +++ b/lib/pure/parsesql.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2009 Andreas Rumpf # # See the file "copying.txt", included in this @@ -10,13 +10,13 @@ ## The ``parsesql`` module implements a high performance SQL file ## parser. It parses PostgreSQL syntax and the SQL ANSI standard. -import +import hashes, strutils, lexbase, streams # ------------------- scanner ------------------------------------------------- type - TTokKind = enum ## enumeration of all SQL tokens + TokKind = enum ## enumeration of all SQL tokens tkInvalid, ## invalid token tkEof, ## end of file reached tkIdentifier, ## abc @@ -38,36 +38,38 @@ type tkBracketRi, ## ']' tkDot ## '.' - TToken {.final.} = object # a token - kind: TTokKind # the type of the token + Token = object # a token + kind: TokKind # the type of the token literal: string # the parsed (string) literal - TSqlLexer* = object of TBaseLexer ## the parser object. + SqlLexer* = object of BaseLexer ## the parser object. filename: string +{.deprecated: [TToken: Token, TSqlLexer: SqlLexer].} + const - tokKindToStr: array[TTokKind, string] = [ + tokKindToStr: array[TokKind, string] = [ "invalid", "[EOF]", "identifier", "quoted identifier", "string constant", "escape string constant", "dollar quoted constant", "bit string constant", "hex string constant", "integer constant", "numeric constant", "operator", ";", ":", ",", "(", ")", "[", "]", "." ] -proc open(L: var TSqlLexer, input: PStream, filename: string) = +proc open(L: var SqlLexer, input: Stream, filename: string) = lexbase.open(L, input) L.filename = filename -proc close(L: var TSqlLexer) = +proc close(L: var SqlLexer) = lexbase.close(L) -proc getColumn(L: TSqlLexer): int = +proc getColumn(L: SqlLexer): int = ## get the current column the parser has arrived at. - result = getColNumber(L, L.bufPos) + result = getColNumber(L, L.bufpos) -proc getLine(L: TSqlLexer): int = - result = L.linenumber +proc getLine(L: SqlLexer): int = + result = L.lineNumber -proc handleHexChar(c: var TSqlLexer, xi: var int) = +proc handleHexChar(c: var SqlLexer, xi: var int) = case c.buf[c.bufpos] of '0'..'9': xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('0')) @@ -81,76 +83,76 @@ proc handleHexChar(c: var TSqlLexer, xi: var int) = else: discard -proc handleOctChar(c: var TSqlLexer, xi: var int) = +proc handleOctChar(c: var SqlLexer, xi: var int) = if c.buf[c.bufpos] in {'0'..'7'}: xi = (xi shl 3) or (ord(c.buf[c.bufpos]) - ord('0')) inc(c.bufpos) -proc getEscapedChar(c: var TSqlLexer, tok: var TToken) = +proc getEscapedChar(c: var SqlLexer, tok: var Token) = inc(c.bufpos) case c.buf[c.bufpos] of 'n', 'N': add(tok.literal, '\L') - Inc(c.bufpos) + inc(c.bufpos) of 'r', 'R', 'c', 'C': add(tok.literal, '\c') - Inc(c.bufpos) + inc(c.bufpos) of 'l', 'L': add(tok.literal, '\L') - Inc(c.bufpos) + inc(c.bufpos) of 'f', 'F': add(tok.literal, '\f') inc(c.bufpos) of 'e', 'E': add(tok.literal, '\e') - Inc(c.bufpos) + inc(c.bufpos) of 'a', 'A': add(tok.literal, '\a') - Inc(c.bufpos) + inc(c.bufpos) of 'b', 'B': add(tok.literal, '\b') - Inc(c.bufpos) + inc(c.bufpos) of 'v', 'V': add(tok.literal, '\v') - Inc(c.bufpos) + inc(c.bufpos) of 't', 'T': add(tok.literal, '\t') - Inc(c.bufpos) + inc(c.bufpos) of '\'', '\"': add(tok.literal, c.buf[c.bufpos]) - Inc(c.bufpos) + inc(c.bufpos) of '\\': add(tok.literal, '\\') - Inc(c.bufpos) + inc(c.bufpos) of 'x', 'X': inc(c.bufpos) var xi = 0 handleHexChar(c, xi) handleHexChar(c, xi) - add(tok.literal, Chr(xi)) + add(tok.literal, chr(xi)) of '0'..'7': var xi = 0 handleOctChar(c, xi) handleOctChar(c, xi) handleOctChar(c, xi) - if (xi <= 255): add(tok.literal, Chr(xi)) + if (xi <= 255): add(tok.literal, chr(xi)) else: tok.kind = tkInvalid else: tok.kind = tkInvalid -proc HandleCRLF(c: var TSqlLexer, pos: int): int = +proc handleCRLF(c: var SqlLexer, pos: int): int = case c.buf[pos] - of '\c': result = lexbase.HandleCR(c, pos) - of '\L': result = lexbase.HandleLF(c, pos) + of '\c': result = lexbase.handleCR(c, pos) + of '\L': result = lexbase.handleLF(c, pos) else: result = pos -proc skip(c: var TSqlLexer) = +proc skip(c: var SqlLexer) = var pos = c.bufpos var buf = c.buf var nested = 0 while true: case buf[pos] of ' ', '\t': - Inc(pos) + inc(pos) of '-': if buf[pos+1] == '-': while not (buf[pos] in {'\c', '\L', lexbase.EndOfFile}): inc(pos) @@ -163,7 +165,7 @@ proc skip(c: var TSqlLexer) = case buf[pos] of '\0': break of '\c', '\L': - pos = HandleCRLF(c, pos) + pos = handleCRLF(c, pos) buf = c.buf of '*': if buf[pos+1] == '/': @@ -181,14 +183,14 @@ proc skip(c: var TSqlLexer) = else: inc(pos) else: break of '\c', '\L': - pos = HandleCRLF(c, pos) + pos = handleCRLF(c, pos) buf = c.buf else: break # EndOfFile also leaves the loop c.bufpos = pos -proc getString(c: var TSqlLexer, tok: var TToken, kind: TTokKind) = - var pos = c.bufPos + 1 +proc getString(c: var SqlLexer, tok: var Token, kind: TokKind) = + var pos = c.bufpos + 1 var buf = c.buf tok.kind = kind block parseLoop: @@ -206,16 +208,16 @@ proc getString(c: var TSqlLexer, tok: var TToken, kind: TTokKind) = tok.kind = tkInvalid break parseLoop elif (ch == '\\') and kind == tkEscapeConstant: - c.bufPos = pos + c.bufpos = pos getEscapedChar(c, tok) - pos = c.bufPos + pos = c.bufpos else: add(tok.literal, ch) - Inc(pos) + inc(pos) c.bufpos = pos - var line = c.linenumber + var line = c.lineNumber skip(c) - if c.linenumber > line: + if c.lineNumber > line: # a new line whitespace has been parsed, so we check if the string # continues after the whitespace: buf = c.buf # may have been reallocated @@ -225,8 +227,8 @@ proc getString(c: var TSqlLexer, tok: var TToken, kind: TTokKind) = else: break parseLoop c.bufpos = pos -proc getDollarString(c: var TSqlLexer, tok: var TToken) = - var pos = c.bufPos + 1 +proc getDollarString(c: var SqlLexer, tok: var Token) = + var pos = c.bufpos + 1 var buf = c.buf tok.kind = tkDollarQuotedConstant var tag = "$" @@ -240,7 +242,7 @@ proc getDollarString(c: var TSqlLexer, tok: var TToken) = while true: case buf[pos] of '\c', '\L': - pos = HandleCRLF(c, pos) + pos = handleCRLF(c, pos) buf = c.buf add(tok.literal, "\L") of '\0': @@ -261,19 +263,19 @@ proc getDollarString(c: var TSqlLexer, tok: var TToken) = inc(pos) c.bufpos = pos -proc getSymbol(c: var TSqlLexer, tok: var TToken) = +proc getSymbol(c: var SqlLexer, tok: var Token) = var pos = c.bufpos var buf = c.buf while true: add(tok.literal, buf[pos]) - Inc(pos) + inc(pos) if buf[pos] notin {'a'..'z','A'..'Z','0'..'9','_','$', '\128'..'\255'}: break c.bufpos = pos tok.kind = tkIdentifier -proc getQuotedIdentifier(c: var TSqlLexer, tok: var TToken) = - var pos = c.bufPos + 1 +proc getQuotedIdentifier(c: var SqlLexer, tok: var Token) = + var pos = c.bufpos + 1 var buf = c.buf tok.kind = tkQuotedIdentifier while true: @@ -290,11 +292,11 @@ proc getQuotedIdentifier(c: var TSqlLexer, tok: var TToken) = break else: add(tok.literal, ch) - Inc(pos) + inc(pos) c.bufpos = pos -proc getBitHexString(c: var TSqlLexer, tok: var TToken, validChars: TCharSet) = - var pos = c.bufPos + 1 +proc getBitHexString(c: var SqlLexer, tok: var Token, validChars: set[char]) = + var pos = c.bufpos + 1 var buf = c.buf block parseLoop: while true: @@ -302,7 +304,7 @@ proc getBitHexString(c: var TSqlLexer, tok: var TToken, validChars: TCharSet) = var ch = buf[pos] if ch in validChars: add(tok.literal, ch) - Inc(pos) + inc(pos) elif ch == '\'': inc(pos) break @@ -310,9 +312,9 @@ proc getBitHexString(c: var TSqlLexer, tok: var TToken, validChars: TCharSet) = tok.kind = tkInvalid break parseLoop c.bufpos = pos - var line = c.linenumber + var line = c.lineNumber skip(c) - if c.linenumber > line: + if c.lineNumber > line: # a new line whitespace has been parsed, so we check if the string # continues after the whitespace: buf = c.buf # may have been reallocated @@ -322,9 +324,9 @@ proc getBitHexString(c: var TSqlLexer, tok: var TToken, validChars: TCharSet) = else: break parseLoop c.bufpos = pos -proc getNumeric(c: var TSqlLexer, tok: var TToken) = +proc getNumeric(c: var SqlLexer, tok: var Token) = tok.kind = tkInteger - var pos = c.bufPos + var pos = c.bufpos var buf = c.buf while buf[pos] in Digits: add(tok.literal, buf[pos]) @@ -353,11 +355,11 @@ proc getNumeric(c: var TSqlLexer, tok: var TToken) = tok.kind = tkInvalid c.bufpos = pos -proc getOperator(c: var TSqlLexer, tok: var TToken) = +proc getOperator(c: var SqlLexer, tok: var Token) = const operators = {'+', '-', '*', '/', '<', '>', '=', '~', '!', '@', '#', '%', '^', '&', '|', '`', '?'} tok.kind = tkOperator - var pos = c.bufPos + var pos = c.bufpos var buf = c.buf var trailingPlusMinus = false while true: @@ -379,14 +381,14 @@ proc getOperator(c: var TSqlLexer, tok: var TToken) = inc(pos) c.bufpos = pos -proc getTok(c: var TSqlLexer, tok: var TToken) = +proc getTok(c: var SqlLexer, tok: var Token) = tok.kind = tkInvalid - setlen(tok.literal, 0) + setLen(tok.literal, 0) skip(c) case c.buf[c.bufpos] of ';': - tok.kind = tkSemiColon - inc(c.bufPos) + tok.kind = tkSemicolon + inc(c.bufpos) add(tok.literal, ';') of ',': tok.kind = tkComma @@ -397,19 +399,19 @@ proc getTok(c: var TSqlLexer, tok: var TToken) = inc(c.bufpos) add(tok.literal, ':') of 'e', 'E': - if c.buf[c.bufPos + 1] == '\'': - Inc(c.bufPos) + if c.buf[c.bufpos + 1] == '\'': + inc(c.bufpos) getString(c, tok, tkEscapeConstant) else: getSymbol(c, tok) of 'b', 'B': - if c.buf[c.bufPos + 1] == '\'': + if c.buf[c.bufpos + 1] == '\'': tok.kind = tkBitStringConstant getBitHexString(c, tok, {'0'..'1'}) else: getSymbol(c, tok) of 'x', 'X': - if c.buf[c.bufPos + 1] == '\'': + if c.buf[c.bufpos + 1] == '\'': tok.kind = tkHexStringConstant getBitHexString(c, tok, {'a'..'f','A'..'F','0'..'9'}) else: @@ -421,18 +423,18 @@ proc getTok(c: var TSqlLexer, tok: var TToken) = add(tok.literal, '[') of ']': tok.kind = tkBracketRi - Inc(c.bufpos) + inc(c.bufpos) add(tok.literal, ']') of '(': tok.kind = tkParLe - Inc(c.bufpos) + inc(c.bufpos) add(tok.literal, '(') of ')': tok.kind = tkParRi - Inc(c.bufpos) + inc(c.bufpos) add(tok.literal, ')') of '.': - if c.buf[c.bufPos + 1] in Digits: + if c.buf[c.bufpos + 1] in Digits: getNumeric(c, tok) else: tok.kind = tkDot @@ -454,7 +456,7 @@ proc getTok(c: var TSqlLexer, tok: var TToken) = add(tok.literal, c.buf[c.bufpos]) inc(c.bufpos) -proc errorStr(L: TSqlLexer, msg: string): string = +proc errorStr(L: SqlLexer, msg: string): string = result = "$1($2, $3) Error: $4" % [L.filename, $getLine(L), $getColumn(L), msg] @@ -465,7 +467,7 @@ proc errorStr(L: TSqlLexer, msg: string): string = # :: left PostgreSQL-style typecast # [ ] left array element selection # - right unary minus -# ^ left exponentiation +# ^ left exponentiation # * / % left multiplication, division, modulo # + - left addition, subtraction # IS IS TRUE, IS FALSE, IS UNKNOWN, IS NULL @@ -483,7 +485,7 @@ proc errorStr(L: TSqlLexer, msg: string): string = # OR left logical disjunction type - TSqlNodeKind* = enum ## kind of SQL abstract syntax tree + SqlNodeKind* = enum ## kind of SQL abstract syntax tree nkNone, nkIdent, nkStringLit, @@ -536,79 +538,82 @@ type nkEnumDef type - EInvalidSql* = object of EInvalidValue ## Invalid SQL encountered - PSqlNode* = ref TSqlNode ## an SQL abstract syntax tree node - TSqlNode* = object ## an SQL abstract syntax tree node - case kind*: TSqlNodeKind ## kind of syntax tree + SqlParseError* = object of ValueError ## Invalid SQL encountered + SqlNode* = ref SqlNodeObj ## an SQL abstract syntax tree node + SqlNodeObj* = object ## an SQL abstract syntax tree node + case kind*: SqlNodeKind ## kind of syntax tree of nkIdent, nkStringLit, nkBitStringLit, nkHexStringLit, nkIntegerLit, nkNumericLit: strVal*: string ## AST leaf: the identifier, numeric literal ## string literal, etc. else: - sons*: seq[PSqlNode] ## the node's children + sons*: seq[SqlNode] ## the node's children + + SqlParser* = object of SqlLexer ## SQL parser object + tok: Token - TSqlParser* = object of TSqlLexer ## SQL parser object - tok: TToken +{.deprecated: [EInvalidSql: SqlParseError, PSqlNode: SqlNode, + TSqlNode: SqlNodeObj, TSqlParser: SqlParser, TSqlNodeKind: SqlNodeKind].} -proc newNode(k: TSqlNodeKind): PSqlNode = +proc newNode(k: SqlNodeKind): SqlNode = new(result) result.kind = k -proc newNode(k: TSqlNodeKind, s: string): PSqlNode = +proc newNode(k: SqlNodeKind, s: string): SqlNode = new(result) result.kind = k result.strVal = s -proc len*(n: PSqlNode): int = +proc len*(n: SqlNode): int = if isNil(n.sons): result = 0 else: result = n.sons.len -proc add*(father, n: PSqlNode) = +proc add*(father, n: SqlNode) = if isNil(father.sons): father.sons = @[] add(father.sons, n) -proc getTok(p: var TSqlParser) = +proc getTok(p: var SqlParser) = getTok(p, p.tok) -proc sqlError(p: TSqlParser, msg: string) = - var e: ref EInvalidSql +proc sqlError(p: SqlParser, msg: string) = + var e: ref SqlParseError new(e) e.msg = errorStr(p, msg) raise e -proc isKeyw(p: TSqlParser, keyw: string): bool = +proc isKeyw(p: SqlParser, keyw: string): bool = result = p.tok.kind == tkIdentifier and cmpIgnoreCase(p.tok.literal, keyw) == 0 -proc isOpr(p: TSqlParser, opr: string): bool = +proc isOpr(p: SqlParser, opr: string): bool = result = p.tok.kind == tkOperator and cmpIgnoreCase(p.tok.literal, opr) == 0 -proc optKeyw(p: var TSqlParser, keyw: string) = +proc optKeyw(p: var SqlParser, keyw: string) = if p.tok.kind == tkIdentifier and cmpIgnoreCase(p.tok.literal, keyw) == 0: getTok(p) -proc expectIdent(p: TSqlParser) = +proc expectIdent(p: SqlParser) = if p.tok.kind != tkIdentifier and p.tok.kind != tkQuotedIdentifier: sqlError(p, "identifier expected") -proc expect(p: TSqlParser, kind: TTokKind) = +proc expect(p: SqlParser, kind: TokKind) = if p.tok.kind != kind: sqlError(p, tokKindToStr[kind] & " expected") -proc eat(p: var TSqlParser, kind: TTokKind) = +proc eat(p: var SqlParser, kind: TokKind) = if p.tok.kind == kind: getTok(p) else: sqlError(p, tokKindToStr[kind] & " expected") -proc eat(p: var TSqlParser, keyw: string) = +proc eat(p: var SqlParser, keyw: string) = if isKeyw(p, keyw): getTok(p) else: sqlError(p, keyw.toUpper() & " expected") -proc parseDataType(p: var TSqlParser): PSqlNode = +proc parseDataType(p: var SqlParser): SqlNode = if isKeyw(p, "enum"): result = newNode(nkEnumDef) getTok(p) @@ -636,7 +641,7 @@ proc parseDataType(p: var TSqlParser): PSqlNode = getTok(p) eat(p, tkParRi) -proc getPrecedence(p: TSqlParser): int = +proc getPrecedence(p: SqlParser): int = if isOpr(p, "*") or isOpr(p, "/") or isOpr(p, "%"): result = 6 elif isOpr(p, "+") or isOpr(p, "-"): @@ -655,9 +660,9 @@ proc getPrecedence(p: TSqlParser): int = else: result = - 1 -proc parseExpr(p: var TSqlParser): PSqlNode +proc parseExpr(p: var SqlParser): SqlNode -proc identOrLiteral(p: var TSqlParser): PSqlNode = +proc identOrLiteral(p: var SqlParser): SqlNode = case p.tok.kind of tkIdentifier, tkQuotedIdentifier: result = newNode(nkIdent, p.tok.literal) @@ -685,7 +690,7 @@ proc identOrLiteral(p: var TSqlParser): PSqlNode = sqlError(p, "expression expected") getTok(p) # we must consume a token here to prevend endless loops! -proc primary(p: var TSqlParser): PSqlNode = +proc primary(p: var SqlParser): SqlNode = if p.tok.kind == tkOperator or isKeyw(p, "not"): result = newNode(nkPrefix) result.add(newNode(nkIdent, p.tok.literal)) @@ -723,9 +728,9 @@ proc primary(p: var TSqlParser): PSqlNode = getTok(p) else: break -proc lowestExprAux(p: var TSqlParser, v: var PSqlNode, limit: int): int = +proc lowestExprAux(p: var SqlParser, v: var SqlNode, limit: int): int = var - v2, node, opNode: PSqlNode + v2, node, opNode: SqlNode v = primary(p) # expand while operators have priorities higher than 'limit' var opPred = getPrecedence(p) result = opPred @@ -740,14 +745,14 @@ proc lowestExprAux(p: var TSqlParser, v: var PSqlNode, limit: int): int = v = node opPred = getPrecedence(p) -proc parseExpr(p: var TSqlParser): PSqlNode = +proc parseExpr(p: var SqlParser): SqlNode = discard lowestExprAux(p, result, - 1) -proc parseTableName(p: var TSqlParser): PSqlNode = +proc parseTableName(p: var SqlParser): SqlNode = expectIdent(p) result = primary(p) -proc parseColumnReference(p: var TSqlParser): PSqlNode = +proc parseColumnReference(p: var SqlParser): SqlNode = result = parseTableName(p) if p.tok.kind == tkParLe: getTok(p) @@ -760,12 +765,12 @@ proc parseColumnReference(p: var TSqlParser): PSqlNode = result.add(parseTableName(p)) eat(p, tkParRi) -proc parseCheck(p: var TSqlParser): PSqlNode = +proc parseCheck(p: var SqlParser): SqlNode = getTok(p) result = newNode(nkCheck) result.add(parseExpr(p)) -proc parseConstraint(p: var TSqlParser): PSqlNode = +proc parseConstraint(p: var SqlParser): SqlNode = getTok(p) result = newNode(nkConstraint) expectIdent(p) @@ -774,7 +779,7 @@ proc parseConstraint(p: var TSqlParser): PSqlNode = eat(p, "check") result.add(parseExpr(p)) -proc parseColumnConstraints(p: var TSqlParser, result: PSqlNode) = +proc parseColumnConstraints(p: var SqlParser, result: SqlNode) = while true: if isKeyw(p, "default"): getTok(p) @@ -806,7 +811,7 @@ proc parseColumnConstraints(p: var TSqlParser, result: PSqlNode) = else: break -proc parseColumnDef(p: var TSqlParser): PSqlNode = +proc parseColumnDef(p: var SqlParser): SqlNode = expectIdent(p) result = newNode(nkColumnDef) result.add(newNode(nkIdent, p.tok.literal)) @@ -814,7 +819,7 @@ proc parseColumnDef(p: var TSqlParser): PSqlNode = result.add(parseDataType(p)) parseColumnConstraints(p, result) -proc parseIfNotExists(p: var TSqlParser, k: TSqlNodeKind): PSqlNode = +proc parseIfNotExists(p: var SqlParser, k: SqlNodeKind): SqlNode = getTok(p) if isKeyw(p, "if"): getTok(p) @@ -824,7 +829,7 @@ proc parseIfNotExists(p: var TSqlParser, k: TSqlNodeKind): PSqlNode = else: result = newNode(k) -proc parseParIdentList(p: var TSqlParser, father: PSqlNode) = +proc parseParIdentList(p: var SqlParser, father: SqlNode) = eat(p, tkParLe) while true: expectIdent(p) @@ -834,7 +839,7 @@ proc parseParIdentList(p: var TSqlParser, father: PSqlNode) = getTok(p) eat(p, tkParRi) -proc parseTableConstraint(p: var TSqlParser): PSqlNode = +proc parseTableConstraint(p: var SqlParser): SqlNode = if isKeyw(p, "primary"): getTok(p) eat(p, "key") @@ -861,7 +866,7 @@ proc parseTableConstraint(p: var TSqlParser): PSqlNode = else: sqlError(p, "column definition expected") -proc parseTableDef(p: var TSqlParser): PSqlNode = +proc parseTableDef(p: var SqlParser): SqlNode = result = parseIfNotExists(p, nkCreateTable) expectIdent(p) result.add(newNode(nkIdent, p.tok.literal)) @@ -876,7 +881,7 @@ proc parseTableDef(p: var TSqlParser): PSqlNode = if p.tok.kind != tkComma: break eat(p, tkParRi) -proc parseTypeDef(p: var TSqlParser): PSqlNode = +proc parseTypeDef(p: var SqlParser): SqlNode = result = parseIfNotExists(p, nkCreateType) expectIdent(p) result.add(newNode(nkIdent, p.tok.literal)) @@ -884,12 +889,12 @@ proc parseTypeDef(p: var TSqlParser): PSqlNode = eat(p, "as") result.add(parseDataType(p)) -proc parseWhere(p: var TSqlParser): PSqlNode = +proc parseWhere(p: var SqlParser): SqlNode = getTok(p) result = newNode(nkWhere) result.add(parseExpr(p)) -proc parseIndexDef(p: var TSqlParser): PSqlNode = +proc parseIndexDef(p: var SqlParser): SqlNode = result = parseIfNotExists(p, nkCreateIndex) if isKeyw(p, "primary"): getTok(p) @@ -914,7 +919,7 @@ proc parseIndexDef(p: var TSqlParser): PSqlNode = getTok(p) eat(p, tkParRi) -proc parseInsert(p: var TSqlParser): PSqlNode = +proc parseInsert(p: var SqlParser): SqlNode = getTok(p) eat(p, "into") expectIdent(p) @@ -941,7 +946,7 @@ proc parseInsert(p: var TSqlParser): PSqlNode = result.add(n) eat(p, tkParRi) -proc parseUpdate(p: var TSqlParser): PSqlNode = +proc parseUpdate(p: var SqlParser): SqlNode = getTok(p) result = newNode(nkUpdate) result.add(primary(p)) @@ -962,7 +967,7 @@ proc parseUpdate(p: var TSqlParser): PSqlNode = else: result.add(nil) -proc parseDelete(p: var TSqlParser): PSqlNode = +proc parseDelete(p: var SqlParser): SqlNode = getTok(p) result = newNode(nkDelete) eat(p, "from") @@ -972,7 +977,7 @@ proc parseDelete(p: var TSqlParser): PSqlNode = else: result.add(nil) -proc parseSelect(p: var TSqlParser): PSqlNode = +proc parseSelect(p: var SqlParser): SqlNode = getTok(p) if isKeyw(p, "distinct"): getTok(p) @@ -1041,7 +1046,7 @@ proc parseSelect(p: var TSqlParser): PSqlNode = getTok(p) result.add(n) -proc parseStmt(p: var TSqlParser): PSqlNode = +proc parseStmt(p: var SqlParser): SqlNode = if isKeyw(p, "create"): getTok(p) optKeyw(p, "cached") @@ -1071,43 +1076,43 @@ proc parseStmt(p: var TSqlParser): PSqlNode = else: sqlError(p, "CREATE expected") -proc open(p: var TSqlParser, input: PStream, filename: string) = +proc open(p: var SqlParser, input: Stream, filename: string) = ## opens the parser `p` and assigns the input stream `input` to it. ## `filename` is only used for error messages. - open(TSqlLexer(p), input, filename) + open(SqlLexer(p), input, filename) p.tok.kind = tkInvalid p.tok.literal = "" getTok(p) -proc parse(p: var TSqlParser): PSqlNode = +proc parse(p: var SqlParser): SqlNode = ## parses the content of `p`'s input stream and returns the SQL AST. ## Syntax errors raise an `EInvalidSql` exception. result = newNode(nkStmtList) while p.tok.kind != tkEof: var s = parseStmt(p) - eat(p, tkSemiColon) + eat(p, tkSemicolon) result.add(s) if result.len == 1: result = result.sons[0] -proc close(p: var TSqlParser) = +proc close(p: var SqlParser) = ## closes the parser `p`. The associated input stream is closed too. - close(TSqlLexer(p)) + close(SqlLexer(p)) -proc parseSQL*(input: PStream, filename: string): PSqlNode = +proc parseSQL*(input: Stream, filename: string): SqlNode = ## parses the SQL from `input` into an AST and returns the AST. ## `filename` is only used for error messages. ## Syntax errors raise an `EInvalidSql` exception. - var p: TSqlParser + var p: SqlParser open(p, input, filename) try: result = parse(p) finally: close(p) -proc ra(n: PSqlNode, s: var string, indent: int) +proc ra(n: SqlNode, s: var string, indent: int) -proc rs(n: PSqlNode, s: var string, indent: int, +proc rs(n: SqlNode, s: var string, indent: int, prefix = "(", suffix = ")", sep = ", ") = if n.len > 0: @@ -1117,7 +1122,7 @@ proc rs(n: PSqlNode, s: var string, indent: int, ra(n.sons[i], s, indent) s.add(suffix) -proc ra(n: PSqlNode, s: var string, indent: int) = +proc ra(n: SqlNode, s: var string, indent: int) = if n == nil: return case n.kind of nkNone: discard @@ -1320,7 +1325,7 @@ proc ra(n: PSqlNode, s: var string, indent: int) = #for x, y, z in db.select(fromm = a, b where = a.name == b.name): # writeln x, y, z -proc renderSQL*(n: PSqlNode): string = +proc renderSQL*(n: SqlNode): string = ## Converts an SQL abstract syntax tree to its string representation. result = "" ra(n, result, 0) diff --git a/lib/pure/parseurl.nim b/lib/pure/parseurl.nim index 67c6de905..32e69b89a 100644 --- a/lib/pure/parseurl.nim +++ b/lib/pure/parseurl.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Dominik Picheta # # See the file "copying.txt", included in this @@ -15,12 +15,14 @@ import strutils type - TUrl* = tuple[ ## represents a *Uniform Resource Locator* (URL) - ## any optional component is "" if it does not exist + Url* = tuple[ ## represents a *Uniform Resource Locator* (URL) + ## any optional component is "" if it does not exist scheme, username, password, hostname, port, path, query, anchor: string] - -proc parseUrl*(url: string): TUrl {.deprecated.} = + +{.deprecated: [TUrl: Url].} + +proc parseUrl*(url: string): Url {.deprecated.} = var i = 0 var scheme, username, password: string = "" @@ -29,12 +31,12 @@ proc parseUrl*(url: string): TUrl {.deprecated.} = var temp = "" if url[i] != '/': # url isn't a relative path - while True: + while true: # Scheme if url[i] == ':': if url[i+1] == '/' and url[i+2] == '/': scheme = temp - temp.setlen(0) + temp.setLen(0) inc(i, 3) # Skip the // # Authority(username, password) if url[i] == '@': @@ -43,7 +45,7 @@ proc parseUrl*(url: string): TUrl {.deprecated.} = if colon >= 0: password = username.substr(colon+1) username = username.substr(0, colon-1) - temp.setlen(0) + temp.setLen(0) inc(i) #Skip the @ # hostname(subdomain, domain, port) if url[i] == '/' or url[i] == '\0': @@ -53,7 +55,7 @@ proc parseUrl*(url: string): TUrl {.deprecated.} = port = hostname.substr(colon+1) hostname = hostname.substr(0, colon-1) - temp.setlen(0) + temp.setLen(0) break temp.add(url[i]) @@ -61,16 +63,16 @@ proc parseUrl*(url: string): TUrl {.deprecated.} = if url[i] == '/': inc(i) # Skip the '/' # Path - while True: + while true: if url[i] == '?': path = temp - temp.setlen(0) + temp.setLen(0) if url[i] == '#': if temp[0] == '?': query = temp else: path = temp - temp.setlen(0) + temp.setLen(0) if url[i] == '\0': if temp[0] == '?': @@ -86,7 +88,7 @@ proc parseUrl*(url: string): TUrl {.deprecated.} = return (scheme, username, password, hostname, port, path, query, anchor) -proc `$`*(u: TUrl): string {.deprecated.} = +proc `$`*(u: Url): string {.deprecated.} = ## turns the URL `u` into its string representation. result = "" if u.scheme.len > 0: diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim index 06ee07aa8..8f8ca6ab3 100644 --- a/lib/pure/parseutils.nim +++ b/lib/pure/parseutils.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -35,7 +35,7 @@ proc parseHex*(s: string, number: var int, start = 0): int {. ## can use this feature to *chain* calls, though the result int will quickly ## overflow. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var value = 0 ## discard parseHex("0x38", value) ## assert value == 56 @@ -227,7 +227,7 @@ proc parseInt*(s: string, number: var int, start = 0): int {. result = parseBiggestInt(s, res, start) if (sizeof(int) <= 4) and ((res < low(int)) or (res > high(int))): - raise newException(EOverflow, "overflow") + raise newException(OverflowError, "overflow") else: number = int(res) @@ -332,7 +332,7 @@ proc parseFloat*(s: string, number: var float, start = 0): int {. number = bf type - TInterpolatedKind* = enum ## describes for `interpolatedFragments` + InterpolatedKind* = enum ## describes for `interpolatedFragments` ## which part of the interpolated string is ## yielded; for example in "str$$$var${expr}" ikStr, ## ``str`` part of the interpolated string @@ -340,19 +340,21 @@ type ikVar, ## ``var`` part of the interpolated string ikExpr ## ``expr`` part of the interpolated string -iterator interpolatedFragments*(s: string): tuple[kind: TInterpolatedKind, +{.deprecated: [TInterpolatedKind: InterpolatedKind].} + +iterator interpolatedFragments*(s: string): tuple[kind: InterpolatedKind, value: string] = ## Tokenizes the string `s` into substrings for interpolation purposes. ## ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for k, v in interpolatedFragments(" $this is ${an example} $$"): ## echo "(", k, ", \"", v, "\")" ## ## Results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## (ikString, " ") ## (ikExpr, "this") ## (ikString, " is ") @@ -360,7 +362,7 @@ iterator interpolatedFragments*(s: string): tuple[kind: TInterpolatedKind, ## (ikString, " ") ## (ikDollar, "$") var i = 0 - var kind: TInterpolatedKind + var kind: InterpolatedKind while true: var j = i if s[j] == '$': @@ -376,7 +378,7 @@ iterator interpolatedFragments*(s: string): tuple[kind: TInterpolatedKind, break dec nesting of '\0': - raise newException(EInvalidValue, + raise newException(ValueError, "Expected closing '}': " & s[i..s.len]) else: discard inc j @@ -392,7 +394,7 @@ iterator interpolatedFragments*(s: string): tuple[kind: TInterpolatedKind, inc i # skip $ kind = ikDollar else: - raise newException(EInvalidValue, + raise newException(ValueError, "Unable to parse a varible name at " & s[i..s.len]) else: while j < s.len and s[j] != '$': inc j diff --git a/lib/pure/parsexml.nim b/lib/pure/parsexml.nim index 667b8aed6..39dead3c0 100644 --- a/lib/pure/parsexml.nim +++ b/lib/pure/parsexml.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this @@ -33,7 +33,7 @@ ## XML parser to accomplish a simple task: To determine the title of an HTML ## document. ## -## .. code-block:: nimrod +## .. code-block:: nim ## :file: examples/htmltitle.nim ## ## @@ -44,7 +44,7 @@ ## XML parser to accomplish another simple task: To determine all the links ## an HTML document contains. ## -## .. code-block:: nimrod +## .. code-block:: nim ## :file: examples/htmlrefs.nim ## @@ -56,7 +56,7 @@ import # xmlElementCloseEnd, ## ``/>`` type - TXmlEventKind* = enum ## enumation of all events that may occur when parsing + XmlEventKind* = enum ## enumation of all events that may occur when parsing xmlError, ## an error ocurred during parsing xmlEof, ## end of file reached xmlCharData, ## character data @@ -72,7 +72,7 @@ type xmlEntity, ## &entity; xmlSpecial ## ``<! ... data ... >`` - TXmlError* = enum ## enumeration that lists all errors that can occur + XmlErrorKind* = enum ## enumeration that lists all errors that can occur errNone, ## no error errEndOfCDataExpected, ## ``]]>`` expected errNameExpected, ## name expected @@ -83,23 +83,26 @@ type errQuoteExpected, ## ``"`` or ``'`` expected errEndOfCommentExpected ## ``-->`` expected - TParserState = enum + ParserState = enum stateStart, stateNormal, stateAttr, stateEmptyElementTag, stateError - TXmlParseOption* = enum ## options for the XML parser + XmlParseOption* = enum ## options for the XML parser reportWhitespace, ## report whitespace reportComments ## report comments - TXmlParser* = object of TBaseLexer ## the parser object. + XmlParser* = object of BaseLexer ## the parser object. a, b, c: string - kind: TXmlEventKind - err: TXmlError - state: TParserState + kind: XmlEventKind + err: XmlErrorKind + state: ParserState filename: string - options: set[TXmlParseOption] - + options: set[XmlParseOption] + +{.deprecated: [TXmlParser: XmlParser, TXmlParseOptions: XmlParseOption, + TXmlError: XmlErrorKind, TXmlEventKind: XmlEventKind].} + const - errorMessages: array [TXmlError, string] = [ + errorMessages: array[XmlErrorKind, string] = [ "no error", "']]>' expected", "name expected", @@ -111,8 +114,8 @@ const "'-->' expected" ] -proc open*(my: var TXmlParser, input: PStream, filename: string, - options: set[TXmlParseOption] = {}) = +proc open*(my: var XmlParser, input: Stream, filename: string, + options: set[XmlParseOption] = {}) = ## initializes the parser with an input stream. `Filename` is only used ## for nice error messages. The parser's behaviour can be controlled by ## the `options` parameter: If `options` contains ``reportWhitespace`` @@ -127,97 +130,97 @@ proc open*(my: var TXmlParser, input: PStream, filename: string, my.b = "" my.options = options -proc close*(my: var TXmlParser) {.inline.} = +proc close*(my: var XmlParser) {.inline.} = ## closes the parser `my` and its associated input stream. lexbase.close(my) -proc kind*(my: TXmlParser): TXmlEventKind {.inline.} = +proc kind*(my: XmlParser): XmlEventKind {.inline.} = ## returns the current event type for the XML parser return my.kind -proc charData*(my: TXmlParser): string {.inline.} = +proc charData*(my: XmlParser): string {.inline.} = ## returns the character data for the events: ``xmlCharData``, ## ``xmlWhitespace``, ``xmlComment``, ``xmlCData``, ``xmlSpecial`` assert(my.kind in {xmlCharData, xmlWhitespace, xmlComment, xmlCData, xmlSpecial}) return my.a -proc elementName*(my: TXmlParser): string {.inline.} = +proc elementName*(my: XmlParser): string {.inline.} = ## returns the element name for the events: ``xmlElementStart``, ## ``xmlElementEnd``, ``xmlElementOpen`` assert(my.kind in {xmlElementStart, xmlElementEnd, xmlElementOpen}) return my.a -proc entityName*(my: TXmlParser): string {.inline.} = +proc entityName*(my: XmlParser): string {.inline.} = ## returns the entity name for the event: ``xmlEntity`` assert(my.kind == xmlEntity) return my.a -proc attrKey*(my: TXmlParser): string {.inline.} = +proc attrKey*(my: XmlParser): string {.inline.} = ## returns the attribute key for the event ``xmlAttribute`` assert(my.kind == xmlAttribute) return my.a -proc attrValue*(my: TXmlParser): string {.inline.} = +proc attrValue*(my: XmlParser): string {.inline.} = ## returns the attribute value for the event ``xmlAttribute`` assert(my.kind == xmlAttribute) return my.b -proc PIName*(my: TXmlParser): string {.inline.} = +proc piName*(my: XmlParser): string {.inline.} = ## returns the processing instruction name for the event ``xmlPI`` assert(my.kind == xmlPI) return my.a -proc PIRest*(my: TXmlParser): string {.inline.} = +proc piRest*(my: XmlParser): string {.inline.} = ## returns the rest of the processing instruction for the event ``xmlPI`` assert(my.kind == xmlPI) return my.b -proc rawData*(my: TXmlParser): string {.inline.} = +proc rawData*(my: XmlParser): string {.inline.} = ## returns the underlying 'data' string by reference. ## This is only used for speed hacks. shallowCopy(result, my.a) -proc rawData2*(my: TXmlParser): string {.inline.} = +proc rawData2*(my: XmlParser): string {.inline.} = ## returns the underlying second 'data' string by reference. ## This is only used for speed hacks. shallowCopy(result, my.b) -proc getColumn*(my: TXmlParser): int {.inline.} = +proc getColumn*(my: XmlParser): int {.inline.} = ## get the current column the parser has arrived at. - result = getColNumber(my, my.bufPos) + result = getColNumber(my, my.bufpos) -proc getLine*(my: TXmlParser): int {.inline.} = +proc getLine*(my: XmlParser): int {.inline.} = ## get the current line the parser has arrived at. - result = my.linenumber + result = my.lineNumber -proc getFilename*(my: TXmlParser): string {.inline.} = +proc getFilename*(my: XmlParser): string {.inline.} = ## get the filename of the file that the parser processes. result = my.filename -proc errorMsg*(my: TXmlParser): string = +proc errorMsg*(my: XmlParser): string = ## returns a helpful error message for the event ``xmlError`` assert(my.kind == xmlError) result = "$1($2, $3) Error: $4" % [ my.filename, $getLine(my), $getColumn(my), errorMessages[my.err]] -proc errorMsgExpected*(my: TXmlParser, tag: string): string = +proc errorMsgExpected*(my: XmlParser, tag: string): string = ## returns an error message "<tag> expected" in the same format as the ## other error messages result = "$1($2, $3) Error: $4" % [ my.filename, $getLine(my), $getColumn(my), "<$1> expected" % tag] -proc errorMsg*(my: TXmlParser, msg: string): string = +proc errorMsg*(my: XmlParser, msg: string): string = ## returns an error message with text `msg` in the same format as the ## other error messages result = "$1($2, $3) Error: $4" % [ my.filename, $getLine(my), $getColumn(my), msg] -proc markError(my: var TXmlParser, kind: TXmlError) {.inline.} = +proc markError(my: var XmlParser, kind: XmlErrorKind) {.inline.} = my.err = kind my.state = stateError -proc parseCDATA(my: var TXMLParser) = +proc parseCDATA(my: var XmlParser) = var pos = my.bufpos + len("<![CDATA[") var buf = my.buf while true: @@ -232,20 +235,20 @@ proc parseCDATA(my: var TXMLParser) = markError(my, errEndOfCDataExpected) break of '\c': - pos = lexbase.HandleCR(my, pos) + pos = lexbase.handleCR(my, pos) buf = my.buf add(my.a, '\L') of '\L': - pos = lexbase.HandleLF(my, pos) + pos = lexbase.handleLF(my, pos) buf = my.buf add(my.a, '\L') else: add(my.a, buf[pos]) inc(pos) my.bufpos = pos # store back - my.kind = xmlCDATA + my.kind = xmlCData -proc parseComment(my: var TXMLParser) = +proc parseComment(my: var XmlParser) = var pos = my.bufpos + len("<!--") var buf = my.buf while true: @@ -260,11 +263,11 @@ proc parseComment(my: var TXMLParser) = markError(my, errEndOfCommentExpected) break of '\c': - pos = lexbase.HandleCR(my, pos) + pos = lexbase.handleCR(my, pos) buf = my.buf if my.options.contains(reportComments): add(my.a, '\L') of '\L': - pos = lexbase.HandleLF(my, pos) + pos = lexbase.handleLF(my, pos) buf = my.buf if my.options.contains(reportComments): add(my.a, '\L') else: @@ -273,21 +276,21 @@ proc parseComment(my: var TXMLParser) = my.bufpos = pos my.kind = xmlComment -proc parseWhitespace(my: var TXmlParser, skip=False) = +proc parseWhitespace(my: var XmlParser, skip=false) = var pos = my.bufpos var buf = my.buf while true: case buf[pos] of ' ', '\t': if not skip: add(my.a, buf[pos]) - Inc(pos) + inc(pos) of '\c': # the specification says that CR-LF, CR are to be transformed to LF - pos = lexbase.HandleCR(my, pos) + pos = lexbase.handleCR(my, pos) buf = my.buf if not skip: add(my.a, '\L') of '\L': - pos = lexbase.HandleLF(my, pos) + pos = lexbase.handleLF(my, pos) buf = my.buf if not skip: add(my.a, '\L') else: @@ -298,10 +301,10 @@ const NameStartChar = {'A'..'Z', 'a'..'z', '_', ':', '\128'..'\255'} NameChar = {'A'..'Z', 'a'..'z', '0'..'9', '.', '-', '_', ':', '\128'..'\255'} -proc parseName(my: var TXmlParser, dest: var string) = +proc parseName(my: var XmlParser, dest: var string) = var pos = my.bufpos var buf = my.buf - if buf[pos] in nameStartChar: + if buf[pos] in NameStartChar: while true: add(dest, buf[pos]) inc(pos) @@ -310,7 +313,7 @@ proc parseName(my: var TXmlParser, dest: var string) = else: markError(my, errNameExpected) -proc parseEntity(my: var TXmlParser, dest: var string) = +proc parseEntity(my: var XmlParser, dest: var string) = var pos = my.bufpos+1 var buf = my.buf my.kind = xmlCharData @@ -330,7 +333,7 @@ proc parseEntity(my: var TXmlParser, dest: var string) = while buf[pos] in {'0'..'9'}: r = r * 10 + (ord(buf[pos]) - ord('0')) inc(pos) - add(dest, toUTF8(TRune(r))) + add(dest, toUTF8(Rune(r))) elif buf[pos] == 'l' and buf[pos+1] == 't' and buf[pos+2] == ';': add(dest, '<') inc(pos, 2) @@ -360,10 +363,10 @@ proc parseEntity(my: var TXmlParser, dest: var string) = if buf[pos] == ';': inc(pos) else: - markError(my, errSemiColonExpected) + markError(my, errSemicolonExpected) my.bufpos = pos -proc parsePI(my: var TXmlParser) = +proc parsePI(my: var XmlParser) = inc(my.bufpos, "<?".len) parseName(my, my.a) var pos = my.bufpos @@ -382,11 +385,11 @@ proc parsePI(my: var TXmlParser) = inc(pos) of '\c': # the specification says that CR-LF, CR are to be transformed to LF - pos = lexbase.HandleCR(my, pos) + pos = lexbase.handleCR(my, pos) buf = my.buf add(my.b, '\L') of '\L': - pos = lexbase.HandleLF(my, pos) + pos = lexbase.handleLF(my, pos) buf = my.buf add(my.b, '\L') else: @@ -395,7 +398,7 @@ proc parsePI(my: var TXmlParser) = my.bufpos = pos my.kind = xmlPI -proc parseSpecial(my: var TXmlParser) = +proc parseSpecial(my: var XmlParser) = # things that start with <! var pos = my.bufpos + 2 var buf = my.buf @@ -417,11 +420,11 @@ proc parseSpecial(my: var TXmlParser) = inc(pos) add(my.a, '>') of '\c': - pos = lexbase.HandleCR(my, pos) + pos = lexbase.handleCR(my, pos) buf = my.buf add(my.a, '\L') of '\L': - pos = lexbase.HandleLF(my, pos) + pos = lexbase.handleLF(my, pos) buf = my.buf add(my.a, '\L') else: @@ -430,7 +433,7 @@ proc parseSpecial(my: var TXmlParser) = my.bufpos = pos my.kind = xmlSpecial -proc parseTag(my: var TXmlParser) = +proc parseTag(my: var XmlParser) = inc(my.bufpos) parseName(my, my.a) # if we have no name, do not interpret the '<': @@ -438,7 +441,7 @@ proc parseTag(my: var TXmlParser) = my.kind = xmlCharData add(my.a, '<') return - parseWhitespace(my, skip=True) + parseWhitespace(my, skip=true) if my.buf[my.bufpos] in NameStartChar: # an attribute follows: my.kind = xmlElementOpen @@ -455,17 +458,17 @@ proc parseTag(my: var TXmlParser) = else: markError(my, errGtExpected) -proc parseEndTag(my: var TXmlParser) = +proc parseEndTag(my: var XmlParser) = inc(my.bufpos, 2) parseName(my, my.a) - parseWhitespace(my, skip=True) + parseWhitespace(my, skip=true) if my.buf[my.bufpos] == '>': inc(my.bufpos) else: markError(my, errGtExpected) my.kind = xmlElementEnd -proc parseAttribute(my: var TXmlParser) = +proc parseAttribute(my: var XmlParser) = my.kind = xmlAttribute setLen(my.a, 0) setLen(my.b, 0) @@ -474,12 +477,12 @@ proc parseAttribute(my: var TXmlParser) = if my.a.len == 0: markError(my, errGtExpected) return - parseWhitespace(my, skip=True) + parseWhitespace(my, skip=true) if my.buf[my.bufpos] != '=': markError(my, errEqExpected) return inc(my.bufpos) - parseWhitespace(my, skip=True) + parseWhitespace(my, skip=true) var pos = my.bufpos var buf = my.buf @@ -504,11 +507,11 @@ proc parseAttribute(my: var TXmlParser) = pendingSpace = true inc(pos) of '\c': - pos = lexbase.HandleCR(my, pos) + pos = lexbase.handleCR(my, pos) buf = my.buf pendingSpace = true of '\L': - pos = lexbase.HandleLF(my, pos) + pos = lexbase.handleLF(my, pos) buf = my.buf pendingSpace = true else: @@ -524,9 +527,9 @@ proc parseAttribute(my: var TXmlParser) = else: markError(my, errQuoteExpected) my.bufpos = pos - parseWhitespace(my, skip=True) + parseWhitespace(my, skip=true) -proc parseCharData(my: var TXmlParser) = +proc parseCharData(my: var XmlParser) = var pos = my.bufpos var buf = my.buf while true: @@ -534,11 +537,11 @@ proc parseCharData(my: var TXmlParser) = of '\0', '<', '&': break of '\c': # the specification says that CR-LF, CR are to be transformed to LF - pos = lexbase.HandleCR(my, pos) + pos = lexbase.handleCR(my, pos) buf = my.buf add(my.a, '\L') of '\L': - pos = lexbase.HandleLF(my, pos) + pos = lexbase.handleLF(my, pos) buf = my.buf add(my.a, '\L') else: @@ -547,7 +550,7 @@ proc parseCharData(my: var TXmlParser) = my.bufpos = pos my.kind = xmlCharData -proc rawGetTok(my: var TXmlParser) = +proc rawGetTok(my: var XmlParser) = my.kind = xmlError setLen(my.a, 0) var pos = my.bufpos @@ -571,7 +574,7 @@ proc rawGetTok(my: var TXmlParser) = else: parseTag(my) of ' ', '\t', '\c', '\l': - parseWhiteSpace(my) + parseWhitespace(my) my.kind = xmlWhitespace of '\0': my.kind = xmlEof @@ -581,7 +584,7 @@ proc rawGetTok(my: var TXmlParser) = parseCharData(my) assert my.kind != xmlError -proc getTok(my: var TXmlParser) = +proc getTok(my: var XmlParser) = while true: rawGetTok(my) case my.kind @@ -591,7 +594,7 @@ proc getTok(my: var TXmlParser) = if my.options.contains(reportWhitespace): break else: break -proc next*(my: var TXmlParser) = +proc next*(my: var XmlParser) = ## retrieves the first/next event. This controls the parser. case my.state of stateNormal: @@ -626,19 +629,19 @@ proc next*(my: var TXmlParser) = when isMainModule: import os - var s = newFileStream(ParamStr(1), fmRead) - if s == nil: quit("cannot open the file" & ParamStr(1)) - var x: TXmlParser - open(x, s, ParamStr(1)) + var s = newFileStream(paramStr(1), fmRead) + if s == nil: quit("cannot open the file" & paramStr(1)) + var x: XmlParser + open(x, s, paramStr(1)) while true: next(x) case x.kind - of xmlError: Echo(x.errorMsg()) + of xmlError: echo(x.errorMsg()) of xmlEof: break of xmlCharData: echo(x.charData) of xmlWhitespace: echo("|$1|" % x.charData) of xmlComment: echo("<!-- $1 -->" % x.charData) - of xmlPI: echo("<? $1 ## $2 ?>" % [x.PIName, x.PIRest]) + of xmlPI: echo("<? $1 ## $2 ?>" % [x.piName, x.piRest]) of xmlElementStart: echo("<$1>" % x.elementName) of xmlElementEnd: echo("</$1>" % x.elementName) diff --git a/lib/pure/pegs.nim b/lib/pure/pegs.nim index efe169c1d..6eb7dee78 100644 --- a/lib/pure/pegs.nim +++ b/lib/pure/pegs.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -32,7 +32,7 @@ const ## can be captured. More subpatterns cannot be captured! type - TPegKind = enum + PegKind = enum pkEmpty, pkAny, ## any character (.) pkAnyRune, ## any Unicode character (_) @@ -67,28 +67,30 @@ type pkRule, ## a <- b pkList, ## a, b pkStartAnchor ## ^ --> Internal DSL: startAnchor() - TNonTerminalFlag = enum + NonTerminalFlag = enum ntDeclared, ntUsed - TNonTerminal {.final.} = object ## represents a non terminal symbol + NonTerminalObj = object ## represents a non terminal symbol name: string ## the name of the symbol line: int ## line the symbol has been declared/used in col: int ## column the symbol has been declared/used in - flags: set[TNonTerminalFlag] ## the nonterminal's flags + flags: set[NonTerminalFlag] ## the nonterminal's flags rule: TNode ## the rule that the symbol refers to - TNode {.final, shallow.} = object - case kind: TPegKind + TNode {.shallow.} = object + case kind: PegKind of pkEmpty..pkWhitespace: nil of pkTerminal, pkTerminalIgnoreCase, pkTerminalIgnoreStyle: term: string of pkChar, pkGreedyRepChar: ch: char of pkCharChoice, pkGreedyRepSet: charChoice: ref set[char] - of pkNonTerminal: nt: PNonTerminal + of pkNonTerminal: nt: NonTerminal of pkBackRef..pkBackRefIgnoreStyle: index: range[0..MaxSubpatterns] else: sons: seq[TNode] - PNonTerminal* = ref TNonTerminal + NonTerminal* = ref NonTerminalObj - TPeg* = TNode ## type that represents a PEG + Peg* = TNode ## type that represents a PEG -proc term*(t: string): TPeg {.nosideEffect, rtl, extern: "npegs$1Str".} = +{.deprecated: [TPeg: Peg].} + +proc term*(t: string): Peg {.nosideEffect, rtl, extern: "npegs$1Str".} = ## constructs a PEG from a terminal string if t.len != 1: result.kind = pkTerminal @@ -97,35 +99,35 @@ proc term*(t: string): TPeg {.nosideEffect, rtl, extern: "npegs$1Str".} = result.kind = pkChar result.ch = t[0] -proc termIgnoreCase*(t: string): TPeg {. +proc termIgnoreCase*(t: string): Peg {. nosideEffect, rtl, extern: "npegs$1".} = ## constructs a PEG from a terminal string; ignore case for matching result.kind = pkTerminalIgnoreCase result.term = t -proc termIgnoreStyle*(t: string): TPeg {. +proc termIgnoreStyle*(t: string): Peg {. nosideEffect, rtl, extern: "npegs$1".} = ## constructs a PEG from a terminal string; ignore style for matching result.kind = pkTerminalIgnoreStyle result.term = t -proc term*(t: char): TPeg {.nosideEffect, rtl, extern: "npegs$1Char".} = +proc term*(t: char): Peg {.nosideEffect, rtl, extern: "npegs$1Char".} = ## constructs a PEG from a terminal char assert t != '\0' result.kind = pkChar result.ch = t -proc charSet*(s: set[char]): TPeg {.nosideEffect, rtl, extern: "npegs$1".} = +proc charSet*(s: set[char]): Peg {.nosideEffect, rtl, extern: "npegs$1".} = ## constructs a PEG from a character set `s` assert '\0' notin s result.kind = pkCharChoice new(result.charChoice) result.charChoice[] = s -proc len(a: TPeg): int {.inline.} = return a.sons.len -proc add(d: var TPeg, s: TPeg) {.inline.} = add(d.sons, s) +proc len(a: Peg): int {.inline.} = return a.sons.len +proc add(d: var Peg, s: Peg) {.inline.} = add(d.sons, s) -proc addChoice(dest: var TPeg, elem: TPeg) = +proc addChoice(dest: var Peg, elem: Peg) = var L = dest.len-1 if L >= 0 and dest.sons[L].kind == pkCharChoice: # caution! Do not introduce false aliasing here! @@ -137,7 +139,7 @@ proc addChoice(dest: var TPeg, elem: TPeg) = else: add(dest, elem) else: add(dest, elem) -template multipleOp(k: TPegKind, localOpt: expr) = +template multipleOp(k: PegKind, localOpt: expr) = result.kind = k result.sons = @[] for x in items(a): @@ -149,12 +151,12 @@ template multipleOp(k: TPegKind, localOpt: expr) = if result.len == 1: result = result.sons[0] -proc `/`*(a: varargs[TPeg]): TPeg {. +proc `/`*(a: varargs[Peg]): Peg {. nosideEffect, rtl, extern: "npegsOrderedChoice".} = ## constructs an ordered choice with the PEGs in `a` multipleOp(pkOrderedChoice, addChoice) -proc addSequence(dest: var TPeg, elem: TPeg) = +proc addSequence(dest: var Peg, elem: Peg) = var L = dest.len-1 if L >= 0 and dest.sons[L].kind == pkTerminal: # caution! Do not introduce false aliasing here! @@ -166,12 +168,12 @@ proc addSequence(dest: var TPeg, elem: TPeg) = else: add(dest, elem) else: add(dest, elem) -proc sequence*(a: varargs[TPeg]): TPeg {. +proc sequence*(a: varargs[Peg]): Peg {. nosideEffect, rtl, extern: "npegs$1".} = ## constructs a sequence with all the PEGs from `a` multipleOp(pkSequence, addSequence) -proc `?`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsOptional".} = +proc `?`*(a: Peg): Peg {.nosideEffect, rtl, extern: "npegsOptional".} = ## constructs an optional for the PEG `a` if a.kind in {pkOption, pkGreedyRep, pkGreedyAny, pkGreedyRepChar, pkGreedyRepSet}: @@ -182,7 +184,7 @@ proc `?`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsOptional".} = result.kind = pkOption result.sons = @[a] -proc `*`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsGreedyRep".} = +proc `*`*(a: Peg): Peg {.nosideEffect, rtl, extern: "npegsGreedyRep".} = ## constructs a "greedy repetition" for the PEG `a` case a.kind of pkGreedyRep, pkGreedyRepChar, pkGreedyRepSet, pkGreedyAny, pkOption: @@ -200,111 +202,99 @@ proc `*`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsGreedyRep".} = result.kind = pkGreedyRep result.sons = @[a] -proc `!*`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsSearch".} = +proc `!*`*(a: Peg): Peg {.nosideEffect, rtl, extern: "npegsSearch".} = ## constructs a "search" for the PEG `a` result.kind = pkSearch result.sons = @[a] -proc `!*\`*(a: TPeg): TPeg {.noSideEffect, rtl, +proc `!*\`*(a: Peg): Peg {.noSideEffect, rtl, extern: "npgegsCapturedSearch".} = ## constructs a "captured search" for the PEG `a` result.kind = pkCapturedSearch result.sons = @[a] - -when false: - proc contains(a: TPeg, k: TPegKind): bool = - if a.kind == k: return true - case a.kind - of pkEmpty, pkAny, pkAnyRune, pkGreedyAny, pkNewLine, pkTerminal, - pkTerminalIgnoreCase, pkTerminalIgnoreStyle, pkChar, pkGreedyRepChar, - pkCharChoice, pkGreedyRepSet: nil - of pkNonTerminal: return true - else: - for i in 0..a.sons.len-1: - if contains(a.sons[i], k): return true -proc `+`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsGreedyPosRep".} = +proc `+`*(a: Peg): Peg {.nosideEffect, rtl, extern: "npegsGreedyPosRep".} = ## constructs a "greedy positive repetition" with the PEG `a` return sequence(a, *a) -proc `&`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsAndPredicate".} = +proc `&`*(a: Peg): Peg {.nosideEffect, rtl, extern: "npegsAndPredicate".} = ## constructs an "and predicate" with the PEG `a` result.kind = pkAndPredicate result.sons = @[a] -proc `!`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsNotPredicate".} = +proc `!`*(a: Peg): Peg {.nosideEffect, rtl, extern: "npegsNotPredicate".} = ## constructs a "not predicate" with the PEG `a` result.kind = pkNotPredicate result.sons = @[a] -proc any*: TPeg {.inline.} = +proc any*: Peg {.inline.} = ## constructs the PEG `any character`:idx: (``.``) result.kind = pkAny -proc anyRune*: TPeg {.inline.} = +proc anyRune*: Peg {.inline.} = ## constructs the PEG `any rune`:idx: (``_``) result.kind = pkAnyRune -proc newLine*: TPeg {.inline.} = +proc newLine*: Peg {.inline.} = ## constructs the PEG `newline`:idx: (``\n``) - result.kind = pkNewline + result.kind = pkNewLine -proc unicodeLetter*: TPeg {.inline.} = +proc unicodeLetter*: Peg {.inline.} = ## constructs the PEG ``\letter`` which matches any Unicode letter. result.kind = pkLetter -proc unicodeLower*: TPeg {.inline.} = +proc unicodeLower*: Peg {.inline.} = ## constructs the PEG ``\lower`` which matches any Unicode lowercase letter. result.kind = pkLower -proc unicodeUpper*: TPeg {.inline.} = +proc unicodeUpper*: Peg {.inline.} = ## constructs the PEG ``\upper`` which matches any Unicode uppercase letter. result.kind = pkUpper -proc unicodeTitle*: TPeg {.inline.} = +proc unicodeTitle*: Peg {.inline.} = ## constructs the PEG ``\title`` which matches any Unicode title letter. result.kind = pkTitle -proc unicodeWhitespace*: TPeg {.inline.} = +proc unicodeWhitespace*: Peg {.inline.} = ## constructs the PEG ``\white`` which matches any Unicode ## whitespace character. result.kind = pkWhitespace -proc startAnchor*: TPeg {.inline.} = +proc startAnchor*: Peg {.inline.} = ## constructs the PEG ``^`` which matches the start of the input. result.kind = pkStartAnchor -proc endAnchor*: TPeg {.inline.} = +proc endAnchor*: Peg {.inline.} = ## constructs the PEG ``$`` which matches the end of the input. result = !any() -proc capture*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsCapture".} = +proc capture*(a: Peg): Peg {.nosideEffect, rtl, extern: "npegsCapture".} = ## constructs a capture with the PEG `a` result.kind = pkCapture result.sons = @[a] -proc backref*(index: range[1..MaxSubPatterns]): TPeg {. +proc backref*(index: range[1..MaxSubpatterns]): Peg {. nosideEffect, rtl, extern: "npegs$1".} = ## constructs a back reference of the given `index`. `index` starts counting ## from 1. result.kind = pkBackRef result.index = index-1 -proc backrefIgnoreCase*(index: range[1..MaxSubPatterns]): TPeg {. +proc backrefIgnoreCase*(index: range[1..MaxSubpatterns]): Peg {. nosideEffect, rtl, extern: "npegs$1".} = ## constructs a back reference of the given `index`. `index` starts counting ## from 1. Ignores case for matching. result.kind = pkBackRefIgnoreCase result.index = index-1 -proc backrefIgnoreStyle*(index: range[1..MaxSubPatterns]): TPeg {. +proc backrefIgnoreStyle*(index: range[1..MaxSubpatterns]): Peg {. nosideEffect, rtl, extern: "npegs$1".}= ## constructs a back reference of the given `index`. `index` starts counting ## from 1. Ignores style for matching. result.kind = pkBackRefIgnoreStyle result.index = index-1 -proc spaceCost(n: TPeg): int = +proc spaceCost(n: Peg): int = case n.kind of pkEmpty: discard of pkTerminal, pkTerminalIgnoreCase, pkTerminalIgnoreStyle, pkChar, @@ -319,7 +309,7 @@ proc spaceCost(n: TPeg): int = inc(result, spaceCost(n.sons[i])) if result >= InlineThreshold: break -proc nonterminal*(n: PNonTerminal): TPeg {. +proc nonterminal*(n: NonTerminal): Peg {. nosideEffect, rtl, extern: "npegs$1".} = ## constructs a PEG that consists of the nonterminal symbol assert n != nil @@ -330,7 +320,7 @@ proc nonterminal*(n: PNonTerminal): TPeg {. result.kind = pkNonTerminal result.nt = n -proc newNonTerminal*(name: string, line, column: int): PNonTerminal {. +proc newNonTerminal*(name: string, line, column: int): NonTerminal {. nosideEffect, rtl, extern: "npegs$1".} = ## constructs a nonterminal symbol new(result) @@ -415,7 +405,7 @@ proc charSetEsc(cc: set[char]): string = else: result = '[' & charSetEscAux(cc) & ']' -proc toStrAux(r: TPeg, res: var string) = +proc toStrAux(r: Peg, res: var string) = case r.kind of pkEmpty: add(res, "()") of pkAny: add(res, '.') @@ -426,7 +416,7 @@ proc toStrAux(r: TPeg, res: var string) = of pkTitle: add(res, "\\title") of pkWhitespace: add(res, "\\white") - of pkNewline: add(res, "\\n") + of pkNewLine: add(res, "\\n") of pkTerminal: add(res, singleQuoteEsc(r.term)) of pkTerminalIgnoreCase: add(res, 'i') @@ -501,7 +491,7 @@ proc toStrAux(r: TPeg, res: var string) = of pkStartAnchor: add(res, '^') -proc `$` *(r: TPeg): string {.nosideEffect, rtl, extern: "npegsToString".} = +proc `$` *(r: Peg): string {.nosideEffect, rtl, extern: "npegsToString".} = ## converts a PEG to its string representation result = "" toStrAux(r, result) @@ -509,13 +499,15 @@ proc `$` *(r: TPeg): string {.nosideEffect, rtl, extern: "npegsToString".} = # --------------------- core engine ------------------------------------------- type - TCaptures* {.final.} = object ## contains the captured substrings. - matches: array[0..maxSubpatterns-1, tuple[first, last: int]] + Captures* = object ## contains the captured substrings. + matches: array[0..MaxSubpatterns-1, tuple[first, last: int]] ml: int origStart: int -proc bounds*(c: TCaptures, - i: range[0..maxSubpatterns-1]): tuple[first, last: int] = +{.deprecated: [TCaptures: Captures].} + +proc bounds*(c: Captures, + i: range[0..MaxSubpatterns-1]): tuple[first, last: int] = ## returns the bounds ``[first..last]`` of the `i`'th capture. result = c.matches[i] @@ -533,7 +525,7 @@ when not useUnicode: proc isTitle(a: char): bool {.inline.} = return false proc isWhiteSpace(a: char): bool {.inline.} = return a in {' ', '\9'..'\13'} -proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {. +proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {. nosideEffect, rtl, extern: "npegs$1".} = ## low-level matching proc that implements the PEG interpreter. Use this ## for maximum efficiency (every other PEG operation ends up calling this @@ -551,7 +543,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {. result = -1 of pkLetter: if s[start] != '\0': - var a: TRune + var a: Rune result = start fastRuneAt(s, result, a) if isAlpha(a): dec(result, start) @@ -560,7 +552,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {. result = -1 of pkLower: if s[start] != '\0': - var a: TRune + var a: Rune result = start fastRuneAt(s, result, a) if isLower(a): dec(result, start) @@ -569,7 +561,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {. result = -1 of pkUpper: if s[start] != '\0': - var a: TRune + var a: Rune result = start fastRuneAt(s, result, a) if isUpper(a): dec(result, start) @@ -578,7 +570,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {. result = -1 of pkTitle: if s[start] != '\0': - var a: TRune + var a: Rune result = start fastRuneAt(s, result, a) if isTitle(a): dec(result, start) @@ -587,7 +579,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {. result = -1 of pkWhitespace: if s[start] != '\0': - var a: TRune + var a: Rune result = start fastRuneAt(s, result, a) if isWhiteSpace(a): dec(result, start) @@ -611,7 +603,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {. of pkTerminalIgnoreCase: var i = 0 - a, b: TRune + a, b: Rune result = start while i < len(p.term): fastRuneAt(p.term, i, a) @@ -623,15 +615,15 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {. of pkTerminalIgnoreStyle: var i = 0 - a, b: TRune + a, b: Rune result = start while i < len(p.term): while true: fastRuneAt(p.term, i, a) - if a != TRune('_'): break + if a != Rune('_'): break while true: fastRuneAt(s, result, b) - if b != TRune('_'): break + if b != Rune('_'): break if toLower(a) != toLower(b): result = -1 break @@ -682,7 +674,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {. while start+result < s.len: var x = rawMatch(s, p.sons[0], start+result, c) if x >= 0: - if idx < maxSubpatterns: + if idx < MaxSubpatterns: c.matches[idx] = (start, start+result-1) #else: silently ignore the capture inc(result, x) @@ -726,7 +718,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {. inc(c.ml) result = rawMatch(s, p.sons[0], start, c) if result >= 0: - if idx < maxSubpatterns: + if idx < MaxSubpatterns: c.matches[idx] = (start, start+result-1) #else: silently ignore the capture else: @@ -734,7 +726,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {. of pkBackRef..pkBackRefIgnoreStyle: if p.index >= c.ml: return -1 var (a, b) = c.matches[p.index] - var n: TPeg + var n: Peg n.kind = succ(pkTerminal, ord(p.kind)-ord(pkBackRef)) n.term = s.substr(a, b) result = rawMatch(s, n, start, c) @@ -745,53 +737,58 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {. template fillMatches(s, caps, c: expr) = for k in 0..c.ml-1: - caps[k] = substr(s, c.matches[k][0], c.matches[k][1]) + let startIdx = c.matches[k][0] + let endIdx = c.matches[k][1] + if startIdx != -1: + caps[k] = substr(s, startIdx, endIdx) + else: + caps[k] = nil -proc match*(s: string, pattern: TPeg, matches: var openArray[string], +proc match*(s: string, pattern: Peg, matches: var openArray[string], start = 0): bool {.nosideEffect, rtl, extern: "npegs$1Capture".} = ## returns ``true`` if ``s[start..]`` matches the ``pattern`` and ## the captured substrings in the array ``matches``. If it does not ## match, nothing is written into ``matches`` and ``false`` is ## returned. - var c: TCaptures + var c: Captures c.origStart = start result = rawMatch(s, pattern, start, c) == len(s) - start if result: fillMatches(s, matches, c) -proc match*(s: string, pattern: TPeg, +proc match*(s: string, pattern: Peg, start = 0): bool {.nosideEffect, rtl, extern: "npegs$1".} = ## returns ``true`` if ``s`` matches the ``pattern`` beginning from ``start``. - var c: TCaptures + var c: Captures c.origStart = start result = rawMatch(s, pattern, start, c) == len(s)-start -proc matchLen*(s: string, pattern: TPeg, matches: var openArray[string], +proc matchLen*(s: string, pattern: Peg, matches: var openArray[string], start = 0): int {.nosideEffect, rtl, extern: "npegs$1Capture".} = ## the same as ``match``, but it returns the length of the match, ## if there is no match, -1 is returned. Note that a match length ## of zero can happen. It's possible that a suffix of `s` remains ## that does not belong to the match. - var c: TCaptures + var c: Captures c.origStart = start result = rawMatch(s, pattern, start, c) if result >= 0: fillMatches(s, matches, c) -proc matchLen*(s: string, pattern: TPeg, +proc matchLen*(s: string, pattern: Peg, start = 0): int {.nosideEffect, rtl, extern: "npegs$1".} = ## the same as ``match``, but it returns the length of the match, ## if there is no match, -1 is returned. Note that a match length ## of zero can happen. It's possible that a suffix of `s` remains ## that does not belong to the match. - var c: TCaptures + var c: Captures c.origStart = start result = rawMatch(s, pattern, start, c) -proc find*(s: string, pattern: TPeg, matches: var openArray[string], +proc find*(s: string, pattern: Peg, matches: var openArray[string], start = 0): int {.nosideEffect, rtl, extern: "npegs$1Capture".} = ## returns the starting position of ``pattern`` in ``s`` and the captured ## substrings in the array ``matches``. If it does not match, nothing ## is written into ``matches`` and -1 is returned. - var c: TCaptures + var c: Captures c.origStart = start for i in start .. s.len-1: c.ml = 0 @@ -801,14 +798,14 @@ proc find*(s: string, pattern: TPeg, matches: var openArray[string], return -1 # could also use the pattern here: (!P .)* P -proc findBounds*(s: string, pattern: TPeg, matches: var openArray[string], +proc findBounds*(s: string, pattern: Peg, matches: var openArray[string], start = 0): tuple[first, last: int] {. nosideEffect, rtl, extern: "npegs$1Capture".} = ## returns the starting position and end position of ``pattern`` in ``s`` ## and the captured ## substrings in the array ``matches``. If it does not match, nothing ## is written into ``matches`` and (-1,0) is returned. - var c: TCaptures + var c: Captures c.origStart = start for i in start .. s.len-1: c.ml = 0 @@ -818,19 +815,19 @@ proc findBounds*(s: string, pattern: TPeg, matches: var openArray[string], return (i, i+L-1) return (-1, 0) -proc find*(s: string, pattern: TPeg, +proc find*(s: string, pattern: Peg, start = 0): int {.nosideEffect, rtl, extern: "npegs$1".} = ## returns the starting position of ``pattern`` in ``s``. If it does not ## match, -1 is returned. - var c: TCaptures + var c: Captures c.origStart = start for i in start .. s.len-1: if rawMatch(s, pattern, i, c) >= 0: return i return -1 -iterator findAll*(s: string, pattern: TPeg, start = 0): string = +iterator findAll*(s: string, pattern: Peg, start = 0): string = ## yields all matching *substrings* of `s` that match `pattern`. - var c: TCaptures + var c: Captures c.origStart = start var i = start while i < s.len: @@ -842,7 +839,7 @@ iterator findAll*(s: string, pattern: TPeg, start = 0): string = yield substr(s, i, i+L-1) inc(i, L) -proc findAll*(s: string, pattern: TPeg, start = 0): seq[string] {. +proc findAll*(s: string, pattern: Peg, start = 0): seq[string] {. nosideEffect, rtl, extern: "npegs$1".} = ## returns all matching *substrings* of `s` that match `pattern`. ## If it does not match, @[] is returned. @@ -851,11 +848,11 @@ proc findAll*(s: string, pattern: TPeg, start = 0): seq[string] {. when not defined(nimhygiene): {.pragma: inject.} -template `=~`*(s: string, pattern: TPeg): bool = +template `=~`*(s: string, pattern: Peg): bool = ## This calls ``match`` with an implicit declared ``matches`` array that ## can be used in the scope of the ``=~`` call: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## if line =~ peg"\s* {\w+} \s* '=' \s* {\w+}": ## # matches a key=value pair: @@ -869,53 +866,53 @@ template `=~`*(s: string, pattern: TPeg): bool = ## else: ## echo("syntax error") ## - bind maxSubpatterns + bind MaxSubpatterns when not declaredInScope(matches): var matches {.inject.}: array[0..MaxSubpatterns-1, string] match(s, pattern, matches) # ------------------------- more string handling ------------------------------ -proc contains*(s: string, pattern: TPeg, start = 0): bool {. +proc contains*(s: string, pattern: Peg, start = 0): bool {. nosideEffect, rtl, extern: "npegs$1".} = ## same as ``find(s, pattern, start) >= 0`` return find(s, pattern, start) >= 0 -proc contains*(s: string, pattern: TPeg, matches: var openArray[string], +proc contains*(s: string, pattern: Peg, matches: var openArray[string], start = 0): bool {.nosideEffect, rtl, extern: "npegs$1Capture".} = ## same as ``find(s, pattern, matches, start) >= 0`` return find(s, pattern, matches, start) >= 0 -proc startsWith*(s: string, prefix: TPeg, start = 0): bool {. +proc startsWith*(s: string, prefix: Peg, start = 0): bool {. nosideEffect, rtl, extern: "npegs$1".} = ## returns true if `s` starts with the pattern `prefix` result = matchLen(s, prefix, start) >= 0 -proc endsWith*(s: string, suffix: TPeg, start = 0): bool {. +proc endsWith*(s: string, suffix: Peg, start = 0): bool {. nosideEffect, rtl, extern: "npegs$1".} = ## returns true if `s` ends with the pattern `prefix` - var c: TCaptures + var c: Captures c.origStart = start for i in start .. s.len-1: if rawMatch(s, suffix, i, c) == s.len - i: return true -proc replacef*(s: string, sub: TPeg, by: string): string {. +proc replacef*(s: string, sub: Peg, by: string): string {. nosideEffect, rtl, extern: "npegs$1".} = ## Replaces `sub` in `s` by the string `by`. Captures can be accessed in `by` ## with the notation ``$i`` and ``$#`` (see strutils.`%`). Examples: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "var1=key; var2=key2".replace(peg"{\ident}'='{\ident}", "$1<-$2$2") ## ## Results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## "var1<-keykey; val2<-key2key2" result = "" var i = 0 - var caps: array[0..maxSubpatterns-1, string] - var c: TCaptures + var caps: array[0..MaxSubpatterns-1, string] + var c: Captures while i < s.len: c.ml = 0 var x = rawMatch(s, sub, i, c) @@ -928,13 +925,13 @@ proc replacef*(s: string, sub: TPeg, by: string): string {. inc(i, x) add(result, substr(s, i)) -proc replace*(s: string, sub: TPeg, by = ""): string {. +proc replace*(s: string, sub: Peg, by = ""): string {. nosideEffect, rtl, extern: "npegs$1".} = ## Replaces `sub` in `s` by the string `by`. Captures cannot be accessed ## in `by`. result = "" var i = 0 - var c: TCaptures + var c: Captures while i < s.len: var x = rawMatch(s, sub, i, c) if x <= 0: @@ -946,14 +943,14 @@ proc replace*(s: string, sub: TPeg, by = ""): string {. add(result, substr(s, i)) proc parallelReplace*(s: string, subs: varargs[ - tuple[pattern: TPeg, repl: string]]): string {. + tuple[pattern: Peg, repl: string]]): string {. nosideEffect, rtl, extern: "npegs$1".} = ## Returns a modified copy of `s` with the substitutions in `subs` ## applied in parallel. result = "" var i = 0 - var c: TCaptures - var caps: array[0..maxSubpatterns-1, string] + var c: Captures + var caps: array[0..MaxSubpatterns-1, string] while i < s.len: block searchSubs: for j in 0..high(subs): @@ -970,7 +967,7 @@ proc parallelReplace*(s: string, subs: varargs[ add(result, substr(s, i)) proc transformFile*(infile, outfile: string, - subs: varargs[tuple[pattern: TPeg, repl: string]]) {. + subs: varargs[tuple[pattern: Peg, repl: string]]) {. rtl, extern: "npegs$1".} = ## reads in the file `infile`, performs a parallel replacement (calls ## `parallelReplace`) and writes back to `outfile`. Raises ``EIO`` if an @@ -978,25 +975,25 @@ proc transformFile*(infile, outfile: string, var x = readFile(infile).string writeFile(outfile, x.parallelReplace(subs)) -iterator split*(s: string, sep: TPeg): string = +iterator split*(s: string, sep: Peg): string = ## Splits the string `s` into substrings. ## ## Substrings are separated by the PEG `sep`. ## Examples: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for word in split("00232this02939is39an22example111", peg"\d+"): ## writeln(stdout, word) ## ## Results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "this" ## "is" ## "an" ## "example" ## - var c: TCaptures + var c: Captures var first = 0 last = 0 @@ -1013,7 +1010,7 @@ iterator split*(s: string, sep: TPeg): string = if first < last: yield substr(s, first, last-1) -proc split*(s: string, sep: TPeg): seq[string] {. +proc split*(s: string, sep: Peg): seq[string] {. nosideEffect, rtl, extern: "npegs$1".} = ## Splits the string `s` into substrings. accumulateResult(split(s, sep)) @@ -1060,10 +1057,10 @@ type charset: set[char] ## if kind == tkCharSet index: int ## if kind == tkBackref - TPegLexer {.inheritable.} = object ## the lexer object. + PegLexer {.inheritable.} = object ## the lexer object. bufpos: int ## the current position within the buffer buf: cstring ## the buffer itself - LineNumber: int ## the current line number + lineNumber: int ## the current line number lineStart: int ## index of last line start in buffer colOffset: int ## column to add filename: string @@ -1076,20 +1073,20 @@ const "@", "built-in", "escaped", "$", "$", "^" ] -proc handleCR(L: var TPegLexer, pos: int): int = +proc handleCR(L: var PegLexer, pos: int): int = assert(L.buf[pos] == '\c') - inc(L.linenumber) + inc(L.lineNumber) result = pos+1 if L.buf[result] == '\L': inc(result) L.lineStart = result -proc handleLF(L: var TPegLexer, pos: int): int = +proc handleLF(L: var PegLexer, pos: int): int = assert(L.buf[pos] == '\L') - inc(L.linenumber) + inc(L.lineNumber) result = pos+1 L.lineStart = result -proc init(L: var TPegLexer, input, filename: string, line = 1, col = 0) = +proc init(L: var PegLexer, input, filename: string, line = 1, col = 0) = L.buf = input L.bufpos = 0 L.lineNumber = line @@ -1097,18 +1094,18 @@ proc init(L: var TPegLexer, input, filename: string, line = 1, col = 0) = L.lineStart = 0 L.filename = filename -proc getColumn(L: TPegLexer): int {.inline.} = +proc getColumn(L: PegLexer): int {.inline.} = result = abs(L.bufpos - L.lineStart) + L.colOffset -proc getLine(L: TPegLexer): int {.inline.} = - result = L.linenumber +proc getLine(L: PegLexer): int {.inline.} = + result = L.lineNumber -proc errorStr(L: TPegLexer, msg: string, line = -1, col = -1): string = +proc errorStr(L: PegLexer, msg: string, line = -1, col = -1): string = var line = if line < 0: getLine(L) else: line var col = if col < 0: getColumn(L) else: col result = "$1($2, $3) Error: $4" % [L.filename, $line, $col, msg] -proc handleHexChar(c: var TPegLexer, xi: var int) = +proc handleHexChar(c: var PegLexer, xi: var int) = case c.buf[c.bufpos] of '0'..'9': xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('0')) @@ -1121,7 +1118,7 @@ proc handleHexChar(c: var TPegLexer, xi: var int) = inc(c.bufpos) else: discard -proc getEscapedChar(c: var TPegLexer, tok: var TToken) = +proc getEscapedChar(c: var PegLexer, tok: var TToken) = inc(c.bufpos) case c.buf[c.bufpos] of 'r', 'R', 'c', 'C': @@ -1167,13 +1164,13 @@ proc getEscapedChar(c: var TPegLexer, tok: var TToken) = else: tok.kind = tkInvalid of '\0'..'\31': tok.kind = tkInvalid - elif c.buf[c.bufpos] in strutils.letters: + elif c.buf[c.bufpos] in strutils.Letters: tok.kind = tkInvalid else: add(tok.literal, c.buf[c.bufpos]) inc(c.bufpos) -proc skip(c: var TPegLexer) = +proc skip(c: var PegLexer) = var pos = c.bufpos var buf = c.buf while true: @@ -1192,9 +1189,9 @@ proc skip(c: var TPegLexer) = break # EndOfFile also leaves the loop c.bufpos = pos -proc getString(c: var TPegLexer, tok: var TToken) = +proc getString(c: var PegLexer, tok: var TToken) = tok.kind = tkStringLit - var pos = c.bufPos + 1 + var pos = c.bufpos + 1 var buf = c.buf var quote = buf[pos-1] while true: @@ -1214,8 +1211,8 @@ proc getString(c: var TPegLexer, tok: var TToken) = inc(pos) c.bufpos = pos -proc getDollar(c: var TPegLexer, tok: var TToken) = - var pos = c.bufPos + 1 +proc getDollar(c: var PegLexer, tok: var TToken) = + var pos = c.bufpos + 1 var buf = c.buf if buf[pos] in {'0'..'9'}: tok.kind = tkBackref @@ -1227,10 +1224,10 @@ proc getDollar(c: var TPegLexer, tok: var TToken) = tok.kind = tkDollar c.bufpos = pos -proc getCharSet(c: var TPegLexer, tok: var TToken) = +proc getCharSet(c: var PegLexer, tok: var TToken) = tok.kind = tkCharSet tok.charset = {} - var pos = c.bufPos + 1 + var pos = c.bufpos + 1 var buf = c.buf var caret = false if buf[pos] == '^': @@ -1278,7 +1275,7 @@ proc getCharSet(c: var TPegLexer, tok: var TToken) = c.bufpos = pos if caret: tok.charset = {'\1'..'\xFF'} - tok.charset -proc getSymbol(c: var TPegLexer, tok: var TToken) = +proc getSymbol(c: var PegLexer, tok: var TToken) = var pos = c.bufpos var buf = c.buf while true: @@ -1288,7 +1285,7 @@ proc getSymbol(c: var TPegLexer, tok: var TToken) = c.bufpos = pos tok.kind = tkIdentifier -proc getBuiltin(c: var TPegLexer, tok: var TToken) = +proc getBuiltin(c: var PegLexer, tok: var TToken) = if c.buf[c.bufpos+1] in strutils.Letters: inc(c.bufpos) getSymbol(c, tok) @@ -1297,7 +1294,7 @@ proc getBuiltin(c: var TPegLexer, tok: var TToken) = tok.kind = tkEscaped getEscapedChar(c, tok) # may set tok.kind to tkInvalid -proc getTok(c: var TPegLexer, tok: var TToken) = +proc getTok(c: var PegLexer, tok: var TToken) = tok.kind = tkInvalid tok.modifier = modNone setLen(tok.literal, 0) @@ -1403,7 +1400,7 @@ proc getTok(c: var TPegLexer, tok: var TToken) = add(tok.literal, c.buf[c.bufpos]) inc(c.bufpos) -proc arrowIsNextTok(c: TPegLexer): bool = +proc arrowIsNextTok(c: PegLexer): bool = # the only look ahead we need var pos = c.bufpos while c.buf[pos] in {'\t', ' '}: inc(pos) @@ -1412,33 +1409,33 @@ proc arrowIsNextTok(c: TPegLexer): bool = # ----------------------------- parser ---------------------------------------- type - EInvalidPeg* = object of EInvalidValue ## raised if an invalid + EInvalidPeg* = object of ValueError ## raised if an invalid ## PEG has been detected - TPegParser = object of TPegLexer ## the PEG parser object + PegParser = object of PegLexer ## the PEG parser object tok: TToken - nonterms: seq[PNonTerminal] + nonterms: seq[NonTerminal] modifier: TModifier captures: int identIsVerbatim: bool - skip: TPeg + skip: Peg -proc pegError(p: TPegParser, msg: string, line = -1, col = -1) = +proc pegError(p: PegParser, msg: string, line = -1, col = -1) = var e: ref EInvalidPeg new(e) e.msg = errorStr(p, msg, line, col) raise e -proc getTok(p: var TPegParser) = +proc getTok(p: var PegParser) = getTok(p, p.tok) if p.tok.kind == tkInvalid: pegError(p, "invalid token") -proc eat(p: var TPegParser, kind: TTokKind) = +proc eat(p: var PegParser, kind: TTokKind) = if p.tok.kind == kind: getTok(p) else: pegError(p, tokKindToStr[kind] & " expected") -proc parseExpr(p: var TPegParser): TPeg +proc parseExpr(p: var PegParser): Peg -proc getNonTerminal(p: var TPegParser, name: string): PNonTerminal = +proc getNonTerminal(p: var PegParser, name: string): NonTerminal = for i in 0..high(p.nonterms): result = p.nonterms[i] if cmpIgnoreStyle(result.name, name) == 0: return @@ -1446,19 +1443,19 @@ proc getNonTerminal(p: var TPegParser, name: string): PNonTerminal = result = newNonTerminal(name, getLine(p), getColumn(p)) add(p.nonterms, result) -proc modifiedTerm(s: string, m: TModifier): TPeg = +proc modifiedTerm(s: string, m: TModifier): Peg = case m of modNone, modVerbatim: result = term(s) of modIgnoreCase: result = termIgnoreCase(s) of modIgnoreStyle: result = termIgnoreStyle(s) -proc modifiedBackref(s: int, m: TModifier): TPeg = +proc modifiedBackref(s: int, m: TModifier): Peg = case m of modNone, modVerbatim: result = backref(s) of modIgnoreCase: result = backrefIgnoreCase(s) of modIgnoreStyle: result = backrefIgnoreStyle(s) -proc builtin(p: var TPegParser): TPeg = +proc builtin(p: var PegParser): Peg = # do not use "y", "skip" or "i" as these would be ambiguous case p.tok.literal of "n": result = newLine() @@ -1478,11 +1475,11 @@ proc builtin(p: var TPegParser): TPeg = of "white": result = unicodeWhitespace() else: pegError(p, "unknown built-in: " & p.tok.literal) -proc token(terminal: TPeg, p: TPegParser): TPeg = +proc token(terminal: Peg, p: PegParser): Peg = if p.skip.kind == pkEmpty: result = terminal else: result = sequence(p.skip, terminal) -proc primary(p: var TPegParser): TPeg = +proc primary(p: var PegParser): Peg = case p.tok.kind of tkAmp: getTok(p) @@ -1571,11 +1568,11 @@ proc primary(p: var TPegParser): TPeg = getTok(p) else: break -proc seqExpr(p: var TPegParser): TPeg = +proc seqExpr(p: var PegParser): Peg = result = primary(p) while true: case p.tok.kind - of tkAmp, tkNot, tkAt, tkStringLit, tkCharset, tkParLe, tkCurlyLe, + of tkAmp, tkNot, tkAt, tkStringLit, tkCharSet, tkParLe, tkCurlyLe, tkAny, tkAnyRune, tkBuiltin, tkEscaped, tkDollar, tkBackref, tkHat, tkCurlyAt: result = sequence(result, primary(p)) @@ -1585,13 +1582,13 @@ proc seqExpr(p: var TPegParser): TPeg = else: break else: break -proc parseExpr(p: var TPegParser): TPeg = +proc parseExpr(p: var PegParser): Peg = result = seqExpr(p) while p.tok.kind == tkBar: getTok(p) result = result / seqExpr(p) -proc parseRule(p: var TPegParser): PNonTerminal = +proc parseRule(p: var PegParser): NonTerminal = if p.tok.kind == tkIdentifier and arrowIsNextTok(p): result = getNonTerminal(p, p.tok.literal) if ntDeclared in result.flags: @@ -1605,7 +1602,7 @@ proc parseRule(p: var TPegParser): PNonTerminal = else: pegError(p, "rule expected, but found: " & p.tok.literal) -proc rawParse(p: var TPegParser): TPeg = +proc rawParse(p: var PegParser): Peg = ## parses a rule or a PEG expression while p.tok.kind == tkBuiltin: case p.tok.literal @@ -1635,12 +1632,12 @@ proc rawParse(p: var TPegParser): TPeg = elif ntUsed notin nt.flags and i > 0: pegError(p, "unused rule: " & nt.name, nt.line, nt.col) -proc parsePeg*(pattern: string, filename = "pattern", line = 1, col = 0): TPeg = - ## constructs a TPeg object from `pattern`. `filename`, `line`, `col` are +proc parsePeg*(pattern: string, filename = "pattern", line = 1, col = 0): Peg = + ## constructs a Peg object from `pattern`. `filename`, `line`, `col` are ## used for error messages, but they only provide start offsets. `parsePeg` ## keeps track of line and column numbers within `pattern`. - var p: TPegParser - init(TPegLexer(p), pattern, filename, line, col) + var p: PegParser + init(PegLexer(p), pattern, filename, line, col) p.tok.kind = tkInvalid p.tok.modifier = modNone p.tok.literal = "" @@ -1650,8 +1647,8 @@ proc parsePeg*(pattern: string, filename = "pattern", line = 1, col = 0): TPeg = getTok(p) result = rawParse(p) -proc peg*(pattern: string): TPeg = - ## constructs a TPeg object from the `pattern`. The short name has been +proc peg*(pattern: string): Peg = + ## constructs a Peg object from the `pattern`. The short name has been ## chosen to encourage its use as a raw string modifier:: ## ## peg"{\ident} \s* '=' \s* {.*}" @@ -1704,7 +1701,7 @@ when isMainModule: expr.rule = sequence(capture(ident), *sequence( nonterminal(ws), term('+'), nonterminal(ws), nonterminal(expr))) - var c: TCaptures + var c: Captures var s = "a+b + c +d+e+f" assert rawMatch(s, expr.rule, 0, c) == len(s) var a = "" @@ -1720,7 +1717,7 @@ when isMainModule: assert match("_______ana", peg"A <- 'ana' / . A") assert match("abcs%%%", peg"A <- ..A / .A / '%'") - var matches: array[0..maxSubpatterns-1, string] + var matches: array[0..MaxSubpatterns-1, string] if "abc" =~ peg"{'a'}'bc' 'xyz' / {\ident}": assert matches[0] == "abc" else: @@ -1775,3 +1772,14 @@ when isMainModule: assert match("prefix/start", peg"^start$", 7) + if "foo" =~ peg"{'a'}?.*": + assert matches[0] == nil + else: assert false + + if "foo" =~ peg"{''}.*": + assert matches[0] == "" + else: assert false + + if "foo" =~ peg"{'foo'}": + assert matches[0] == "foo" + else: assert false diff --git a/lib/pure/pegs.nimfix b/lib/pure/pegs.nimfix new file mode 100644 index 000000000..8dd172a48 --- /dev/null +++ b/lib/pure/pegs.nimfix @@ -0,0 +1,1770 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2012 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## Simple PEG (Parsing expression grammar) matching. Uses no memorization, but +## uses superoperators and symbol inlining to improve performance. Note: +## Matching performance is hopefully competitive with optimized regular +## expression engines. +## +## .. include:: ../doc/pegdocs.txt +## + +include "system/inclrtl" + +const + useUnicode = true ## change this to deactivate proper UTF-8 support + +import + strutils + +when useUnicode: + import unicode + +const + InlineThreshold = 5 ## number of leaves; -1 to disable inlining + MaxSubpatterns* = 10 ## defines the maximum number of subpatterns that + ## can be captured. More subpatterns cannot be captured! + +type + PegKind = enum + pkEmpty, + pkAny, ## any character (.) + pkAnyRune, ## any Unicode character (_) + pkNewLine, ## CR-LF, LF, CR + pkLetter, ## Unicode letter + pkLower, ## Unicode lower case letter + pkUpper, ## Unicode upper case letter + pkTitle, ## Unicode title character + pkWhitespace, ## Unicode whitespace character + pkTerminal, + pkTerminalIgnoreCase, + pkTerminalIgnoreStyle, + pkChar, ## single character to match + pkCharChoice, + pkNonTerminal, + pkSequence, ## a b c ... --> Internal DSL: peg(a, b, c) + pkOrderedChoice, ## a / b / ... --> Internal DSL: a / b or /[a, b, c] + pkGreedyRep, ## a* --> Internal DSL: *a + ## a+ --> (a a*) + pkGreedyRepChar, ## x* where x is a single character (superop) + pkGreedyRepSet, ## [set]* (superop) + pkGreedyAny, ## .* or _* (superop) + pkOption, ## a? --> Internal DSL: ?a + pkAndPredicate, ## &a --> Internal DSL: &a + pkNotPredicate, ## !a --> Internal DSL: !a + pkCapture, ## {a} --> Internal DSL: capture(a) + pkBackRef, ## $i --> Internal DSL: backref(i) + pkBackRefIgnoreCase, + pkBackRefIgnoreStyle, + pkSearch, ## @a --> Internal DSL: !*a + pkCapturedSearch, ## {@} a --> Internal DSL: !*\a + pkRule, ## a <- b + pkList, ## a, b + pkStartAnchor ## ^ --> Internal DSL: startAnchor() + NonTerminalFlag = enum + ntDeclared, ntUsed + NonTerminalObj = object ## represents a non terminal symbol + name: string ## the name of the symbol + line: int ## line the symbol has been declared/used in + col: int ## column the symbol has been declared/used in + flags: set[NonTerminalFlag] ## the nonterminal's flags + rule: TNode ## the rule that the symbol refers to + TNode {.shallow.} = object + case kind: PegKind + of pkEmpty..pkWhitespace: nil + of pkTerminal, pkTerminalIgnoreCase, pkTerminalIgnoreStyle: term: string + of pkChar, pkGreedyRepChar: ch: char + of pkCharChoice, pkGreedyRepSet: charChoice: ref set[char] + of pkNonTerminal: nt: PNonTerminal + of pkBackRef..pkBackRefIgnoreStyle: index: range[0..MaxSubpatterns] + else: sons: seq[TNode] + PNonTerminal* = ref NonTerminalObj + TPeg* = TNode + +block: + type + Peg = TNode + NonTerminal = PNonTerminal + {.deprecated: [TPeg: Peg, PNonTerminal: NonTerminal].} + +proc term*(t: string): TPeg {.nosideEffect, rtl, extern: "npegs$1Str".} = + ## constructs a PEG from a terminal string + if t.len != 1: + result.kind = pkTerminal + result.term = t + else: + result.kind = pkChar + result.ch = t[0] + +proc termIgnoreCase*(t: string): TPeg {.nosideEffect, rtl, extern: "npegs$1".} = + ## constructs a PEG from a terminal string; ignore case for matching + result.kind = pkTerminalIgnoreCase + result.term = t + +proc termIgnoreStyle*(t: string): TPeg {.nosideEffect, rtl, extern: "npegs$1".} = + ## constructs a PEG from a terminal string; ignore style for matching + result.kind = pkTerminalIgnoreStyle + result.term = t + +proc term*(t: char): TPeg {.nosideEffect, rtl, extern: "npegs$1Char".} = + ## constructs a PEG from a terminal char + assert t != '\0' + result.kind = pkChar + result.ch = t + +proc charSet*(s: set[char]): TPeg {.nosideEffect, rtl, extern: "npegs$1".} = + ## constructs a PEG from a character set `s` + assert '\0' notin s + result.kind = pkCharChoice + new(result.charChoice) + result.charChoice[] = s + +proc len(a: TPeg): int {.inline.} = return a.sons.len +proc add(d: var TPeg, s: TPeg) {.inline.} = add(d.sons, s) + +proc addChoice(dest: var TPeg, elem: TPeg) = + var L = dest.len-1 + if L >= 0 and dest.sons[L].kind == pkCharChoice: + # caution! Do not introduce false aliasing here! + case elem.kind + of pkCharChoice: + dest.sons[L] = charSet(dest.sons[L].charChoice[] + elem.charChoice[]) + of pkChar: + dest.sons[L] = charSet(dest.sons[L].charChoice[] + {elem.ch}) + else: add(dest, elem) + else: add(dest, elem) + +template multipleOp(k: PegKind, localOpt: expr) = + result.kind = k + result.sons = @[] + for x in items(a): + if x.kind == k: + for y in items(x.sons): + localOpt(result, y) + else: + localOpt(result, x) + if result.len == 1: + result = result.sons[0] + +proc `/`*(a: varargs[TPeg]): TPeg {. + nosideEffect, rtl, extern: "npegsOrderedChoice".} = + ## constructs an ordered choice with the PEGs in `a` + multipleOp(pkOrderedChoice, addChoice) + +proc addSequence(dest: var TPeg, elem: TPeg) = + var L = dest.len-1 + if L >= 0 and dest.sons[L].kind == pkTerminal: + # caution! Do not introduce false aliasing here! + case elem.kind + of pkTerminal: + dest.sons[L] = term(dest.sons[L].term & elem.term) + of pkChar: + dest.sons[L] = term(dest.sons[L].term & elem.ch) + else: add(dest, elem) + else: add(dest, elem) + +proc sequence*(a: varargs[TPeg]): TPeg {. + nosideEffect, rtl, extern: "npegs$1".} = + ## constructs a sequence with all the PEGs from `a` + multipleOp(pkSequence, addSequence) + +proc `?`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsOptional".} = + ## constructs an optional for the PEG `a` + if a.kind in {pkOption, pkGreedyRep, pkGreedyAny, pkGreedyRepChar, + pkGreedyRepSet}: + # a* ? --> a* + # a? ? --> a? + result = a + else: + result.kind = pkOption + result.sons = @[a] + +proc `*`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsGreedyRep".} = + ## constructs a "greedy repetition" for the PEG `a` + case a.kind + of pkGreedyRep, pkGreedyRepChar, pkGreedyRepSet, pkGreedyAny, pkOption: + assert false + # produces endless loop! + of pkChar: + result.kind = pkGreedyRepChar + result.ch = a.ch + of pkCharChoice: + result.kind = pkGreedyRepSet + result.charChoice = a.charChoice # copying a reference suffices! + of pkAny, pkAnyRune: + result.kind = pkGreedyAny + else: + result.kind = pkGreedyRep + result.sons = @[a] + +proc `!*`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsSearch".} = + ## constructs a "search" for the PEG `a` + result.kind = pkSearch + result.sons = @[a] + +proc `!*\`*(a: TPeg): TPeg {.noSideEffect, rtl, + extern: "npgegsCapturedSearch".} = + ## constructs a "captured search" for the PEG `a` + result.kind = pkCapturedSearch + result.sons = @[a] + +proc `+`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsGreedyPosRep".} = + ## constructs a "greedy positive repetition" with the PEG `a` + return sequence(a, *a) + +proc `&`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsAndPredicate".} = + ## constructs an "and predicate" with the PEG `a` + result.kind = pkAndPredicate + result.sons = @[a] + +proc `!`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsNotPredicate".} = + ## constructs a "not predicate" with the PEG `a` + result.kind = pkNotPredicate + result.sons = @[a] + +proc any*: TPeg {.inline.} = + ## constructs the PEG `any character`:idx: (``.``) + result.kind = pkAny + +proc anyRune*: TPeg {.inline.} = + ## constructs the PEG `any rune`:idx: (``_``) + result.kind = pkAnyRune + +proc newLine*: TPeg {.inline.} = + ## constructs the PEG `newline`:idx: (``\n``) + result.kind = pkNewLine + +proc unicodeLetter*: TPeg {.inline.} = + ## constructs the PEG ``\letter`` which matches any Unicode letter. + result.kind = pkLetter + +proc unicodeLower*: TPeg {.inline.} = + ## constructs the PEG ``\lower`` which matches any Unicode lowercase letter. + result.kind = pkLower + +proc unicodeUpper*: TPeg {.inline.} = + ## constructs the PEG ``\upper`` which matches any Unicode uppercase letter. + result.kind = pkUpper + +proc unicodeTitle*: TPeg {.inline.} = + ## constructs the PEG ``\title`` which matches any Unicode title letter. + result.kind = pkTitle + +proc unicodeWhitespace*: TPeg {.inline.} = + ## constructs the PEG ``\white`` which matches any Unicode + ## whitespace character. + result.kind = pkWhitespace + +proc startAnchor*: TPeg {.inline.} = + ## constructs the PEG ``^`` which matches the start of the input. + result.kind = pkStartAnchor + +proc endAnchor*: TPeg {.inline.} = + ## constructs the PEG ``$`` which matches the end of the input. + result = !any() + +proc capture*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsCapture".} = + ## constructs a capture with the PEG `a` + result.kind = pkCapture + result.sons = @[a] + +proc backref*(index: range[1..MaxSubpatterns]): TPeg {. + nosideEffect, rtl, extern: "npegs$1".} = + ## constructs a back reference of the given `index`. `index` starts counting + ## from 1. + result.kind = pkBackRef + result.index = index-1 + +proc backrefIgnoreCase*(index: range[1..MaxSubpatterns]): TPeg {. + nosideEffect, rtl, extern: "npegs$1".} = + ## constructs a back reference of the given `index`. `index` starts counting + ## from 1. Ignores case for matching. + result.kind = pkBackRefIgnoreCase + result.index = index-1 + +proc backrefIgnoreStyle*(index: range[1..MaxSubpatterns]): TPeg {. + nosideEffect, rtl, extern: "npegs$1".}= + ## constructs a back reference of the given `index`. `index` starts counting + ## from 1. Ignores style for matching. + result.kind = pkBackRefIgnoreStyle + result.index = index-1 + +proc spaceCost(n: TPeg): int = + case n.kind + of pkEmpty: discard + of pkTerminal, pkTerminalIgnoreCase, pkTerminalIgnoreStyle, pkChar, + pkGreedyRepChar, pkCharChoice, pkGreedyRepSet, + pkAny..pkWhitespace, pkGreedyAny: + result = 1 + of pkNonTerminal: + # we cannot inline a rule with a non-terminal + result = InlineThreshold+1 + else: + for i in 0..n.len-1: + inc(result, spaceCost(n.sons[i])) + if result >= InlineThreshold: break + +proc nonterminal*(n: PNonTerminal): TPeg {. + nosideEffect, rtl, extern: "npegs$1".} = + ## constructs a PEG that consists of the nonterminal symbol + assert n != nil + if ntDeclared in n.flags and spaceCost(n.rule) < InlineThreshold: + when false: echo "inlining symbol: ", n.name + result = n.rule # inlining of rule enables better optimizations + else: + result.kind = pkNonTerminal + result.nt = n + +proc newNonTerminal*(name: string, line, column: int): PNonTerminal {. + nosideEffect, rtl, extern: "npegs$1".} = + ## constructs a nonterminal symbol + new(result) + result.name = name + result.line = line + result.col = column + +template letters*: expr = + ## expands to ``charset({'A'..'Z', 'a'..'z'})`` + charSet({'A'..'Z', 'a'..'z'}) + +template digits*: expr = + ## expands to ``charset({'0'..'9'})`` + charSet({'0'..'9'}) + +template whitespace*: expr = + ## expands to ``charset({' ', '\9'..'\13'})`` + charSet({' ', '\9'..'\13'}) + +template identChars*: expr = + ## expands to ``charset({'a'..'z', 'A'..'Z', '0'..'9', '_'})`` + charSet({'a'..'z', 'A'..'Z', '0'..'9', '_'}) + +template identStartChars*: expr = + ## expands to ``charset({'A'..'Z', 'a'..'z', '_'})`` + charSet({'a'..'z', 'A'..'Z', '_'}) + +template ident*: expr = + ## same as ``[a-zA-Z_][a-zA-z_0-9]*``; standard identifier + sequence(charSet({'a'..'z', 'A'..'Z', '_'}), + *charSet({'a'..'z', 'A'..'Z', '0'..'9', '_'})) + +template natural*: expr = + ## same as ``\d+`` + +digits + +# ------------------------- debugging ----------------------------------------- + +proc esc(c: char, reserved = {'\0'..'\255'}): string = + case c + of '\b': result = "\\b" + of '\t': result = "\\t" + of '\c': result = "\\c" + of '\L': result = "\\l" + of '\v': result = "\\v" + of '\f': result = "\\f" + of '\e': result = "\\e" + of '\a': result = "\\a" + of '\\': result = "\\\\" + of 'a'..'z', 'A'..'Z', '0'..'9', '_': result = $c + elif c < ' ' or c >= '\128': result = '\\' & $ord(c) + elif c in reserved: result = '\\' & c + else: result = $c + +proc singleQuoteEsc(c: char): string = return "'" & esc(c, {'\''}) & "'" + +proc singleQuoteEsc(str: string): string = + result = "'" + for c in items(str): add result, esc(c, {'\''}) + add result, '\'' + +proc charSetEscAux(cc: set[char]): string = + const reserved = {'^', '-', ']'} + result = "" + var c1 = 0 + while c1 <= 0xff: + if chr(c1) in cc: + var c2 = c1 + while c2 < 0xff and chr(succ(c2)) in cc: inc(c2) + if c1 == c2: + add result, esc(chr(c1), reserved) + elif c2 == succ(c1): + add result, esc(chr(c1), reserved) & esc(chr(c2), reserved) + else: + add result, esc(chr(c1), reserved) & '-' & esc(chr(c2), reserved) + c1 = c2 + inc(c1) + +proc charSetEsc(cc: set[char]): string = + if card(cc) >= 128+64: + result = "[^" & charSetEscAux({'\1'..'\xFF'} - cc) & ']' + else: + result = '[' & charSetEscAux(cc) & ']' + +proc toStrAux(r: TPeg, res: var string) = + case r.kind + of pkEmpty: add(res, "()") + of pkAny: add(res, '.') + of pkAnyRune: add(res, '_') + of pkLetter: add(res, "\\letter") + of pkLower: add(res, "\\lower") + of pkUpper: add(res, "\\upper") + of pkTitle: add(res, "\\title") + of pkWhitespace: add(res, "\\white") + + of pkNewLine: add(res, "\\n") + of pkTerminal: add(res, singleQuoteEsc(r.term)) + of pkTerminalIgnoreCase: + add(res, 'i') + add(res, singleQuoteEsc(r.term)) + of pkTerminalIgnoreStyle: + add(res, 'y') + add(res, singleQuoteEsc(r.term)) + of pkChar: add(res, singleQuoteEsc(r.ch)) + of pkCharChoice: add(res, charSetEsc(r.charChoice[])) + of pkNonTerminal: add(res, r.nt.name) + of pkSequence: + add(res, '(') + toStrAux(r.sons[0], res) + for i in 1 .. high(r.sons): + add(res, ' ') + toStrAux(r.sons[i], res) + add(res, ')') + of pkOrderedChoice: + add(res, '(') + toStrAux(r.sons[0], res) + for i in 1 .. high(r.sons): + add(res, " / ") + toStrAux(r.sons[i], res) + add(res, ')') + of pkGreedyRep: + toStrAux(r.sons[0], res) + add(res, '*') + of pkGreedyRepChar: + add(res, singleQuoteEsc(r.ch)) + add(res, '*') + of pkGreedyRepSet: + add(res, charSetEsc(r.charChoice[])) + add(res, '*') + of pkGreedyAny: + add(res, ".*") + of pkOption: + toStrAux(r.sons[0], res) + add(res, '?') + of pkAndPredicate: + add(res, '&') + toStrAux(r.sons[0], res) + of pkNotPredicate: + add(res, '!') + toStrAux(r.sons[0], res) + of pkSearch: + add(res, '@') + toStrAux(r.sons[0], res) + of pkCapturedSearch: + add(res, "{@}") + toStrAux(r.sons[0], res) + of pkCapture: + add(res, '{') + toStrAux(r.sons[0], res) + add(res, '}') + of pkBackRef: + add(res, '$') + add(res, $r.index) + of pkBackRefIgnoreCase: + add(res, "i$") + add(res, $r.index) + of pkBackRefIgnoreStyle: + add(res, "y$") + add(res, $r.index) + of pkRule: + toStrAux(r.sons[0], res) + add(res, " <- ") + toStrAux(r.sons[1], res) + of pkList: + for i in 0 .. high(r.sons): + toStrAux(r.sons[i], res) + add(res, "\n") + of pkStartAnchor: + add(res, '^') + +proc `$` *(r: TPeg): string {.nosideEffect, rtl, extern: "npegsToString".} = + ## converts a PEG to its string representation + result = "" + toStrAux(r, result) + +# --------------------- core engine ------------------------------------------- + +type + Captures* = object ## contains the captured substrings. + matches: array[0..MaxSubpatterns-1, tuple[first, last: int]] + ml: int + origStart: int + +{.deprecated: [TCaptures: Captures].} + +proc bounds*(c: Captures, + i: range[0..MaxSubpatterns-1]): tuple[first, last: int] = + ## returns the bounds ``[first..last]`` of the `i`'th capture. + result = c.matches[i] + +when not useUnicode: + type + TRune = char + template fastRuneAt(s, i, ch: expr) = + ch = s[i] + inc(i) + template runeLenAt(s, i: expr): expr = 1 + + proc isAlpha(a: char): bool {.inline.} = return a in {'a'..'z','A'..'Z'} + proc isUpper(a: char): bool {.inline.} = return a in {'A'..'Z'} + proc isLower(a: char): bool {.inline.} = return a in {'a'..'z'} + proc isTitle(a: char): bool {.inline.} = return false + proc isWhiteSpace(a: char): bool {.inline.} = return a in {' ', '\9'..'\13'} + +proc rawMatch*(s: string, p: TPeg, start: int, c: var Captures): int {. + nosideEffect, rtl, extern: "npegs$1".} = + ## low-level matching proc that implements the PEG interpreter. Use this + ## for maximum efficiency (every other PEG operation ends up calling this + ## proc). + ## Returns -1 if it does not match, else the length of the match + case p.kind + of pkEmpty: result = 0 # match of length 0 + of pkAny: + if s[start] != '\0': result = 1 + else: result = -1 + of pkAnyRune: + if s[start] != '\0': + result = runeLenAt(s, start) + else: + result = -1 + of pkLetter: + if s[start] != '\0': + var a: Rune + result = start + fastRuneAt(s, result, a) + if isAlpha(a): dec(result, start) + else: result = -1 + else: + result = -1 + of pkLower: + if s[start] != '\0': + var a: Rune + result = start + fastRuneAt(s, result, a) + if isLower(a): dec(result, start) + else: result = -1 + else: + result = -1 + of pkUpper: + if s[start] != '\0': + var a: Rune + result = start + fastRuneAt(s, result, a) + if isUpper(a): dec(result, start) + else: result = -1 + else: + result = -1 + of pkTitle: + if s[start] != '\0': + var a: Rune + result = start + fastRuneAt(s, result, a) + if isTitle(a): dec(result, start) + else: result = -1 + else: + result = -1 + of pkWhitespace: + if s[start] != '\0': + var a: Rune + result = start + fastRuneAt(s, result, a) + if isWhiteSpace(a): dec(result, start) + else: result = -1 + else: + result = -1 + of pkGreedyAny: + result = len(s) - start + of pkNewLine: + if s[start] == '\L': result = 1 + elif s[start] == '\C': + if s[start+1] == '\L': result = 2 + else: result = 1 + else: result = -1 + of pkTerminal: + result = len(p.term) + for i in 0..result-1: + if p.term[i] != s[start+i]: + result = -1 + break + of pkTerminalIgnoreCase: + var + i = 0 + a, b: Rune + result = start + while i < len(p.term): + fastRuneAt(p.term, i, a) + fastRuneAt(s, result, b) + if toLower(a) != toLower(b): + result = -1 + break + dec(result, start) + of pkTerminalIgnoreStyle: + var + i = 0 + a, b: Rune + result = start + while i < len(p.term): + while true: + fastRuneAt(p.term, i, a) + if a != Rune('_'): break + while true: + fastRuneAt(s, result, b) + if b != Rune('_'): break + if toLower(a) != toLower(b): + result = -1 + break + dec(result, start) + of pkChar: + if p.ch == s[start]: result = 1 + else: result = -1 + of pkCharChoice: + if contains(p.charChoice[], s[start]): result = 1 + else: result = -1 + of pkNonTerminal: + var oldMl = c.ml + when false: echo "enter: ", p.nt.name + result = rawMatch(s, p.nt.rule, start, c) + when false: echo "leave: ", p.nt.name + if result < 0: c.ml = oldMl + of pkSequence: + var oldMl = c.ml + result = 0 + for i in 0..high(p.sons): + var x = rawMatch(s, p.sons[i], start+result, c) + if x < 0: + c.ml = oldMl + result = -1 + break + else: inc(result, x) + of pkOrderedChoice: + var oldMl = c.ml + for i in 0..high(p.sons): + result = rawMatch(s, p.sons[i], start, c) + if result >= 0: break + c.ml = oldMl + of pkSearch: + var oldMl = c.ml + result = 0 + while start+result < s.len: + var x = rawMatch(s, p.sons[0], start+result, c) + if x >= 0: + inc(result, x) + return + inc(result) + result = -1 + c.ml = oldMl + of pkCapturedSearch: + var idx = c.ml # reserve a slot for the subpattern + inc(c.ml) + result = 0 + while start+result < s.len: + var x = rawMatch(s, p.sons[0], start+result, c) + if x >= 0: + if idx < MaxSubpatterns: + c.matches[idx] = (start, start+result-1) + #else: silently ignore the capture + inc(result, x) + return + inc(result) + result = -1 + c.ml = idx + of pkGreedyRep: + result = 0 + while true: + var x = rawMatch(s, p.sons[0], start+result, c) + # if x == 0, we have an endless loop; so the correct behaviour would be + # not to break. But endless loops can be easily introduced: + # ``(comment / \w*)*`` is such an example. Breaking for x == 0 does the + # expected thing in this case. + if x <= 0: break + inc(result, x) + of pkGreedyRepChar: + result = 0 + var ch = p.ch + while ch == s[start+result]: inc(result) + of pkGreedyRepSet: + result = 0 + while contains(p.charChoice[], s[start+result]): inc(result) + of pkOption: + result = max(0, rawMatch(s, p.sons[0], start, c)) + of pkAndPredicate: + var oldMl = c.ml + result = rawMatch(s, p.sons[0], start, c) + if result >= 0: result = 0 # do not consume anything + else: c.ml = oldMl + of pkNotPredicate: + var oldMl = c.ml + result = rawMatch(s, p.sons[0], start, c) + if result < 0: result = 0 + else: + c.ml = oldMl + result = -1 + of pkCapture: + var idx = c.ml # reserve a slot for the subpattern + inc(c.ml) + result = rawMatch(s, p.sons[0], start, c) + if result >= 0: + if idx < MaxSubpatterns: + c.matches[idx] = (start, start+result-1) + #else: silently ignore the capture + else: + c.ml = idx + of pkBackRef..pkBackRefIgnoreStyle: + if p.index >= c.ml: return -1 + var (a, b) = c.matches[p.index] + var n: TPeg + n.kind = succ(pkTerminal, ord(p.kind)-ord(pkBackRef)) + n.term = s.substr(a, b) + result = rawMatch(s, n, start, c) + of pkStartAnchor: + if c.origStart == start: result = 0 + else: result = -1 + of pkRule, pkList: assert false + +template fillMatches(s, caps, c: expr) = + for k in 0..c.ml-1: + caps[k] = substr(s, c.matches[k][0], c.matches[k][1]) + +proc match*(s: string, pattern: TPeg, matches: var openArray[string], + start = 0): bool {.nosideEffect, rtl, extern: "npegs$1Capture".} = + ## returns ``true`` if ``s[start..]`` matches the ``pattern`` and + ## the captured substrings in the array ``matches``. If it does not + ## match, nothing is written into ``matches`` and ``false`` is + ## returned. + var c: Captures + c.origStart = start + result = rawMatch(s, pattern, start, c) == len(s) - start + if result: fillMatches(s, matches, c) + +proc match*(s: string, pattern: TPeg, + start = 0): bool {.nosideEffect, rtl, extern: "npegs$1".} = + ## returns ``true`` if ``s`` matches the ``pattern`` beginning from ``start``. + var c: Captures + c.origStart = start + result = rawMatch(s, pattern, start, c) == len(s)-start + +proc matchLen*(s: string, pattern: TPeg, matches: var openArray[string], + start = 0): int {.nosideEffect, rtl, extern: "npegs$1Capture".} = + ## the same as ``match``, but it returns the length of the match, + ## if there is no match, -1 is returned. Note that a match length + ## of zero can happen. It's possible that a suffix of `s` remains + ## that does not belong to the match. + var c: Captures + c.origStart = start + result = rawMatch(s, pattern, start, c) + if result >= 0: fillMatches(s, matches, c) + +proc matchLen*(s: string, pattern: TPeg, + start = 0): int {.nosideEffect, rtl, extern: "npegs$1".} = + ## the same as ``match``, but it returns the length of the match, + ## if there is no match, -1 is returned. Note that a match length + ## of zero can happen. It's possible that a suffix of `s` remains + ## that does not belong to the match. + var c: Captures + c.origStart = start + result = rawMatch(s, pattern, start, c) + +proc find*(s: string, pattern: TPeg, matches: var openArray[string], + start = 0): int {.nosideEffect, rtl, extern: "npegs$1Capture".} = + ## returns the starting position of ``pattern`` in ``s`` and the captured + ## substrings in the array ``matches``. If it does not match, nothing + ## is written into ``matches`` and -1 is returned. + var c: Captures + c.origStart = start + for i in start .. s.len-1: + c.ml = 0 + if rawMatch(s, pattern, i, c) >= 0: + fillMatches(s, matches, c) + return i + return -1 + # could also use the pattern here: (!P .)* P + +proc findBounds*(s: string, pattern: TPeg, matches: var openArray[string], + start = 0): tuple[first, last: int] {. + nosideEffect, rtl, extern: "npegs$1Capture".} = + ## returns the starting position and end position of ``pattern`` in ``s`` + ## and the captured + ## substrings in the array ``matches``. If it does not match, nothing + ## is written into ``matches`` and (-1,0) is returned. + var c: Captures + c.origStart = start + for i in start .. s.len-1: + c.ml = 0 + var L = rawMatch(s, pattern, i, c) + if L >= 0: + fillMatches(s, matches, c) + return (i, i+L-1) + return (-1, 0) + +proc find*(s: string, pattern: TPeg, + start = 0): int {.nosideEffect, rtl, extern: "npegs$1".} = + ## returns the starting position of ``pattern`` in ``s``. If it does not + ## match, -1 is returned. + var c: Captures + c.origStart = start + for i in start .. s.len-1: + if rawMatch(s, pattern, i, c) >= 0: return i + return -1 + +iterator findAll*(s: string, pattern: TPeg, start = 0): string = + ## yields all matching *substrings* of `s` that match `pattern`. + var c: Captures + c.origStart = start + var i = start + while i < s.len: + c.ml = 0 + var L = rawMatch(s, pattern, i, c) + if L < 0: + inc(i, 1) + else: + yield substr(s, i, i+L-1) + inc(i, L) + +proc findAll*(s: string, pattern: TPeg, start = 0): seq[string] {. + nosideEffect, rtl, extern: "npegs$1".} = + ## returns all matching *substrings* of `s` that match `pattern`. + ## If it does not match, @[] is returned. + accumulateResult(findAll(s, pattern, start)) + +when not defined(nimhygiene): + {.pragma: inject.} + +template `=~`*(s: string, pattern: TPeg): bool = + ## This calls ``match`` with an implicit declared ``matches`` array that + ## can be used in the scope of the ``=~`` call: + ## + ## .. code-block:: nim + ## + ## if line =~ peg"\s* {\w+} \s* '=' \s* {\w+}": + ## # matches a key=value pair: + ## echo("Key: ", matches[0]) + ## echo("Value: ", matches[1]) + ## elif line =~ peg"\s*{'#'.*}": + ## # matches a comment + ## # note that the implicit ``matches`` array is different from the + ## # ``matches`` array of the first branch + ## echo("comment: ", matches[0]) + ## else: + ## echo("syntax error") + ## + bind MaxSubpatterns + when not declaredInScope(matches): + var matches {.inject.}: array[0..MaxSubpatterns-1, string] + match(s, pattern, matches) + +# ------------------------- more string handling ------------------------------ + +proc contains*(s: string, pattern: TPeg, start = 0): bool {. + nosideEffect, rtl, extern: "npegs$1".} = + ## same as ``find(s, pattern, start) >= 0`` + return find(s, pattern, start) >= 0 + +proc contains*(s: string, pattern: TPeg, matches: var openArray[string], + start = 0): bool {.nosideEffect, rtl, extern: "npegs$1Capture".} = + ## same as ``find(s, pattern, matches, start) >= 0`` + return find(s, pattern, matches, start) >= 0 + +proc startsWith*(s: string, prefix: TPeg, start = 0): bool {. + nosideEffect, rtl, extern: "npegs$1".} = + ## returns true if `s` starts with the pattern `prefix` + result = matchLen(s, prefix, start) >= 0 + +proc endsWith*(s: string, suffix: TPeg, start = 0): bool {. + nosideEffect, rtl, extern: "npegs$1".} = + ## returns true if `s` ends with the pattern `prefix` + var c: Captures + c.origStart = start + for i in start .. s.len-1: + if rawMatch(s, suffix, i, c) == s.len - i: return true + +proc replacef*(s: string, sub: TPeg, by: string): string {. + nosideEffect, rtl, extern: "npegs$1".} = + ## Replaces `sub` in `s` by the string `by`. Captures can be accessed in `by` + ## with the notation ``$i`` and ``$#`` (see strutils.`%`). Examples: + ## + ## .. code-block:: nim + ## "var1=key; var2=key2".replace(peg"{\ident}'='{\ident}", "$1<-$2$2") + ## + ## Results in: + ## + ## .. code-block:: nim + ## + ## "var1<-keykey; val2<-key2key2" + result = "" + var i = 0 + var caps: array[0..MaxSubpatterns-1, string] + var c: Captures + while i < s.len: + c.ml = 0 + var x = rawMatch(s, sub, i, c) + if x <= 0: + add(result, s[i]) + inc(i) + else: + fillMatches(s, caps, c) + addf(result, by, caps) + inc(i, x) + add(result, substr(s, i)) + +proc replace*(s: string, sub: TPeg, by = ""): string {. + nosideEffect, rtl, extern: "npegs$1".} = + ## Replaces `sub` in `s` by the string `by`. Captures cannot be accessed + ## in `by`. + result = "" + var i = 0 + var c: Captures + while i < s.len: + var x = rawMatch(s, sub, i, c) + if x <= 0: + add(result, s[i]) + inc(i) + else: + add(result, by) + inc(i, x) + add(result, substr(s, i)) + +proc parallelReplace*(s: string, subs: varargs[ + tuple[pattern: TPeg, repl: string]]): string {. + nosideEffect, rtl, extern: "npegs$1".} = + ## Returns a modified copy of `s` with the substitutions in `subs` + ## applied in parallel. + result = "" + var i = 0 + var c: Captures + var caps: array[0..MaxSubpatterns-1, string] + while i < s.len: + block searchSubs: + for j in 0..high(subs): + c.ml = 0 + var x = rawMatch(s, subs[j][0], i, c) + if x > 0: + fillMatches(s, caps, c) + addf(result, subs[j][1], caps) + inc(i, x) + break searchSubs + add(result, s[i]) + inc(i) + # copy the rest: + add(result, substr(s, i)) + +proc transformFile*(infile, outfile: string, + subs: varargs[tuple[pattern: TPeg, repl: string]]) {. + rtl, extern: "npegs$1".} = + ## reads in the file `infile`, performs a parallel replacement (calls + ## `parallelReplace`) and writes back to `outfile`. Raises ``EIO`` if an + ## error occurs. This is supposed to be used for quick scripting. + var x = readFile(infile).string + writeFile(outfile, x.parallelReplace(subs)) + +iterator split*(s: string, sep: TPeg): string = + ## Splits the string `s` into substrings. + ## + ## Substrings are separated by the PEG `sep`. + ## Examples: + ## + ## .. code-block:: nim + ## for word in split("00232this02939is39an22example111", peg"\d+"): + ## writeln(stdout, word) + ## + ## Results in: + ## + ## .. code-block:: nim + ## "this" + ## "is" + ## "an" + ## "example" + ## + var c: Captures + var + first = 0 + last = 0 + while last < len(s): + c.ml = 0 + var x = rawMatch(s, sep, last, c) + if x > 0: inc(last, x) + first = last + while last < len(s): + inc(last) + c.ml = 0 + x = rawMatch(s, sep, last, c) + if x > 0: break + if first < last: + yield substr(s, first, last-1) + +proc split*(s: string, sep: TPeg): seq[string] {. + nosideEffect, rtl, extern: "npegs$1".} = + ## Splits the string `s` into substrings. + accumulateResult(split(s, sep)) + +# ------------------- scanner ------------------------------------------------- + +type + TModifier = enum + modNone, + modVerbatim, + modIgnoreCase, + modIgnoreStyle + TTokKind = enum ## enumeration of all tokens + tkInvalid, ## invalid token + tkEof, ## end of file reached + tkAny, ## . + tkAnyRune, ## _ + tkIdentifier, ## abc + tkStringLit, ## "abc" or 'abc' + tkCharSet, ## [^A-Z] + tkParLe, ## '(' + tkParRi, ## ')' + tkCurlyLe, ## '{' + tkCurlyRi, ## '}' + tkCurlyAt, ## '{@}' + tkArrow, ## '<-' + tkBar, ## '/' + tkStar, ## '*' + tkPlus, ## '+' + tkAmp, ## '&' + tkNot, ## '!' + tkOption, ## '?' + tkAt, ## '@' + tkBuiltin, ## \identifier + tkEscaped, ## \\ + tkBackref, ## '$' + tkDollar, ## '$' + tkHat ## '^' + + TToken {.final.} = object ## a token + kind: TTokKind ## the type of the token + modifier: TModifier + literal: string ## the parsed (string) literal + charset: set[char] ## if kind == tkCharSet + index: int ## if kind == tkBackref + + PegLexer {.inheritable.} = object ## the lexer object. + bufpos: int ## the current position within the buffer + buf: cstring ## the buffer itself + lineNumber: int ## the current line number + lineStart: int ## index of last line start in buffer + colOffset: int ## column to add + filename: string + +const + tokKindToStr: array[TTokKind, string] = [ + "invalid", "[EOF]", ".", "_", "identifier", "string literal", + "character set", "(", ")", "{", "}", "{@}", + "<-", "/", "*", "+", "&", "!", "?", + "@", "built-in", "escaped", "$", "$", "^" + ] + +proc handleCR(L: var PegLexer, pos: int): int = + assert(L.buf[pos] == '\c') + inc(L.lineNumber) + result = pos+1 + if L.buf[result] == '\L': inc(result) + L.lineStart = result + +proc handleLF(L: var PegLexer, pos: int): int = + assert(L.buf[pos] == '\L') + inc(L.lineNumber) + result = pos+1 + L.lineStart = result + +proc init(L: var PegLexer, input, filename: string, line = 1, col = 0) = + L.buf = input + L.bufpos = 0 + L.lineNumber = line + L.colOffset = col + L.lineStart = 0 + L.filename = filename + +proc getColumn(L: PegLexer): int {.inline.} = + result = abs(L.bufpos - L.lineStart) + L.colOffset + +proc getLine(L: PegLexer): int {.inline.} = + result = L.lineNumber + +proc errorStr(L: PegLexer, msg: string, line = -1, col = -1): string = + var line = if line < 0: getLine(L) else: line + var col = if col < 0: getColumn(L) else: col + result = "$1($2, $3) Error: $4" % [L.filename, $line, $col, msg] + +proc handleHexChar(c: var PegLexer, xi: var int) = + case c.buf[c.bufpos] + of '0'..'9': + xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('0')) + inc(c.bufpos) + of 'a'..'f': + xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('a') + 10) + inc(c.bufpos) + of 'A'..'F': + xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('A') + 10) + inc(c.bufpos) + else: discard + +proc getEscapedChar(c: var PegLexer, tok: var TToken) = + inc(c.bufpos) + case c.buf[c.bufpos] + of 'r', 'R', 'c', 'C': + add(tok.literal, '\c') + inc(c.bufpos) + of 'l', 'L': + add(tok.literal, '\L') + inc(c.bufpos) + of 'f', 'F': + add(tok.literal, '\f') + inc(c.bufpos) + of 'e', 'E': + add(tok.literal, '\e') + inc(c.bufpos) + of 'a', 'A': + add(tok.literal, '\a') + inc(c.bufpos) + of 'b', 'B': + add(tok.literal, '\b') + inc(c.bufpos) + of 'v', 'V': + add(tok.literal, '\v') + inc(c.bufpos) + of 't', 'T': + add(tok.literal, '\t') + inc(c.bufpos) + of 'x', 'X': + inc(c.bufpos) + var xi = 0 + handleHexChar(c, xi) + handleHexChar(c, xi) + if xi == 0: tok.kind = tkInvalid + else: add(tok.literal, chr(xi)) + of '0'..'9': + var val = ord(c.buf[c.bufpos]) - ord('0') + inc(c.bufpos) + var i = 1 + while (i <= 3) and (c.buf[c.bufpos] in {'0'..'9'}): + val = val * 10 + ord(c.buf[c.bufpos]) - ord('0') + inc(c.bufpos) + inc(i) + if val > 0 and val <= 255: add(tok.literal, chr(val)) + else: tok.kind = tkInvalid + of '\0'..'\31': + tok.kind = tkInvalid + elif c.buf[c.bufpos] in strutils.Letters: + tok.kind = tkInvalid + else: + add(tok.literal, c.buf[c.bufpos]) + inc(c.bufpos) + +proc skip(c: var PegLexer) = + var pos = c.bufpos + var buf = c.buf + while true: + case buf[pos] + of ' ', '\t': + inc(pos) + of '#': + while not (buf[pos] in {'\c', '\L', '\0'}): inc(pos) + of '\c': + pos = handleCR(c, pos) + buf = c.buf + of '\L': + pos = handleLF(c, pos) + buf = c.buf + else: + break # EndOfFile also leaves the loop + c.bufpos = pos + +proc getString(c: var PegLexer, tok: var TToken) = + tok.kind = tkStringLit + var pos = c.bufpos + 1 + var buf = c.buf + var quote = buf[pos-1] + while true: + case buf[pos] + of '\\': + c.bufpos = pos + getEscapedChar(c, tok) + pos = c.bufpos + of '\c', '\L', '\0': + tok.kind = tkInvalid + break + elif buf[pos] == quote: + inc(pos) + break + else: + add(tok.literal, buf[pos]) + inc(pos) + c.bufpos = pos + +proc getDollar(c: var PegLexer, tok: var TToken) = + var pos = c.bufpos + 1 + var buf = c.buf + if buf[pos] in {'0'..'9'}: + tok.kind = tkBackref + tok.index = 0 + while buf[pos] in {'0'..'9'}: + tok.index = tok.index * 10 + ord(buf[pos]) - ord('0') + inc(pos) + else: + tok.kind = tkDollar + c.bufpos = pos + +proc getCharSet(c: var PegLexer, tok: var TToken) = + tok.kind = tkCharSet + tok.charset = {} + var pos = c.bufpos + 1 + var buf = c.buf + var caret = false + if buf[pos] == '^': + inc(pos) + caret = true + while true: + var ch: char + case buf[pos] + of ']': + inc(pos) + break + of '\\': + c.bufpos = pos + getEscapedChar(c, tok) + pos = c.bufpos + ch = tok.literal[tok.literal.len-1] + of '\C', '\L', '\0': + tok.kind = tkInvalid + break + else: + ch = buf[pos] + inc(pos) + incl(tok.charset, ch) + if buf[pos] == '-': + if buf[pos+1] == ']': + incl(tok.charset, '-') + inc(pos) + else: + inc(pos) + var ch2: char + case buf[pos] + of '\\': + c.bufpos = pos + getEscapedChar(c, tok) + pos = c.bufpos + ch2 = tok.literal[tok.literal.len-1] + of '\C', '\L', '\0': + tok.kind = tkInvalid + break + else: + ch2 = buf[pos] + inc(pos) + for i in ord(ch)+1 .. ord(ch2): + incl(tok.charset, chr(i)) + c.bufpos = pos + if caret: tok.charset = {'\1'..'\xFF'} - tok.charset + +proc getSymbol(c: var PegLexer, tok: var TToken) = + var pos = c.bufpos + var buf = c.buf + while true: + add(tok.literal, buf[pos]) + inc(pos) + if buf[pos] notin strutils.IdentChars: break + c.bufpos = pos + tok.kind = tkIdentifier + +proc getBuiltin(c: var PegLexer, tok: var TToken) = + if c.buf[c.bufpos+1] in strutils.Letters: + inc(c.bufpos) + getSymbol(c, tok) + tok.kind = tkBuiltin + else: + tok.kind = tkEscaped + getEscapedChar(c, tok) # may set tok.kind to tkInvalid + +proc getTok(c: var PegLexer, tok: var TToken) = + tok.kind = tkInvalid + tok.modifier = modNone + setLen(tok.literal, 0) + skip(c) + case c.buf[c.bufpos] + of '{': + inc(c.bufpos) + if c.buf[c.bufpos] == '@' and c.buf[c.bufpos+1] == '}': + tok.kind = tkCurlyAt + inc(c.bufpos, 2) + add(tok.literal, "{@}") + else: + tok.kind = tkCurlyLe + add(tok.literal, '{') + of '}': + tok.kind = tkCurlyRi + inc(c.bufpos) + add(tok.literal, '}') + of '[': + getCharSet(c, tok) + of '(': + tok.kind = tkParLe + inc(c.bufpos) + add(tok.literal, '(') + of ')': + tok.kind = tkParRi + inc(c.bufpos) + add(tok.literal, ')') + of '.': + tok.kind = tkAny + inc(c.bufpos) + add(tok.literal, '.') + of '_': + tok.kind = tkAnyRune + inc(c.bufpos) + add(tok.literal, '_') + of '\\': + getBuiltin(c, tok) + of '\'', '"': getString(c, tok) + of '$': getDollar(c, tok) + of '\0': + tok.kind = tkEof + tok.literal = "[EOF]" + of 'a'..'z', 'A'..'Z', '\128'..'\255': + getSymbol(c, tok) + if c.buf[c.bufpos] in {'\'', '"'} or + c.buf[c.bufpos] == '$' and c.buf[c.bufpos+1] in {'0'..'9'}: + case tok.literal + of "i": tok.modifier = modIgnoreCase + of "y": tok.modifier = modIgnoreStyle + of "v": tok.modifier = modVerbatim + else: discard + setLen(tok.literal, 0) + if c.buf[c.bufpos] == '$': + getDollar(c, tok) + else: + getString(c, tok) + if tok.modifier == modNone: tok.kind = tkInvalid + of '+': + tok.kind = tkPlus + inc(c.bufpos) + add(tok.literal, '+') + of '*': + tok.kind = tkStar + inc(c.bufpos) + add(tok.literal, '+') + of '<': + if c.buf[c.bufpos+1] == '-': + inc(c.bufpos, 2) + tok.kind = tkArrow + add(tok.literal, "<-") + else: + add(tok.literal, '<') + of '/': + tok.kind = tkBar + inc(c.bufpos) + add(tok.literal, '/') + of '?': + tok.kind = tkOption + inc(c.bufpos) + add(tok.literal, '?') + of '!': + tok.kind = tkNot + inc(c.bufpos) + add(tok.literal, '!') + of '&': + tok.kind = tkAmp + inc(c.bufpos) + add(tok.literal, '!') + of '@': + tok.kind = tkAt + inc(c.bufpos) + add(tok.literal, '@') + if c.buf[c.bufpos] == '@': + tok.kind = tkCurlyAt + inc(c.bufpos) + add(tok.literal, '@') + of '^': + tok.kind = tkHat + inc(c.bufpos) + add(tok.literal, '^') + else: + add(tok.literal, c.buf[c.bufpos]) + inc(c.bufpos) + +proc arrowIsNextTok(c: PegLexer): bool = + # the only look ahead we need + var pos = c.bufpos + while c.buf[pos] in {'\t', ' '}: inc(pos) + result = c.buf[pos] == '<' and c.buf[pos+1] == '-' + +# ----------------------------- parser ---------------------------------------- + +type + EInvalidPeg* = object of ValueError ## raised if an invalid + ## PEG has been detected + PegParser = object of PegLexer ## the PEG parser object + tok: TToken + nonterms: seq[PNonTerminal] + modifier: TModifier + captures: int + identIsVerbatim: bool + skip: TPeg + +proc pegError(p: PegParser, msg: string, line = -1, col = -1) = + var e: ref EInvalidPeg + new(e) + e.msg = errorStr(p, msg, line, col) + raise e + +proc getTok(p: var PegParser) = + getTok(p, p.tok) + if p.tok.kind == tkInvalid: pegError(p, "invalid token") + +proc eat(p: var PegParser, kind: TTokKind) = + if p.tok.kind == kind: getTok(p) + else: pegError(p, tokKindToStr[kind] & " expected") + +proc parseExpr(p: var PegParser): TPeg + +proc getNonTerminal(p: var PegParser, name: string): PNonTerminal = + for i in 0..high(p.nonterms): + result = p.nonterms[i] + if cmpIgnoreStyle(result.name, name) == 0: return + # forward reference: + result = newNonTerminal(name, getLine(p), getColumn(p)) + add(p.nonterms, result) + +proc modifiedTerm(s: string, m: TModifier): TPeg = + case m + of modNone, modVerbatim: result = term(s) + of modIgnoreCase: result = termIgnoreCase(s) + of modIgnoreStyle: result = termIgnoreStyle(s) + +proc modifiedBackref(s: int, m: TModifier): TPeg = + case m + of modNone, modVerbatim: result = backref(s) + of modIgnoreCase: result = backrefIgnoreCase(s) + of modIgnoreStyle: result = backrefIgnoreStyle(s) + +proc builtin(p: var PegParser): TPeg = + # do not use "y", "skip" or "i" as these would be ambiguous + case p.tok.literal + of "n": result = newLine() + of "d": result = charSet({'0'..'9'}) + of "D": result = charSet({'\1'..'\xff'} - {'0'..'9'}) + of "s": result = charSet({' ', '\9'..'\13'}) + of "S": result = charSet({'\1'..'\xff'} - {' ', '\9'..'\13'}) + of "w": result = charSet({'a'..'z', 'A'..'Z', '_', '0'..'9'}) + of "W": result = charSet({'\1'..'\xff'} - {'a'..'z','A'..'Z','_','0'..'9'}) + of "a": result = charSet({'a'..'z', 'A'..'Z'}) + of "A": result = charSet({'\1'..'\xff'} - {'a'..'z', 'A'..'Z'}) + of "ident": result = pegs.ident + of "letter": result = unicodeLetter() + of "upper": result = unicodeUpper() + of "lower": result = unicodeLower() + of "title": result = unicodeTitle() + of "white": result = unicodeWhitespace() + else: pegError(p, "unknown built-in: " & p.tok.literal) + +proc token(terminal: TPeg, p: PegParser): TPeg = + if p.skip.kind == pkEmpty: result = terminal + else: result = sequence(p.skip, terminal) + +proc primary(p: var PegParser): TPeg = + case p.tok.kind + of tkAmp: + getTok(p) + return &primary(p) + of tkNot: + getTok(p) + return !primary(p) + of tkAt: + getTok(p) + return !*primary(p) + of tkCurlyAt: + getTok(p) + return !*\primary(p).token(p) + else: discard + case p.tok.kind + of tkIdentifier: + if p.identIsVerbatim: + var m = p.tok.modifier + if m == modNone: m = p.modifier + result = modifiedTerm(p.tok.literal, m).token(p) + getTok(p) + elif not arrowIsNextTok(p): + var nt = getNonTerminal(p, p.tok.literal) + incl(nt.flags, ntUsed) + result = nonterminal(nt).token(p) + getTok(p) + else: + pegError(p, "expression expected, but found: " & p.tok.literal) + of tkStringLit: + var m = p.tok.modifier + if m == modNone: m = p.modifier + result = modifiedTerm(p.tok.literal, m).token(p) + getTok(p) + of tkCharSet: + if '\0' in p.tok.charset: + pegError(p, "binary zero ('\\0') not allowed in character class") + result = charSet(p.tok.charset).token(p) + getTok(p) + of tkParLe: + getTok(p) + result = parseExpr(p) + eat(p, tkParRi) + of tkCurlyLe: + getTok(p) + result = capture(parseExpr(p)).token(p) + eat(p, tkCurlyRi) + inc(p.captures) + of tkAny: + result = any().token(p) + getTok(p) + of tkAnyRune: + result = anyRune().token(p) + getTok(p) + of tkBuiltin: + result = builtin(p).token(p) + getTok(p) + of tkEscaped: + result = term(p.tok.literal[0]).token(p) + getTok(p) + of tkDollar: + result = endAnchor() + getTok(p) + of tkHat: + result = startAnchor() + getTok(p) + of tkBackref: + var m = p.tok.modifier + if m == modNone: m = p.modifier + result = modifiedBackref(p.tok.index, m).token(p) + if p.tok.index < 0 or p.tok.index > p.captures: + pegError(p, "invalid back reference index: " & $p.tok.index) + getTok(p) + else: + pegError(p, "expression expected, but found: " & p.tok.literal) + getTok(p) # we must consume a token here to prevent endless loops! + while true: + case p.tok.kind + of tkOption: + result = ?result + getTok(p) + of tkStar: + result = *result + getTok(p) + of tkPlus: + result = +result + getTok(p) + else: break + +proc seqExpr(p: var PegParser): TPeg = + result = primary(p) + while true: + case p.tok.kind + of tkAmp, tkNot, tkAt, tkStringLit, tkCharSet, tkParLe, tkCurlyLe, + tkAny, tkAnyRune, tkBuiltin, tkEscaped, tkDollar, tkBackref, + tkHat, tkCurlyAt: + result = sequence(result, primary(p)) + of tkIdentifier: + if not arrowIsNextTok(p): + result = sequence(result, primary(p)) + else: break + else: break + +proc parseExpr(p: var PegParser): TPeg = + result = seqExpr(p) + while p.tok.kind == tkBar: + getTok(p) + result = result / seqExpr(p) + +proc parseRule(p: var PegParser): PNonTerminal = + if p.tok.kind == tkIdentifier and arrowIsNextTok(p): + result = getNonTerminal(p, p.tok.literal) + if ntDeclared in result.flags: + pegError(p, "attempt to redefine: " & result.name) + result.line = getLine(p) + result.col = getColumn(p) + getTok(p) + eat(p, tkArrow) + result.rule = parseExpr(p) + incl(result.flags, ntDeclared) # NOW inlining may be attempted + else: + pegError(p, "rule expected, but found: " & p.tok.literal) + +proc rawParse(p: var PegParser): TPeg = + ## parses a rule or a PEG expression + while p.tok.kind == tkBuiltin: + case p.tok.literal + of "i": + p.modifier = modIgnoreCase + getTok(p) + of "y": + p.modifier = modIgnoreStyle + getTok(p) + of "skip": + getTok(p) + p.skip = ?primary(p) + else: break + if p.tok.kind == tkIdentifier and arrowIsNextTok(p): + result = parseRule(p).rule + while p.tok.kind != tkEof: + discard parseRule(p) + else: + p.identIsVerbatim = true + result = parseExpr(p) + if p.tok.kind != tkEof: + pegError(p, "EOF expected, but found: " & p.tok.literal) + for i in 0..high(p.nonterms): + var nt = p.nonterms[i] + if ntDeclared notin nt.flags: + pegError(p, "undeclared identifier: " & nt.name, nt.line, nt.col) + elif ntUsed notin nt.flags and i > 0: + pegError(p, "unused rule: " & nt.name, nt.line, nt.col) + +proc parsePeg*(pattern: string, filename = "pattern", line = 1, col = 0): TPeg = + ## constructs a Peg object from `pattern`. `filename`, `line`, `col` are + ## used for error messages, but they only provide start offsets. `parsePeg` + ## keeps track of line and column numbers within `pattern`. + var p: PegParser + init(PegLexer(p), pattern, filename, line, col) + p.tok.kind = tkInvalid + p.tok.modifier = modNone + p.tok.literal = "" + p.tok.charset = {} + p.nonterms = @[] + p.identIsVerbatim = false + getTok(p) + result = rawParse(p) + +proc peg*(pattern: string): TPeg = + ## constructs a Peg object from the `pattern`. The short name has been + ## chosen to encourage its use as a raw string modifier:: + ## + ## peg"{\ident} \s* '=' \s* {.*}" + result = parsePeg(pattern, "pattern") + +proc escapePeg*(s: string): string = + ## escapes `s` so that it is matched verbatim when used as a peg. + result = "" + var inQuote = false + for c in items(s): + case c + of '\0'..'\31', '\'', '"', '\\': + if inQuote: + result.add('\'') + inQuote = false + result.add("\\x") + result.add(toHex(ord(c), 2)) + else: + if not inQuote: + result.add('\'') + inQuote = true + result.add(c) + if inQuote: result.add('\'') + +when isMainModule: + assert escapePeg("abc''def'") == r"'abc'\x27\x27'def'\x27" + assert match("(a b c)", peg"'(' @ ')'") + assert match("W_HI_Le", peg"\y 'while'") + assert(not match("W_HI_L", peg"\y 'while'")) + assert(not match("W_HI_Le", peg"\y v'while'")) + assert match("W_HI_Le", peg"y'while'") + + assert($ +digits == $peg"\d+") + assert "0158787".match(peg"\d+") + assert "ABC 0232".match(peg"\w+\s+\d+") + assert "ABC".match(peg"\d+ / \w+") + + for word in split("00232this02939is39an22example111", peg"\d+"): + writeln(stdout, word) + + assert matchLen("key", ident) == 3 + + var pattern = sequence(ident, *whitespace, term('='), *whitespace, ident) + assert matchLen("key1= cal9", pattern) == 11 + + var ws = newNonTerminal("ws", 1, 1) + ws.rule = *whitespace + + var expr = newNonTerminal("expr", 1, 1) + expr.rule = sequence(capture(ident), *sequence( + nonterminal(ws), term('+'), nonterminal(ws), nonterminal(expr))) + + var c: Captures + var s = "a+b + c +d+e+f" + assert rawMatch(s, expr.rule, 0, c) == len(s) + var a = "" + for i in 0..c.ml-1: + a.add(substr(s, c.matches[i][0], c.matches[i][1])) + assert a == "abcdef" + #echo expr.rule + + #const filename = "lib/devel/peg/grammar.txt" + #var grammar = parsePeg(newFileStream(filename, fmRead), filename) + #echo "a <- [abc]*?".match(grammar) + assert find("_____abc_______", term("abc"), 2) == 5 + assert match("_______ana", peg"A <- 'ana' / . A") + assert match("abcs%%%", peg"A <- ..A / .A / '%'") + + var matches: array[0..MaxSubpatterns-1, string] + if "abc" =~ peg"{'a'}'bc' 'xyz' / {\ident}": + assert matches[0] == "abc" + else: + assert false + + var g2 = peg"""S <- A B / C D + A <- 'a'+ + B <- 'b'+ + C <- 'c'+ + D <- 'd'+ + """ + assert($g2 == "((A B) / (C D))") + assert match("cccccdddddd", g2) + assert("var1=key; var2=key2".replacef(peg"{\ident}'='{\ident}", "$1<-$2$2") == + "var1<-keykey; var2<-key2key2") + assert("var1=key; var2=key2".replace(peg"{\ident}'='{\ident}", "$1<-$2$2") == + "$1<-$2$2; $1<-$2$2") + assert "var1=key; var2=key2".endsWith(peg"{\ident}'='{\ident}") + + if "aaaaaa" =~ peg"'aa' !. / ({'a'})+": + assert matches[0] == "a" + else: + assert false + + if match("abcdefg", peg"c {d} ef {g}", matches, 2): + assert matches[0] == "d" + assert matches[1] == "g" + else: + assert false + + for x in findAll("abcdef", peg".", 3): + echo x + + for x in findAll("abcdef", peg"^{.}", 3): + assert x == "d" + + if "f(a, b)" =~ peg"{[0-9]+} / ({\ident} '(' {@} ')')": + assert matches[0] == "f" + assert matches[1] == "a, b" + else: + assert false + + assert match("eine übersicht und außerdem", peg"(\letter \white*)+") + # ß is not a lower cased letter?! + assert match("eine übersicht und auerdem", peg"(\lower \white*)+") + assert match("EINE ÃœBERSICHT UND AUSSERDEM", peg"(\upper \white*)+") + assert(not match("456678", peg"(\letter)+")) + + assert("var1 = key; var2 = key2".replacef( + peg"\skip(\s*) {\ident}'='{\ident}", "$1<-$2$2") == + "var1<-keykey;var2<-key2key2") + + assert match("prefix/start", peg"^start$", 7) + diff --git a/lib/pure/poly.nim b/lib/pure/poly.nim index 45e528604..286e5a8fd 100644 --- a/lib/pure/poly.nim +++ b/lib/pure/poly.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Robert Persson # # See the file "copying.txt", included in this @@ -12,17 +12,18 @@ import strutils import numeric type - TPoly* = object - cofs:seq[float] + Poly* = object + cofs:seq[float] - -proc degree*(p:TPoly):int= +{.deprecated: [TPoly: Poly].} + +proc degree*(p:Poly):int= ## Returns the degree of the polynomial, ## that is the number of coefficients-1 return p.cofs.len-1 -proc eval*(p:TPoly,x:float):float= +proc eval*(p:Poly,x:float):float= ## Evaluates a polynomial function value for `x` ## quickly using Horners method var n=p.degree @@ -32,7 +33,7 @@ proc eval*(p:TPoly,x:float):float= result = result*x+p.cofs[n] dec n -proc `[]` *(p:TPoly;idx:int):float= +proc `[]` *(p:Poly;idx:int):float= ## Gets a coefficient of the polynomial. ## p[2] will returns the quadric term, p[3] the cubic etc. ## Out of bounds index will return 0.0. @@ -40,7 +41,7 @@ proc `[]` *(p:TPoly;idx:int):float= return 0.0 return p.cofs[idx] -proc `[]=` *(p:var TPoly;idx:int,v:float)= +proc `[]=` *(p:var Poly;idx:int,v:float)= ## Sets an coefficient of the polynomial by index. ## p[2] set the quadric term, p[3] the cubic etc. ## If index is out of range for the coefficients, @@ -56,14 +57,14 @@ proc `[]=` *(p:var TPoly;idx:int,v:float)= p.cofs[idx]=v -iterator items*(p:TPoly):float= +iterator items*(p:Poly):float= ## Iterates through the corfficients of the polynomial. var i=p.degree while i>=0: yield p[i] dec i -proc clean*(p:var TPoly;zerotol=0.0)= +proc clean*(p:var Poly;zerotol=0.0)= ## Removes leading zero coefficients of the polynomial. ## An optional tolerance can be given for what's considered zero. var n=p.degree @@ -76,7 +77,7 @@ proc clean*(p:var TPoly;zerotol=0.0)= if relen: p.cofs.setLen(n+1) -proc `$` *(p:TPoly):string = +proc `$` *(p:Poly):string = ## Gets a somewhat reasonable string representation of the polynomial ## The format should be compatible with most online function plotters, ## for example directly in google search @@ -104,13 +105,13 @@ proc `$` *(p:TPoly):string = result="0" -proc derivative*(p:TPoly):TPoly= +proc derivative*(p: Poly): Poly= ## Returns a new polynomial, which is the derivative of `p` newSeq[float](result.cofs,p.degree) for idx in 0..high(result.cofs): result.cofs[idx]=p.cofs[idx+1]*float(idx+1) -proc diff*(p:TPoly,x:float):float= +proc diff*(p:Poly,x:float):float= ## Evaluates the differentiation of a polynomial with ## respect to `x` quickly using a modifed Horners method var n=p.degree @@ -120,7 +121,7 @@ proc diff*(p:TPoly,x:float):float= result = result*x+p[n]*float(n) dec n -proc integral*(p:TPoly):TPoly= +proc integral*(p:Poly):Poly= ## Returns a new polynomial which is the indefinite ## integral of `p`. The constant term is set to 0.0 newSeq(result.cofs,p.cofs.len+1) @@ -129,7 +130,7 @@ proc integral*(p:TPoly):TPoly= result.cofs[i]=p.cofs[i-1]/float(i) -proc integrate*(p:TPoly;xmin,xmax:float):float= +proc integrate*(p:Poly;xmin,xmax:float):float= ## Computes the definite integral of `p` between `xmin` and `xmax` ## quickly using a modified version of Horners method var @@ -147,7 +148,7 @@ proc integrate*(p:TPoly;xmin,xmax:float):float= result=s2*xmax-s1*xmin -proc initPoly*(cofs:varargs[float]):TPoly= +proc initPoly*(cofs:varargs[float]):Poly= ## Initializes a polynomial with given coefficients. ## The most significant coefficient is first, so to create x^2-2x+3: ## intiPoly(1.0,-2.0,3.0) @@ -163,7 +164,7 @@ proc initPoly*(cofs:varargs[float]):TPoly= result.clean #remove leading zero terms -proc divMod*(p,d:TPoly;q,r:var TPoly)= +proc divMod*(p,d:Poly;q,r:var Poly)= ## Divides `p` with `d`, and stores the quotinent in `q` and ## the remainder in `d` var @@ -191,7 +192,7 @@ proc divMod*(p,d:TPoly;q,r:var TPoly)= r.clean # drop zero coefficients in remainder -proc `+` *(p1:TPoly,p2:TPoly):TPoly= +proc `+` *(p1:Poly,p2:Poly):Poly= ## Adds two polynomials var n=max(p1.cofs.len,p2.cofs.len) newSeq(result.cofs,n) @@ -201,7 +202,7 @@ proc `+` *(p1:TPoly,p2:TPoly):TPoly= result.clean # drop zero coefficients in remainder -proc `*` *(p1:TPoly,p2:TPoly):TPoly= +proc `*` *(p1:Poly,p2:Poly):Poly= ## Multiplies the polynomial `p1` with `p2` var d1=p1.degree @@ -218,24 +219,24 @@ proc `*` *(p1:TPoly,p2:TPoly):TPoly= result.clean -proc `*` *(p:TPoly,f:float):TPoly= +proc `*` *(p:Poly,f:float):Poly= ## Multiplies the polynomial `p` with a real number newSeq(result.cofs,p.cofs.len) for i in 0..high(p.cofs): result[i]=p.cofs[i]*f result.clean -proc `*` *(f:float,p:TPoly):TPoly= +proc `*` *(f:float,p:Poly):Poly= ## Multiplies a real number with a polynomial return p*f -proc `-`*(p:TPoly):TPoly= +proc `-`*(p:Poly):Poly= ## Negates a polynomial result=p for i in countup(0,<result.cofs.len): result.cofs[i]= -result.cofs[i] -proc `-` *(p1:TPoly,p2:TPoly):TPoly= +proc `-` *(p1:Poly,p2:Poly):Poly= ## Subtract `p1` with `p2` var n=max(p1.cofs.len,p2.cofs.len) newSeq(result.cofs,n) @@ -245,26 +246,26 @@ proc `-` *(p1:TPoly,p2:TPoly):TPoly= result.clean # drop zero coefficients in remainder -proc `/`*(p:TPoly,f:float):TPoly= +proc `/`*(p:Poly,f:float):Poly= ## Divides polynomial `p` with a real number `f` newSeq(result.cofs,p.cofs.len) for i in 0..high(p.cofs): result[i]=p.cofs[i]/f result.clean -proc `/` *(p,q:TPoly):TPoly= +proc `/` *(p,q:Poly):Poly= ## Divides polynomial `p` with polynomial `q` - var dummy:TPoly + var dummy:Poly p.divMod(q,result,dummy) -proc `mod` *(p,q:TPoly):TPoly= +proc `mod` *(p,q:Poly):Poly= ## Computes the polynomial modulo operation, ## that is the remainder of `p`/`q` - var dummy:TPoly + var dummy:Poly p.divMod(q,dummy,result) -proc normalize*(p:var TPoly)= +proc normalize*(p:var Poly)= ## Multiplies the polynomial inplace by a term so that ## the leading term is 1.0. ## This might lead to an unstable polynomial @@ -281,9 +282,9 @@ proc solveQuadric*(a,b,c:float;zerotol=0.0):seq[float]= p=b/(2.0*a) - if p==inf or p==neginf: #linear equation.. + if p==Inf or p==NegInf: #linear equation.. var linrt= -c/b - if linrt==inf or linrt==neginf: #constant only + if linrt==Inf or linrt==NegInf: #constant only return @[] return @[linrt] @@ -299,7 +300,7 @@ proc solveQuadric*(a,b,c:float;zerotol=0.0):seq[float]= var sr=sqrt(d) result= @[-sr-p,sr-p] -proc getRangeForRoots(p:TPoly):tuple[xmin,xmax:float]= +proc getRangeForRoots(p:Poly):tuple[xmin,xmax:float]= ## helper function for `roots` function ## quickly computes a range, guaranteed to contain ## all the real roots of the polynomial @@ -310,16 +311,16 @@ proc getRangeForRoots(p:TPoly):tuple[xmin,xmax:float]= var bound1,bound2:float for i in countup(0,deg): - var c=abs(p.cofs[i]/d) - bound1=max(bound1,c+1.0) - bound2=bound2+c - + var c=abs(p.cofs[i]/d) + bound1=max(bound1,c+1.0) + bound2=bound2+c + bound2=max(1.0,bound2) result.xmax=min(bound1,bound2) result.xmin= -result.xmax -proc addRoot(p:TPoly,res:var seq[float],xp0,xp1,tol,zerotol,mergetol:float,maxiter:int)= +proc addRoot(p:Poly,res:var seq[float],xp0,xp1,tol,zerotol,mergetol:float,maxiter:int)= ## helper function for `roots` function ## try to do a numeric search for a single root in range xp0-xp1, ## adding it to `res` (allocating `res` if nil) @@ -335,7 +336,7 @@ proc addRoot(p:TPoly,res:var seq[float],xp0,xp1,tol,zerotol,mergetol:float,maxit res.add(br.rootx) -proc roots*(p:TPoly,tol=1.0e-9,zerotol=1.0e-6,mergetol=1.0e-12,maxiter=1000):seq[float]= +proc roots*(p:Poly,tol=1.0e-9,zerotol=1.0e-6,mergetol=1.0e-12,maxiter=1000):seq[float]= ## Computes the real roots of the polynomial `p` ## `tol` is the tolerance used to break searching for each root when reached. ## `zerotol` is the tolerance, which is 'close enough' to zero to be considered a root @@ -348,7 +349,7 @@ proc roots*(p:TPoly,tol=1.0e-9,zerotol=1.0e-6,mergetol=1.0e-12,maxiter=1000):seq return @[] elif p.degree==1: #linear var linrt= -p.cofs[0]/p.cofs[1] - if linrt==inf or linrt==neginf: + if linrt==Inf or linrt==NegInf: return @[] #constant only => no roots return @[linrt] elif p.degree==2: diff --git a/lib/pure/rawsockets.nim b/lib/pure/rawsockets.nim index fea09dfa2..62a011999 100644 --- a/lib/pure/rawsockets.nim +++ b/lib/pure/rawsockets.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Dominik Picheta # # See the file "copying.txt", included in this @@ -14,7 +14,7 @@ import unsigned, os -when hostos == "solaris": +when hostOS == "solaris": {.passl: "-lsocket -lnsl".} const useWinVersion = defined(Windows) or defined(nimdoc) @@ -28,7 +28,7 @@ else: export fcntl, F_GETFL, O_NONBLOCK, F_SETFL, EAGAIN, EWOULDBLOCK, MSG_NOSIGNAL, EINTR, EINPROGRESS, ECONNRESET, EPIPE, ENETRESET -export TSocketHandle, TSockaddr_in, TAddrinfo, INADDR_ANY, TSockAddr, TSockLen, +export SocketHandle, Sockaddr_in, Addrinfo, INADDR_ANY, SockAddr, SockLen, inet_ntoa, recv, `==`, connect, send, accept, recvfrom, sendto export @@ -40,22 +40,22 @@ export MSG_PEEK type - TPort* = distinct uint16 ## port type + Port* = distinct uint16 ## port type - TDomain* = enum ## domain, which specifies the protocol family of the + Domain* = enum ## domain, which specifies the protocol family of the ## created socket. Other domains than those that are listed ## here are unsupported. AF_UNIX, ## for local socket (using a file). Unsupported on Windows. AF_INET = 2, ## for network protocol IPv4 or AF_INET6 = 23 ## for network protocol IPv6. - TType* = enum ## second argument to `socket` proc + SockType* = enum ## second argument to `socket` proc SOCK_STREAM = 1, ## reliable stream-oriented service or Stream Sockets SOCK_DGRAM = 2, ## datagram service or Datagram Sockets SOCK_RAW = 3, ## raw protocols atop the network layer. SOCK_SEQPACKET = 5 ## reliable sequenced packet service - TProtocol* = enum ## third argument to `socket` proc + Protocol* = enum ## third argument to `socket` proc IPPROTO_TCP = 6, ## Transmission control protocol. IPPROTO_UDP = 17, ## User datagram protocol. IPPROTO_IP, ## Internet protocol. Unsupported on Windows. @@ -63,19 +63,22 @@ type IPPROTO_RAW, ## Raw IP Packets Protocol. Unsupported on Windows. IPPROTO_ICMP ## Control message protocol. Unsupported on Windows. - TServent* {.pure, final.} = object ## information about a service + Servent* = object ## information about a service name*: string aliases*: seq[string] - port*: TPort + port*: Port proto*: string - Thostent* {.pure, final.} = object ## information about a given host + Hostent* = object ## information about a given host name*: string aliases*: seq[string] - addrtype*: TDomain + addrtype*: Domain length*: int addrList*: seq[string] +{.deprecated: [TPort: Port, TDomain: Domain, TType: SockType, + TProtocol: Protocol, TServent: Servent, THostent: Hostent].} + when useWinVersion: let osInvalidSocket* = winlean.INVALID_SOCKET @@ -86,37 +89,37 @@ when useWinVersion: FIONBIO* = IOC_IN.int32 or ((sizeof(int32) and IOCPARM_MASK) shl 16) or (102 shl 8) or 126 - proc ioctlsocket*(s: TSocketHandle, cmd: clong, + proc ioctlsocket*(s: SocketHandle, cmd: clong, argptr: ptr clong): cint {. stdcall, importc: "ioctlsocket", dynlib: "ws2_32.dll".} else: let osInvalidSocket* = posix.INVALID_SOCKET -proc `==`*(a, b: TPort): bool {.borrow.} +proc `==`*(a, b: Port): bool {.borrow.} ## ``==`` for ports. -proc `$`*(p: TPort): string {.borrow.} +proc `$`*(p: Port): string {.borrow.} ## returns the port number as a string -proc toInt*(domain: TDomain): cint +proc toInt*(domain: Domain): cint ## Converts the TDomain enum to a platform-dependent ``cint``. -proc toInt*(typ: TType): cint +proc toInt*(typ: SockType): cint ## Converts the TType enum to a platform-dependent ``cint``. -proc toInt*(p: TProtocol): cint +proc toInt*(p: Protocol): cint ## Converts the TProtocol enum to a platform-dependent ``cint``. when not useWinVersion: - proc toInt(domain: TDomain): cint = + proc toInt(domain: Domain): cint = case domain of AF_UNIX: result = posix.AF_UNIX of AF_INET: result = posix.AF_INET of AF_INET6: result = posix.AF_INET6 else: discard - proc toInt(typ: TType): cint = + proc toInt(typ: SockType): cint = case typ of SOCK_STREAM: result = posix.SOCK_STREAM of SOCK_DGRAM: result = posix.SOCK_DGRAM @@ -124,7 +127,7 @@ when not useWinVersion: of SOCK_RAW: result = posix.SOCK_RAW else: discard - proc toInt(p: TProtocol): cint = + proc toInt(p: Protocol): cint = case p of IPPROTO_TCP: result = posix.IPPROTO_TCP of IPPROTO_UDP: result = posix.IPPROTO_UDP @@ -135,34 +138,41 @@ when not useWinVersion: else: discard else: - proc toInt(domain: TDomain): cint = + proc toInt(domain: Domain): cint = result = toU16(ord(domain)) - proc toInt(typ: TType): cint = + proc toInt(typ: SockType): cint = result = cint(ord(typ)) - proc toInt(p: TProtocol): cint = + proc toInt(p: Protocol): cint = result = cint(ord(p)) -proc newRawSocket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, - protocol: TProtocol = IPPROTO_TCP): TSocketHandle = +proc newRawSocket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM, + protocol: Protocol = IPPROTO_TCP): SocketHandle = ## Creates a new socket; returns `InvalidSocket` if an error occurs. socket(toInt(domain), toInt(typ), toInt(protocol)) -proc close*(socket: TSocketHandle) = +proc newRawSocket*(domain: cint, typ: cint, protocol: cint): SocketHandle = + ## Creates a new socket; returns `InvalidSocket` if an error occurs. + ## + ## Use this overload if one of the enums specified above does + ## not contain what you need. + socket(domain, typ, protocol) + +proc close*(socket: SocketHandle) = ## closes a socket. when useWinVersion: - discard winlean.closeSocket(socket) + discard winlean.closesocket(socket) else: discard posix.close(socket) # TODO: These values should not be discarded. An EOS should be raised. # http://stackoverflow.com/questions/12463473/what-happens-if-you-call-close-on-a-bsd-socket-multiple-times -proc bindAddr*(socket: TSocketHandle, name: ptr TSockAddr, namelen: TSockLen): cint = +proc bindAddr*(socket: SocketHandle, name: ptr SockAddr, namelen: SockLen): cint = result = bindSocket(socket, name, namelen) -proc listen*(socket: TSocketHandle, backlog = SOMAXCONN): cint {.tags: [FReadIO].} = +proc listen*(socket: SocketHandle, backlog = SOMAXCONN): cint {.tags: [ReadIOEffect].} = ## Marks ``socket`` as accepting connections. ## ``Backlog`` specifies the maximum length of the ## queue of pending connections. @@ -171,24 +181,24 @@ proc listen*(socket: TSocketHandle, backlog = SOMAXCONN): cint {.tags: [FReadIO] else: result = posix.listen(socket, cint(backlog)) -proc getAddrInfo*(address: string, port: TPort, af: TDomain = AF_INET, typ: TType = SOCK_STREAM, - prot: TProtocol = IPPROTO_TCP): ptr TAddrInfo = +proc getAddrInfo*(address: string, port: Port, af: Domain = AF_INET, typ: SockType = SOCK_STREAM, + prot: Protocol = IPPROTO_TCP): ptr AddrInfo = ## ## ## **Warning**: The resulting ``ptr TAddrInfo`` must be freed using ``dealloc``! - var hints: TAddrInfo + var hints: AddrInfo result = nil hints.ai_family = toInt(af) hints.ai_socktype = toInt(typ) hints.ai_protocol = toInt(prot) - var gaiResult = getAddrInfo(address, $port, addr(hints), result) + var gaiResult = getaddrinfo(address, $port, addr(hints), result) if gaiResult != 0'i32: when useWinVersion: - osError(osLastError()) + raiseOSError(osLastError()) else: - raise newException(EOS, $gai_strerror(gaiResult)) + raise newException(OSError, $gai_strerror(gaiResult)) -proc dealloc*(ai: ptr TAddrInfo) = +proc dealloc*(ai: ptr AddrInfo) = freeaddrinfo(ai) proc ntohl*(x: int32): int32 = @@ -220,7 +230,7 @@ proc htons*(x: int16): int16 = ## order, this is a no-op; otherwise, it performs a 2-byte swap operation. result = rawsockets.ntohs(x) -proc getServByName*(name, proto: string): TServent {.tags: [FReadIO].} = +proc getServByName*(name, proto: string): Servent {.tags: [ReadIOEffect].} = ## Searches the database from the beginning and finds the first entry for ## which the service name specified by ``name`` matches the s_name member ## and the protocol name specified by ``proto`` matches the s_proto member. @@ -230,13 +240,13 @@ proc getServByName*(name, proto: string): TServent {.tags: [FReadIO].} = var s = winlean.getservbyname(name, proto) else: var s = posix.getservbyname(name, proto) - if s == nil: raise newException(EOS, "Service not found.") + if s == nil: raise newException(OSError, "Service not found.") result.name = $s.s_name result.aliases = cstringArrayToSeq(s.s_aliases) - result.port = TPort(s.s_port) + result.port = Port(s.s_port) result.proto = $s.s_proto -proc getServByPort*(port: TPort, proto: string): TServent {.tags: [FReadIO].} = +proc getServByPort*(port: Port, proto: string): Servent {.tags: [ReadIOEffect].} = ## Searches the database from the beginning and finds the first entry for ## which the port specified by ``port`` matches the s_port member and the ## protocol name specified by ``proto`` matches the s_proto member. @@ -246,125 +256,125 @@ proc getServByPort*(port: TPort, proto: string): TServent {.tags: [FReadIO].} = var s = winlean.getservbyport(ze(int16(port)).cint, proto) else: var s = posix.getservbyport(ze(int16(port)).cint, proto) - if s == nil: raise newException(EOS, "Service not found.") + if s == nil: raise newException(OSError, "Service not found.") result.name = $s.s_name result.aliases = cstringArrayToSeq(s.s_aliases) - result.port = TPort(s.s_port) + result.port = Port(s.s_port) result.proto = $s.s_proto -proc getHostByAddr*(ip: string): Thostent {.tags: [FReadIO].} = +proc getHostByAddr*(ip: string): Hostent {.tags: [ReadIOEffect].} = ## This function will lookup the hostname of an IP Address. - var myaddr: TInAddr + var myaddr: InAddr myaddr.s_addr = inet_addr(ip) when useWinVersion: var s = winlean.gethostbyaddr(addr(myaddr), sizeof(myaddr).cuint, cint(rawsockets.AF_INET)) - if s == nil: osError(osLastError()) + if s == nil: raiseOSError(osLastError()) else: - var s = posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).TSocklen, + var s = posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).Socklen, cint(posix.AF_INET)) if s == nil: - raise newException(EOS, $hstrerror(h_errno)) + raise newException(OSError, $hstrerror(h_errno)) result.name = $s.h_name result.aliases = cstringArrayToSeq(s.h_aliases) - when useWinVersion: - result.addrtype = TDomain(s.h_addrtype) + when useWinVersion: + result.addrtype = Domain(s.h_addrtype) else: if s.h_addrtype == posix.AF_INET: result.addrtype = AF_INET elif s.h_addrtype == posix.AF_INET6: result.addrtype = AF_INET6 else: - raise newException(EOS, "unknown h_addrtype") + raise newException(OSError, "unknown h_addrtype") result.addrList = cstringArrayToSeq(s.h_addr_list) result.length = int(s.h_length) -proc getHostByName*(name: string): Thostent {.tags: [FReadIO].} = +proc getHostByName*(name: string): Hostent {.tags: [ReadIOEffect].} = ## This function will lookup the IP address of a hostname. when useWinVersion: var s = winlean.gethostbyname(name) else: var s = posix.gethostbyname(name) - if s == nil: osError(osLastError()) + if s == nil: raiseOSError(osLastError()) result.name = $s.h_name result.aliases = cstringArrayToSeq(s.h_aliases) - when useWinVersion: - result.addrtype = TDomain(s.h_addrtype) + when useWinVersion: + result.addrtype = Domain(s.h_addrtype) else: if s.h_addrtype == posix.AF_INET: result.addrtype = AF_INET elif s.h_addrtype == posix.AF_INET6: result.addrtype = AF_INET6 else: - raise newException(EOS, "unknown h_addrtype") + raise newException(OSError, "unknown h_addrtype") result.addrList = cstringArrayToSeq(s.h_addr_list) result.length = int(s.h_length) -proc getSockName*(socket: TSocketHandle): TPort = +proc getSockName*(socket: SocketHandle): Port = ## returns the socket's associated port number. - var name: Tsockaddr_in + var name: Sockaddr_in when useWinVersion: name.sin_family = int16(ord(AF_INET)) else: name.sin_family = posix.AF_INET #name.sin_port = htons(cint16(port)) #name.sin_addr.s_addr = htonl(INADDR_ANY) - var namelen = sizeof(name).TSocklen - if getsockname(socket, cast[ptr TSockAddr](addr(name)), + var namelen = sizeof(name).SockLen + if getsockname(socket, cast[ptr SockAddr](addr(name)), addr(namelen)) == -1'i32: - osError(osLastError()) - result = TPort(rawsockets.ntohs(name.sin_port)) + raiseOSError(osLastError()) + result = Port(rawsockets.ntohs(name.sin_port)) -proc getSockOptInt*(socket: TSocketHandle, level, optname: int): int {. - tags: [FReadIO].} = +proc getSockOptInt*(socket: SocketHandle, level, optname: int): int {. + tags: [ReadIOEffect].} = ## getsockopt for integer options. var res: cint - var size = sizeof(res).TSocklen + var size = sizeof(res).SockLen if getsockopt(socket, cint(level), cint(optname), addr(res), addr(size)) < 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) result = int(res) -proc setSockOptInt*(socket: TSocketHandle, level, optname, optval: int) {. - tags: [FWriteIO].} = +proc setSockOptInt*(socket: SocketHandle, level, optname, optval: int) {. + tags: [WriteIOEffect].} = ## setsockopt for integer options. var value = cint(optval) if setsockopt(socket, cint(level), cint(optname), addr(value), - sizeof(value).TSocklen) < 0'i32: - osError(osLastError()) + sizeof(value).SockLen) < 0'i32: + raiseOSError(osLastError()) -proc setBlocking*(s: TSocketHandle, blocking: bool) = +proc setBlocking*(s: SocketHandle, blocking: bool) = ## Sets blocking mode on socket. ## ## Raises EOS on error. when useWinVersion: var mode = clong(ord(not blocking)) # 1 for non-blocking, 0 for blocking if ioctlsocket(s, FIONBIO, addr(mode)) == -1: - osError(osLastError()) + raiseOSError(osLastError()) else: # BSD sockets var x: int = fcntl(s, F_GETFL, 0) if x == -1: - osError(osLastError()) + raiseOSError(osLastError()) else: var mode = if blocking: x and not O_NONBLOCK else: x or O_NONBLOCK if fcntl(s, F_SETFL, mode) == -1: - osError(osLastError()) + raiseOSError(osLastError()) -proc timeValFromMilliseconds(timeout = 500): Ttimeval = +proc timeValFromMilliseconds(timeout = 500): Timeval = if timeout != -1: var seconds = timeout div 1000 result.tv_sec = seconds.int32 result.tv_usec = ((timeout - seconds * 1000) * 1000).int32 -proc createFdSet(fd: var TFdSet, s: seq[TSocketHandle], m: var int) = +proc createFdSet(fd: var TFdSet, s: seq[SocketHandle], m: var int) = FD_ZERO(fd) for i in items(s): m = max(m, int(i)) FD_SET(i, fd) -proc pruneSocketSet(s: var seq[TSocketHandle], fd: var TFdSet) = +proc pruneSocketSet(s: var seq[SocketHandle], fd: var TFdSet) = var i = 0 var L = s.len while i < L: @@ -375,7 +385,7 @@ proc pruneSocketSet(s: var seq[TSocketHandle], fd: var TFdSet) = inc(i) setLen(s, L) -proc select*(readfds: var seq[TSocketHandle], timeout = 500): int = +proc select*(readfds: var seq[SocketHandle], timeout = 500): int = ## Traditional select function. This function will return the number of ## sockets that are ready to be read from, written to, or which have errors. ## If there are none; 0 is returned. @@ -383,7 +393,7 @@ proc select*(readfds: var seq[TSocketHandle], timeout = 500): int = ## ## A socket is removed from the specific ``seq`` when it has data waiting to ## be read/written to or has errors (``exceptfds``). - var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) + var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) var rd: TFdSet var m = 0 @@ -396,8 +406,8 @@ proc select*(readfds: var seq[TSocketHandle], timeout = 500): int = pruneSocketSet(readfds, (rd)) -proc selectWrite*(writefds: var seq[TSocketHandle], - timeout = 500): int {.tags: [FReadIO].} = +proc selectWrite*(writefds: var seq[SocketHandle], + timeout = 500): int {.tags: [ReadIOEffect].} = ## When a socket in ``writefds`` is ready to be written to then a non-zero ## value will be returned specifying the count of the sockets which can be ## written to. The sockets which can be written to will also be removed @@ -405,7 +415,7 @@ proc selectWrite*(writefds: var seq[TSocketHandle], ## ## ``timeout`` is specified in miliseconds and ``-1`` can be specified for ## an unlimited time. - var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) + var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) var wr: TFdSet var m = 0 @@ -419,5 +429,5 @@ proc selectWrite*(writefds: var seq[TSocketHandle], pruneSocketSet(writefds, (wr)) when defined(Windows): - var wsa: TWSADATA - if WSAStartup(0x0101'i16, addr wsa) != 0: osError(osLastError()) + var wsa: WSAData + if wsaStartup(0x0101'i16, addr wsa) != 0: raiseOSError(osLastError()) diff --git a/lib/pure/redis.nim b/lib/pure/redis.nim index 959f5c6ef..52d81b3a4 100644 --- a/lib/pure/redis.nim +++ b/lib/pure/redis.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Dominik Picheta # # See the file "copying.txt", included in this @@ -20,135 +20,139 @@ const redisNil* = "\0\0" type - PPipeline = ref object + Pipeline = ref object enabled: bool buffer: string expected: int ## number of replies expected if pipelined type - TSendMode = enum + SendMode = enum normal, pipelined, multiple type - TRedis* {.pure, final.} = object - socket: TSocket + Redis* = object + socket: Socket connected: bool - pipeline: PPipeline + pipeline: Pipeline - TRedisStatus* = string - TRedisInteger* = biggestInt - TRedisString* = string ## Bulk reply - TRedisList* = seq[TRedisString] ## Multi-bulk reply + RedisStatus* = string + RedisInteger* = BiggestInt + RedisString* = string ## Bulk reply + RedisList* = seq[RedisString] ## Multi-bulk reply - EInvalidReply* = object of ESynch ## Invalid reply from redis - ERedis* = object of ESynch ## Error in redis + ReplyError* = object of IOError ## Invalid reply from redis + RedisError* = object of IOError ## Error in redis -proc newPipeline(): PPipeline = +{.deprecated: [TSendMode: SendMode, TRedis: Redis, TRedisStatus: RedisStatus, + TRedisInteger: RedisInteger, TRedisString: RedisString, + TRedisList: RedisList, EInvalidReply: ReplyError, ERedis: RedisError].} + +proc newPipeline(): Pipeline = new(result) result.buffer = "" result.enabled = false result.expected = 0 -proc open*(host = "localhost", port = 6379.TPort): TRedis = +proc open*(host = "localhost", port = 6379.Port): Redis = ## Opens a connection to the redis server. result.socket = socket(buffered = false) - if result.socket == InvalidSocket: - OSError(OSLastError()) + if result.socket == invalidSocket: + raiseOSError(osLastError()) result.socket.connect(host, port) result.pipeline = newPipeline() proc raiseInvalidReply(expected, got: char) = - raise newException(EInvalidReply, + raise newException(ReplyError, "Expected '$1' at the beginning of a status reply got '$2'" % [$expected, $got]) -proc raiseNoOK(status: string, pipelineEnabled:bool) = +proc raiseNoOK(status: string, pipelineEnabled: bool) = if pipelineEnabled and not (status == "QUEUED" or status == "PIPELINED"): - raise newException(EInvalidReply, "Expected \"QUEUED\" or \"PIPELINED\" got \"$1\"" % status) + raise newException(ReplyError, "Expected \"QUEUED\" or \"PIPELINED\" got \"$1\"" % status) elif not pipelineEnabled and status != "OK": - raise newException(EInvalidReply, "Expected \"OK\" got \"$1\"" % status) + raise newException(ReplyError, "Expected \"OK\" got \"$1\"" % status) -template readSocket(r: TRedis, dummyVal:expr): stmt = - var line {.inject.} :TaintedString = "" +template readSocket(r: Redis, dummyVal:expr): stmt = + var line {.inject.}: TaintedString = "" if r.pipeline.enabled: return dummyVal else: readLine(r.socket, line) -proc parseStatus(r: TRedis, line: string = ""): TRedisStatus = +proc parseStatus(r: Redis, line: string = ""): RedisStatus = if r.pipeline.enabled: return "PIPELINED" if line == "": - raise newException(ERedis, "Server closed connection prematurely") + raise newException(RedisError, "Server closed connection prematurely") if line[0] == '-': - raise newException(ERedis, strip(line)) + raise newException(RedisError, strip(line)) if line[0] != '+': raiseInvalidReply('+', line[0]) return line.substr(1) # Strip '+' -proc readStatus(r:TRedis): TRedisStatus = +proc readStatus(r:Redis): RedisStatus = r.readSocket("PIPELINED") return r.parseStatus(line) -proc parseInteger(r: TRedis, line: string = ""): TRedisInteger = +proc parseInteger(r: Redis, line: string = ""): RedisInteger = if r.pipeline.enabled: return -1 #if line == "+QUEUED": # inside of multi # return -1 if line == "": - raise newException(ERedis, "Server closed connection prematurely") + raise newException(RedisError, "Server closed connection prematurely") if line[0] == '-': - raise newException(ERedis, strip(line)) + raise newException(RedisError, strip(line)) if line[0] != ':': raiseInvalidReply(':', line[0]) # Strip ':' if parseBiggestInt(line, result, 1) == 0: - raise newException(EInvalidReply, "Unable to parse integer.") + raise newException(ReplyError, "Unable to parse integer.") -proc readInteger(r: TRedis): TRedisInteger = +proc readInteger(r: Redis): RedisInteger = r.readSocket(-1) return r.parseInteger(line) -proc recv(sock: TSocket, size: int): TaintedString = +proc recv(sock: Socket, size: int): TaintedString = result = newString(size).TaintedString if sock.recv(cstring(result), size) != size: - raise newException(EInvalidReply, "recv failed") + raise newException(ReplyError, "recv failed") -proc parseSingleString(r: TRedis, line:string, allowMBNil = False): TRedisString = +proc parseSingleString(r: Redis, line:string, allowMBNil = false): RedisString = if r.pipeline.enabled: return "" # Error. if line[0] == '-': - raise newException(ERedis, strip(line)) + raise newException(RedisError, strip(line)) # Some commands return a /bulk/ value or a /multi-bulk/ nil. Odd. if allowMBNil: if line == "*-1": - return RedisNil + return redisNil if line[0] != '$': raiseInvalidReply('$', line[0]) var numBytes = parseInt(line.substr(1)) if numBytes == -1: - return RedisNil + return redisNil var s = r.socket.recv(numBytes+2) result = strip(s.string) -proc readSingleString(r: TRedis): TRedisString = +proc readSingleString(r: Redis): RedisString = r.readSocket("") return r.parseSingleString(line) -proc readNext(r: TRedis): TRedisList +proc readNext(r: Redis): RedisList -proc parseArrayLines(r: TRedis, countLine:string): TRedisList = +proc parseArrayLines(r: Redis, countLine:string): RedisList = if countLine.string[0] != '*': raiseInvalidReply('*', countLine.string[0]) @@ -162,24 +166,24 @@ proc parseArrayLines(r: TRedis, countLine:string): TRedisList = for item in parsed: result.add(item) -proc readArrayLines(r: TRedis): TRedisList = +proc readArrayLines(r: Redis): RedisList = r.readSocket(nil) return r.parseArrayLines(line) -proc parseBulkString(r: TRedis, allowMBNil = False, line:string = ""): TRedisString = +proc parseBulkString(r: Redis, allowMBNil = false, line:string = ""): RedisString = if r.pipeline.enabled: return "" return r.parseSingleString(line, allowMBNil) -proc readBulkString(r: TRedis, allowMBNil = false): TRedisString = +proc readBulkString(r: Redis, allowMBNil = false): RedisString = r.readSocket("") return r.parseBulkString(allowMBNil, line) -proc readArray(r: TRedis): TRedisList = +proc readArray(r: Redis): RedisList = r.readSocket(@[]) return r.parseArrayLines(line) -proc readNext(r: TRedis): TRedisList = +proc readNext(r: Redis): RedisList = r.readSocket(@[]) var res = case line[0] @@ -188,12 +192,12 @@ proc readNext(r: TRedis): TRedisList = of '$': @[r.parseBulkString(true,line)] of '*': r.parseArrayLines(line) else: - raise newException(EInvalidReply, "readNext failed on line: " & line) + raise newException(ReplyError, "readNext failed on line: " & line) nil r.pipeline.expected -= 1 return res -proc flushPipeline*(r: TRedis, wasMulti = false): TRedisList = +proc flushPipeline*(r: Redis, wasMulti = false): RedisList = ## Send buffered commands, clear buffer, return results if r.pipeline.buffer.len > 0: r.socket.send(r.pipeline.buffer) @@ -212,7 +216,7 @@ proc flushPipeline*(r: TRedis, wasMulti = false): TRedisList = r.pipeline.expected = 0 -proc startPipelining*(r: TRedis) = +proc startPipelining*(r: Redis) = ## Enable command pipelining (reduces network roundtrips). ## Note that when enabled, you must call flushPipeline to actually send commands, except ## for multi/exec() which enable and flush the pipeline automatically. @@ -221,7 +225,7 @@ proc startPipelining*(r: TRedis) = r.pipeline.expected = 0 r.pipeline.enabled = true -proc sendCommand(r: TRedis, cmd: string, args: varargs[string]) = +proc sendCommand(r: Redis, cmd: string, args: varargs[string]) = var request = "*" & $(1 + args.len()) & "\c\L" request.add("$" & $cmd.len() & "\c\L") request.add(cmd & "\c\L") @@ -235,7 +239,7 @@ proc sendCommand(r: TRedis, cmd: string, args: varargs[string]) = else: r.socket.send(request) -proc sendCommand(r: TRedis, cmd: string, arg1: string, +proc sendCommand(r: Redis, cmd: string, arg1: string, args: varargs[string]) = var request = "*" & $(2 + args.len()) & "\c\L" request.add("$" & $cmd.len() & "\c\L") @@ -254,68 +258,68 @@ proc sendCommand(r: TRedis, cmd: string, arg1: string, # Keys -proc del*(r: TRedis, keys: varargs[string]): TRedisInteger = +proc del*(r: Redis, keys: varargs[string]): RedisInteger = ## Delete a key or multiple keys r.sendCommand("DEL", keys) return r.readInteger() -proc exists*(r: TRedis, key: string): bool = +proc exists*(r: Redis, key: string): bool = ## Determine if a key exists r.sendCommand("EXISTS", key) return r.readInteger() == 1 -proc expire*(r: TRedis, key: string, seconds: int): bool = +proc expire*(r: Redis, key: string, seconds: int): bool = ## Set a key's time to live in seconds. Returns `false` if the key could ## not be found or the timeout could not be set. r.sendCommand("EXPIRE", key, $seconds) return r.readInteger() == 1 -proc expireAt*(r: TRedis, key: string, timestamp: int): bool = +proc expireAt*(r: Redis, key: string, timestamp: int): bool = ## Set the expiration for a key as a UNIX timestamp. Returns `false` ## if the key could not be found or the timeout could not be set. r.sendCommand("EXPIREAT", key, $timestamp) return r.readInteger() == 1 -proc keys*(r: TRedis, pattern: string): TRedisList = +proc keys*(r: Redis, pattern: string): RedisList = ## Find all keys matching the given pattern r.sendCommand("KEYS", pattern) return r.readArray() -proc move*(r: TRedis, key: string, db: int): bool = +proc move*(r: Redis, key: string, db: int): bool = ## Move a key to another database. Returns `true` on a successful move. r.sendCommand("MOVE", key, $db) return r.readInteger() == 1 -proc persist*(r: TRedis, key: string): bool = +proc persist*(r: Redis, key: string): bool = ## Remove the expiration from a key. ## Returns `true` when the timeout was removed. r.sendCommand("PERSIST", key) return r.readInteger() == 1 -proc randomKey*(r: TRedis): TRedisString = +proc randomKey*(r: Redis): RedisString = ## Return a random key from the keyspace r.sendCommand("RANDOMKEY") return r.readBulkString() -proc rename*(r: TRedis, key, newkey: string): TRedisStatus = +proc rename*(r: Redis, key, newkey: string): RedisStatus = ## Rename a key. ## ## **WARNING:** Overwrites `newkey` if it exists! r.sendCommand("RENAME", key, newkey) raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc renameNX*(r: TRedis, key, newkey: string): bool = +proc renameNX*(r: Redis, key, newkey: string): bool = ## Same as ``rename`` but doesn't continue if `newkey` exists. ## Returns `true` if key was renamed. r.sendCommand("RENAMENX", key, newkey) return r.readInteger() == 1 -proc ttl*(r: TRedis, key: string): TRedisInteger = +proc ttl*(r: Redis, key: string): RedisInteger = ## Get the time to live for a key r.sendCommand("TTL", key) return r.readInteger() -proc keyType*(r: TRedis, key: string): TRedisStatus = +proc keyType*(r: Redis, key: string): RedisStatus = ## Determine the type stored at key r.sendCommand("TYPE", key) return r.readStatus() @@ -323,131 +327,131 @@ proc keyType*(r: TRedis, key: string): TRedisStatus = # Strings -proc append*(r: TRedis, key, value: string): TRedisInteger = +proc append*(r: Redis, key, value: string): RedisInteger = ## Append a value to a key r.sendCommand("APPEND", key, value) return r.readInteger() -proc decr*(r: TRedis, key: string): TRedisInteger = +proc decr*(r: Redis, key: string): RedisInteger = ## Decrement the integer value of a key by one r.sendCommand("DECR", key) return r.readInteger() -proc decrBy*(r: TRedis, key: string, decrement: int): TRedisInteger = +proc decrBy*(r: Redis, key: string, decrement: int): RedisInteger = ## Decrement the integer value of a key by the given number r.sendCommand("DECRBY", key, $decrement) return r.readInteger() -proc get*(r: TRedis, key: string): TRedisString = +proc get*(r: Redis, key: string): RedisString = ## Get the value of a key. Returns `redisNil` when `key` doesn't exist. r.sendCommand("GET", key) return r.readBulkString() -proc getBit*(r: TRedis, key: string, offset: int): TRedisInteger = +proc getBit*(r: Redis, key: string, offset: int): RedisInteger = ## Returns the bit value at offset in the string value stored at key r.sendCommand("GETBIT", key, $offset) return r.readInteger() -proc getRange*(r: TRedis, key: string, start, stop: int): TRedisString = +proc getRange*(r: Redis, key: string, start, stop: int): RedisString = ## Get a substring of the string stored at a key r.sendCommand("GETRANGE", key, $start, $stop) return r.readBulkString() -proc getSet*(r: TRedis, key: string, value: string): TRedisString = +proc getSet*(r: Redis, key: string, value: string): RedisString = ## Set the string value of a key and return its old value. Returns `redisNil` ## when key doesn't exist. r.sendCommand("GETSET", key, value) return r.readBulkString() -proc incr*(r: TRedis, key: string): TRedisInteger = +proc incr*(r: Redis, key: string): RedisInteger = ## Increment the integer value of a key by one. r.sendCommand("INCR", key) return r.readInteger() -proc incrBy*(r: TRedis, key: string, increment: int): TRedisInteger = +proc incrBy*(r: Redis, key: string, increment: int): RedisInteger = ## Increment the integer value of a key by the given number r.sendCommand("INCRBY", key, $increment) return r.readInteger() -proc setk*(r: TRedis, key, value: string) = +proc setk*(r: Redis, key, value: string) = ## Set the string value of a key. ## ## NOTE: This function had to be renamed due to a clash with the `set` type. r.sendCommand("SET", key, value) raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc setNX*(r: TRedis, key, value: string): bool = +proc setNX*(r: Redis, key, value: string): bool = ## Set the value of a key, only if the key does not exist. Returns `true` ## if the key was set. r.sendCommand("SETNX", key, value) return r.readInteger() == 1 -proc setBit*(r: TRedis, key: string, offset: int, - value: string): TRedisInteger = +proc setBit*(r: Redis, key: string, offset: int, + value: string): RedisInteger = ## Sets or clears the bit at offset in the string value stored at key r.sendCommand("SETBIT", key, $offset, value) return r.readInteger() -proc setEx*(r: TRedis, key: string, seconds: int, value: string): TRedisStatus = +proc setEx*(r: Redis, key: string, seconds: int, value: string): RedisStatus = ## Set the value and expiration of a key r.sendCommand("SETEX", key, $seconds, value) raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc setRange*(r: TRedis, key: string, offset: int, - value: string): TRedisInteger = +proc setRange*(r: Redis, key: string, offset: int, + value: string): RedisInteger = ## Overwrite part of a string at key starting at the specified offset r.sendCommand("SETRANGE", key, $offset, value) return r.readInteger() -proc strlen*(r: TRedis, key: string): TRedisInteger = +proc strlen*(r: Redis, key: string): RedisInteger = ## Get the length of the value stored in a key. Returns 0 when key doesn't ## exist. r.sendCommand("STRLEN", key) return r.readInteger() # Hashes -proc hDel*(r: TRedis, key, field: string): bool = +proc hDel*(r: Redis, key, field: string): bool = ## Delete a hash field at `key`. Returns `true` if the field was removed. r.sendCommand("HDEL", key, field) return r.readInteger() == 1 -proc hExists*(r: TRedis, key, field: string): bool = +proc hExists*(r: Redis, key, field: string): bool = ## Determine if a hash field exists. r.sendCommand("HEXISTS", key, field) return r.readInteger() == 1 -proc hGet*(r: TRedis, key, field: string): TRedisString = +proc hGet*(r: Redis, key, field: string): RedisString = ## Get the value of a hash field r.sendCommand("HGET", key, field) return r.readBulkString() -proc hGetAll*(r: TRedis, key: string): TRedisList = +proc hGetAll*(r: Redis, key: string): RedisList = ## Get all the fields and values in a hash r.sendCommand("HGETALL", key) return r.readArray() -proc hIncrBy*(r: TRedis, key, field: string, incr: int): TRedisInteger = +proc hIncrBy*(r: Redis, key, field: string, incr: int): RedisInteger = ## Increment the integer value of a hash field by the given number r.sendCommand("HINCRBY", key, field, $incr) return r.readInteger() -proc hKeys*(r: TRedis, key: string): TRedisList = +proc hKeys*(r: Redis, key: string): RedisList = ## Get all the fields in a hash r.sendCommand("HKEYS", key) return r.readArray() -proc hLen*(r: TRedis, key: string): TRedisInteger = +proc hLen*(r: Redis, key: string): RedisInteger = ## Get the number of fields in a hash r.sendCommand("HLEN", key) return r.readInteger() -proc hMGet*(r: TRedis, key: string, fields: varargs[string]): TRedisList = +proc hMGet*(r: Redis, key: string, fields: varargs[string]): RedisList = ## Get the values of all the given hash fields r.sendCommand("HMGET", key, fields) return r.readArray() -proc hMSet*(r: TRedis, key: string, - fieldValues: openarray[tuple[field, value: string]]) = +proc hMSet*(r: Redis, key: string, + fieldValues: openArray[tuple[field, value: string]]) = ## Set multiple hash fields to multiple values var args = @[key] for field, value in items(fieldValues): @@ -456,24 +460,24 @@ proc hMSet*(r: TRedis, key: string, r.sendCommand("HMSET", args) raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc hSet*(r: TRedis, key, field, value: string): TRedisInteger = +proc hSet*(r: Redis, key, field, value: string): RedisInteger = ## Set the string value of a hash field r.sendCommand("HSET", key, field, value) return r.readInteger() -proc hSetNX*(r: TRedis, key, field, value: string): TRedisInteger = +proc hSetNX*(r: Redis, key, field, value: string): RedisInteger = ## Set the value of a hash field, only if the field does **not** exist r.sendCommand("HSETNX", key, field, value) return r.readInteger() -proc hVals*(r: TRedis, key: string): TRedisList = +proc hVals*(r: Redis, key: string): RedisList = ## Get all the values in a hash r.sendCommand("HVALS", key) return r.readArray() # Lists -proc bLPop*(r: TRedis, keys: varargs[string], timeout: int): TRedisList = +proc bLPop*(r: Redis, keys: varargs[string], timeout: int): RedisList = ## Remove and get the *first* element in a list, or block until ## one is available var args: seq[string] = @[] @@ -482,7 +486,7 @@ proc bLPop*(r: TRedis, keys: varargs[string], timeout: int): TRedisList = r.sendCommand("BLPOP", args) return r.readArray() -proc bRPop*(r: TRedis, keys: varargs[string], timeout: int): TRedisList = +proc bRPop*(r: Redis, keys: varargs[string], timeout: int): RedisList = ## Remove and get the *last* element in a list, or block until one ## is available. var args: seq[string] = @[] @@ -491,8 +495,8 @@ proc bRPop*(r: TRedis, keys: varargs[string], timeout: int): TRedisList = r.sendCommand("BRPOP", args) return r.readArray() -proc bRPopLPush*(r: TRedis, source, destination: string, - timeout: int): TRedisString = +proc bRPopLPush*(r: Redis, source, destination: string, + timeout: int): RedisString = ## Pop a value from a list, push it to another list and return it; or ## block until one is available. ## @@ -500,32 +504,32 @@ proc bRPopLPush*(r: TRedis, source, destination: string, r.sendCommand("BRPOPLPUSH", source, destination, $timeout) return r.readBulkString(true) # Multi-Bulk nil allowed. -proc lIndex*(r: TRedis, key: string, index: int): TRedisString = +proc lIndex*(r: Redis, key: string, index: int): RedisString = ## Get an element from a list by its index r.sendCommand("LINDEX", key, $index) return r.readBulkString() -proc lInsert*(r: TRedis, key: string, before: bool, pivot, value: string): - TRedisInteger = +proc lInsert*(r: Redis, key: string, before: bool, pivot, value: string): + RedisInteger = ## Insert an element before or after another element in a list var pos = if before: "BEFORE" else: "AFTER" r.sendCommand("LINSERT", key, pos, pivot, value) return r.readInteger() -proc lLen*(r: TRedis, key: string): TRedisInteger = +proc lLen*(r: Redis, key: string): RedisInteger = ## Get the length of a list r.sendCommand("LLEN", key) return r.readInteger() -proc lPop*(r: TRedis, key: string): TRedisString = +proc lPop*(r: Redis, key: string): RedisString = ## Remove and get the first element in a list r.sendCommand("LPOP", key) return r.readBulkString() -proc lPush*(r: TRedis, key, value: string, create: bool = True): TRedisInteger = +proc lPush*(r: Redis, key, value: string, create: bool = true): RedisInteger = ## Prepend a value to a list. Returns the length of the list after the push. ## The ``create`` param specifies whether a list should be created if it - ## doesn't exist at ``key``. More specifically if ``create`` is True, `LPUSH` + ## doesn't exist at ``key``. More specifically if ``create`` is true, `LPUSH` ## will be used, otherwise `LPUSHX`. if create: r.sendCommand("LPUSH", key, value) @@ -533,42 +537,42 @@ proc lPush*(r: TRedis, key, value: string, create: bool = True): TRedisInteger = r.sendCommand("LPUSHX", key, value) return r.readInteger() -proc lRange*(r: TRedis, key: string, start, stop: int): TRedisList = +proc lRange*(r: Redis, key: string, start, stop: int): RedisList = ## Get a range of elements from a list. Returns `nil` when `key` ## doesn't exist. r.sendCommand("LRANGE", key, $start, $stop) return r.readArray() -proc lRem*(r: TRedis, key: string, value: string, count: int = 0): TRedisInteger = +proc lRem*(r: Redis, key: string, value: string, count: int = 0): RedisInteger = ## Remove elements from a list. Returns the number of elements that have been ## removed. r.sendCommand("LREM", key, $count, value) return r.readInteger() -proc lSet*(r: TRedis, key: string, index: int, value: string) = +proc lSet*(r: Redis, key: string, index: int, value: string) = ## Set the value of an element in a list by its index r.sendCommand("LSET", key, $index, value) raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc lTrim*(r: TRedis, key: string, start, stop: int) = +proc lTrim*(r: Redis, key: string, start, stop: int) = ## Trim a list to the specified range r.sendCommand("LTRIM", key, $start, $stop) raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc rPop*(r: TRedis, key: string): TRedisString = +proc rPop*(r: Redis, key: string): RedisString = ## Remove and get the last element in a list r.sendCommand("RPOP", key) return r.readBulkString() -proc rPopLPush*(r: TRedis, source, destination: string): TRedisString = +proc rPopLPush*(r: Redis, source, destination: string): RedisString = ## Remove the last element in a list, append it to another list and return it r.sendCommand("RPOPLPUSH", source, destination) return r.readBulkString() -proc rPush*(r: TRedis, key, value: string, create: bool = True): TRedisInteger = +proc rPush*(r: Redis, key, value: string, create: bool = true): RedisInteger = ## Append a value to a list. Returns the length of the list after the push. ## The ``create`` param specifies whether a list should be created if it - ## doesn't exist at ``key``. More specifically if ``create`` is True, `RPUSH` + ## doesn't exist at ``key``. More specifically if ``create`` is true, `RPUSH` ## will be used, otherwise `RPUSHX`. if create: r.sendCommand("RPUSH", key, value) @@ -578,106 +582,106 @@ proc rPush*(r: TRedis, key, value: string, create: bool = True): TRedisInteger = # Sets -proc sadd*(r: TRedis, key: string, member: string): TRedisInteger = +proc sadd*(r: Redis, key: string, member: string): RedisInteger = ## Add a member to a set r.sendCommand("SADD", key, member) return r.readInteger() -proc scard*(r: TRedis, key: string): TRedisInteger = +proc scard*(r: Redis, key: string): RedisInteger = ## Get the number of members in a set r.sendCommand("SCARD", key) return r.readInteger() -proc sdiff*(r: TRedis, keys: varargs[string]): TRedisList = +proc sdiff*(r: Redis, keys: varargs[string]): RedisList = ## Subtract multiple sets r.sendCommand("SDIFF", keys) return r.readArray() -proc sdiffstore*(r: TRedis, destination: string, - keys: varargs[string]): TRedisInteger = +proc sdiffstore*(r: Redis, destination: string, + keys: varargs[string]): RedisInteger = ## Subtract multiple sets and store the resulting set in a key r.sendCommand("SDIFFSTORE", destination, keys) return r.readInteger() -proc sinter*(r: TRedis, keys: varargs[string]): TRedisList = +proc sinter*(r: Redis, keys: varargs[string]): RedisList = ## Intersect multiple sets r.sendCommand("SINTER", keys) return r.readArray() -proc sinterstore*(r: TRedis, destination: string, - keys: varargs[string]): TRedisInteger = +proc sinterstore*(r: Redis, destination: string, + keys: varargs[string]): RedisInteger = ## Intersect multiple sets and store the resulting set in a key r.sendCommand("SINTERSTORE", destination, keys) return r.readInteger() -proc sismember*(r: TRedis, key: string, member: string): TRedisInteger = +proc sismember*(r: Redis, key: string, member: string): RedisInteger = ## Determine if a given value is a member of a set r.sendCommand("SISMEMBER", key, member) return r.readInteger() -proc smembers*(r: TRedis, key: string): TRedisList = +proc smembers*(r: Redis, key: string): RedisList = ## Get all the members in a set r.sendCommand("SMEMBERS", key) return r.readArray() -proc smove*(r: TRedis, source: string, destination: string, - member: string): TRedisInteger = +proc smove*(r: Redis, source: string, destination: string, + member: string): RedisInteger = ## Move a member from one set to another r.sendCommand("SMOVE", source, destination, member) return r.readInteger() -proc spop*(r: TRedis, key: string): TRedisString = +proc spop*(r: Redis, key: string): RedisString = ## Remove and return a random member from a set r.sendCommand("SPOP", key) return r.readBulkString() -proc srandmember*(r: TRedis, key: string): TRedisString = +proc srandmember*(r: Redis, key: string): RedisString = ## Get a random member from a set r.sendCommand("SRANDMEMBER", key) return r.readBulkString() -proc srem*(r: TRedis, key: string, member: string): TRedisInteger = +proc srem*(r: Redis, key: string, member: string): RedisInteger = ## Remove a member from a set r.sendCommand("SREM", key, member) return r.readInteger() -proc sunion*(r: TRedis, keys: varargs[string]): TRedisList = +proc sunion*(r: Redis, keys: varargs[string]): RedisList = ## Add multiple sets r.sendCommand("SUNION", keys) return r.readArray() -proc sunionstore*(r: TRedis, destination: string, - key: varargs[string]): TRedisInteger = +proc sunionstore*(r: Redis, destination: string, + key: varargs[string]): RedisInteger = ## Add multiple sets and store the resulting set in a key r.sendCommand("SUNIONSTORE", destination, key) return r.readInteger() # Sorted sets -proc zadd*(r: TRedis, key: string, score: int, member: string): TRedisInteger = +proc zadd*(r: Redis, key: string, score: int, member: string): RedisInteger = ## Add a member to a sorted set, or update its score if it already exists r.sendCommand("ZADD", key, $score, member) return r.readInteger() -proc zcard*(r: TRedis, key: string): TRedisInteger = +proc zcard*(r: Redis, key: string): RedisInteger = ## Get the number of members in a sorted set r.sendCommand("ZCARD", key) return r.readInteger() -proc zcount*(r: TRedis, key: string, min: string, max: string): TRedisInteger = +proc zcount*(r: Redis, key: string, min: string, max: string): RedisInteger = ## Count the members in a sorted set with scores within the given values r.sendCommand("ZCOUNT", key, min, max) return r.readInteger() -proc zincrby*(r: TRedis, key: string, increment: string, - member: string): TRedisString = +proc zincrby*(r: Redis, key: string, increment: string, + member: string): RedisString = ## Increment the score of a member in a sorted set r.sendCommand("ZINCRBY", key, increment, member) return r.readBulkString() -proc zinterstore*(r: TRedis, destination: string, numkeys: string, - keys: openarray[string], weights: openarray[string] = [], - aggregate: string = ""): TRedisInteger = +proc zinterstore*(r: Redis, destination: string, numkeys: string, + keys: openArray[string], weights: openArray[string] = [], + aggregate: string = ""): RedisInteger = ## Intersect multiple sorted sets and store the resulting sorted set in ## a new key var args = @[destination, numkeys] @@ -694,8 +698,8 @@ proc zinterstore*(r: TRedis, destination: string, numkeys: string, return r.readInteger() -proc zrange*(r: TRedis, key: string, start: string, stop: string, - withScores: bool): TRedisList = +proc zrange*(r: Redis, key: string, start: string, stop: string, + withScores: bool): RedisList = ## Return a range of members in a sorted set, by index if not withScores: r.sendCommand("ZRANGE", key, start, stop) @@ -703,9 +707,9 @@ proc zrange*(r: TRedis, key: string, start: string, stop: string, r.sendCommand("ZRANGE", "WITHSCORES", key, start, stop) return r.readArray() -proc zrangebyscore*(r: TRedis, key: string, min: string, max: string, - withScore: bool = false, limit: bool = False, - limitOffset: int = 0, limitCount: int = 0): TRedisList = +proc zrangebyscore*(r: Redis, key: string, min: string, max: string, + withScore: bool = false, limit: bool = false, + limitOffset: int = 0, limitCount: int = 0): RedisList = ## Return a range of members in a sorted set, by score var args = @[key, min, max] @@ -718,30 +722,30 @@ proc zrangebyscore*(r: TRedis, key: string, min: string, max: string, r.sendCommand("ZRANGEBYSCORE", args) return r.readArray() -proc zrank*(r: TRedis, key: string, member: string): TRedisString = +proc zrank*(r: Redis, key: string, member: string): RedisString = ## Determine the index of a member in a sorted set r.sendCommand("ZRANK", key, member) return r.readBulkString() -proc zrem*(r: TRedis, key: string, member: string): TRedisInteger = +proc zrem*(r: Redis, key: string, member: string): RedisInteger = ## Remove a member from a sorted set r.sendCommand("ZREM", key, member) return r.readInteger() -proc zremrangebyrank*(r: TRedis, key: string, start: string, - stop: string): TRedisInteger = +proc zremrangebyrank*(r: Redis, key: string, start: string, + stop: string): RedisInteger = ## Remove all members in a sorted set within the given indexes r.sendCommand("ZREMRANGEBYRANK", key, start, stop) return r.readInteger() -proc zremrangebyscore*(r: TRedis, key: string, min: string, - max: string): TRedisInteger = +proc zremrangebyscore*(r: Redis, key: string, min: string, + max: string): RedisInteger = ## Remove all members in a sorted set within the given scores r.sendCommand("ZREMRANGEBYSCORE", key, min, max) return r.readInteger() -proc zrevrange*(r: TRedis, key: string, start: string, stop: string, - withScore: bool): TRedisList = +proc zrevrange*(r: Redis, key: string, start: string, stop: string, + withScore: bool): RedisList = ## Return a range of members in a sorted set, by index, ## with scores ordered from high to low if withScore: @@ -749,9 +753,9 @@ proc zrevrange*(r: TRedis, key: string, start: string, stop: string, else: r.sendCommand("ZREVRANGE", key, start, stop) return r.readArray() -proc zrevrangebyscore*(r: TRedis, key: string, min: string, max: string, - withScore: bool = false, limit: bool = False, - limitOffset: int = 0, limitCount: int = 0): TRedisList = +proc zrevrangebyscore*(r: Redis, key: string, min: string, max: string, + withScore: bool = false, limit: bool = false, + limitOffset: int = 0, limitCount: int = 0): RedisList = ## Return a range of members in a sorted set, by score, with ## scores ordered from high to low var args = @[key, min, max] @@ -765,20 +769,20 @@ proc zrevrangebyscore*(r: TRedis, key: string, min: string, max: string, r.sendCommand("ZREVRANGEBYSCORE", args) return r.readArray() -proc zrevrank*(r: TRedis, key: string, member: string): TRedisString = +proc zrevrank*(r: Redis, key: string, member: string): RedisString = ## Determine the index of a member in a sorted set, with ## scores ordered from high to low r.sendCommand("ZREVRANK", key, member) return r.readBulkString() -proc zscore*(r: TRedis, key: string, member: string): TRedisString = +proc zscore*(r: Redis, key: string, member: string): RedisString = ## Get the score associated with the given member in a sorted set r.sendCommand("ZSCORE", key, member) return r.readBulkString() -proc zunionstore*(r: TRedis, destination: string, numkeys: string, - keys: openarray[string], weights: openarray[string] = [], - aggregate: string = ""): TRedisInteger = +proc zunionstore*(r: Redis, destination: string, numkeys: string, + keys: openArray[string], weights: openArray[string] = [], + aggregate: string = ""): RedisInteger = ## Add multiple sorted sets and store the resulting sorted set in a new key var args = @[destination, numkeys] for i in items(keys): args.add(i) @@ -828,12 +832,12 @@ proc unsubscribe*(r: TRedis, [channel: openarray[string], : string): ???? = # Transactions -proc discardMulti*(r: TRedis) = +proc discardMulti*(r: Redis) = ## Discard all commands issued after MULTI r.sendCommand("DISCARD") raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc exec*(r: TRedis): TRedisList = +proc exec*(r: Redis): RedisList = ## Execute all commands issued after MULTI r.sendCommand("EXEC") r.pipeline.enabled = false @@ -842,106 +846,106 @@ proc exec*(r: TRedis): TRedisList = return r.flushPipeline(true) -proc multi*(r: TRedis) = +proc multi*(r: Redis) = ## Mark the start of a transaction block r.startPipelining() r.sendCommand("MULTI") raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc unwatch*(r: TRedis) = +proc unwatch*(r: Redis) = ## Forget about all watched keys r.sendCommand("UNWATCH") raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc watch*(r: TRedis, key: varargs[string]) = +proc watch*(r: Redis, key: varargs[string]) = ## Watch the given keys to determine execution of the MULTI/EXEC block r.sendCommand("WATCH", key) raiseNoOK(r.readStatus(), r.pipeline.enabled) # Connection -proc auth*(r: TRedis, password: string) = +proc auth*(r: Redis, password: string) = ## Authenticate to the server r.sendCommand("AUTH", password) raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc echoServ*(r: TRedis, message: string): TRedisString = +proc echoServ*(r: Redis, message: string): RedisString = ## Echo the given string r.sendCommand("ECHO", message) return r.readBulkString() -proc ping*(r: TRedis): TRedisStatus = +proc ping*(r: Redis): RedisStatus = ## Ping the server r.sendCommand("PING") return r.readStatus() -proc quit*(r: TRedis) = +proc quit*(r: Redis) = ## Close the connection r.sendCommand("QUIT") raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc select*(r: TRedis, index: int): TRedisStatus = +proc select*(r: Redis, index: int): RedisStatus = ## Change the selected database for the current connection r.sendCommand("SELECT", $index) return r.readStatus() # Server -proc bgrewriteaof*(r: TRedis) = +proc bgrewriteaof*(r: Redis) = ## Asynchronously rewrite the append-only file r.sendCommand("BGREWRITEAOF") raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc bgsave*(r: TRedis) = +proc bgsave*(r: Redis) = ## Asynchronously save the dataset to disk r.sendCommand("BGSAVE") raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc configGet*(r: TRedis, parameter: string): TRedisList = +proc configGet*(r: Redis, parameter: string): RedisList = ## Get the value of a configuration parameter r.sendCommand("CONFIG", "GET", parameter) return r.readArray() -proc configSet*(r: TRedis, parameter: string, value: string) = +proc configSet*(r: Redis, parameter: string, value: string) = ## Set a configuration parameter to the given value r.sendCommand("CONFIG", "SET", parameter, value) raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc configResetStat*(r: TRedis) = +proc configResetStat*(r: Redis) = ## Reset the stats returned by INFO r.sendCommand("CONFIG", "RESETSTAT") raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc dbsize*(r: TRedis): TRedisInteger = +proc dbsize*(r: Redis): RedisInteger = ## Return the number of keys in the selected database r.sendCommand("DBSIZE") return r.readInteger() -proc debugObject*(r: TRedis, key: string): TRedisStatus = +proc debugObject*(r: Redis, key: string): RedisStatus = ## Get debugging information about a key r.sendCommand("DEBUG", "OBJECT", key) return r.readStatus() -proc debugSegfault*(r: TRedis) = +proc debugSegfault*(r: Redis) = ## Make the server crash r.sendCommand("DEBUG", "SEGFAULT") -proc flushall*(r: TRedis): TRedisStatus = +proc flushall*(r: Redis): RedisStatus = ## Remove all keys from all databases r.sendCommand("FLUSHALL") raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc flushdb*(r: TRedis): TRedisStatus = +proc flushdb*(r: Redis): RedisStatus = ## Remove all keys from the current database r.sendCommand("FLUSHDB") raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc info*(r: TRedis): TRedisString = +proc info*(r: Redis): RedisString = ## Get information and statistics about the server r.sendCommand("INFO") return r.readBulkString() -proc lastsave*(r: TRedis): TRedisInteger = +proc lastsave*(r: Redis): RedisInteger = ## Get the UNIX time stamp of the last successful save to disk r.sendCommand("LASTSAVE") return r.readInteger() @@ -953,24 +957,24 @@ proc monitor*(r: TRedis) = raiseNoOK(r.readStatus(), r.pipeline.enabled) """ -proc save*(r: TRedis) = +proc save*(r: Redis) = ## Synchronously save the dataset to disk r.sendCommand("SAVE") raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc shutdown*(r: TRedis) = +proc shutdown*(r: Redis) = ## Synchronously save the dataset to disk and then shut down the server r.sendCommand("SHUTDOWN") var s = "".TaintedString r.socket.readLine(s) - if s.string.len != 0: raise newException(ERedis, s.string) + if s.string.len != 0: raise newException(RedisError, s.string) -proc slaveof*(r: TRedis, host: string, port: string) = +proc slaveof*(r: Redis, host: string, port: string) = ## Make the server a slave of another instance, or promote it as master r.sendCommand("SLAVEOF", host, port) raiseNoOK(r.readStatus(), r.pipeline.enabled) -iterator hPairs*(r: TRedis, key: string): tuple[key, value: string] = +iterator hPairs*(r: Redis, key: string): tuple[key, value: string] = ## Iterator for keys and values in a hash. var contents = r.hGetAll(key) @@ -982,7 +986,7 @@ iterator hPairs*(r: TRedis, key: string): tuple[key, value: string] = yield (k, i) k = "" -proc someTests(r: TRedis, how: TSendMode):seq[string] = +proc someTests(r: Redis, how: SendMode):seq[string] = var list:seq[string] = @[] if how == pipelined: @@ -1003,10 +1007,10 @@ proc someTests(r: TRedis, how: TSendMode):seq[string] = for r in res: list.add(r) list.add(r.get("invalid_key")) - list.add($(r.lpush("mylist","itema"))) - list.add($(r.lpush("mylist","itemb"))) - r.ltrim("mylist",0,1) - var p = r.lrange("mylist", 0, -1) + list.add($(r.lPush("mylist","itema"))) + list.add($(r.lPush("mylist","itemb"))) + r.lTrim("mylist",0,1) + var p = r.lRange("mylist", 0, -1) for i in items(p): if not isNil(i): diff --git a/lib/pure/romans.nim b/lib/pure/romans.nim index dee3226d8..79fb75526 100644 --- a/lib/pure/romans.nim +++ b/lib/pure/romans.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2011 Philippe Lhoste # # See the file "copying.txt", included in this diff --git a/lib/pure/ropes.nim b/lib/pure/ropes.nim index eb3792bce..995dff2aa 100644 --- a/lib/pure/ropes.nim +++ b/lib/pure/ropes.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this @@ -10,7 +10,7 @@ ## This module contains support for a `rope`:idx: data type. ## Ropes can represent very long strings efficiently; especially concatenation ## is done in O(1) instead of O(n). They are essentially concatenation -## trees that are only flattened when converting to a native Nimrod +## trees that are only flattened when converting to a native Nim ## string. The empty string is represented by ``nil``. Ropes are immutable and ## subtrees can be shared without copying. ## Leaves can be cached for better memory efficiency at the cost of @@ -30,13 +30,15 @@ var cacheEnabled = false type - PRope* = ref TRope ## empty rope is represented by nil - TRope {.acyclic, final, pure.} = object - left, right: PRope + Rope* = ref RopeObj ## empty rope is represented by nil + RopeObj {.acyclic.} = object + left, right: Rope length: int data: string # != nil if a leaf -proc isConc(r: PRope): bool {.inline.} = return isNil(r.data) +{.deprecated: [PRope: Rope].} + +proc isConc(r: Rope): bool {.inline.} = return isNil(r.data) # Note that the left and right pointers are not needed for leafs. # Leaves have relatively high memory overhead (~30 bytes on a 32 @@ -46,25 +48,25 @@ proc isConc(r: PRope): bool {.inline.} = return isNil(r.data) # performance. But for the caching tree we use the leaf's left and right # pointers. -proc len*(a: PRope): int {.rtl, extern: "nro$1".} = +proc len*(a: Rope): int {.rtl, extern: "nro$1".} = ## the rope's length if a == nil: result = 0 else: result = a.length -proc newRope(): PRope = new(result) -proc newRope(data: string): PRope = +proc newRope(): Rope = new(result) +proc newRope(data: string): Rope = new(result) result.length = len(data) result.data = data var - cache {.threadvar.}: PRope # the root of the cache tree - N {.threadvar.}: PRope # dummy rope needed for splay algorithm + cache {.threadvar.}: Rope # the root of the cache tree + N {.threadvar.}: Rope # dummy rope needed for splay algorithm when countCacheMisses: var misses, hits: int -proc splay(s: string, tree: PRope, cmpres: var int): PRope = +proc splay(s: string, tree: Rope, cmpres: var int): Rope = var c: int var t = tree N.left = nil @@ -102,7 +104,7 @@ proc splay(s: string, tree: PRope, cmpres: var int): PRope = t.right = N.left result = t -proc insertInCache(s: string, tree: PRope): PRope = +proc insertInCache(s: string, tree: Rope): Rope = var t = tree if t == nil: result = newRope(s) @@ -128,7 +130,7 @@ proc insertInCache(s: string, tree: PRope): PRope = result.left = t t.right = nil -proc rope*(s: string): PRope {.rtl, extern: "nro$1Str".} = +proc rope*(s: string): Rope {.rtl, extern: "nro$1Str".} = ## Converts a string to a rope. if s.len == 0: result = nil @@ -138,11 +140,11 @@ proc rope*(s: string): PRope {.rtl, extern: "nro$1Str".} = else: result = newRope(s) -proc rope*(i: BiggestInt): PRope {.rtl, extern: "nro$1BiggestInt".} = +proc rope*(i: BiggestInt): Rope {.rtl, extern: "nro$1BiggestInt".} = ## Converts an int to a rope. result = rope($i) -proc rope*(f: BiggestFloat): PRope {.rtl, extern: "nro$1BiggestFloat".} = +proc rope*(f: BiggestFloat): Rope {.rtl, extern: "nro$1BiggestFloat".} = ## Converts a float to a rope. result = rope($f) @@ -156,7 +158,7 @@ proc disableCache*() {.rtl, extern: "nro$1".} = cache = nil cacheEnabled = false -proc `&`*(a, b: PRope): PRope {.rtl, extern: "nroConcRopeRope".} = +proc `&`*(a, b: Rope): Rope {.rtl, extern: "nroConcRopeRope".} = ## the concatenation operator for ropes. if a == nil: result = b @@ -176,27 +178,27 @@ proc `&`*(a, b: PRope): PRope {.rtl, extern: "nroConcRopeRope".} = result.left = a result.right = b -proc `&`*(a: PRope, b: string): PRope {.rtl, extern: "nroConcRopeStr".} = +proc `&`*(a: Rope, b: string): Rope {.rtl, extern: "nroConcRopeStr".} = ## the concatenation operator for ropes. result = a & rope(b) -proc `&`*(a: string, b: PRope): PRope {.rtl, extern: "nroConcStrRope".} = +proc `&`*(a: string, b: Rope): Rope {.rtl, extern: "nroConcStrRope".} = ## the concatenation operator for ropes. result = rope(a) & b -proc `&`*(a: openarray[PRope]): PRope {.rtl, extern: "nroConcOpenArray".} = +proc `&`*(a: openArray[Rope]): Rope {.rtl, extern: "nroConcOpenArray".} = ## the concatenation operator for an openarray of ropes. for i in countup(0, high(a)): result = result & a[i] -proc add*(a: var PRope, b: PRope) {.rtl, extern: "nro$1Rope".} = +proc add*(a: var Rope, b: Rope) {.rtl, extern: "nro$1Rope".} = ## adds `b` to the rope `a`. a = a & b -proc add*(a: var PRope, b: string) {.rtl, extern: "nro$1Str".} = +proc add*(a: var Rope, b: string) {.rtl, extern: "nro$1Str".} = ## adds `b` to the rope `a`. a = a & b -proc `[]`*(r: PRope, i: int): char {.rtl, extern: "nroCharAt".} = +proc `[]`*(r: Rope, i: int): char {.rtl, extern: "nroCharAt".} = ## returns the character at position `i` in the rope `r`. This is quite ## expensive! Worst-case: O(n). If ``i >= r.len``, ``\0`` is returned. var x = r @@ -213,7 +215,7 @@ proc `[]`*(r: PRope, i: int): char {.rtl, extern: "nroCharAt".} = x = x.right dec(j, x.len) -iterator leaves*(r: PRope): string = +iterator leaves*(r: Rope): string = ## iterates over any leaf string in the rope `r`. if r != nil: var stack = @[r] @@ -226,16 +228,16 @@ iterator leaves*(r: PRope): string = assert(it.data != nil) yield it.data -iterator items*(r: PRope): char = +iterator items*(r: Rope): char = ## iterates over any character in the rope `r`. for s in leaves(r): for c in items(s): yield c -proc write*(f: TFile, r: PRope) {.rtl, extern: "nro$1".} = +proc write*(f: File, r: Rope) {.rtl, extern: "nro$1".} = ## writes a rope to a file. for s in leaves(r): write(f, s) -proc `$`*(r: PRope): string {.rtl, extern: "nroToString".}= +proc `$`*(r: Rope): string {.rtl, extern: "nroToString".}= ## converts a rope back to a string. result = newString(r.len) setLen(result, 0) @@ -245,11 +247,11 @@ when false: # Format string caching seems reasonable: All leaves can be shared and format # string parsing has to be done only once. A compiled format string is stored # as a rope. A negative length is used for the index into the args array. - proc compiledArg(idx: int): PRope = + proc compiledArg(idx: int): Rope = new(result) result.length = -idx - proc compileFrmt(frmt: string): PRope = + proc compileFrmt(frmt: string): Rope = var i = 0 var length = len(frmt) result = nil @@ -289,7 +291,7 @@ when false: if i - 1 >= start: add(result, substr(frmt, start, i-1)) -proc `%`*(frmt: string, args: openarray[PRope]): PRope {. +proc `%`*(frmt: string, args: openArray[Rope]): Rope {. rtl, extern: "nroFormat".} = ## `%` substitution operator for ropes. Does not support the ``$identifier`` ## nor ``${identifier}`` notations. @@ -322,9 +324,9 @@ proc `%`*(frmt: string, args: openarray[PRope]): PRope {. j = j * 10 + ord(frmt[i]) - ord('0') inc(i) if frmt[i] == '}': inc(i) - else: raise newException(EInvalidValue, "invalid format string") + else: raise newException(ValueError, "invalid format string") add(result, args[j-1]) - else: raise newException(EInvalidValue, "invalid format string") + else: raise newException(ValueError, "invalid format string") var start = i while i < length: if frmt[i] != '$': inc(i) @@ -332,15 +334,15 @@ proc `%`*(frmt: string, args: openarray[PRope]): PRope {. if i - 1 >= start: add(result, substr(frmt, start, i - 1)) -proc addf*(c: var PRope, frmt: string, args: openarray[PRope]) {. +proc addf*(c: var Rope, frmt: string, args: openArray[Rope]) {. rtl, extern: "nro$1".} = ## shortcut for ``add(c, frmt % args)``. add(c, frmt % args) -proc equalsFile*(r: PRope, f: TFile): bool {.rtl, extern: "nro$1File".} = +proc equalsFile*(r: Rope, f: File): bool {.rtl, extern: "nro$1File".} = ## returns true if the contents of the file `f` equal `r`. var bufSize = 1024 # reasonable start value - var buf = alloc(BufSize) + var buf = alloc(bufSize) for s in leaves(r): if s.len > bufSize: bufSize = max(bufSize * 2, s.len) @@ -352,10 +354,10 @@ proc equalsFile*(r: PRope, f: TFile): bool {.rtl, extern: "nro$1File".} = result = readBuffer(f, buf, 1) == 0 # really at the end of file? dealloc(buf) -proc equalsFile*(r: PRope, f: string): bool {.rtl, extern: "nro$1Str".} = +proc equalsFile*(r: Rope, f: string): bool {.rtl, extern: "nro$1Str".} = ## returns true if the contents of the file `f` equal `r`. If `f` does not ## exist, false is returned. - var bin: TFile + var bin: File result = open(bin, f) if result: result = equalsFile(r, bin) diff --git a/lib/pure/scgi.nim b/lib/pure/scgi.nim index 45f837833..58b37833a 100644 --- a/lib/pure/scgi.nim +++ b/lib/pure/scgi.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf, Dominik Picheta # # See the file "copying.txt", included in this @@ -9,13 +9,13 @@ ## This module implements helper procs for SCGI applications. Example: ## -## .. code-block:: Nimrod +## .. code-block:: Nim ## ## import strtabs, sockets, scgi ## ## var counter = 0 -## proc handleRequest(client: TSocket, input: string, -## headers: PStringTable): bool {.procvar.} = +## proc handleRequest(client: Socket, input: string, +## headers: StringTableRef): bool {.procvar.} = ## inc(counter) ## client.writeStatusOkTextContent() ## client.send("Hello for the $#th time." % $counter & "\c\L") @@ -31,11 +31,11 @@ include "system/inclrtl" import sockets, strutils, os, strtabs, asyncio type - EScgi* = object of EIO ## the exception that is raised, if a SCGI error occurs + ScgiError* = object of IOError ## the exception that is raised, if a SCGI error occurs -proc scgiError*(msg: string) {.noreturn.} = - ## raises an EScgi exception with message `msg`. - var e: ref EScgi +proc raiseScgiError*(msg: string) {.noreturn.} = + ## raises an ScgiError exception with message `msg`. + var e: ref ScgiError new(e) e.msg = msg raise e @@ -45,7 +45,7 @@ proc parseWord(inp: string, outp: var string, start: int): int = while inp[result] != '\0': inc(result) outp = substr(inp, start, result-1) -proc parseHeaders(s: string, L: int): PStringTable = +proc parseHeaders(s: string, L: int): StringTableRef = result = newStringTable() var i = 0 while i < L: @@ -54,73 +54,77 @@ proc parseHeaders(s: string, L: int): PStringTable = i = parseWord(s, val, i)+1 result[key] = val if s[i] == ',': inc(i) - else: scgiError("',' after netstring expected") + else: raiseScgiError("',' after netstring expected") -proc recvChar(s: TSocket): char = +proc recvChar(s: Socket): char = var c: char if recv(s, addr(c), sizeof(c)) == sizeof(c): result = c type - TScgiState* = object of TObject ## SCGI state object - server: TSocket + ScgiState* = object of RootObj ## SCGI state object + server: Socket bufLen: int - client*: TSocket ## the client socket to send data to - headers*: PStringTable ## the parsed headers + client*: Socket ## the client socket to send data to + headers*: StringTableRef ## the parsed headers input*: string ## the input buffer # Async - TClientMode = enum + ClientMode = enum ClientReadChar, ClientReadHeaders, ClientReadContent - PAsyncClient = ref object - c: PAsyncSocket - mode: TClientMode + AsyncClient = ref object + c: AsyncSocket + mode: ClientMode dataLen: int - headers: PStringTable ## the parsed headers + headers: StringTableRef ## the parsed headers input: string ## the input buffer - TAsyncScgiState = object - handleRequest: proc (client: PAsyncSocket, - input: string, headers: PStringTable) {.closure,gcsafe.} - asyncServer: PAsyncSocket - disp: PDispatcher - PAsyncScgiState* = ref TAsyncScgiState - -proc recvBuffer(s: var TScgiState, L: int) = + AsyncScgiStateObj = object + handleRequest: proc (client: AsyncSocket, + input: string, + headers: StringTableRef) {.closure, gcsafe.} + asyncServer: AsyncSocket + disp: Dispatcher + AsyncScgiState* = ref AsyncScgiStateObj + +{.deprecated: [EScgi: ScgiError, TScgiState: ScgiState, + PAsyncScgiState: AsyncScgiState, scgiError: raiseScgiError].} + +proc recvBuffer(s: var ScgiState, L: int) = if L > s.bufLen: s.bufLen = L s.input = newString(L) if L > 0 and recv(s.client, cstring(s.input), L) != L: - scgiError("could not read all data") + raiseScgiError("could not read all data") setLen(s.input, L) -proc open*(s: var TScgiState, port = TPort(4000), address = "127.0.0.1", - reuseAddr = False) = +proc open*(s: var ScgiState, port = Port(4000), address = "127.0.0.1", + reuseAddr = false) = ## opens a connection. s.bufLen = 4000 - s.input = newString(s.buflen) # will be reused + s.input = newString(s.bufLen) # will be reused s.server = socket() - if s.server == InvalidSocket: osError(osLastError()) + if s.server == invalidSocket: raiseOSError(osLastError()) new(s.client) # Initialise s.client for `next` - if s.server == InvalidSocket: scgiError("could not open socket") + if s.server == invalidSocket: raiseScgiError("could not open socket") #s.server.connect(connectionName, port) if reuseAddr: - s.server.setSockOpt(OptReuseAddr, True) + s.server.setSockOpt(OptReuseAddr, true) bindAddr(s.server, port, address) listen(s.server) -proc close*(s: var TScgiState) = +proc close*(s: var ScgiState) = ## closes the connection. s.server.close() -proc next*(s: var TScgistate, timeout: int = -1): bool = +proc next*(s: var ScgiState, timeout: int = -1): bool = ## proceed to the first/next request. Waits ``timeout`` miliseconds for a ## request, if ``timeout`` is `-1` then this function will never time out. - ## Returns `True` if a new request has been processed. + ## Returns `true` if a new request has been processed. var rsocks = @[s.server] if select(rsocks, timeout) == 1 and rsocks.len == 1: new(s.client) @@ -131,18 +135,18 @@ proc next*(s: var TScgistate, timeout: int = -1): bool = if d == '\0': s.client.close() return false - if d notin strutils.digits: - if d != ':': scgiError("':' after length expected") + if d notin strutils.Digits: + if d != ':': raiseScgiError("':' after length expected") break L = L * 10 + ord(d) - ord('0') recvBuffer(s, L+1) s.headers = parseHeaders(s.input, L) - if s.headers["SCGI"] != "1": scgiError("SCGI Version 1 expected") + if s.headers["SCGI"] != "1": raiseScgiError("SCGI Version 1 expected") L = parseInt(s.headers["CONTENT_LENGTH"]) recvBuffer(s, L) - return True + return true -proc writeStatusOkTextContent*(c: TSocket, contentType = "text/html") = +proc writeStatusOkTextContent*(c: Socket, contentType = "text/html") = ## sends the following string to the socket `c`:: ## ## Status: 200 OK\r\LContent-Type: text/html\r\L\r\L @@ -151,11 +155,11 @@ proc writeStatusOkTextContent*(c: TSocket, contentType = "text/html") = c.send("Status: 200 OK\r\L" & "Content-Type: $1\r\L\r\L" % contentType) -proc run*(handleRequest: proc (client: TSocket, input: string, - headers: PStringTable): bool {.nimcall,gcsafe.}, - port = TPort(4000)) = +proc run*(handleRequest: proc (client: Socket, input: string, + headers: StringTableRef): bool {.nimcall,gcsafe.}, + port = Port(4000)) = ## encapsulates the SCGI object and main loop. - var s: TScgiState + var s: ScgiState s.open(port) var stop = false while not stop: @@ -166,11 +170,11 @@ proc run*(handleRequest: proc (client: TSocket, input: string, # -- AsyncIO start -proc recvBufferAsync(client: PAsyncClient, L: int): TReadLineResult = +proc recvBufferAsync(client: AsyncClient, L: int): ReadLineResult = result = ReadPartialLine var data = "" if L < 1: - scgiError("Cannot read negative or zero length: " & $L) + raiseScgiError("Cannot read negative or zero length: " & $L) let ret = recvAsync(client.c, data, L) if ret == 0 and data == "": client.c.close() @@ -181,16 +185,16 @@ proc recvBufferAsync(client: PAsyncClient, L: int): TReadLineResult = if ret == L: return ReadFullLine -proc checkCloseSocket(client: PAsyncClient) = +proc checkCloseSocket(client: AsyncClient) = if not client.c.isClosed: if client.c.isSendDataBuffered: - client.c.setHandleWrite do (s: PAsyncSocket): + client.c.setHandleWrite do (s: AsyncSocket): if not s.isClosed and not s.isSendDataBuffered: s.close() s.delHandleWrite() else: client.c.close() -proc handleClientRead(client: PAsyncClient, s: PAsyncScgiState) = +proc handleClientRead(client: AsyncClient, s: AsyncScgiState) = case client.mode of ClientReadChar: while true: @@ -202,8 +206,8 @@ proc handleClientRead(client: PAsyncClient, s: PAsyncScgiState) = return if ret == -1: return # No more data available - if d[0] notin strutils.digits: - if d[0] != ':': scgiError("':' after length expected") + if d[0] notin strutils.Digits: + if d[0] != ':': raiseScgiError("':' after length expected") break client.dataLen = client.dataLen * 10 + ord(d[0]) - ord('0') client.mode = ClientReadHeaders @@ -213,7 +217,7 @@ proc handleClientRead(client: PAsyncClient, s: PAsyncScgiState) = case ret of ReadFullLine: client.headers = parseHeaders(client.input, client.input.len-1) - if client.headers["SCGI"] != "1": scgiError("SCGI Version 1 expected") + if client.headers["SCGI"] != "1": raiseScgiError("SCGI Version 1 expected") client.input = "" # For next part let contentLen = parseInt(client.headers["CONTENT_LENGTH"]) @@ -236,50 +240,50 @@ proc handleClientRead(client: PAsyncClient, s: PAsyncScgiState) = s.handleRequest(client.c, client.input, client.headers) checkCloseSocket(client) -proc handleAccept(sock: PAsyncSocket, s: PAsyncScgiState) = - var client: PAsyncSocket +proc handleAccept(sock: AsyncSocket, s: AsyncScgiState) = + var client: AsyncSocket new(client) accept(s.asyncServer, client) - var asyncClient = PAsyncClient(c: client, mode: ClientReadChar, dataLen: 0, + var asyncClient = AsyncClient(c: client, mode: ClientReadChar, dataLen: 0, headers: newStringTable(), input: "") client.handleRead = - proc (sock: PAsyncSocket) = + proc (sock: AsyncSocket) = handleClientRead(asyncClient, s) s.disp.register(client) -proc open*(handleRequest: proc (client: PAsyncSocket, - input: string, headers: PStringTable) {. +proc open*(handleRequest: proc (client: AsyncSocket, + input: string, headers: StringTableRef) {. closure, gcsafe.}, - port = TPort(4000), address = "127.0.0.1", - reuseAddr = false): PAsyncScgiState = - ## Creates an ``PAsyncScgiState`` object which serves as a SCGI server. + port = Port(4000), address = "127.0.0.1", + reuseAddr = false): AsyncScgiState = + ## Creates an ``AsyncScgiState`` object which serves as a SCGI server. ## ## After the execution of ``handleRequest`` the client socket will be closed ## automatically unless it has already been closed. - var cres: PAsyncScgiState + var cres: AsyncScgiState new(cres) - cres.asyncServer = AsyncSocket() - cres.asyncServer.handleAccept = proc (s: PAsyncSocket) = handleAccept(s, cres) + cres.asyncServer = asyncSocket() + cres.asyncServer.handleAccept = proc (s: AsyncSocket) = handleAccept(s, cres) if reuseAddr: - cres.asyncServer.setSockOpt(OptReuseAddr, True) + cres.asyncServer.setSockOpt(OptReuseAddr, true) bindAddr(cres.asyncServer, port, address) listen(cres.asyncServer) cres.handleRequest = handleRequest result = cres -proc register*(d: PDispatcher, s: PAsyncScgiState): PDelegate {.discardable.} = +proc register*(d: Dispatcher, s: AsyncScgiState): Delegate {.discardable.} = ## Registers ``s`` with dispatcher ``d``. result = d.register(s.asyncServer) s.disp = d -proc close*(s: PAsyncScgiState) = - ## Closes the ``PAsyncScgiState``. +proc close*(s: AsyncScgiState) = + ## Closes the ``AsyncScgiState``. s.asyncServer.close() when false: var counter = 0 - proc handleRequest(client: TSocket, input: string, - headers: PStringTable): bool {.procvar.} = + proc handleRequest(client: Socket, input: string, + headers: StringTableRef): bool {.procvar.} = inc(counter) client.writeStatusOkTextContent() client.send("Hello for the $#th time." % $counter & "\c\L") diff --git a/lib/pure/selectors.nim b/lib/pure/selectors.nim index bd53c2dbf..1c988c609 100644 --- a/lib/pure/selectors.nim +++ b/lib/pure/selectors.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Dominik Picheta # # See the file "copying.txt", included in this @@ -18,57 +18,57 @@ elif defined(windows): else: import posix -proc hash*(x: TSocketHandle): THash {.borrow.} -proc `$`*(x: TSocketHandle): string {.borrow.} +proc hash*(x: SocketHandle): THash {.borrow.} +proc `$`*(x: SocketHandle): string {.borrow.} type - TEvent* = enum + Event* = enum EvRead, EvWrite - PSelectorKey* = ref object - fd*: TSocketHandle - events*: set[TEvent] ## The events which ``fd`` listens for. - data*: PObject ## User object. + SelectorKey* = ref object + fd*: SocketHandle + events*: set[Event] ## The events which ``fd`` listens for. + data*: RootRef ## User object. - TReadyInfo* = tuple[key: PSelectorKey, events: set[TEvent]] + ReadyInfo* = tuple[key: SelectorKey, events: set[Event]] when defined(nimdoc): type - PSelector* = ref object + Selector* = ref object ## An object which holds file descripters to be checked for read/write ## status. - fds: TTable[TSocketHandle, PSelectorKey] + fds: Table[SocketHandle, SelectorKey] - proc register*(s: PSelector, fd: TSocketHandle, events: set[TEvent], - data: PObject): PSelectorKey {.discardable.} = + proc register*(s: Selector, fd: SocketHandle, events: set[Event], + data: RootRef): SelectorKey {.discardable.} = ## Registers file descriptor ``fd`` to selector ``s`` with a set of TEvent ## ``events``. - proc update*(s: PSelector, fd: TSocketHandle, - events: set[TEvent]): PSelectorKey {.discardable.} = + proc update*(s: Selector, fd: SocketHandle, + events: set[Event]): SelectorKey {.discardable.} = ## Updates the events which ``fd`` wants notifications for. - proc select*(s: PSelector, timeout: int): seq[TReadyInfo] = + proc select*(s: Selector, timeout: int): seq[ReadyInfo] = ## The ``events`` field of the returned ``key`` contains the original events ## for which the ``fd`` was bound. This is contrary to the ``events`` field ## of the ``TReadyInfo`` tuple which determines which events are ready ## on the ``fd``. - proc contains*(s: PSelector, fd: TSocketHandle): bool = + proc contains*(s: Selector, fd: SocketHandle): bool = ## Determines whether selector contains a file descriptor. - proc `[]`*(s: PSelector, fd: TSocketHandle): PSelectorKey = + proc `[]`*(s: Selector, fd: SocketHandle): SelectorKey = ## Retrieves the selector key for ``fd``. elif defined(linux): type - PSelector* = ref object + Selector* = ref object epollFD: cint events: array[64, epoll_event] - fds: TTable[TSocketHandle, PSelectorKey] + fds: Table[SocketHandle, SelectorKey] - proc createEventStruct(events: set[TEvent], fd: TSocketHandle): epoll_event = + proc createEventStruct(events: set[Event], fd: SocketHandle): epoll_event = if EvRead in events: result.events = EPOLLIN if EvWrite in events: @@ -76,22 +76,22 @@ elif defined(linux): result.events = result.events or EPOLLRDHUP result.data.fd = fd.cint - proc register*(s: PSelector, fd: TSocketHandle, events: set[TEvent], - data: PObject): PSelectorKey {.discardable.} = + proc register*(s: Selector, fd: SocketHandle, events: set[Event], + data: RootRef): SelectorKey {.discardable.} = ## Registers file descriptor ``fd`` to selector ``s`` with a set of TEvent ## ``events``. var event = createEventStruct(events, fd) if events != {}: if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fd, addr(event)) != 0: - OSError(OSLastError()) + raiseOSError(osLastError()) - var key = PSelectorKey(fd: fd, events: events, data: data) + var key = SelectorKey(fd: fd, events: events, data: data) s.fds[fd] = key result = key - proc update*(s: PSelector, fd: TSocketHandle, - events: set[TEvent]): PSelectorKey {.discardable.} = + proc update*(s: Selector, fd: SocketHandle, + events: set[Event]): SelectorKey {.discardable.} = ## Updates the events which ``fd`` wants notifications for. if s.fds[fd].events != events: if events == {}: @@ -101,7 +101,7 @@ elif defined(linux): # because its got fds which are waiting for no events and # are therefore constantly ready. (leading to 100% CPU usage). if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fd, nil) != 0: - OSError(OSLastError()) + raiseOSError(osLastError()) s.fds[fd].events = events else: var event = createEventStruct(events, fd) @@ -109,36 +109,36 @@ elif defined(linux): # This fd is idle. It's not a member of this epoll instance and must # be re-registered. if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fd, addr(event)) != 0: - OSError(OSLastError()) + raiseOSError(osLastError()) else: if epoll_ctl(s.epollFD, EPOLL_CTL_MOD, fd, addr(event)) != 0: - OSError(OSLastError()) + raiseOSError(osLastError()) s.fds[fd].events = events result = s.fds[fd] - proc unregister*(s: PSelector, fd: TSocketHandle): PSelectorKey {.discardable.} = + proc unregister*(s: Selector, fd: SocketHandle): SelectorKey {.discardable.} = if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fd, nil) != 0: - let err = OSLastError() + let err = osLastError() if err.cint notin {ENOENT, EBADF}: # TODO: Why do we sometimes get an EBADF? Is this normal? - OSError(err) + raiseOSError(err) result = s.fds[fd] s.fds.del(fd) - proc close*(s: PSelector) = - if s.epollFD.close() != 0: OSError(OSLastError()) + proc close*(s: Selector) = + if s.epollFD.close() != 0: raiseOSError(osLastError()) dealloc(addr s.events) # TODO: Test this - proc epollHasFd(s: PSelector, fd: TSocketHandle): bool = + proc epollHasFd(s: Selector, fd: SocketHandle): bool = result = true var event = createEventStruct(s.fds[fd].events, fd) if epoll_ctl(s.epollFD, EPOLL_CTL_MOD, fd, addr(event)) != 0: let err = osLastError() if err.cint in {ENOENT, EBADF}: return false - OSError(OSLastError()) + raiseOSError(osLastError()) - proc select*(s: PSelector, timeout: int): seq[TReadyInfo] = + proc select*(s: Selector, timeout: int): seq[ReadyInfo] = ## ## The ``events`` field of the returned ``key`` contains the original events ## for which the ``fd`` was bound. This is contrary to the ``events`` field @@ -146,12 +146,12 @@ elif defined(linux): ## on the ``fd``. result = @[] let evNum = epoll_wait(s.epollFD, addr s.events[0], 64.cint, timeout.cint) - if evNum < 0: OSError(OSLastError()) + if evNum < 0: raiseOSError(osLastError()) if evNum == 0: return @[] for i in 0 .. <evNum: - let fd = s.events[i].data.fd.TSocketHandle + let fd = s.events[i].data.fd.SocketHandle - var evSet: set[TEvent] = {} + var evSet: set[Event] = {} if (s.events[i].events and EPOLLIN) != 0: evSet = evSet + {EvRead} if (s.events[i].events and EPOLLOUT) != 0: evSet = evSet + {EvWrite} let selectorKey = s.fds[fd] @@ -160,15 +160,15 @@ elif defined(linux): #echo("Epoll: ", result[i].key.fd, " ", result[i].events, " ", result[i].key.events) - proc newSelector*(): PSelector = + proc newSelector*(): Selector = new result result.epollFD = epoll_create(64) #result.events = cast[array[64, epoll_event]](alloc0(sizeof(epoll_event)*64)) - result.fds = initTable[TSocketHandle, PSelectorKey]() + result.fds = initTable[SocketHandle, SelectorKey]() if result.epollFD < 0: - OSError(OSLastError()) + raiseOSError(osLastError()) - proc contains*(s: PSelector, fd: TSocketHandle): bool = + proc contains*(s: Selector, fd: SocketHandle): bool = ## Determines whether selector contains a file descriptor. if s.fds.hasKey(fd): # Ensure the underlying epoll instance still contains this fd. @@ -179,46 +179,46 @@ elif defined(linux): else: return false - proc `[]`*(s: PSelector, fd: TSocketHandle): PSelectorKey = + proc `[]`*(s: Selector, fd: SocketHandle): SelectorKey = ## Retrieves the selector key for ``fd``. return s.fds[fd] elif not defined(nimdoc): # TODO: kqueue for bsd/mac os x. type - PSelector* = ref object - fds: TTable[TSocketHandle, PSelectorKey] + Selector* = ref object + fds: Table[SocketHandle, SelectorKey] - proc register*(s: PSelector, fd: TSocketHandle, events: set[TEvent], - data: PObject): PSelectorKey {.discardable.} = + proc register*(s: Selector, fd: SocketHandle, events: set[Event], + data: RootRef): SelectorKey {.discardable.} = if s.fds.hasKey(fd): - raise newException(EInvalidValue, "File descriptor already exists.") - var sk = PSelectorKey(fd: fd, events: events, data: data) + raise newException(ValueError, "File descriptor already exists.") + var sk = SelectorKey(fd: fd, events: events, data: data) s.fds[fd] = sk result = sk - proc update*(s: PSelector, fd: TSocketHandle, - events: set[TEvent]): PSelectorKey {.discardable.} = + proc update*(s: Selector, fd: SocketHandle, + events: set[Event]): SelectorKey {.discardable.} = ## Updates the events which ``fd`` wants notifications for. if not s.fds.hasKey(fd): - raise newException(EInvalidValue, "File descriptor not found.") + raise newException(ValueError, "File descriptor not found.") s.fds[fd].events = events result = s.fds[fd] - proc unregister*(s: PSelector, fd: TSocketHandle): PSelectorKey {.discardable.} = + proc unregister*(s: Selector, fd: SocketHandle): SelectorKey {.discardable.} = result = s.fds[fd] s.fds.del(fd) - proc close*(s: PSelector) = nil + proc close*(s: Selector) = discard - proc timeValFromMilliseconds(timeout: int): TTimeVal = + proc timeValFromMilliseconds(timeout: int): TimeVal = if timeout != -1: var seconds = timeout div 1000 result.tv_sec = seconds.int32 result.tv_usec = ((timeout - seconds * 1000) * 1000).int32 - proc createFdSet(rd, wr: var TFdSet, fds: TTable[TSocketHandle, PSelectorKey], + proc createFdSet(rd, wr: var TFdSet, fds: Table[SocketHandle, SelectorKey], m: var int) = FD_ZERO(rd); FD_ZERO(wr) for k, v in pairs(fds): @@ -229,20 +229,20 @@ elif not defined(nimdoc): m = max(m, int(k)) FD_SET(k, wr) - proc getReadyFDs(rd, wr: var TFdSet, fds: TTable[TSocketHandle, PSelectorKey]): - seq[TReadyInfo] = + proc getReadyFDs(rd, wr: var TFdSet, fds: Table[SocketHandle, SelectorKey]): + seq[ReadyInfo] = result = @[] for k, v in pairs(fds): - var events: set[TEvent] = {} + var events: set[Event] = {} if FD_ISSET(k, rd) != 0'i32: events = events + {EvRead} if FD_ISSET(k, wr) != 0'i32: events = events + {EvWrite} result.add((v, events)) - proc select(fds: TTable[TSocketHandle, PSelectorKey], timeout = 500): - seq[TReadyInfo] = - var tv {.noInit.}: TTimeVal = timeValFromMilliseconds(timeout) + proc select(fds: Table[SocketHandle, SelectorKey], timeout = 500): + seq[ReadyInfo] = + var tv {.noInit.}: TimeVal = timeValFromMilliseconds(timeout) var rd, wr: TFdSet var m = 0 @@ -255,26 +255,26 @@ elif not defined(nimdoc): retCode = int(select(cint(m+1), addr(rd), addr(wr), nil, nil)) if retCode < 0: - OSError(OSLastError()) + raiseOSError(osLastError()) elif retCode == 0: return @[] else: return getReadyFDs(rd, wr, fds) - proc select*(s: PSelector, timeout: int): seq[TReadyInfo] = + proc select*(s: Selector, timeout: int): seq[ReadyInfo] = result = select(s.fds, timeout) - proc newSelector*(): PSelector = + proc newSelector*(): Selector = new result - result.fds = initTable[TSocketHandle, PSelectorKey]() + result.fds = initTable[SocketHandle, SelectorKey]() - proc contains*(s: PSelector, fd: TSocketHandle): bool = + proc contains*(s: Selector, fd: SocketHandle): bool = return s.fds.hasKey(fd) - proc `[]`*(s: PSelector, fd: TSocketHandle): PSelectorKey = + proc `[]`*(s: Selector, fd: SocketHandle): SelectorKey = return s.fds[fd] -proc contains*(s: PSelector, key: PSelectorKey): bool = +proc contains*(s: Selector, key: SelectorKey): bool = ## Determines whether selector contains this selector key. More accurate ## than checking if the file descriptor is in the selector because it ## ensures that the keys are equal. File descriptors may not always be @@ -282,20 +282,24 @@ proc contains*(s: PSelector, key: PSelectorKey): bool = ## the new one may have the same value. return key.fd in s and s.fds[key.fd] == key +{.deprecated: [TEvent: Event, PSelectorKey: SelectorKey, + TReadyInfo: ReadyInfo, PSelector: Selector].} + + when isMainModule and not defined(nimdoc): # Select() import sockets type - PSockWrapper = ref object of PObject - sock: TSocket + SockWrapper = ref object of RootObj + sock: Socket var sock = socket() - if sock == sockets.InvalidSocket: osError(osLastError()) + if sock == sockets.InvalidSocket: raiseOSError(osLastError()) #sock.setBlocking(false) - sock.connect("irc.freenode.net", TPort(6667)) + sock.connect("irc.freenode.net", Port(6667)) var selector = newSelector() - var data = PSockWrapper(sock: sock) + var data = SockWrapper(sock: sock) let key = selector.register(sock.getFD, {EvWrite}, data) var i = 0 while true: diff --git a/lib/pure/smtp.nim b/lib/pure/smtp.nim index 88afeb589..e088e0bd9 100644 --- a/lib/pure/smtp.nim +++ b/lib/pure/smtp.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Dominik Picheta # # See the file "copying.txt", included in this @@ -16,11 +16,11 @@ ## Example gmail use: ## ## -## .. code-block:: Nimrod -## var msg = createMessage("Hello from Nimrod's SMTP", +## .. code-block:: Nim +## var msg = createMessage("Hello from Nim's SMTP", ## "Hello!.\n Is this awesome or what?", ## @["foo@gmail.com"]) -## var smtp = connect("smtp.gmail.com", 465, True, True) +## var smtp = connect("smtp.gmail.com", 465, true, true) ## smtp.auth("username", "password") ## smtp.sendmail("username@gmail.com", @["foo@gmail.com"], $msg) ## @@ -28,22 +28,32 @@ ## For SSL support this module relies on OpenSSL. If you want to ## enable SSL, compile with ``-d:ssl``. -import sockets, strutils, strtabs, base64, os +import net, strutils, strtabs, base64, os +import asyncnet, asyncdispatch type - TSMTP* {.final.} = object - sock: TSocket - debug: Bool + Smtp* = object + sock: Socket + debug: bool - TMessage* {.final.} = object + Message* = object msgTo: seq[string] msgCc: seq[string] msgSubject: string - msgOtherHeaders: PStringTable + msgOtherHeaders: StringTableRef msgBody: string - EInvalidReply* = object of EIO - + ReplyError* = object of IOError + + AsyncSmtp* = ref object + sock: AsyncSocket + address: string + port: Port + useSsl: bool + debug: bool + +{.deprecated: [EInvalidReply: ReplyError, TMessage: Message, TSMTP: Smtp].} + proc debugSend(smtp: TSMTP, cmd: string) = if smtp.debug: echo("C:" & cmd) @@ -68,19 +78,25 @@ proc checkReply(smtp: var TSMTP, reply: string) = const compiledWithSsl = defined(ssl) -proc connect*(address: string, port = 25, - ssl = false, debug = false): TSMTP = +when not defined(ssl): + type PSSLContext = ref object + let defaultSSLContext: PSSLContext = nil +else: + let defaultSSLContext = newContext(verifyMode = CVerifyNone) + +proc connect*(address: string, port = Port(25), + ssl = false, debug = false, + sslContext = defaultSSLContext): TSMTP = ## Establishes a connection with a SMTP server. ## May fail with EInvalidReply or with a socket error. - result.sock = socket() + result.sock = newSocket() if ssl: when compiledWithSsl: - let ctx = newContext(verifyMode = CVerifyNone) - ctx.wrapSocket(result.sock) + sslContext.wrapSocket(result.sock) else: raise newException(ESystem, "SMTP module compiled without SSL support") - result.sock.connect(address, TPort(port)) + result.sock.connect(address, port) result.debug = debug result.checkReply("220") @@ -160,6 +176,82 @@ proc `$`*(msg: TMessage): string = result.add("\c\L") result.add(msg.msgBody) +proc newAsyncSmtp*(address: string, port: Port, useSsl = false, + sslContext = defaultSslContext): AsyncSmtp = + ## Creates a new ``AsyncSmtp`` instance. + new result + result.address = address + result.port = port + result.useSsl = useSsl + + result.sock = newAsyncSocket() + if useSsl: + when compiledWithSsl: + sslContext.wrapSocket(result.sock) + else: + raise newException(ESystem, + "SMTP module compiled without SSL support") + +proc quitExcpt(smtp: AsyncSmtp, msg: string): PFuture[void] = + var retFuture = newFuture[void]() + var sendFut = smtp.sock.send("QUIT") + sendFut.callback = + proc () = + # TODO: Fix this in async procs. + raise newException(ReplyError, msg) + return retFuture + +proc checkReply(smtp: AsyncSmtp, reply: string) {.async.} = + var line = await smtp.sock.recvLine() + if not line.string.startswith(reply): + await quitExcpt(smtp, "Expected " & reply & " reply, got: " & line.string) + +proc connect*(smtp: AsyncSmtp) {.async.} = + ## Establishes a connection with a SMTP server. + ## May fail with EInvalidReply or with a socket error. + await smtp.sock.connect(smtp.address, smtp.port) + + await smtp.checkReply("220") + await smtp.sock.send("HELO " & smtp.address & "\c\L") + await smtp.checkReply("250") + +proc auth*(smtp: AsyncSmtp, username, password: string) {.async.} = + ## Sends an AUTH command to the server to login as the `username` + ## using `password`. + ## May fail with EInvalidReply. + + await smtp.sock.send("AUTH LOGIN\c\L") + await smtp.checkReply("334") # TODO: Check whether it's asking for the "Username:" + # i.e "334 VXNlcm5hbWU6" + await smtp.sock.send(encode(username) & "\c\L") + await smtp.checkReply("334") # TODO: Same as above, only "Password:" (I think?) + + await smtp.sock.send(encode(password) & "\c\L") + await smtp.checkReply("235") # Check whether the authentification was successful. + +proc sendMail*(smtp: AsyncSmtp, fromAddr: string, + toAddrs: seq[string], msg: string) {.async.} = + ## Sends ``msg`` from ``fromAddr`` to the addresses specified in ``toAddrs``. + ## Messages may be formed using ``createMessage`` by converting the + ## TMessage into a string. + + await smtp.sock.send("MAIL FROM:<" & fromAddr & ">\c\L") + await smtp.checkReply("250") + for address in items(toAddrs): + await smtp.sock.send("RCPT TO:<" & smtp.address & ">\c\L") + await smtp.checkReply("250") + + # Send the message + await smtp.sock.send("DATA " & "\c\L") + await smtp.checkReply("354") + await smtp.sock.send(msg & "\c\L") + await smtp.sock.send(".\c\L") + await smtp.checkReply("250") + +proc close*(smtp: AsyncSmtp) {.async.} = + ## Disconnects from the SMTP server and closes the socket. + await smtp.sock.send("QUIT\c\L") + smtp.sock.close() when isMainModule: #var msg = createMessage("Test subject!", @@ -170,15 +262,16 @@ when isMainModule: #smtp.sendmail("root@localhost", @["dominik@localhost"], $msg) #echo(decode("a17sm3701420wbe.12")) - var msg = createMessage("Hello from Nimrod's SMTP!", - "Hello!!!!.\n Is this awesome or what?", - @["someone@yahoo.com", "someone@gmail.com"]) - echo(msg) - - var smtp = connect("smtp.gmail.com", 465, True, True) - smtp.auth("someone", "password") - smtp.sendmail("someone@gmail.com", - @["someone@yahoo.com", "someone@gmail.com"], $msg) - smtp.close() - + proc main() {.async.} = + var client = newAsyncSmtp("smtp.gmail.com", Port(465), true) + await client.connect() + await client.auth("johndoe", "foo") + var msg = createMessage("Hello from Nim's SMTP!", + "Hello!!!!.\n Is this awesome or what?", + @["blah@gmail.com"]) + echo(msg) + await client.sendMail("blah@gmail.com", @["blah@gmail.com"], $msg) + await client.close() + + waitFor main() diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim index 7b8b3d557..36389edcc 100644 --- a/lib/pure/sockets.nim +++ b/lib/pure/sockets.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf, Dominik Picheta # # See the file "copying.txt", included in this @@ -14,8 +14,8 @@ ## the ``socket`` function to `false`. Be aware that some functions may not yet ## support buffered sockets (mainly the recvFrom function). ## -## Most procedures raise EOS on error, but some may return ``-1`` or a boolean -## ``false``. +## Most procedures raise OSError on error, but some may return ``-1`` or a +## boolean ``false``. ## ## SSL is supported through the OpenSSL library. This support can be activated ## by compiling with the ``-d:ssl`` switch. When an SSL socket is used it will @@ -47,25 +47,29 @@ else: when defined(ssl): type - ESSL* = object of ESynch + SSLError* = object of Exception - TSSLCVerifyMode* = enum + SSLCVerifyMode* = enum CVerifyNone, CVerifyPeer - TSSLProtVersion* = enum + SSLProtVersion* = enum protSSLv2, protSSLv3, protTLSv1, protSSLv23 - PSSLContext* = distinct PSSLCTX + SSLContext* = distinct PSSLCTX - TSSLAcceptResult* = enum + SSLAcceptResult* = enum AcceptNoClient = 0, AcceptNoHandshake, AcceptSuccess + {.deprecated: [ESSL: SSLError, TSSLCVerifyMode: SSLCVerifyMode, + TSSLProtVersion: SSLProtVersion, PSSLContext: SSLContext, + TSSLAcceptResult: SSLAcceptResult].} + const BufferSize*: int = 4000 ## size of a buffered socket's buffer type TSocketImpl = object ## socket type - fd: TSocketHandle + fd: SocketHandle case isBuffered: bool # determines whether this socket is buffered. of true: buffer: array[0..BufferSize, char] @@ -76,31 +80,31 @@ type case isSsl: bool of true: sslHandle: PSSL - sslContext: PSSLContext + sslContext: SSLContext sslNoHandshake: bool # True if needs handshake. sslHasPeekChar: bool sslPeekChar: char of false: nil nonblocking: bool - TSocket* = ref TSocketImpl + Socket* = ref TSocketImpl - TPort* = distinct uint16 ## port type + Port* = distinct uint16 ## port type - TDomain* = enum ## domain, which specifies the protocol family of the + Domain* = enum ## domain, which specifies the protocol family of the ## created socket. Other domains than those that are listed ## here are unsupported. AF_UNIX, ## for local socket (using a file). Unsupported on Windows. AF_INET = 2, ## for network protocol IPv4 or AF_INET6 = 23 ## for network protocol IPv6. - TType* = enum ## second argument to `socket` proc + SockType* = enum ## second argument to `socket` proc SOCK_STREAM = 1, ## reliable stream-oriented service or Stream Sockets SOCK_DGRAM = 2, ## datagram service or Datagram Sockets SOCK_RAW = 3, ## raw protocols atop the network layer. SOCK_SEQPACKET = 5 ## reliable sequenced packet service - TProtocol* = enum ## third argument to `socket` proc + Protocol* = enum ## third argument to `socket` proc IPPROTO_TCP = 6, ## Transmission control protocol. IPPROTO_UDP = 17, ## User datagram protocol. IPPROTO_IP, ## Internet protocol. Unsupported on Windows. @@ -108,33 +112,40 @@ type IPPROTO_RAW, ## Raw IP Packets Protocol. Unsupported on Windows. IPPROTO_ICMP ## Control message protocol. Unsupported on Windows. - TServent* {.pure, final.} = object ## information about a service + Servent* = object ## information about a service name*: string aliases*: seq[string] - port*: TPort + port*: Port proto*: string - Thostent* {.pure, final.} = object ## information about a given host + Hostent* = object ## information about a given host name*: string aliases*: seq[string] - addrtype*: TDomain + addrtype*: Domain length*: int addrList*: seq[string] - TSOBool* = enum ## Boolean socket options. + SOBool* = enum ## Boolean socket options. OptAcceptConn, OptBroadcast, OptDebug, OptDontRoute, OptKeepAlive, OptOOBInline, OptReuseAddr - TRecvLineResult* = enum ## result for recvLineAsync + RecvLineResult* = enum ## result for recvLineAsync RecvFullLine, RecvPartialLine, RecvDisconnected, RecvFail - TReadLineResult* = enum ## result for readLineAsync + ReadLineResult* = enum ## result for readLineAsync ReadFullLine, ReadPartialLine, ReadDisconnected, ReadNone - ETimeout* = object of ESynch + TimeoutError* = object of Exception + +{.deprecated: [TSocket: Socket, TType: SockType, TPort: Port, TDomain: Domain, + TProtocol: Protocol, TServent: Servent, THostent: Hostent, + TSOBool: SOBool, TRecvLineResult: RecvLineResult, + TReadLineResult: ReadLineResult, ETimeout: TimeoutError].} -let - invalidSocket*: TSocket = nil ## invalid socket +when defined(booting): + let invalidSocket*: Socket = nil ## invalid socket +else: + const invalidSocket*: Socket = nil ## invalid socket when defined(windows): let @@ -143,7 +154,7 @@ else: let osInvalidSocket = posix.INVALID_SOCKET -proc newTSocket(fd: TSocketHandle, isBuff: bool): TSocket = +proc newTSocket(fd: SocketHandle, isBuff: bool): Socket = if fd == osInvalidSocket: return nil new(result) @@ -153,10 +164,10 @@ proc newTSocket(fd: TSocketHandle, isBuff: bool): TSocket = result.currPos = 0 result.nonblocking = false -proc `==`*(a, b: TPort): bool {.borrow.} +proc `==`*(a, b: Port): bool {.borrow.} ## ``==`` for ports. -proc `$`*(p: TPort): string {.borrow.} +proc `$`*(p: Port): string {.borrow.} ## returns the port number as a string proc ntohl*(x: int32): int32 = @@ -189,14 +200,14 @@ proc htons*(x: int16): int16 = result = sockets.ntohs(x) when defined(Posix): - proc toInt(domain: TDomain): cint = + proc toInt(domain: Domain): cint = case domain of AF_UNIX: result = posix.AF_UNIX of AF_INET: result = posix.AF_INET of AF_INET6: result = posix.AF_INET6 else: discard - proc toInt(typ: TType): cint = + proc toInt(typ: SockType): cint = case typ of SOCK_STREAM: result = posix.SOCK_STREAM of SOCK_DGRAM: result = posix.SOCK_DGRAM @@ -204,7 +215,7 @@ when defined(Posix): of SOCK_RAW: result = posix.SOCK_RAW else: discard - proc toInt(p: TProtocol): cint = + proc toInt(p: Protocol): cint = case p of IPPROTO_TCP: result = posix.IPPROTO_TCP of IPPROTO_UDP: result = posix.IPPROTO_UDP @@ -215,17 +226,17 @@ when defined(Posix): else: discard else: - proc toInt(domain: TDomain): cint = + proc toInt(domain: Domain): cint = result = toU16(ord(domain)) - proc toInt(typ: TType): cint = + proc toInt(typ: SockType): cint = result = cint(ord(typ)) - proc toInt(p: TProtocol): cint = + proc toInt(p: Protocol): cint = result = cint(ord(p)) -proc socket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, - protocol: TProtocol = IPPROTO_TCP, buffered = true): TSocket = +proc socket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM, + protocol: Protocol = IPPROTO_TCP, buffered = true): Socket = ## Creates a new socket; returns `InvalidSocket` if an error occurs. # TODO: Perhaps this should just raise EOS when an error occurs. @@ -241,14 +252,14 @@ when defined(ssl): ErrLoadBioStrings() OpenSSL_add_all_algorithms() - proc SSLError(s = "") = + proc raiseSSLError(s = "") = if s != "": raise newException(ESSL, s) let err = ErrPeekLastError() if err == 0: raise newException(ESSL, "No error reported.") if err == -1: - OSError(OSLastError()) + raiseOSError(osLastError()) var errStr = ErrErrorString(err, nil) raise newException(ESSL, $errStr) @@ -262,18 +273,18 @@ when defined(ssl): if certFile != "": var ret = SSLCTXUseCertificateChainFile(ctx, certFile) if ret != 1: - SSLError() + raiseSslError() # TODO: Password? www.rtfm.com/openssl-examples/part1.pdf if keyFile != "": if SSL_CTX_use_PrivateKey_file(ctx, keyFile, SSL_FILETYPE_PEM) != 1: - SSLError() + raiseSslError() if SSL_CTX_check_private_key(ctx) != 1: - SSLError("Verification of private key file failed.") + raiseSslError("Verification of private key file failed.") - proc newContext*(protVersion = ProtSSLv23, verifyMode = CVerifyPeer, + proc newContext*(protVersion = protSSLv23, verifyMode = CVerifyPeer, certFile = "", keyFile = ""): PSSLContext = ## Creates an SSL context. ## @@ -298,21 +309,21 @@ when defined(ssl): when not defined(linux) and not defined(OpenBSD): newCTX = SSL_CTX_new(SSLv2_method()) else: - SSLError() + raiseSslError() of protSSLv3: newCTX = SSL_CTX_new(SSLv3_method()) of protTLSv1: newCTX = SSL_CTX_new(TLSv1_method()) if newCTX.SSLCTXSetCipherList("ALL") != 1: - SSLError() + raiseSslError() case verifyMode of CVerifyPeer: newCTX.SSLCTXSetVerify(SSLVerifyPeer, nil) of CVerifyNone: newCTX.SSLCTXSetVerify(SSLVerifyNone, nil) if newCTX == nil: - SSLError() + raiseSslError() discard newCTX.SSLCTXSetMode(SSL_MODE_AUTO_RETRY) newCTX.loadCertificates(certFile, keyFile) @@ -331,12 +342,12 @@ when defined(ssl): socket.sslNoHandshake = false socket.sslHasPeekChar = false if socket.sslHandle == nil: - SSLError() + raiseSslError() if SSLSetFd(socket.sslHandle, socket.fd) != 1: - SSLError() + raiseSslError() -proc socketError*(socket: TSocket, err: int = -1, async = false) = +proc raiseSocketError*(socket: Socket, err: int = -1, async = false) = ## Raises proper errors based on return values of ``recv`` functions. ## ## If ``async`` is ``True`` no error will be thrown in the case when the @@ -349,20 +360,20 @@ proc socketError*(socket: TSocket, err: int = -1, async = false) = var ret = SSLGetError(socket.sslHandle, err.cint) case ret of SSL_ERROR_ZERO_RETURN: - SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") + raiseSslError("TLS/SSL connection failed to initiate, socket closed prematurely.") of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: if async: return - else: SSLError("Not enough data on socket.") + else: raiseSslError("Not enough data on socket.") of SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_READ: if async: return - else: SSLError("Not enough data on socket.") + else: raiseSslError("Not enough data on socket.") of SSL_ERROR_WANT_X509_LOOKUP: - SSLError("Function for x509 lookup has been called.") + raiseSslError("Function for x509 lookup has been called.") of SSL_ERROR_SYSCALL, SSL_ERROR_SSL: - SSLError() - else: SSLError("Unknown Error") + raiseSslError() + else: raiseSslError("Unknown Error") if err == -1 and not (when defined(ssl): socket.isSSL else: false): let lastError = osLastError() @@ -370,21 +381,21 @@ proc socketError*(socket: TSocket, err: int = -1, async = false) = when defined(windows): if lastError.int32 == WSAEWOULDBLOCK: return - else: osError(lastError) + else: raiseOSError(lastError) else: if lastError.int32 == EAGAIN or lastError.int32 == EWOULDBLOCK: return - else: osError(lastError) - else: osError(lastError) + else: raiseOSError(lastError) + else: raiseOSError(lastError) -proc listen*(socket: TSocket, backlog = SOMAXCONN) {.tags: [FReadIO].} = +proc listen*(socket: Socket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} = ## Marks ``socket`` as accepting connections. ## ``Backlog`` specifies the maximum length of the ## queue of pending connections. - if listen(socket.fd, cint(backlog)) < 0'i32: osError(osLastError()) + if listen(socket.fd, cint(backlog)) < 0'i32: raiseOSError(osLastError()) proc invalidIp4(s: string) {.noreturn, noinline.} = - raise newException(EInvalidValue, "invalid ip4 address: " & s) + raise newException(ValueError, "invalid ip4 address: " & s) proc parseIp4*(s: string): BiggestInt = ## parses an IP version 4 in dotted decimal form like "a.b.c.d". @@ -420,58 +431,58 @@ template gaiNim(a, p, h, list: expr): stmt = var gaiResult = getaddrinfo(a, $p, addr(h), list) if gaiResult != 0'i32: when defined(windows): - osError(osLastError()) + raiseOSError(osLastError()) else: - raise newException(EOS, $gai_strerror(gaiResult)) + raise newException(OSError, $gai_strerror(gaiResult)) -proc bindAddr*(socket: TSocket, port = TPort(0), address = "") {. - tags: [FReadIO].} = +proc bindAddr*(socket: Socket, port = Port(0), address = "") {. + tags: [ReadIOEffect].} = ## binds an address/port number to a socket. ## Use address string in dotted decimal form like "a.b.c.d" ## or leave "" for any address. if address == "": - var name: Tsockaddr_in + var name: Sockaddr_in when defined(Windows): name.sin_family = int16(ord(AF_INET)) else: name.sin_family = posix.AF_INET name.sin_port = sockets.htons(int16(port)) name.sin_addr.s_addr = sockets.htonl(INADDR_ANY) - if bindSocket(socket.fd, cast[ptr TSockAddr](addr(name)), - sizeof(name).TSocklen) < 0'i32: - osError(osLastError()) + if bindSocket(socket.fd, cast[ptr SockAddr](addr(name)), + sizeof(name).SockLen) < 0'i32: + raiseOSError(osLastError()) else: - var hints: Taddrinfo - var aiList: ptr Taddrinfo = nil + var hints: AddrInfo + var aiList: ptr AddrInfo = nil hints.ai_family = toInt(AF_INET) hints.ai_socktype = toInt(SOCK_STREAM) hints.ai_protocol = toInt(IPPROTO_TCP) gaiNim(address, port, hints, aiList) - if bindSocket(socket.fd, aiList.ai_addr, aiList.ai_addrlen.TSocklen) < 0'i32: - osError(osLastError()) + if bindSocket(socket.fd, aiList.ai_addr, aiList.ai_addrlen.SockLen) < 0'i32: + raiseOSError(osLastError()) -proc getSockName*(socket: TSocket): TPort = +proc getSockName*(socket: Socket): Port = ## returns the socket's associated port number. - var name: Tsockaddr_in + var name: Sockaddr_in when defined(Windows): name.sin_family = int16(ord(AF_INET)) else: name.sin_family = posix.AF_INET #name.sin_port = htons(cint16(port)) #name.sin_addr.s_addr = htonl(INADDR_ANY) - var namelen = sizeof(name).TSocklen - if getsockname(socket.fd, cast[ptr TSockAddr](addr(name)), + var namelen = sizeof(name).SockLen + if getsockname(socket.fd, cast[ptr SockAddr](addr(name)), addr(namelen)) == -1'i32: - osError(osLastError()) - result = TPort(sockets.ntohs(name.sin_port)) + raiseOSError(osLastError()) + result = Port(sockets.ntohs(name.sin_port)) template acceptAddrPlain(noClientRet, successRet: expr, sslImplementation: stmt): stmt {.immediate.} = assert(client != nil) - var sockAddress: Tsockaddr_in - var addrLen = sizeof(sockAddress).TSocklen - var sock = accept(server.fd, cast[ptr TSockAddr](addr(sockAddress)), + var sockAddress: Sockaddr_in + var addrLen = sizeof(sockAddress).SockLen + var sock = accept(server.fd, cast[ptr SockAddr](addr(sockAddress)), addr(addrLen)) if sock == osInvalidSocket: @@ -484,7 +495,7 @@ template acceptAddrPlain(noClientRet, successRet: expr, return else: return noClientRet - else: osError(err) + else: raiseOSError(err) else: if err.int32 == EAGAIN or err.int32 == EWOULDBLOCK: client = invalidSocket @@ -493,7 +504,7 @@ template acceptAddrPlain(noClientRet, successRet: expr, return else: return noClientRet - else: osError(err) + else: raiseOSError(err) else: client.fd = sock client.isBuffered = server.isBuffered @@ -505,8 +516,8 @@ template acceptAddrPlain(noClientRet, successRet: expr, else: return successRet -proc acceptAddr*(server: TSocket, client: var TSocket, address: var string) {. - tags: [FReadIO].} = +proc acceptAddr*(server: Socket, client: var Socket, address: var string) {. + tags: [ReadIOEffect].} = ## Blocks until a connection is being made from a client. When a connection ## is made sets ``client`` to the client socket and ``address`` to the address ## of the connecting client. @@ -535,18 +546,18 @@ proc acceptAddr*(server: TSocket, client: var TSocket, address: var string) {. if err != SSL_ERROR_WANT_ACCEPT: case err of SSL_ERROR_ZERO_RETURN: - SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") + raiseSslError("TLS/SSL connection failed to initiate, socket closed prematurely.") of SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: - SSLError("acceptAddrSSL should be used for non-blocking SSL sockets.") + raiseSslError("acceptAddrSSL should be used for non-blocking SSL sockets.") of SSL_ERROR_WANT_X509_LOOKUP: - SSLError("Function for x509 lookup has been called.") + raiseSslError("Function for x509 lookup has been called.") of SSL_ERROR_SYSCALL, SSL_ERROR_SSL: - SSLError() + raiseSslError() else: - SSLError("Unknown error") + raiseSslError("Unknown error") -proc setBlocking*(s: TSocket, blocking: bool) {.tags: [], gcsafe.} +proc setBlocking*(s: Socket, blocking: bool) {.tags: [], gcsafe.} ## Sets blocking mode on socket when defined(ssl): @@ -581,17 +592,17 @@ when defined(ssl): if err != SSL_ERROR_WANT_ACCEPT: case err of SSL_ERROR_ZERO_RETURN: - SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") + raiseSslError("TLS/SSL connection failed to initiate, socket closed prematurely.") of SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: client.sslNoHandshake = true return AcceptNoHandshake of SSL_ERROR_WANT_X509_LOOKUP: - SSLError("Function for x509 lookup has been called.") + raiseSslError("Function for x509 lookup has been called.") of SSL_ERROR_SYSCALL, SSL_ERROR_SSL: - SSLError() + raiseSslError() else: - SSLError("Unknown error") + raiseSslError("Unknown error") client.sslNoHandshake = false if client.isSSL and client.sslNoHandshake: @@ -601,7 +612,7 @@ when defined(ssl): acceptAddrPlain(AcceptNoClient, AcceptSuccess): doHandshake() -proc accept*(server: TSocket, client: var TSocket) {.tags: [FReadIO].} = +proc accept*(server: Socket, client: var Socket) {.tags: [ReadIOEffect].} = ## Equivalent to ``acceptAddr`` but doesn't return the address, only the ## socket. ## @@ -611,24 +622,24 @@ proc accept*(server: TSocket, client: var TSocket) {.tags: [FReadIO].} = var addrDummy = "" acceptAddr(server, client, addrDummy) -proc acceptAddr*(server: TSocket): tuple[client: TSocket, address: string] {. - deprecated, tags: [FReadIO].} = +proc acceptAddr*(server: Socket): tuple[client: Socket, address: string] {. + deprecated, tags: [ReadIOEffect].} = ## Slightly different version of ``acceptAddr``. ## ## **Deprecated since version 0.9.0:** Please use the function above. - var client: TSocket + var client: Socket new(client) var address = "" acceptAddr(server, client, address) return (client, address) -proc accept*(server: TSocket): TSocket {.deprecated, tags: [FReadIO].} = +proc accept*(server: Socket): Socket {.deprecated, tags: [ReadIOEffect].} = ## **Deprecated since version 0.9.0:** Please use the function above. new(result) var address = "" acceptAddr(server, result, address) -proc close*(socket: TSocket) = +proc close*(socket: Socket) = ## closes a socket. when defined(windows): discard winlean.closesocket(socket.fd) @@ -640,7 +651,7 @@ proc close*(socket: TSocket) = if socket.isSSL: discard SSLShutdown(socket.sslHandle) -proc getServByName*(name, proto: string): TServent {.tags: [FReadIO].} = +proc getServByName*(name, proto: string): Servent {.tags: [ReadIOEffect].} = ## Searches the database from the beginning and finds the first entry for ## which the service name specified by ``name`` matches the s_name member ## and the protocol name specified by ``proto`` matches the s_proto member. @@ -650,13 +661,13 @@ proc getServByName*(name, proto: string): TServent {.tags: [FReadIO].} = var s = winlean.getservbyname(name, proto) else: var s = posix.getservbyname(name, proto) - if s == nil: raise newException(EOS, "Service not found.") + if s == nil: raise newException(OSError, "Service not found.") result.name = $s.s_name result.aliases = cstringArrayToSeq(s.s_aliases) - result.port = TPort(s.s_port) + result.port = Port(s.s_port) result.proto = $s.s_proto -proc getServByPort*(port: TPort, proto: string): TServent {.tags: [FReadIO].} = +proc getServByPort*(port: Port, proto: string): Servent {.tags: [ReadIOEffect].} = ## Searches the database from the beginning and finds the first entry for ## which the port specified by ``port`` matches the s_port member and the ## protocol name specified by ``proto`` matches the s_proto member. @@ -666,81 +677,81 @@ proc getServByPort*(port: TPort, proto: string): TServent {.tags: [FReadIO].} = var s = winlean.getservbyport(ze(int16(port)).cint, proto) else: var s = posix.getservbyport(ze(int16(port)).cint, proto) - if s == nil: raise newException(EOS, "Service not found.") + if s == nil: raise newException(OSError, "Service not found.") result.name = $s.s_name result.aliases = cstringArrayToSeq(s.s_aliases) - result.port = TPort(s.s_port) + result.port = Port(s.s_port) result.proto = $s.s_proto -proc getHostByAddr*(ip: string): Thostent {.tags: [FReadIO].} = +proc getHostByAddr*(ip: string): Hostent {.tags: [ReadIOEffect].} = ## This function will lookup the hostname of an IP Address. - var myaddr: TInAddr + var myaddr: InAddr myaddr.s_addr = inet_addr(ip) when defined(windows): var s = winlean.gethostbyaddr(addr(myaddr), sizeof(myaddr).cuint, cint(sockets.AF_INET)) - if s == nil: osError(osLastError()) + if s == nil: raiseOSError(osLastError()) else: - var s = posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).TSocklen, + var s = posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).Socklen, cint(posix.AF_INET)) if s == nil: - raise newException(EOS, $hstrerror(h_errno)) + raise newException(OSError, $hstrerror(h_errno)) result.name = $s.h_name result.aliases = cstringArrayToSeq(s.h_aliases) when defined(windows): - result.addrtype = TDomain(s.h_addrtype) + result.addrtype = Domain(s.h_addrtype) else: if s.h_addrtype == posix.AF_INET: result.addrtype = AF_INET elif s.h_addrtype == posix.AF_INET6: result.addrtype = AF_INET6 else: - raise newException(EOS, "unknown h_addrtype") + raise newException(OSError, "unknown h_addrtype") result.addrList = cstringArrayToSeq(s.h_addr_list) result.length = int(s.h_length) -proc getHostByName*(name: string): Thostent {.tags: [FReadIO].} = +proc getHostByName*(name: string): Hostent {.tags: [ReadIOEffect].} = ## This function will lookup the IP address of a hostname. when defined(Windows): var s = winlean.gethostbyname(name) else: var s = posix.gethostbyname(name) - if s == nil: osError(osLastError()) + if s == nil: raiseOSError(osLastError()) result.name = $s.h_name result.aliases = cstringArrayToSeq(s.h_aliases) when defined(windows): - result.addrtype = TDomain(s.h_addrtype) + result.addrtype = Domain(s.h_addrtype) else: if s.h_addrtype == posix.AF_INET: result.addrtype = AF_INET elif s.h_addrtype == posix.AF_INET6: result.addrtype = AF_INET6 else: - raise newException(EOS, "unknown h_addrtype") + raise newException(OSError, "unknown h_addrtype") result.addrList = cstringArrayToSeq(s.h_addr_list) result.length = int(s.h_length) -proc getSockOptInt*(socket: TSocket, level, optname: int): int {. - tags: [FReadIO].} = +proc getSockOptInt*(socket: Socket, level, optname: int): int {. + tags: [ReadIOEffect].} = ## getsockopt for integer options. var res: cint - var size = sizeof(res).TSocklen + var size = sizeof(res).SockLen if getsockopt(socket.fd, cint(level), cint(optname), addr(res), addr(size)) < 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) result = int(res) -proc setSockOptInt*(socket: TSocket, level, optname, optval: int) {. - tags: [FWriteIO].} = +proc setSockOptInt*(socket: Socket, level, optname, optval: int) {. + tags: [WriteIOEffect].} = ## setsockopt for integer options. var value = cint(optval) if setsockopt(socket.fd, cint(level), cint(optname), addr(value), - sizeof(value).TSocklen) < 0'i32: - osError(osLastError()) + sizeof(value).SockLen) < 0'i32: + raiseOSError(osLastError()) -proc toCInt(opt: TSOBool): cint = +proc toCInt(opt: SOBool): cint = case opt of OptAcceptConn: SO_ACCEPTCONN of OptBroadcast: SO_BROADCAST @@ -750,51 +761,51 @@ proc toCInt(opt: TSOBool): cint = of OptOOBInline: SO_OOBINLINE of OptReuseAddr: SO_REUSEADDR -proc getSockOpt*(socket: TSocket, opt: TSOBool, level = SOL_SOCKET): bool {. - tags: [FReadIO].} = +proc getSockOpt*(socket: Socket, opt: SOBool, level = SOL_SOCKET): bool {. + tags: [ReadIOEffect].} = ## Retrieves option ``opt`` as a boolean value. var res: cint - var size = sizeof(res).TSocklen + var size = sizeof(res).SockLen if getsockopt(socket.fd, cint(level), toCInt(opt), addr(res), addr(size)) < 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) result = res != 0 -proc setSockOpt*(socket: TSocket, opt: TSOBool, value: bool, level = SOL_SOCKET) {. - tags: [FWriteIO].} = +proc setSockOpt*(socket: Socket, opt: SOBool, value: bool, level = SOL_SOCKET) {. + tags: [WriteIOEffect].} = ## Sets option ``opt`` to a boolean value specified by ``value``. var valuei = cint(if value: 1 else: 0) if setsockopt(socket.fd, cint(level), toCInt(opt), addr(valuei), - sizeof(valuei).TSocklen) < 0'i32: - osError(osLastError()) + sizeof(valuei).SockLen) < 0'i32: + raiseOSError(osLastError()) -proc connect*(socket: TSocket, address: string, port = TPort(0), - af: TDomain = AF_INET) {.tags: [FReadIO].} = +proc connect*(socket: Socket, address: string, port = Port(0), + af: Domain = AF_INET) {.tags: [ReadIOEffect].} = ## Connects socket to ``address``:``port``. ``Address`` can be an IP address or a ## host name. If ``address`` is a host name, this function will try each IP ## of that host name. ``htons`` is already performed on ``port`` so you must ## not do it. ## ## If ``socket`` is an SSL socket a handshake will be automatically performed. - var hints: Taddrinfo - var aiList: ptr Taddrinfo = nil + var hints: AddrInfo + var aiList: ptr AddrInfo = nil hints.ai_family = toInt(af) hints.ai_socktype = toInt(SOCK_STREAM) hints.ai_protocol = toInt(IPPROTO_TCP) gaiNim(address, port, hints, aiList) # try all possibilities: var success = false - var lastError: TOSErrorCode + var lastError: OSErrorCode var it = aiList while it != nil: - if connect(socket.fd, it.ai_addr, it.ai_addrlen.TSocklen) == 0'i32: + if connect(socket.fd, it.ai_addr, it.ai_addrlen.SockLen) == 0'i32: success = true break else: lastError = osLastError() it = it.ai_next freeaddrinfo(aiList) - if not success: osError(lastError) + if not success: raiseOSError(lastError) when defined(ssl): if socket.isSSL: @@ -803,16 +814,16 @@ proc connect*(socket: TSocket, address: string, port = TPort(0), let err = SSLGetError(socket.sslHandle, ret) case err of SSL_ERROR_ZERO_RETURN: - SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") + raiseSslError("TLS/SSL connection failed to initiate, socket closed prematurely.") of SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: - SSLError("The operation did not complete. Perhaps you should use connectAsync?") + raiseSslError("The operation did not complete. Perhaps you should use connectAsync?") of SSL_ERROR_WANT_X509_LOOKUP: - SSLError("Function for x509 lookup has been called.") + raiseSslError("Function for x509 lookup has been called.") of SSL_ERROR_SYSCALL, SSL_ERROR_SSL: - SSLError() + raiseSslError() else: - SSLError("Unknown error") + raiseSslError("Unknown error") when false: var s: TSockAddrIn @@ -829,8 +840,8 @@ proc connect*(socket: TSocket, address: string, port = TPort(0), if connect(socket.fd, cast[ptr TSockAddr](addr(s)), sizeof(s).cint) < 0'i32: OSError() -proc connectAsync*(socket: TSocket, name: string, port = TPort(0), - af: TDomain = AF_INET) {.tags: [FReadIO].} = +proc connectAsync*(socket: Socket, name: string, port = Port(0), + af: Domain = AF_INET) {.tags: [ReadIOEffect].} = ## A variant of ``connect`` for non-blocking sockets. ## ## This procedure will immediatelly return, it will not block until a connection @@ -839,18 +850,18 @@ proc connectAsync*(socket: TSocket, name: string, port = TPort(0), ## ## **Note**: For SSL sockets, the ``handshake`` procedure must be called ## whenever the socket successfully connects to a server. - var hints: Taddrinfo - var aiList: ptr Taddrinfo = nil + var hints: AddrInfo + var aiList: ptr AddrInfo = nil hints.ai_family = toInt(af) hints.ai_socktype = toInt(SOCK_STREAM) hints.ai_protocol = toInt(IPPROTO_TCP) gaiNim(name, port, hints, aiList) # try all possibilities: var success = false - var lastError: TOSErrorCode + var lastError: OSErrorCode var it = aiList while it != nil: - var ret = connect(socket.fd, it.ai_addr, it.ai_addrlen.TSocklen) + var ret = connect(socket.fd, it.ai_addr, it.ai_addrlen.SockLen) if ret == 0'i32: success = true break @@ -869,7 +880,7 @@ proc connectAsync*(socket: TSocket, name: string, port = TPort(0), it = it.ai_next freeaddrinfo(aiList) - if not success: osError(lastError) + if not success: raiseOSError(lastError) when defined(ssl): if socket.isSSL: socket.sslNoHandshake = true @@ -891,19 +902,19 @@ when defined(ssl): var errret = SSLGetError(socket.sslHandle, ret) case errret of SSL_ERROR_ZERO_RETURN: - SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") + raiseSslError("TLS/SSL connection failed to initiate, socket closed prematurely.") of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT, SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE: return false of SSL_ERROR_WANT_X509_LOOKUP: - SSLError("Function for x509 lookup has been called.") + raiseSslError("Function for x509 lookup has been called.") of SSL_ERROR_SYSCALL, SSL_ERROR_SSL: - SSLError() + raiseSslError() else: - SSLError("Unknown Error") + raiseSslError("Unknown Error") socket.sslNoHandshake = false else: - SSLError("Socket is not an SSL socket.") + raiseSslError("Socket is not an SSL socket.") proc gotHandshake*(socket: TSocket): bool = ## Determines whether a handshake has occurred between a client (``socket``) @@ -913,21 +924,21 @@ when defined(ssl): if socket.isSSL: return not socket.sslNoHandshake else: - SSLError("Socket is not an SSL socket.") + raiseSslError("Socket is not an SSL socket.") -proc timeValFromMilliseconds(timeout = 500): Ttimeval = +proc timeValFromMilliseconds(timeout = 500): Timeval = if timeout != -1: var seconds = timeout div 1000 result.tv_sec = seconds.int32 result.tv_usec = ((timeout - seconds * 1000) * 1000).int32 -proc createFdSet(fd: var TFdSet, s: seq[TSocket], m: var int) = +proc createFdSet(fd: var TFdSet, s: seq[Socket], m: var int) = FD_ZERO(fd) for i in items(s): m = max(m, int(i.fd)) FD_SET(i.fd, fd) -proc pruneSocketSet(s: var seq[TSocket], fd: var TFdSet) = +proc pruneSocketSet(s: var seq[Socket], fd: var TFdSet) = var i = 0 var L = s.len while i < L: @@ -939,7 +950,7 @@ proc pruneSocketSet(s: var seq[TSocket], fd: var TFdSet) = inc(i) setLen(s, L) -proc hasDataBuffered*(s: TSocket): bool = +proc hasDataBuffered*(s: Socket): bool = ## Determines whether a socket has data buffered. result = false if s.isBuffered: @@ -949,10 +960,10 @@ proc hasDataBuffered*(s: TSocket): bool = if s.isSSL and not result: result = s.sslHasPeekChar -proc checkBuffer(readfds: var seq[TSocket]): int = +proc checkBuffer(readfds: var seq[Socket]): int = ## Checks the buffer of each socket in ``readfds`` to see whether there is data. ## Removes the sockets from ``readfds`` and returns the count of removed sockets. - var res: seq[TSocket] = @[] + var res: seq[Socket] = @[] result = 0 for s in readfds: if hasDataBuffered(s): @@ -961,8 +972,8 @@ proc checkBuffer(readfds: var seq[TSocket]): int = if result > 0: readfds = res -proc select*(readfds, writefds, exceptfds: var seq[TSocket], - timeout = 500): int {.tags: [FReadIO].} = +proc select*(readfds, writefds, exceptfds: var seq[Socket], + timeout = 500): int {.tags: [ReadIOEffect].} = ## Traditional select function. This function will return the number of ## sockets that are ready to be read from, written to, or which have errors. ## If there are none; 0 is returned. @@ -975,7 +986,7 @@ proc select*(readfds, writefds, exceptfds: var seq[TSocket], if buffersFilled > 0: return buffersFilled - var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) + var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) var rd, wr, ex: TFdSet var m = 0 @@ -992,13 +1003,13 @@ proc select*(readfds, writefds, exceptfds: var seq[TSocket], pruneSocketSet(writefds, (wr)) pruneSocketSet(exceptfds, (ex)) -proc select*(readfds, writefds: var seq[TSocket], - timeout = 500): int {.tags: [FReadIO].} = +proc select*(readfds, writefds: var seq[Socket], + timeout = 500): int {.tags: [ReadIOEffect].} = ## Variant of select with only a read and write list. let buffersFilled = checkBuffer(readfds) if buffersFilled > 0: return buffersFilled - var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) + var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) var rd, wr: TFdSet var m = 0 @@ -1013,8 +1024,8 @@ proc select*(readfds, writefds: var seq[TSocket], pruneSocketSet(readfds, (rd)) pruneSocketSet(writefds, (wr)) -proc selectWrite*(writefds: var seq[TSocket], - timeout = 500): int {.tags: [FReadIO].} = +proc selectWrite*(writefds: var seq[Socket], + timeout = 500): int {.tags: [ReadIOEffect].} = ## When a socket in ``writefds`` is ready to be written to then a non-zero ## value will be returned specifying the count of the sockets which can be ## written to. The sockets which **cannot** be written to will also be removed @@ -1022,7 +1033,7 @@ proc selectWrite*(writefds: var seq[TSocket], ## ## ``timeout`` is specified in miliseconds and ``-1`` can be specified for ## an unlimited time. - var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) + var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) var wr: TFdSet var m = 0 @@ -1035,12 +1046,12 @@ proc selectWrite*(writefds: var seq[TSocket], pruneSocketSet(writefds, (wr)) -proc select*(readfds: var seq[TSocket], timeout = 500): int = +proc select*(readfds: var seq[Socket], timeout = 500): int = ## variant of select with a read list only let buffersFilled = checkBuffer(readfds) if buffersFilled > 0: return buffersFilled - var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) + var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) var rd: TFdSet var m = 0 @@ -1053,7 +1064,7 @@ proc select*(readfds: var seq[TSocket], timeout = 500): int = pruneSocketSet(readfds, (rd)) -proc readIntoBuf(socket: TSocket, flags: int32): int = +proc readIntoBuf(socket: Socket, flags: int32): int = result = 0 when defined(ssl): if socket.isSSL: @@ -1077,7 +1088,7 @@ template retRead(flags, readBytes: int) {.dirty.} = else: return res -proc recv*(socket: TSocket, data: pointer, size: int): int {.tags: [FReadIO].} = +proc recv*(socket: Socket, data: pointer, size: int): int {.tags: [ReadIOEffect].} = ## Receives data from a socket. ## ## **Note**: This is a low-level function, you may be interested in the higher @@ -1117,8 +1128,8 @@ proc recv*(socket: TSocket, data: pointer, size: int): int {.tags: [FReadIO].} = else: result = recv(socket.fd, data, size.cint, 0'i32) -proc waitFor(socket: TSocket, waited: var float, timeout, size: int, - funcName: string): int {.tags: [FTime].} = +proc waitFor(socket: Socket, waited: var float, timeout, size: int, + funcName: string): int {.tags: [TimeEffect].} = ## determines the amount of characters that can be read. Result will never ## be larger than ``size``. For unbuffered sockets this will be ``1``. ## For buffered sockets it can be as big as ``BufferSize``. @@ -1133,7 +1144,7 @@ proc waitFor(socket: TSocket, waited: var float, timeout, size: int, result = min(result, size) else: if timeout - int(waited * 1000.0) < 1: - raise newException(ETimeout, "Call to '" & funcName & "' timed out.") + raise newException(TimeoutError, "Call to '" & funcName & "' timed out.") when defined(ssl): if socket.isSSL: @@ -1147,13 +1158,13 @@ proc waitFor(socket: TSocket, waited: var float, timeout, size: int, var s = @[socket] var startTime = epochTime() let selRet = select(s, timeout - int(waited * 1000.0)) - if selRet < 0: osError(osLastError()) + if selRet < 0: raiseOSError(osLastError()) if selRet != 1: - raise newException(ETimeout, "Call to '" & funcName & "' timed out.") + raise newException(TimeoutError, "Call to '" & funcName & "' timed out.") waited += (epochTime() - startTime) -proc recv*(socket: TSocket, data: pointer, size: int, timeout: int): int {. - tags: [FReadIO, FTime].} = +proc recv*(socket: Socket, data: pointer, size: int, timeout: int): int {. + tags: [ReadIOEffect, TimeEffect].} = ## overload with a ``timeout`` parameter in miliseconds. var waited = 0.0 # number of seconds already waited @@ -1169,7 +1180,7 @@ proc recv*(socket: TSocket, data: pointer, size: int, timeout: int): int {. result = read -proc recv*(socket: TSocket, data: var string, size: int, timeout = -1): int = +proc recv*(socket: Socket, data: var string, size: int, timeout = -1): int = ## Higher-level version of ``recv``. ## ## When 0 is returned the socket's connection has been closed. @@ -1185,10 +1196,10 @@ proc recv*(socket: TSocket, data: var string, size: int, timeout = -1): int = result = recv(socket, cstring(data), size, timeout) if result < 0: data.setLen(0) - socket.socketError(result) + socket.raiseSocketError(result) data.setLen(result) -proc recvAsync*(socket: TSocket, data: var string, size: int): int = +proc recvAsync*(socket: Socket, data: var string, size: int): int = ## Async version of ``recv``. ## ## When socket is non-blocking and no data is available on the socket, @@ -1199,11 +1210,11 @@ proc recvAsync*(socket: TSocket, data: var string, size: int): int = result = recv(socket, cstring(data), size) if result < 0: data.setLen(0) - socket.socketError(async = true) + socket.raiseSocketError(async = true) result = -1 data.setLen(result) -proc peekChar(socket: TSocket, c: var char): int {.tags: [FReadIO].} = +proc peekChar(socket: Socket, c: var char): int {.tags: [ReadIOEffect].} = if socket.isBuffered: result = 1 if socket.bufLen == 0 or socket.currPos > socket.bufLen-1: @@ -1223,8 +1234,8 @@ proc peekChar(socket: TSocket, c: var char): int {.tags: [FReadIO].} = return result = recv(socket.fd, addr(c), 1, MSG_PEEK) -proc recvLine*(socket: TSocket, line: var TaintedString, timeout = -1): bool {. - tags: [FReadIO, FTime], deprecated.} = +proc recvLine*(socket: Socket, line: var TaintedString, timeout = -1): bool {. + tags: [ReadIOEffect, TimeEffect], deprecated.} = ## Receive a line of data from ``socket``. ## ## If a full line is received ``\r\L`` is not @@ -1270,8 +1281,8 @@ proc recvLine*(socket: TSocket, line: var TaintedString, timeout = -1): bool {. return true add(line.string, c) -proc readLine*(socket: TSocket, line: var TaintedString, timeout = -1) {. - tags: [FReadIO, FTime].} = +proc readLine*(socket: Socket, line: var TaintedString, timeout = -1) {. + tags: [ReadIOEffect, TimeEffect].} = ## Reads a line of data from ``socket``. ## ## If a full line is read ``\r\L`` is not @@ -1296,14 +1307,14 @@ proc readLine*(socket: TSocket, line: var TaintedString, timeout = -1) {. var c: char discard waitFor(socket, waited, timeout, 1, "readLine") var n = recv(socket, addr(c), 1) - if n < 0: socket.socketError() + if n < 0: socket.raiseSocketError() elif n == 0: return if c == '\r': discard waitFor(socket, waited, timeout, 1, "readLine") n = peekChar(socket, c) if n > 0 and c == '\L': discard recv(socket, addr(c), 1) - elif n <= 0: socket.socketError() + elif n <= 0: socket.raiseSocketError() addNLIfEmpty() return elif c == '\L': @@ -1311,8 +1322,8 @@ proc readLine*(socket: TSocket, line: var TaintedString, timeout = -1) {. return add(line.string, c) -proc recvLineAsync*(socket: TSocket, - line: var TaintedString): TRecvLineResult {.tags: [FReadIO], deprecated.} = +proc recvLineAsync*(socket: Socket, + line: var TaintedString): RecvLineResult {.tags: [ReadIOEffect], deprecated.} = ## Similar to ``recvLine`` but designed for non-blocking sockets. ## ## The values of the returned enum should be pretty self explanatory: @@ -1343,8 +1354,8 @@ proc recvLineAsync*(socket: TSocket, elif c == '\L': return RecvFullLine add(line.string, c) -proc readLineAsync*(socket: TSocket, - line: var TaintedString): TReadLineResult {.tags: [FReadIO].} = +proc readLineAsync*(socket: Socket, + line: var TaintedString): ReadLineResult {.tags: [ReadIOEffect].} = ## Similar to ``recvLine`` but designed for non-blocking sockets. ## ## The values of the returned enum should be pretty self explanatory: @@ -1357,7 +1368,7 @@ proc readLineAsync*(socket: TSocket, setLen(line.string, 0) template errorOrNone = - socket.socketError(async = true) + socket.raiseSocketError(async = true) return ReadNone while true: @@ -1378,7 +1389,7 @@ proc readLineAsync*(socket: TSocket, elif c == '\L': return ReadFullLine add(line.string, c) -proc recv*(socket: TSocket): TaintedString {.tags: [FReadIO], deprecated.} = +proc recv*(socket: Socket): TaintedString {.tags: [ReadIOEffect], deprecated.} = ## receives all the available data from the socket. ## Socket errors will result in an ``EOS`` error. ## If socket is not a connectionless socket and socket is not connected @@ -1390,7 +1401,7 @@ proc recv*(socket: TSocket): TaintedString {.tags: [FReadIO], deprecated.} = var pos = 0 while true: var bytesRead = recv(socket, addr(string(result)[pos]), bufSize-1) - if bytesRead == -1: osError(osLastError()) + if bytesRead == -1: raiseOSError(osLastError()) setLen(result.string, pos + bytesRead) if bytesRead != bufSize-1: break # increase capacity: @@ -1402,7 +1413,7 @@ proc recv*(socket: TSocket): TaintedString {.tags: [FReadIO], deprecated.} = while true: var bytesRead = recv(socket, cstring(buf), bufSize-1) # Error - if bytesRead == -1: OSError(OSLastError()) + if bytesRead == -1: OSError(osLastError()) buf[bytesRead] = '\0' # might not be necessary setLen(buf, bytesRead) @@ -1410,8 +1421,8 @@ proc recv*(socket: TSocket): TaintedString {.tags: [FReadIO], deprecated.} = if bytesRead != bufSize-1: break {.push warning[deprecated]: off.} -proc recvTimeout*(socket: TSocket, timeout: int): TaintedString {. - tags: [FReadIO], deprecated.} = +proc recvTimeout*(socket: Socket, timeout: int): TaintedString {. + tags: [ReadIOEffect], deprecated.} = ## overloaded variant to support a ``timeout`` parameter, the ``timeout`` ## parameter specifies the amount of miliseconds to wait for data on the ## socket. @@ -1420,13 +1431,13 @@ proc recvTimeout*(socket: TSocket, timeout: int): TaintedString {. if socket.bufLen == 0: var s = @[socket] if s.select(timeout) != 1: - raise newException(ETimeout, "Call to recv() timed out.") + raise newException(TimeoutError, "Call to recv() timed out.") return socket.recv {.pop.} -proc recvAsync*(socket: TSocket, s: var TaintedString): bool {. - tags: [FReadIO], deprecated.} = +proc recvAsync*(socket: Socket, s: var TaintedString): bool {. + tags: [ReadIOEffect], deprecated.} = ## receives all the data from a non-blocking socket. If socket is non-blocking ## and there are no messages available, `False` will be returned. ## Other socket errors will result in an ``EOS`` error. @@ -1447,27 +1458,27 @@ proc recvAsync*(socket: TSocket, s: var TaintedString): bool {. var ret = SSLGetError(socket.sslHandle, bytesRead.cint) case ret of SSL_ERROR_ZERO_RETURN: - SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") + raiseSslError("TLS/SSL connection failed to initiate, socket closed prematurely.") of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: - SSLError("Unexpected error occured.") # This should just not happen. + raiseSslError("Unexpected error occured.") # This should just not happen. of SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_READ: return false of SSL_ERROR_WANT_X509_LOOKUP: - SSLError("Function for x509 lookup has been called.") + raiseSslError("Function for x509 lookup has been called.") of SSL_ERROR_SYSCALL, SSL_ERROR_SSL: - SSLError() - else: SSLError("Unknown Error") + raiseSslError() + else: raiseSslError("Unknown Error") if bytesRead == -1 and not (when defined(ssl): socket.isSSL else: false): let err = osLastError() when defined(windows): if err.int32 == WSAEWOULDBLOCK: return false - else: osError(err) + else: raiseOSError(err) else: if err.int32 == EAGAIN or err.int32 == EWOULDBLOCK: return false - else: osError(err) + else: raiseOSError(err) setLen(s.string, pos + bytesRead) if bytesRead != bufSize-1: break @@ -1476,9 +1487,9 @@ proc recvAsync*(socket: TSocket, s: var TaintedString): bool {. inc(pos, bytesRead) result = true -proc recvFrom*(socket: TSocket, data: var string, length: int, - address: var string, port: var TPort, flags = 0'i32): int {. - tags: [FReadIO].} = +proc recvFrom*(socket: Socket, data: var string, length: int, + address: var string, port: var Port, flags = 0'i32): int {. + tags: [ReadIOEffect].} = ## Receives data from ``socket``. This function should normally be used with ## connection-less sockets (UDP sockets). ## @@ -1492,19 +1503,19 @@ proc recvFrom*(socket: TSocket, data: var string, length: int, # TODO: Buffered sockets data.setLen(length) - var sockAddress: Tsockaddr_in - var addrLen = sizeof(sockAddress).TSocklen + var sockAddress: Sockaddr_in + var addrLen = sizeof(sockAddress).SockLen result = recvfrom(socket.fd, cstring(data), length.cint, flags.cint, - cast[ptr TSockAddr](addr(sockAddress)), addr(addrLen)) + cast[ptr SockAddr](addr(sockAddress)), addr(addrLen)) if result != -1: data.setLen(result) address = $inet_ntoa(sockAddress.sin_addr) - port = ntohs(sockAddress.sin_port).TPort + port = ntohs(sockAddress.sin_port).Port -proc recvFromAsync*(socket: TSocket, data: var string, length: int, - address: var string, port: var TPort, - flags = 0'i32): bool {.tags: [FReadIO].} = +proc recvFromAsync*(socket: Socket, data: var string, length: int, + address: var string, port: var Port, + flags = 0'i32): bool {.tags: [ReadIOEffect].} = ## Variant of ``recvFrom`` for non-blocking sockets. Unlike ``recvFrom``, ## this function will raise an EOS error whenever a socket error occurs. ## @@ -1516,13 +1527,13 @@ proc recvFromAsync*(socket: TSocket, data: var string, length: int, when defined(windows): if err.int32 == WSAEWOULDBLOCK: return false - else: osError(err) + else: raiseOSError(err) else: if err.int32 == EAGAIN or err.int32 == EWOULDBLOCK: return false - else: osError(err) + else: raiseOSError(err) -proc skip*(socket: TSocket) {.tags: [FReadIO], deprecated.} = +proc skip*(socket: Socket) {.tags: [ReadIOEffect], deprecated.} = ## skips all the data that is pending for the socket ## ## **Deprecated since version 0.9.2**: This function is not safe for use. @@ -1531,7 +1542,7 @@ proc skip*(socket: TSocket) {.tags: [FReadIO], deprecated.} = while recv(socket, buf, bufSize) == bufSize: discard dealloc(buf) -proc skip*(socket: TSocket, size: int, timeout = -1) = +proc skip*(socket: Socket, size: int, timeout = -1) = ## Skips ``size`` amount of bytes. ## ## An optional timeout can be specified in miliseconds, if skipping the @@ -1546,8 +1557,8 @@ proc skip*(socket: TSocket, size: int, timeout = -1) = bytesSkipped += recv(socket, dummy, avail) dealloc(dummy) -proc send*(socket: TSocket, data: pointer, size: int): int {. - tags: [FWriteIO].} = +proc send*(socket: Socket, data: pointer, size: int): int {. + tags: [WriteIOEffect].} = ## sends data to a socket. when defined(ssl): if socket.isSSL: @@ -1560,22 +1571,22 @@ proc send*(socket: TSocket, data: pointer, size: int): int {. const MSG_NOSIGNAL = 0 result = send(socket.fd, data, size, int32(MSG_NOSIGNAL)) -proc send*(socket: TSocket, data: string) {.tags: [FWriteIO].} = +proc send*(socket: Socket, data: string) {.tags: [WriteIOEffect].} = ## sends data to a socket. if socket.nonblocking: - raise newException(EInvalidValue, "This function cannot be used on non-blocking sockets.") + raise newException(ValueError, "This function cannot be used on non-blocking sockets.") let sent = send(socket, cstring(data), data.len) if sent < 0: when defined(ssl): if socket.isSSL: - SSLError() + raiseSslError() - osError(osLastError()) + raiseOSError(osLastError()) if sent != data.len: - raise newException(EOS, "Could not send all data.") + raise newException(OSError, "Could not send all data.") -proc sendAsync*(socket: TSocket, data: string): int {.tags: [FWriteIO].} = +proc sendAsync*(socket: Socket, data: string): int {.tags: [WriteIOEffect].} = ## sends data to a non-blocking socket. ## Returns ``0`` if no data could be sent, if data has been sent ## returns the amount of bytes of ``data`` that was successfully sent. This @@ -1590,16 +1601,16 @@ proc sendAsync*(socket: TSocket, data: string): int {.tags: [FWriteIO].} = let ret = SSLGetError(socket.sslHandle, result.cint) case ret of SSL_ERROR_ZERO_RETURN: - SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") + raiseSslError("TLS/SSL connection failed to initiate, socket closed prematurely.") of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: - SSLError("Unexpected error occured.") # This should just not happen. + raiseSslError("Unexpected error occured.") # This should just not happen. of SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_READ: return 0 of SSL_ERROR_WANT_X509_LOOKUP: - SSLError("Function for x509 lookup has been called.") + raiseSslError("Function for x509 lookup has been called.") of SSL_ERROR_SYSCALL, SSL_ERROR_SSL: - SSLError() - else: SSLError("Unknown Error") + raiseSslError() + else: raiseSslError("Unknown Error") else: return if result == -1: @@ -1607,28 +1618,28 @@ proc sendAsync*(socket: TSocket, data: string): int {.tags: [FWriteIO].} = when defined(windows): if err.int32 == WSAEINPROGRESS: return 0 - else: osError(err) + else: raiseOSError(err) else: if err.int32 == EAGAIN or err.int32 == EWOULDBLOCK: return 0 - else: osError(err) + else: raiseOSError(err) -proc trySend*(socket: TSocket, data: string): bool {.tags: [FWriteIO].} = +proc trySend*(socket: Socket, data: string): bool {.tags: [WriteIOEffect].} = ## safe alternative to ``send``. Does not raise an EOS when an error occurs, ## and instead returns ``false`` on failure. result = send(socket, cstring(data), data.len) == data.len -proc sendTo*(socket: TSocket, address: string, port: TPort, data: pointer, - size: int, af: TDomain = AF_INET, flags = 0'i32): int {. - tags: [FWriteIO].} = +proc sendTo*(socket: Socket, address: string, port: Port, data: pointer, + size: int, af: Domain = AF_INET, flags = 0'i32): int {. + tags: [WriteIOEffect].} = ## low-level sendTo proc. This proc sends ``data`` to the specified ``address``, ## which may be an IP address or a hostname, if a hostname is specified ## this function will try each IP of that hostname. ## ## **Note:** This proc is not available for SSL sockets. - var hints: Taddrinfo - var aiList: ptr Taddrinfo = nil + var hints: AddrInfo + var aiList: ptr AddrInfo = nil hints.ai_family = toInt(af) hints.ai_socktype = toInt(SOCK_STREAM) hints.ai_protocol = toInt(IPPROTO_TCP) @@ -1639,7 +1650,7 @@ proc sendTo*(socket: TSocket, address: string, port: TPort, data: pointer, var it = aiList while it != nil: result = sendto(socket.fd, data, size.cint, flags.cint, it.ai_addr, - it.ai_addrlen.TSocklen) + it.ai_addrlen.SockLen) if result != -1'i32: success = true break @@ -1647,8 +1658,8 @@ proc sendTo*(socket: TSocket, address: string, port: TPort, data: pointer, freeaddrinfo(aiList) -proc sendTo*(socket: TSocket, address: string, port: TPort, - data: string): int {.tags: [FWriteIO].} = +proc sendTo*(socket: Socket, address: string, port: Port, + data: string): int {.tags: [WriteIOEffect].} = ## Friendlier version of the low-level ``sendTo``. result = socket.sendTo(address, port, cstring(data), data.len) @@ -1659,33 +1670,33 @@ when defined(Windows): FIONBIO = IOC_IN.int32 or ((sizeof(int32) and IOCPARM_MASK) shl 16) or (102 shl 8) or 126 - proc ioctlsocket(s: TSocketHandle, cmd: clong, + proc ioctlsocket(s: SocketHandle, cmd: clong, argptr: ptr clong): cint {. stdcall, importc:"ioctlsocket", dynlib: "ws2_32.dll".} -proc setBlocking(s: TSocket, blocking: bool) = +proc setBlocking(s: Socket, blocking: bool) = when defined(Windows): var mode = clong(ord(not blocking)) # 1 for non-blocking, 0 for blocking if ioctlsocket(s.fd, FIONBIO, addr(mode)) == -1: - osError(osLastError()) + raiseOSError(osLastError()) else: # BSD sockets var x: int = fcntl(s.fd, F_GETFL, 0) if x == -1: - osError(osLastError()) + raiseOSError(osLastError()) else: var mode = if blocking: x and not O_NONBLOCK else: x or O_NONBLOCK if fcntl(s.fd, F_SETFL, mode) == -1: - osError(osLastError()) + raiseOSError(osLastError()) s.nonblocking = not blocking discard """ proc setReuseAddr*(s: TSocket) = var blah: int = 1 var mode = SO_REUSEADDR if setsockopt(s.fd, SOL_SOCKET, mode, addr blah, TSOcklen(sizeof(int))) == -1: - OSError(OSLastError()) """ + raiseOSError(osLastError()) """ -proc connect*(socket: TSocket, address: string, port = TPort(0), timeout: int, - af: TDomain = AF_INET) {.tags: [FReadIO, FWriteIO].} = +proc connect*(socket: Socket, address: string, port = Port(0), timeout: int, + af: Domain = AF_INET) {.tags: [ReadIOEffect, WriteIOEffect].} = ## Connects to server as specified by ``address`` on port specified by ``port``. ## ## The ``timeout`` paremeter specifies the time in miliseconds to allow for @@ -1694,9 +1705,9 @@ proc connect*(socket: TSocket, address: string, port = TPort(0), timeout: int, socket.setBlocking(false) socket.connectAsync(address, port, af) - var s: seq[TSocket] = @[socket] + var s: seq[Socket] = @[socket] if selectWrite(s, timeout) != 1: - raise newException(ETimeout, "Call to 'connect' timed out.") + raise newException(TimeoutError, "Call to 'connect' timed out.") else: when defined(ssl): if socket.isSSL: @@ -1704,17 +1715,17 @@ proc connect*(socket: TSocket, address: string, port = TPort(0), timeout: int, doAssert socket.handshake() socket.setBlocking(originalStatus) -proc isSSL*(socket: TSocket): bool = return socket.isSSL +proc isSSL*(socket: Socket): bool = return socket.isSSL ## Determines whether ``socket`` is a SSL socket. -proc getFD*(socket: TSocket): TSocketHandle = return socket.fd +proc getFD*(socket: Socket): SocketHandle = return socket.fd ## Returns the socket's file descriptor -proc isBlocking*(socket: TSocket): bool = not socket.nonblocking +proc isBlocking*(socket: Socket): bool = not socket.nonblocking ## Determines whether ``socket`` is blocking. when defined(Windows): - var wsa: TWSAData - if wsaStartup(0x0101'i16, addr wsa) != 0: osError(osLastError()) + var wsa: WSAData + if wsaStartup(0x0101'i16, addr wsa) != 0: raiseOSError(osLastError()) diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim index 63622a26c..31aa7497d 100644 --- a/lib/pure/streams.nim +++ b/lib/pure/streams.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -8,158 +8,160 @@ # ## This module provides a stream interface and two implementations thereof: -## the `PFileStream` and the `PStringStream` which implement the stream -## interface for Nimrod file objects (`TFile`) and strings. Other modules +## the `FileStream` and the `StringStream` which implement the stream +## interface for Nim file objects (`File`) and strings. Other modules ## may provide other implementations for this standard stream interface. include "system/inclrtl" -proc newEIO(msg: string): ref EIO = +proc newEIO(msg: string): ref IOError = new(result) result.msg = msg type - PStream* = ref TStream - TStream* = object of TObject ## Stream interface that supports - ## writing or reading. Note that these fields - ## here shouldn't be used directly. They are - ## accessible so that a stream implementation - ## can override them. - closeImpl*: proc (s: PStream) {.nimcall, tags: [], gcsafe.} - atEndImpl*: proc (s: PStream): bool {.nimcall, tags: [], gcsafe.} - setPositionImpl*: proc (s: PStream, pos: int) {.nimcall, tags: [], gcsafe.} - getPositionImpl*: proc (s: PStream): int {.nimcall, tags: [], gcsafe.} - readDataImpl*: proc (s: PStream, buffer: pointer, - bufLen: int): int {.nimcall, tags: [FReadIO], gcsafe.} - writeDataImpl*: proc (s: PStream, buffer: pointer, bufLen: int) {.nimcall, - tags: [FWriteIO], gcsafe.} - flushImpl*: proc (s: PStream) {.nimcall, tags: [FWriteIO], gcsafe.} - -proc flush*(s: PStream) = + Stream* = ref StreamObj + StreamObj* = object of RootObj ## Stream interface that supports + ## writing or reading. Note that these fields + ## here shouldn't be used directly. They are + ## accessible so that a stream implementation + ## can override them. + closeImpl*: proc (s: Stream) {.nimcall, tags: [], gcsafe.} + atEndImpl*: proc (s: Stream): bool {.nimcall, tags: [], gcsafe.} + setPositionImpl*: proc (s: Stream, pos: int) {.nimcall, tags: [], gcsafe.} + getPositionImpl*: proc (s: Stream): int {.nimcall, tags: [], gcsafe.} + readDataImpl*: proc (s: Stream, buffer: pointer, + bufLen: int): int {.nimcall, tags: [ReadIOEffect], gcsafe.} + writeDataImpl*: proc (s: Stream, buffer: pointer, bufLen: int) {.nimcall, + tags: [WriteIOEffect], gcsafe.} + flushImpl*: proc (s: Stream) {.nimcall, tags: [WriteIOEffect], gcsafe.} + +{.deprecated: [PStream: Stream, TStream: StreamObj].} + +proc flush*(s: Stream) = ## flushes the buffers that the stream `s` might use. if not isNil(s.flushImpl): s.flushImpl(s) -proc close*(s: PStream) = +proc close*(s: Stream) = ## closes the stream `s`. if not isNil(s.closeImpl): s.closeImpl(s) -proc close*(s, unused: PStream) {.deprecated.} = +proc close*(s, unused: Stream) {.deprecated.} = ## closes the stream `s`. s.closeImpl(s) -proc atEnd*(s: PStream): bool = +proc atEnd*(s: Stream): bool = ## checks if more data can be read from `f`. Returns true if all data has ## been read. result = s.atEndImpl(s) -proc atEnd*(s, unused: PStream): bool {.deprecated.} = +proc atEnd*(s, unused: Stream): bool {.deprecated.} = ## checks if more data can be read from `f`. Returns true if all data has ## been read. result = s.atEndImpl(s) -proc setPosition*(s: PStream, pos: int) = +proc setPosition*(s: Stream, pos: int) = ## sets the position `pos` of the stream `s`. s.setPositionImpl(s, pos) -proc setPosition*(s, unused: PStream, pos: int) {.deprecated.} = +proc setPosition*(s, unused: Stream, pos: int) {.deprecated.} = ## sets the position `pos` of the stream `s`. s.setPositionImpl(s, pos) -proc getPosition*(s: PStream): int = +proc getPosition*(s: Stream): int = ## retrieves the current position in the stream `s`. result = s.getPositionImpl(s) -proc getPosition*(s, unused: PStream): int {.deprecated.} = +proc getPosition*(s, unused: Stream): int {.deprecated.} = ## retrieves the current position in the stream `s`. result = s.getPositionImpl(s) -proc readData*(s: PStream, buffer: pointer, bufLen: int): int = +proc readData*(s: Stream, buffer: pointer, bufLen: int): int = ## low level proc that reads data into an untyped `buffer` of `bufLen` size. result = s.readDataImpl(s, buffer, bufLen) -proc readData*(s, unused: PStream, buffer: pointer, +proc readData*(s, unused: Stream, buffer: pointer, bufLen: int): int {.deprecated.} = ## low level proc that reads data into an untyped `buffer` of `bufLen` size. result = s.readDataImpl(s, buffer, bufLen) -proc writeData*(s: PStream, buffer: pointer, bufLen: int) = +proc writeData*(s: Stream, buffer: pointer, bufLen: int) = ## low level proc that writes an untyped `buffer` of `bufLen` size ## to the stream `s`. s.writeDataImpl(s, buffer, bufLen) -proc writeData*(s, unused: PStream, buffer: pointer, +proc writeData*(s, unused: Stream, buffer: pointer, bufLen: int) {.deprecated.} = ## low level proc that writes an untyped `buffer` of `bufLen` size ## to the stream `s`. s.writeDataImpl(s, buffer, bufLen) -proc write*[T](s: PStream, x: T) = +proc write*[T](s: Stream, x: T) = ## generic write procedure. Writes `x` to the stream `s`. Implementation: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## ## s.writeData(s, addr(x), sizeof(x)) var y: T shallowCopy(y, x) writeData(s, addr(y), sizeof(y)) -proc write*(s: PStream, x: string) = +proc write*(s: Stream, x: string) = ## writes the string `x` to the the stream `s`. No length field or ## terminating zero is written. writeData(s, cstring(x), x.len) -proc writeln*(s: PStream, args: varargs[string, `$`]) = +proc writeln*(s: Stream, args: varargs[string, `$`]) = ## writes one or more strings to the the stream `s` followed ## by a new line. No length field or terminating zero is written. for str in args: write(s, str) write(s, "\n") -proc read[T](s: PStream, result: var T) = +proc read[T](s: Stream, result: var T) = ## generic read procedure. Reads `result` from the stream `s`. if readData(s, addr(result), sizeof(T)) != sizeof(T): raise newEIO("cannot read from stream") -proc readChar*(s: PStream): char = +proc readChar*(s: Stream): char = ## reads a char from the stream `s`. Raises `EIO` if an error occured. ## Returns '\0' as an EOF marker. if readData(s, addr(result), sizeof(result)) != 1: result = '\0' -proc readBool*(s: PStream): bool = +proc readBool*(s: Stream): bool = ## reads a bool from the stream `s`. Raises `EIO` if an error occured. read(s, result) -proc readInt8*(s: PStream): int8 = +proc readInt8*(s: Stream): int8 = ## reads an int8 from the stream `s`. Raises `EIO` if an error occured. read(s, result) -proc readInt16*(s: PStream): int16 = +proc readInt16*(s: Stream): int16 = ## reads an int16 from the stream `s`. Raises `EIO` if an error occured. read(s, result) -proc readInt32*(s: PStream): int32 = +proc readInt32*(s: Stream): int32 = ## reads an int32 from the stream `s`. Raises `EIO` if an error occured. read(s, result) -proc readInt64*(s: PStream): int64 = +proc readInt64*(s: Stream): int64 = ## reads an int64 from the stream `s`. Raises `EIO` if an error occured. read(s, result) -proc readFloat32*(s: PStream): float32 = +proc readFloat32*(s: Stream): float32 = ## reads a float32 from the stream `s`. Raises `EIO` if an error occured. read(s, result) -proc readFloat64*(s: PStream): float64 = +proc readFloat64*(s: Stream): float64 = ## reads a float64 from the stream `s`. Raises `EIO` if an error occured. read(s, result) -proc readStr*(s: PStream, length: int): TaintedString = +proc readStr*(s: Stream, length: int): TaintedString = ## reads a string of length `length` from the stream `s`. Raises `EIO` if ## an error occured. result = newString(length).TaintedString var L = readData(s, addr(string(result)[0]), length) if L != length: setLen(result.string, L) -proc readLine*(s: PStream, line: var TaintedString): bool = +proc readLine*(s: Stream, line: var TaintedString): bool = ## reads a line of text from the stream `s` into `line`. `line` must not be ## ``nil``! May throw an IO exception. ## A line of text may be delimited by ``CR``, ``LF`` or @@ -179,7 +181,7 @@ proc readLine*(s: PStream, line: var TaintedString): bool = line.string.add(c) result = true -proc readLine*(s: PStream): TaintedString = +proc readLine*(s: Stream): TaintedString = ## Reads a line from a stream `s`. Note: This is not very efficient. Raises ## `EIO` if an error occured. result = TaintedString"" @@ -194,42 +196,44 @@ proc readLine*(s: PStream): TaintedString = result.string.add(c) type - PStringStream* = ref TStringStream ## a stream that encapsulates a string - TStringStream* = object of TStream + StringStream* = ref StringStreamObj ## a stream that encapsulates a string + StringStreamObj* = object of StreamObj data*: string pos: int - -proc ssAtEnd(s: PStream): bool = - var s = PStringStream(s) + +{.deprecated: [PStringStream: StringStream, TStringStream: StringStreamObj].} + +proc ssAtEnd(s: Stream): bool = + var s = StringStream(s) return s.pos >= s.data.len -proc ssSetPosition(s: PStream, pos: int) = - var s = PStringStream(s) +proc ssSetPosition(s: Stream, pos: int) = + var s = StringStream(s) s.pos = clamp(pos, 0, s.data.high) -proc ssGetPosition(s: PStream): int = - var s = PStringStream(s) +proc ssGetPosition(s: Stream): int = + var s = StringStream(s) return s.pos -proc ssReadData(s: PStream, buffer: pointer, bufLen: int): int = - var s = PStringStream(s) +proc ssReadData(s: Stream, buffer: pointer, bufLen: int): int = + var s = StringStream(s) result = min(bufLen, s.data.len - s.pos) if result > 0: copyMem(buffer, addr(s.data[s.pos]), result) inc(s.pos, result) -proc ssWriteData(s: PStream, buffer: pointer, bufLen: int) = - var s = PStringStream(s) +proc ssWriteData(s: Stream, buffer: pointer, bufLen: int) = + var s = StringStream(s) if bufLen > 0: setLen(s.data, s.data.len + bufLen) copyMem(addr(s.data[s.pos]), buffer, bufLen) inc(s.pos, bufLen) -proc ssClose(s: PStream) = - var s = PStringStream(s) +proc ssClose(s: Stream) = + var s = StringStream(s) s.data = nil -proc newStringStream*(s: string = ""): PStringStream = +proc newStringStream*(s: string = ""): StringStream = ## creates a new stream from the string `s`. new(result) result.data = s @@ -244,27 +248,28 @@ proc newStringStream*(s: string = ""): PStringStream = when not defined(js): type - PFileStream* = ref TFileStream ## a stream that encapsulates a `TFile` - TFileStream* = object of TStream - f: TFile - - proc fsClose(s: PStream) = - if PFileStream(s).f != nil: - close(PFileStream(s).f) - PFileStream(s).f = nil - proc fsFlush(s: PStream) = flushFile(PFileStream(s).f) - proc fsAtEnd(s: PStream): bool = return endOfFile(PFileStream(s).f) - proc fsSetPosition(s: PStream, pos: int) = setFilePos(PFileStream(s).f, pos) - proc fsGetPosition(s: PStream): int = return int(getFilePos(PFileStream(s).f)) - - proc fsReadData(s: PStream, buffer: pointer, bufLen: int): int = - result = readBuffer(PFileStream(s).f, buffer, bufLen) - - proc fsWriteData(s: PStream, buffer: pointer, bufLen: int) = - if writeBuffer(PFileStream(s).f, buffer, bufLen) != bufLen: + FileStream* = ref FileStreamObj ## a stream that encapsulates a `TFile` + FileStreamObj* = object of Stream + f: File + {.deprecated: [PFileStream: FileStream, TFileStream: FileStreamObj].} + + proc fsClose(s: Stream) = + if FileStream(s).f != nil: + close(FileStream(s).f) + FileStream(s).f = nil + proc fsFlush(s: Stream) = flushFile(FileStream(s).f) + proc fsAtEnd(s: Stream): bool = return endOfFile(FileStream(s).f) + proc fsSetPosition(s: Stream, pos: int) = setFilePos(FileStream(s).f, pos) + proc fsGetPosition(s: Stream): int = return int(getFilePos(FileStream(s).f)) + + proc fsReadData(s: Stream, buffer: pointer, bufLen: int): int = + result = readBuffer(FileStream(s).f, buffer, bufLen) + + proc fsWriteData(s: Stream, buffer: pointer, bufLen: int) = + if writeBuffer(FileStream(s).f, buffer, bufLen) != bufLen: raise newEIO("cannot write to stream") - proc newFileStream*(f: TFile): PFileStream = + proc newFileStream*(f: File): FileStream = ## creates a new stream from the file `f`. new(result) result.f = f @@ -276,11 +281,11 @@ when not defined(js): result.writeDataImpl = fsWriteData result.flushImpl = fsFlush - proc newFileStream*(filename: string, mode: TFileMode): PFileStream = + proc newFileStream*(filename: string, mode: FileMode): FileStream = ## creates a new stream from the file named `filename` with the mode `mode`. ## If the file cannot be opened, nil is returned. See the `system ## <system.html>`_ module for a list of available TFileMode enums. - var f: TFile + var f: File if open(f, filename, mode): result = newFileStream(f) @@ -288,45 +293,47 @@ when true: discard else: type - TFileHandle* = cint ## Operating system file handle - PFileHandleStream* = ref TFileHandleStream - TFileHandleStream* = object of TStream - handle*: TFileHandle + FileHandleStream* = ref FileHandleStreamObj + FileHandleStreamObj* = object of Stream + handle*: FileHandle pos: int - proc newEOS(msg: string): ref EOS = + {.deprecated: [PFileHandleStream: FileHandleStream, + TFileHandleStream: FileHandleStreamObj].} + + proc newEOS(msg: string): ref OSError = new(result) result.msg = msg - proc hsGetPosition(s: PFileHandleStream): int = + proc hsGetPosition(s: FileHandleStream): int = return s.pos when defined(windows): # do not import windows as this increases compile times: - nil + discard else: import posix - proc hsSetPosition(s: PFileHandleStream, pos: int) = + proc hsSetPosition(s: FileHandleStream, pos: int) = discard lseek(s.handle, pos, SEEK_SET) - proc hsClose(s: PFileHandleStream) = discard close(s.handle) - proc hsAtEnd(s: PFileHandleStream): bool = + proc hsClose(s: FileHandleStream) = discard close(s.handle) + proc hsAtEnd(s: FileHandleStream): bool = var pos = hsGetPosition(s) var theEnd = lseek(s.handle, 0, SEEK_END) result = pos >= theEnd hsSetPosition(s, pos) # set position back - proc hsReadData(s: PFileHandleStream, buffer: pointer, bufLen: int): int = + proc hsReadData(s: FileHandleStream, buffer: pointer, bufLen: int): int = result = posix.read(s.handle, buffer, bufLen) inc(s.pos, result) - proc hsWriteData(s: PFileHandleStream, buffer: pointer, bufLen: int) = + proc hsWriteData(s: FileHandleStream, buffer: pointer, bufLen: int) = if posix.write(s.handle, buffer, bufLen) != bufLen: raise newEIO("cannot write to stream") inc(s.pos, bufLen) - proc newFileHandleStream*(handle: TFileHandle): PFileHandleStream = + proc newFileHandleStream*(handle: FileHandle): FileHandleStream = new(result) result.handle = handle result.pos = 0 @@ -338,9 +345,9 @@ else: result.writeData = hsWriteData proc newFileHandleStream*(filename: string, - mode: TFileMode): PFileHandleStream = - when defined(windows): - nil + mode: FileMode): FileHandleStream = + when defined(windows): + discard else: var flags: cint case mode diff --git a/lib/pure/strtabs.nim b/lib/pure/strtabs.nim index 7003acfcf..5b7149d8e 100644 --- a/lib/pure/strtabs.nim +++ b/lib/pure/strtabs.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -18,43 +18,46 @@ import include "system/inclrtl" type - TStringTableMode* = enum ## describes the tables operation mode + StringTableMode* = enum ## describes the tables operation mode modeCaseSensitive, ## the table is case sensitive modeCaseInsensitive, ## the table is case insensitive modeStyleInsensitive ## the table is style insensitive - TKeyValuePair = tuple[key, val: string] - TKeyValuePairSeq = seq[TKeyValuePair] - TStringTable* = object of TObject + KeyValuePair = tuple[key, val: string] + KeyValuePairSeq = seq[KeyValuePair] + StringTableObj* = object of RootObj counter: int - data: TKeyValuePairSeq - mode: TStringTableMode + data: KeyValuePairSeq + mode: StringTableMode - PStringTable* = ref TStringTable ## use this type to declare string tables + StringTableRef* = ref StringTableObj ## use this type to declare string tables -proc len*(t: PStringTable): int {.rtl, extern: "nst$1".} = +{.deprecated: [TStringTableMode: StringTableMode, + TStringTable: StringTableObj, PStringTable: StringTableRef].} + +proc len*(t: StringTableRef): int {.rtl, extern: "nst$1".} = ## returns the number of keys in `t`. result = t.counter -iterator pairs*(t: PStringTable): tuple[key, value: string] = +iterator pairs*(t: StringTableRef): tuple[key, value: string] = ## iterates over every (key, value) pair in the table `t`. for h in 0..high(t.data): if not isNil(t.data[h].key): yield (t.data[h].key, t.data[h].val) -iterator keys*(t: PStringTable): string = +iterator keys*(t: StringTableRef): string = ## iterates over every key in the table `t`. for h in 0..high(t.data): if not isNil(t.data[h].key): yield t.data[h].key -iterator values*(t: PStringTable): string = +iterator values*(t: StringTableRef): string = ## iterates over every value in the table `t`. for h in 0..high(t.data): if not isNil(t.data[h].key): yield t.data[h].val type - TFormatFlag* = enum ## flags for the `%` operator + FormatFlag* = enum ## flags for the `%` operator useEnvironment, ## use environment variable if the ``$key`` ## is not found in the table useEmpty, ## use the empty string as a default, thus it @@ -63,19 +66,21 @@ type useKey ## do not replace ``$key`` if it is not found ## in the table (or in the environment) +{.deprecated: [TFormatFlag: FormatFlag].} + # implementation const growthFactor = 2 startSize = 64 -proc myhash(t: PStringTable, key: string): THash = +proc myhash(t: StringTableRef, key: string): THash = case t.mode of modeCaseSensitive: result = hashes.hash(key) of modeCaseInsensitive: result = hashes.hashIgnoreCase(key) of modeStyleInsensitive: result = hashes.hashIgnoreStyle(key) -proc myCmp(t: PStringTable, a, b: string): bool = +proc myCmp(t: StringTableRef, a, b: string): bool = case t.mode of modeCaseSensitive: result = cmp(a, b) == 0 of modeCaseInsensitive: result = cmpIgnoreCase(a, b) == 0 @@ -88,7 +93,7 @@ proc mustRehash(length, counter: int): bool = proc nextTry(h, maxHash: THash): THash {.inline.} = result = ((5 * h) + 1) and maxHash -proc rawGet(t: PStringTable, key: string): int = +proc rawGet(t: StringTableRef, key: string): int = var h: THash = myhash(t, key) and high(t.data) # start with real hash value while not isNil(t.data[h].key): if myCmp(t, t.data[h].key, key): @@ -96,7 +101,7 @@ proc rawGet(t: PStringTable, key: string): int = h = nextTry(h, high(t.data)) result = - 1 -proc `[]`*(t: PStringTable, key: string): string {.rtl, extern: "nstGet".} = +proc `[]`*(t: StringTableRef, key: string): string {.rtl, extern: "nstGet".} = ## retrieves the value at ``t[key]``. If `key` is not in `t`, "" is returned ## and no exception is raised. One can check with ``hasKey`` whether the key ## exists. @@ -104,33 +109,33 @@ proc `[]`*(t: PStringTable, key: string): string {.rtl, extern: "nstGet".} = if index >= 0: result = t.data[index].val else: result = "" -proc mget*(t: PStringTable, key: string): var string {. +proc mget*(t: StringTableRef, key: string): var string {. rtl, extern: "nstTake".} = ## retrieves the location at ``t[key]``. If `key` is not in `t`, the ## ``EInvalidKey`` exception is raised. var index = rawGet(t, key) if index >= 0: result = t.data[index].val - else: raise newException(EInvalidKey, "key does not exist: " & key) + else: raise newException(KeyError, "key does not exist: " & key) -proc hasKey*(t: PStringTable, key: string): bool {.rtl, extern: "nst$1".} = +proc hasKey*(t: StringTableRef, key: string): bool {.rtl, extern: "nst$1".} = ## returns true iff `key` is in the table `t`. result = rawGet(t, key) >= 0 -proc rawInsert(t: PStringTable, data: var TKeyValuePairSeq, key, val: string) = +proc rawInsert(t: StringTableRef, data: var KeyValuePairSeq, key, val: string) = var h: THash = myhash(t, key) and high(data) while not isNil(data[h].key): h = nextTry(h, high(data)) data[h].key = key data[h].val = val -proc enlarge(t: PStringTable) = - var n: TKeyValuePairSeq +proc enlarge(t: StringTableRef) = + var n: KeyValuePairSeq newSeq(n, len(t.data) * growthFactor) for i in countup(0, high(t.data)): if not isNil(t.data[i].key): rawInsert(t, n, t.data[i].key, t.data[i].val) swap(t.data, n) -proc `[]=`*(t: PStringTable, key, val: string) {.rtl, extern: "nstPut".} = +proc `[]=`*(t: StringTableRef, key, val: string) {.rtl, extern: "nstPut".} = ## puts a (key, value)-pair into `t`. var index = rawGet(t, key) if index >= 0: @@ -141,12 +146,12 @@ proc `[]=`*(t: PStringTable, key, val: string) {.rtl, extern: "nstPut".} = inc(t.counter) proc raiseFormatException(s: string) = - var e: ref EInvalidValue + var e: ref ValueError new(e) e.msg = "format string: key not found: " & s raise e -proc getValue(t: PStringTable, flags: set[TFormatFlag], key: string): string = +proc getValue(t: StringTableRef, flags: set[FormatFlag], key: string): string = if hasKey(t, key): return t[key] # hm difficult: assume safety in taint mode here. XXX This is dangerous! if useEnvironment in flags: result = os.getEnv(key).string @@ -155,7 +160,7 @@ proc getValue(t: PStringTable, flags: set[TFormatFlag], key: string): string = if useKey in flags: result = '$' & key elif not (useEmpty in flags): raiseFormatException(key) -proc newStringTable*(mode: TStringTableMode): PStringTable {. +proc newStringTable*(mode: StringTableMode): StringTableRef {. rtl, extern: "nst$1".} = ## creates a new string table that is empty. new(result) @@ -164,7 +169,7 @@ proc newStringTable*(mode: TStringTableMode): PStringTable {. newSeq(result.data, startSize) proc newStringTable*(keyValuePairs: varargs[string], - mode: TStringTableMode): PStringTable {. + mode: StringTableMode): StringTableRef {. rtl, extern: "nst$1WithPairs".} = ## creates a new string table with given key value pairs. ## Example:: @@ -177,7 +182,7 @@ proc newStringTable*(keyValuePairs: varargs[string], inc(i, 2) proc newStringTable*(keyValuePairs: varargs[tuple[key, val: string]], - mode: TStringTableMode = modeCaseSensitive): PStringTable {. + mode: StringTableMode = modeCaseSensitive): StringTableRef {. rtl, extern: "nst$1WithTableConstr".} = ## creates a new string table with given key value pairs. ## Example:: @@ -186,7 +191,7 @@ proc newStringTable*(keyValuePairs: varargs[tuple[key, val: string]], result = newStringTable(mode) for key, val in items(keyValuePairs): result[key] = val -proc `%`*(f: string, t: PStringTable, flags: set[TFormatFlag] = {}): string {. +proc `%`*(f: string, t: StringTableRef, flags: set[FormatFlag] = {}): string {. rtl, extern: "nstFormat".} = ## The `%` operator for string tables. const @@ -216,7 +221,7 @@ proc `%`*(f: string, t: PStringTable, flags: set[TFormatFlag] = {}): string {. add(result, f[i]) inc(i) -proc `$`*(t: PStringTable): string {.rtl, extern: "nstDollar".} = +proc `$`*(t: StringTableRef): string {.rtl, extern: "nstDollar".} = ## The `$` operator for string tables. if t.len == 0: result = "{:}" diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 1d17de233..55a204b4c 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -23,7 +23,7 @@ import parseutils include "system/inclrtl" type - TCharSet* = set[char] # for compatibility with Nim + TCharSet* {.deprecated.} = set[char] # for compatibility with Nim const Whitespace* = {' ', '\t', '\v', '\r', '\l', '\f'} @@ -54,7 +54,7 @@ const ## make the `find() proc <#find,string,set[char],int>`_ find **invalid** ## characters in strings. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## let invalid = AllChars - Digits ## doAssert "01234".find(invalid) == -1 ## doAssert "01A34".find(invalid) == 2 @@ -117,7 +117,7 @@ proc normalize*(s: string): string {.noSideEffect, procvar, ## Normalizes the string `s`. ## ## That means to convert it to lower case and remove any '_'. This is needed - ## for Nimrod identifiers for example. + ## for Nim identifiers for example. result = newString(s.len) var j = 0 for i in 0..len(s) - 1: @@ -130,7 +130,7 @@ proc normalize*(s: string): string {.noSideEffect, procvar, if j != s.len: setLen(result, j) proc cmpIgnoreCase*(a, b: string): int {.noSideEffect, - rtl, extern: "nsuCmpIgnoreCase", procvar, operator: 4.} = + rtl, extern: "nsuCmpIgnoreCase", procvar.} = ## Compares two strings in a case insensitive manner. Returns: ## ## | 0 iff a == b @@ -148,7 +148,7 @@ proc cmpIgnoreCase*(a, b: string): int {.noSideEffect, # thus we compile without checks here proc cmpIgnoreStyle*(a, b: string): int {.noSideEffect, - rtl, extern: "nsuCmpIgnoreStyle", procvar, operator: 3.} = + rtl, extern: "nsuCmpIgnoreStyle", procvar.} = ## Compares two strings normalized (i.e. case and ## underscores do not matter). Returns: ## @@ -170,7 +170,7 @@ proc cmpIgnoreStyle*(a, b: string): int {.noSideEffect, {.pop.} proc strip*(s: string, leading = true, trailing = true): string {.noSideEffect, - rtl, extern: "nsuStrip", operator: 5.} = + rtl, extern: "nsuStrip".} = ## Strips whitespace from `s` and returns the resulting string. ## ## If `leading` is true, leading whitespace is stripped. @@ -205,7 +205,7 @@ iterator split*(s: string, seps: set[char] = Whitespace): string = ## a single split point and leading/trailing separators will be ignored. ## The following example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for word in split(" this is an example "): ## writeln(stdout, word) ## @@ -219,13 +219,13 @@ iterator split*(s: string, seps: set[char] = Whitespace): string = ## ## And the following code: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for word in split(";;this;is;an;;example;;;", {';'}): ## writeln(stdout, word) ## ## ...produces the same output as the first example. The code: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## let date = "2012-11-20T22:08:08.398990" ## let separators = {' ', '-', ':', 'T'} ## for number in split(date, separators): @@ -258,7 +258,7 @@ iterator split*(s: string, sep: char): string = ## characters, this proc will not coalesce groups of the ## separator, returning a string for each found character. The code: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for word in split(";;this;is;an;;example;;;", ';'): ## writeln(stdout, word) ## @@ -308,13 +308,13 @@ iterator splitLines*(s: string): string = ## ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for line in splitLines("\nthis\nis\nan\n\nexample\n"): ## writeln(stdout, line) ## ## Results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "" ## "this" ## "is" @@ -417,34 +417,34 @@ proc parseInt*(s: string): int {.noSideEffect, procvar, rtl, extern: "nsuParseInt".} = ## Parses a decimal integer value contained in `s`. ## - ## If `s` is not a valid integer, `EInvalidValue` is raised. + ## If `s` is not a valid integer, `ValueError` is raised. var L = parseutils.parseInt(s, result, 0) if L != s.len or L == 0: - raise newException(EInvalidValue, "invalid integer: " & s) + raise newException(ValueError, "invalid integer: " & s) proc parseBiggestInt*(s: string): BiggestInt {.noSideEffect, procvar, rtl, extern: "nsuParseBiggestInt".} = ## Parses a decimal integer value contained in `s`. ## - ## If `s` is not a valid integer, `EInvalidValue` is raised. + ## If `s` is not a valid integer, `ValueError` is raised. var L = parseutils.parseBiggestInt(s, result, 0) if L != s.len or L == 0: - raise newException(EInvalidValue, "invalid integer: " & s) + raise newException(ValueError, "invalid integer: " & s) proc parseFloat*(s: string): float {.noSideEffect, procvar, rtl, extern: "nsuParseFloat".} = ## Parses a decimal floating point value contained in `s`. If `s` is not - ## a valid floating point number, `EInvalidValue` is raised. ``NAN``, + ## a valid floating point number, `ValueError` is raised. ``NAN``, ## ``INF``, ``-INF`` are also supported (case insensitive comparison). var L = parseutils.parseFloat(s, result, 0) if L != s.len or L == 0: - raise newException(EInvalidValue, "invalid float: " & s) + raise newException(ValueError, "invalid float: " & s) proc parseHexInt*(s: string): int {.noSideEffect, procvar, rtl, extern: "nsuParseHexInt".} = ## Parses a hexadecimal integer value contained in `s`. ## - ## If `s` is not a valid integer, `EInvalidValue` is raised. `s` can have one + ## If `s` is not a valid integer, `ValueError` is raised. `s` can have one ## of the following optional prefixes: ``0x``, ``0X``, ``#``. Underscores ## within `s` are ignored. var i = 0 @@ -463,7 +463,7 @@ proc parseHexInt*(s: string): int {.noSideEffect, procvar, result = result shl 4 or (ord(s[i]) - ord('A') + 10) inc(i) of '\0': break - else: raise newException(EInvalidValue, "invalid integer: " & s) + else: raise newException(ValueError, "invalid integer: " & s) proc parseBool*(s: string): bool = ## Parses a value into a `bool`. @@ -471,21 +471,21 @@ proc parseBool*(s: string): bool = ## If ``s`` is one of the following values: ``y, yes, true, 1, on``, then ## returns `true`. If ``s`` is one of the following values: ``n, no, false, ## 0, off``, then returns `false`. If ``s`` is something else a - ## ``EInvalidValue`` exception is raised. + ## ``ValueError`` exception is raised. case normalize(s) of "y", "yes", "true", "1", "on": result = true of "n", "no", "false", "0", "off": result = false - else: raise newException(EInvalidValue, "cannot interpret as a bool: " & s) + else: raise newException(ValueError, "cannot interpret as a bool: " & s) proc parseEnum*[T: enum](s: string): T = ## Parses an enum ``T``. ## - ## Raises ``EInvalidValue`` for an invalid value in `s`. The comparison is + ## Raises ``ValueError`` for an invalid value in `s`. The comparison is ## done in a style insensitive way. for e in low(T)..high(T): if cmpIgnoreStyle(s, $e) == 0: return e - raise newException(EInvalidValue, "invalid enum value: " & s) + raise newException(ValueError, "invalid enum value: " & s) proc parseEnum*[T: enum](s: string, default: T): T = ## Parses an enum ``T``. @@ -502,7 +502,7 @@ proc repeatChar*(count: int, c: char = ' '): string {.noSideEffect, ## Returns a string of length `count` consisting only of ## the character `c`. You can use this proc to left align strings. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## let ## width = 15 ## text1 = "Hello user!" @@ -527,7 +527,7 @@ proc align*(s: string, count: int, padding = ' '): string {. ## returned unchanged. If you need to left align a string use the `repeatChar ## proc <#repeatChar>`_. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## assert align("abc", 4) == " abc" ## assert align("a", 0) == "a" ## assert align("1232", 6) == " 1232" @@ -547,13 +547,13 @@ iterator tokenize*(s: string, seps: set[char] = Whitespace): tuple[ ## Substrings are separated by a substring containing only `seps`. ## Examples: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for word in tokenize(" this is an example "): ## writeln(stdout, word) ## ## Results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## (" ", true) ## ("this", false) ## (" ", true) @@ -676,7 +676,7 @@ proc addSep*(dest: var string, sep = ", ", startLen = 0) {.noSideEffect, ## ## A shorthand for: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## if dest.len > startLen: add(dest, sep) ## ## This is often useful for generating some code where the items need to @@ -684,7 +684,7 @@ proc addSep*(dest: var string, sep = ", ", startLen = 0) {.noSideEffect, ## `startLen`. The following example creates a string describing ## an array of integers: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var arr = "[" ## for x in items([2, 3, 5, 7, 11]): ## addSep(arr, startLen=len("[")) @@ -692,7 +692,7 @@ proc addSep*(dest: var string, sep = ", ", startLen = 0) {.noSideEffect, ## add(arr, "]") if dest.len > startLen: add(dest, sep) -proc allCharsInSet*(s: string, theSet: TCharSet): bool = +proc allCharsInSet*(s: string, theSet: set[char]): bool = ## Returns true iff each character of `s` is in the set `theSet`. for c in items(s): if c notin theSet: return false @@ -739,14 +739,14 @@ proc join*(a: openArray[string]): string {. result = "" type - TSkipTable = array[char, int] + SkipTable = array[char, int] -proc preprocessSub(sub: string, a: var TSkipTable) = +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 -proc findAux(s, sub: string, start: int, a: TSkipTable): int = +proc findAux(s, sub: string, start: int, a: SkipTable): int = # Fast "quick search" algorithm: var m = len(sub) @@ -762,11 +762,11 @@ proc findAux(s, sub: string, start: int, a: TSkipTable): int = return -1 proc find*(s, sub: string, start: int = 0): int {.noSideEffect, - rtl, extern: "nsuFindStr", operator: 6.} = + rtl, extern: "nsuFindStr".} = ## Searches for `sub` in `s` starting at position `start`. ## ## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned. - var a {.noinit.}: TSkipTable + var a {.noinit.}: SkipTable preprocessSub(sub, a) result = findAux(s, sub, start, a) @@ -857,9 +857,9 @@ proc contains*(s: string, chars: set[char]): bool {.noSideEffect.} = return find(s, chars) >= 0 proc replace*(s, sub: string, by = ""): string {.noSideEffect, - rtl, extern: "nsuReplaceStr", operator: 1.} = + rtl, extern: "nsuReplaceStr".} = ## Replaces `sub` in `s` by the string `by`. - var a {.noinit.}: TSkipTable + var a {.noinit.}: SkipTable result = "" preprocessSub(sub, a) var i = 0 @@ -892,7 +892,7 @@ proc replaceWord*(s, sub: string, by = ""): string {.noSideEffect, ## (comparable to ``\\w`` in regular expressions), otherwise it is not ## replaced. const wordChars = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\128'..'\255'} - var a {.noinit.}: TSkipTable + var a {.noinit.}: SkipTable result = "" preprocessSub(sub, a) var i = 0 @@ -929,7 +929,7 @@ proc parseOctInt*(s: string): int {.noSideEffect, rtl, extern: "nsuParseOctInt".} = ## Parses an octal integer value contained in `s`. ## - ## If `s` is not a valid integer, `EInvalidValue` is raised. `s` can have one + ## If `s` is not a valid integer, `ValueError` is raised. `s` can have one ## of the following optional prefixes: ``0o``, ``0O``. Underscores within ## `s` are ignored. var i = 0 @@ -941,7 +941,7 @@ proc parseOctInt*(s: string): int {.noSideEffect, result = result shl 3 or (ord(s[i]) - ord('0')) inc(i) of '\0': break - else: raise newException(EInvalidValue, "invalid integer: " & s) + else: raise newException(ValueError, "invalid integer: " & s) proc toOct*(x: BiggestInt, len: int): string {.noSideEffect, rtl, extern: "nsuToOct".} = @@ -1029,11 +1029,11 @@ proc unescape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect, ## operations. ## ## If `s` does not begin with ``prefix`` and end with ``suffix`` a - ## EInvalidValue exception will be raised. + ## ValueError exception will be raised. result = newStringOfCap(s.len) var i = 0 if s[0 .. prefix.len-1] != prefix: - raise newException(EInvalidValue, + raise newException(ValueError, "String does not start with a prefix of: " & prefix) i.inc() while true: @@ -1058,7 +1058,7 @@ proc unescape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect, result.add(s[i]) i.inc() if s[i .. -1] != suffix: - raise newException(EInvalidValue, + raise newException(ValueError, "String does not end with a suffix of: " & suffix) proc validIdentifier*(s: string): bool {.noSideEffect, @@ -1168,14 +1168,16 @@ proc c_sprintf(buf, frmt: cstring) {.header: "<stdio.h>", importc: "sprintf", varargs, noSideEffect.} type - TFloatFormat* = enum ## the different modes of floating point formating + FloatFormatMode* = enum ## the different modes of floating point formating ffDefault, ## use the shorter floating point notation ffDecimal, ## use decimal floating point notation ffScientific ## use scientific notation (using ``e`` character) -proc formatBiggestFloat*(f: BiggestFloat, format: TFloatFormat = ffDefault, +{.deprecated: [TFloatFormat: FloatFormatMode].} + +proc formatBiggestFloat*(f: BiggestFloat, format: FloatFormatMode = ffDefault, precision: range[0..32] = 16): string {. - noSideEffect, operator: 2, rtl, extern: "nsu$1".} = + noSideEffect, rtl, extern: "nsu$1".} = ## Converts a floating point value `f` to a string. ## ## If ``format == ffDecimal`` then precision is the number of digits to @@ -1183,10 +1185,10 @@ proc formatBiggestFloat*(f: BiggestFloat, format: TFloatFormat = ffDefault, ## If ``format == ffScientific`` then precision is the maximum number ## of significant digits to be printed. ## `precision`'s default value is the maximum number of meaningful digits - ## after the decimal point for Nimrod's ``biggestFloat`` type. + ## after the decimal point for Nim's ``biggestFloat`` type. ## ## If ``precision == 0``, it tries to format it nicely. - const floatFormatToChar: array[TFloatFormat, char] = ['g', 'f', 'e'] + const floatFormatToChar: array[FloatFormatMode, char] = ['g', 'f', 'e'] var frmtstr {.noinit.}: array[0..5, char] buf {.noinit.}: array[0..2500, char] @@ -1204,9 +1206,9 @@ proc formatBiggestFloat*(f: BiggestFloat, format: TFloatFormat = ffDefault, c_sprintf(buf, frmtstr, f) result = $buf -proc formatFloat*(f: float, format: TFloatFormat = ffDefault, +proc formatFloat*(f: float, format: FloatFormatMode = ffDefault, precision: range[0..32] = 16): string {. - noSideEffect, operator: 2, rtl, extern: "nsu$1".} = + noSideEffect, rtl, extern: "nsu$1".} = ## Converts a floating point value `f` to a string. ## ## If ``format == ffDecimal`` then precision is the number of digits to @@ -1214,13 +1216,13 @@ proc formatFloat*(f: float, format: TFloatFormat = ffDefault, ## If ``format == ffScientific`` then precision is the maximum number ## of significant digits to be printed. ## `precision`'s default value is the maximum number of meaningful digits - ## after the decimal point for Nimrod's ``float`` type. + ## after the decimal point for Nim's ``float`` type. result = formatBiggestFloat(f, format, precision) proc formatSize*(bytes: BiggestInt, decimalSep = '.'): string = ## Rounds and formats `bytes`. Examples: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## formatSize(1'i64 shl 31 + 300'i64) == "2.204GB" ## formatSize(4096) == "4KB" @@ -1249,7 +1251,7 @@ proc findNormalized(x: string, inArray: openArray[string]): int = return -1 proc invalidFormatString() {.noinline.} = - raise newException(EInvalidValue, "invalid format string") + raise newException(ValueError, "invalid format string") proc addf*(s: var string, formatstr: string, a: varargs[string, `$`]) {. noSideEffect, rtl, extern: "nsuAddf".} = @@ -1310,12 +1312,12 @@ proc `%` *(formatstr: string, a: openArray[string]): string {.noSideEffect, ## ## This is best explained by an example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "$1 eats $2." % ["The cat", "fish"] ## ## Results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "The cat eats fish." ## ## The substitution variables (the thing after the ``$``) are enumerated @@ -1324,7 +1326,7 @@ proc `%` *(formatstr: string, a: openArray[string]): string {.noSideEffect, ## The notation ``$#`` can be used to refer to the next substitution ## variable: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "$# eats $#." % ["The cat", "fish"] ## ## Substitution variables can also be words (that is @@ -1332,15 +1334,15 @@ proc `%` *(formatstr: string, a: openArray[string]): string {.noSideEffect, ## indices are keys and with odd indices are the corresponding values. ## An example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "$animal eats $food." % ["animal", "The cat", "food", "fish"] ## ## Results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "The cat eats fish." ## - ## The variables are compared with `cmpIgnoreStyle`. `EInvalidValue` is + ## The variables are compared with `cmpIgnoreStyle`. `ValueError` is ## raised if an ill-formed format string has been passed to the `%` operator. result = newStringOfCap(formatstr.len + a.len shl 4) addf(result, formatstr, a) @@ -1380,8 +1382,8 @@ when isMainModule: doAssert "-ld a-ldz -ld".replaceWord("-ld") == " a-ldz " doAssert "-lda-ldz -ld abc".replaceWord("-ld") == "-lda-ldz abc" - type TMyEnum = enum enA, enB, enC, enuD, enE - doAssert parseEnum[TMyEnum]("enu_D") == enuD + type MyEnum = enum enA, enB, enC, enuD, enE + doAssert parseEnum[MyEnum]("enu_D") == enuD doAssert parseEnum("invalid enum value", enC) == enC diff --git a/lib/pure/subexes.nim b/lib/pure/subexes.nim index ed87610d6..c87823926 100644 --- a/lib/pure/subexes.nim +++ b/lib/pure/subexes.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## Nimrod support for `substitution expressions`:idx: (`subex`:idx:). +## Nim support for `substitution expressions`:idx: (`subex`:idx:). ## ## .. include:: ../doc/subexes.txt ## @@ -28,11 +28,13 @@ proc findNormalized(x: string, inArray: openarray[string]): int = return -1 type - EInvalidSubex* = object of EInvalidValue ## exception that is raised for - ## an invalid subex + SubexError* = object of ValueError ## exception that is raised for + ## an invalid subex + +{.deprecated: [EInvalidSubex: SubexError].} proc raiseInvalidFormat(msg: string) {.noinline.} = - raise newException(EInvalidSubex, "invalid format string: " & msg) + raise newException(SubexError, "invalid format string: " & msg) type TFormatParser = object {.pure, final.} @@ -194,6 +196,9 @@ proc scanDollar(p: var TFormatParser, a: openarray[string], s: var string) = of '$': emitChar p, s, '$' inc i + of '*': + for j in 0..a.high: emitStr p, s, a[j] + inc i of '{': call: let (x, y) = scanSlice(p, a) @@ -291,14 +296,16 @@ proc scanDollar(p: var TFormatParser, a: openarray[string], s: var string) = type - TSubex* = distinct string ## string that contains a substitution expression + Subex* = distinct string ## string that contains a substitution expression + +{.deprecated: [TSubex: Subex].} -proc subex*(s: string): TSubex = +proc subex*(s: string): Subex = ## constructs a *substitution expression* from `s`. Currently this performs ## no syntax checking but this may change in later versions. - result = TSubex(s) + result = Subex(s) -proc addf*(s: var string, formatstr: TSubex, a: varargs[string, `$`]) {. +proc addf*(s: var string, formatstr: Subex, a: varargs[string, `$`]) {. noSideEffect, rtl, extern: "nfrmtAddf".} = ## The same as ``add(s, formatstr % a)``, but more efficient. var p: TFormatParser @@ -312,7 +319,7 @@ proc addf*(s: var string, formatstr: TSubex, a: varargs[string, `$`]) {. emitChar(p, s, p.f[i]) inc(i) -proc `%` *(formatstr: TSubex, a: openarray[string]): string {.noSideEffect, +proc `%` *(formatstr: Subex, a: openarray[string]): string {.noSideEffect, rtl, extern: "nfrmtFormatOpenArray".} = ## The `substitution`:idx: operator performs string substitutions in ## `formatstr` and returns a modified `formatstr`. This is often called @@ -321,13 +328,13 @@ proc `%` *(formatstr: TSubex, a: openarray[string]): string {.noSideEffect, result = newStringOfCap(formatstr.string.len + a.len shl 4) addf(result, formatstr, a) -proc `%` *(formatstr: TSubex, a: string): string {.noSideEffect, +proc `%` *(formatstr: Subex, a: string): string {.noSideEffect, rtl, extern: "nfrmtFormatSingleElem".} = ## This is the same as ``formatstr % [a]``. result = newStringOfCap(formatstr.string.len + a.len) addf(result, formatstr, [a]) -proc format*(formatstr: TSubex, a: varargs[string, `$`]): string {.noSideEffect, +proc format*(formatstr: Subex, a: varargs[string, `$`]): string {.noSideEffect, rtl, extern: "nfrmtFormatVarargs".} = ## The `substitution`:idx: operator performs string substitutions in ## `formatstr` and returns a modified `formatstr`. This is often called diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim index 20f1d0695..1c1d973ee 100644 --- a/lib/pure/terminal.nim +++ b/lib/pure/terminal.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -27,12 +27,13 @@ when defined(windows): var hTemp = GetStdHandle(STD_OUTPUT_HANDLE) if DuplicateHandle(GetCurrentProcess(), hTemp, GetCurrentProcess(), addr(conHandle), 0, 1, DUPLICATE_SAME_ACCESS) == 0: - osError(osLastError()) + raiseOSError(osLastError()) proc getCursorPos(): tuple [x,y: int] = var c: TCONSOLESCREENBUFFERINFO - if GetConsoleScreenBufferInfo(conHandle, addr(c)) == 0: osError(osLastError()) - return (int(c.dwCursorPosition.x), int(c.dwCursorPosition.y)) + if GetConsoleScreenBufferInfo(conHandle, addr(c)) == 0: + raiseOSError(osLastError()) + return (int(c.dwCursorPosition.X), int(c.dwCursorPosition.Y)) proc getAttributes(): int16 = var c: TCONSOLESCREENBUFFERINFO @@ -49,9 +50,9 @@ proc setCursorPos*(x, y: int) = ## upper left of the screen. when defined(windows): var c: TCOORD - c.x = int16(x) - c.y = int16(y) - if SetConsoleCursorPosition(conHandle, c) == 0: osError(osLastError()) + c.X = int16(x) + c.Y = int16(y) + if SetConsoleCursorPosition(conHandle, c) == 0: raiseOSError(osLastError()) else: stdout.write("\e[" & $y & ';' & $x & 'f') @@ -61,10 +62,12 @@ proc setCursorXPos*(x: int) = when defined(windows): var scrbuf: TCONSOLESCREENBUFFERINFO var hStdout = conHandle - if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: osError(osLastError()) + if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: + raiseOSError(osLastError()) var origin = scrbuf.dwCursorPosition - origin.x = int16(x) - if SetConsoleCursorPosition(conHandle, origin) == 0: osError(osLastError()) + origin.X = int16(x) + if SetConsoleCursorPosition(conHandle, origin) == 0: + raiseOSError(osLastError()) else: stdout.write("\e[" & $x & 'G') @@ -75,10 +78,12 @@ when defined(windows): when defined(windows): var scrbuf: TCONSOLESCREENBUFFERINFO var hStdout = conHandle - if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: osError(osLastError()) + if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: + raiseOSError(osLastError()) var origin = scrbuf.dwCursorPosition - origin.y = int16(y) - if SetConsoleCursorPosition(conHandle, origin) == 0: osError(osLastError()) + origin.Y = int16(y) + if SetConsoleCursorPosition(conHandle, origin) == 0: + raiseOSError(osLastError()) else: discard @@ -155,18 +160,20 @@ proc eraseLine* = var scrbuf: TCONSOLESCREENBUFFERINFO var numwrote: DWORD var hStdout = conHandle - if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: osError(osLastError()) + if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: + raiseOSError(osLastError()) var origin = scrbuf.dwCursorPosition - origin.x = 0'i16 - if SetConsoleCursorPosition(conHandle, origin) == 0: osError(osLastError()) + origin.X = 0'i16 + if SetConsoleCursorPosition(conHandle, origin) == 0: + raiseOSError(osLastError()) var ht = scrbuf.dwSize.Y - origin.Y var wt = scrbuf.dwSize.X - origin.X if FillConsoleOutputCharacter(hStdout,' ', ht*wt, origin, addr(numwrote)) == 0: - osError(osLastError()) + raiseOSError(osLastError()) if FillConsoleOutputAttribute(hStdout, scrbuf.wAttributes, ht * wt, scrbuf.dwCursorPosition, addr(numwrote)) == 0: - osError(osLastError()) + raiseOSError(osLastError()) else: stdout.write("\e[2K") setCursorXPos(0) @@ -178,14 +185,15 @@ proc eraseScreen* = var numwrote: DWORD var origin: TCOORD # is inititalized to 0, 0 var hStdout = conHandle - if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: osError(osLastError()) + if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: + raiseOSError(osLastError()) if FillConsoleOutputCharacter(hStdout, ' ', scrbuf.dwSize.X*scrbuf.dwSize.Y, origin, addr(numwrote)) == 0: - osError(osLastError()) + raiseOSError(osLastError()) if FillConsoleOutputAttribute(hStdout, scrbuf.wAttributes, scrbuf.dwSize.X * scrbuf.dwSize.Y, origin, addr(numwrote)) == 0: - osError(osLastError()) + raiseOSError(osLastError()) setCursorXPos(0) else: stdout.write("\e[2J") @@ -199,7 +207,7 @@ proc resetAttributes* {.noconv.} = stdout.write("\e[0m") type - TStyle* = enum ## different styles for text output + Style* = enum ## different styles for text output styleBright = 1, ## bright text styleDim, ## dim text styleUnknown, ## unknown @@ -208,13 +216,15 @@ type styleReverse = 7, ## unknown styleHidden ## hidden text +{.deprecated: [TStyle: Style].} + when not defined(windows): var # XXX: These better be thread-local gFG = 0 gBG = 0 -proc setStyle*(style: set[TStyle]) = +proc setStyle*(style: set[Style]) = ## sets the terminal style when defined(windows): var a = 0'i16 @@ -227,7 +237,7 @@ proc setStyle*(style: set[TStyle]) = for s in items(style): stdout.write("\e[" & $ord(s) & 'm') -proc writeStyled*(txt: string, style: set[TStyle] = {styleBright}) = +proc writeStyled*(txt: string, style: set[Style] = {styleBright}) = ## writes the text `txt` in a given `style`. when defined(windows): var old = getAttributes() @@ -244,7 +254,7 @@ proc writeStyled*(txt: string, style: set[TStyle] = {styleBright}) = stdout.write("\e[" & $ord(gBG) & 'm') type - TForegroundColor* = enum ## terminal's foreground colors + ForegroundColor* = enum ## terminal's foreground colors fgBlack = 30, ## black fgRed, ## red fgGreen, ## green @@ -254,7 +264,7 @@ type fgCyan, ## cyan fgWhite ## white - TBackgroundColor* = enum ## terminal's background colors + BackgroundColor* = enum ## terminal's background colors bgBlack = 40, ## black bgRed, ## red bgGreen, ## green @@ -264,13 +274,16 @@ type bgCyan, ## cyan bgWhite ## white -proc setForegroundColor*(fg: TForegroundColor, bright=false) = +{.deprecated: [TForegroundColor: ForegroundColor, + TBackgroundColor: BackgroundColor].} + +proc setForegroundColor*(fg: ForegroundColor, bright=false) = ## sets the terminal's foreground color when defined(windows): var old = getAttributes() and not 0x0007 if bright: old = old or FOREGROUND_INTENSITY - const lookup: array [TForegroundColor, int] = [ + const lookup: array [ForegroundColor, int] = [ 0, (FOREGROUND_RED), (FOREGROUND_GREEN), @@ -285,13 +298,13 @@ proc setForegroundColor*(fg: TForegroundColor, bright=false) = if bright: inc(gFG, 60) stdout.write("\e[" & $gFG & 'm') -proc setBackgroundColor*(bg: TBackgroundColor, bright=false) = +proc setBackgroundColor*(bg: BackgroundColor, bright=false) = ## sets the terminal's background color when defined(windows): var old = getAttributes() and not 0x0070 if bright: old = old or BACKGROUND_INTENSITY - const lookup: array [TBackgroundColor, int] = [ + const lookup: array [BackgroundColor, int] = [ 0, (BACKGROUND_RED), (BACKGROUND_GREEN), @@ -306,22 +319,22 @@ proc setBackgroundColor*(bg: TBackgroundColor, bright=false) = if bright: inc(gBG, 60) stdout.write("\e[" & $gBG & 'm') -proc isatty*(f: TFile): bool = +proc isatty*(f: File): bool = ## returns true if `f` is associated with a terminal device. when defined(posix): - proc isatty(fildes: TFileHandle): cint {. + proc isatty(fildes: FileHandle): cint {. importc: "isatty", header: "<unistd.h>".} else: - proc isatty(fildes: TFileHandle): cint {. + proc isatty(fildes: FileHandle): cint {. importc: "_isatty", header: "<io.h>".} - result = isatty(fileHandle(f)) != 0'i32 + result = isatty(getFileHandle(f)) != 0'i32 -proc styledEchoProcessArg(s: string) = write stdout, s -proc styledEchoProcessArg(style: TStyle) = setStyle({style}) -proc styledEchoProcessArg(style: set[TStyle]) = setStyle style -proc styledEchoProcessArg(color: TForegroundColor) = setForegroundColor color -proc styledEchoProcessArg(color: TBackgroundColor) = setBackgroundColor color +proc styledEchoProcessArg(s: string) = write stdout, s +proc styledEchoProcessArg(style: Style) = setStyle({style}) +proc styledEchoProcessArg(style: set[Style]) = setStyle style +proc styledEchoProcessArg(color: ForegroundColor) = setForegroundColor color +proc styledEchoProcessArg(color: BackgroundColor) = setBackgroundColor color macro styledEcho*(m: varargs[expr]): stmt = ## to be documented. diff --git a/lib/pure/times.nim b/lib/pure/times.nim index 8b33d2c73..1cabd381b 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -21,9 +21,9 @@ import include "system/inclrtl" type - TMonth* = enum ## represents a month + Month* = enum ## represents a month mJan, mFeb, mMar, mApr, mMay, mJun, mJul, mAug, mSep, mOct, mNov, mDec - TWeekDay* = enum ## represents a weekday + WeekDay* = enum ## represents a weekday dMon, dTue, dWed, dThu, dFri, dSat, dSun var @@ -32,12 +32,12 @@ var when defined(posix) and not defined(JS): type - TTimeImpl {.importc: "time_t", header: "<sys/time.h>".} = int - TTime* = distinct TTimeImpl ## distinct type that represents a time - ## measured as number of seconds since the epoch + TimeImpl {.importc: "time_t", header: "<sys/time.h>".} = int + Time* = distinct TimeImpl ## distinct type that represents a time + ## measured as number of seconds since the epoch - Ttimeval {.importc: "struct timeval", header: "<sys/select.h>", - final, pure.} = object ## struct timeval + Timeval {.importc: "struct timeval", + header: "<sys/select.h>".} = object ## struct timeval tv_sec: int ## Seconds. tv_usec: int ## Microseconds. @@ -45,7 +45,7 @@ when defined(posix) and not defined(JS): # Ok, we could, but I don't want circular dependencies. # And gettimeofday() is not defined in the posix module anyway. Sigh. - proc posix_gettimeofday(tp: var Ttimeval, unused: pointer = nil) {. + proc posix_gettimeofday(tp: var Timeval, unused: pointer = nil) {. importc: "gettimeofday", header: "<sys/time.h>".} elif defined(windows): @@ -53,16 +53,16 @@ elif defined(windows): when defined(vcc): # newest version of Visual C++ defines time_t to be of 64 bits - type TTimeImpl {.importc: "time_t", header: "<time.h>".} = int64 + type TimeImpl {.importc: "time_t", header: "<time.h>".} = int64 else: - type TTimeImpl {.importc: "time_t", header: "<time.h>".} = int32 + type TimeImpl {.importc: "time_t", header: "<time.h>".} = int32 type - TTime* = distinct TTimeImpl + Time* = distinct TimeImpl elif defined(JS): type - TTime* {.final, importc.} = object + Time* {.importc.} = object getDay: proc (): int {.tags: [], raises: [], gcsafe.} getFullYear: proc (): int {.tags: [], raises: [], gcsafe.} getHours: proc (): int {.tags: [], raises: [], gcsafe.} @@ -82,7 +82,7 @@ elif defined(JS): getUTCSeconds: proc (): int {.tags: [], raises: [], gcsafe.} getUTCDay: proc (): int {.tags: [], raises: [], gcsafe.} getYear: proc (): int {.tags: [], raises: [], gcsafe.} - parse: proc (s: cstring): TTime {.tags: [], raises: [], gcsafe.} + parse: proc (s: cstring): Time {.tags: [], raises: [], gcsafe.} setDate: proc (x: int) {.tags: [], raises: [], gcsafe.} setFullYear: proc (x: int) {.tags: [], raises: [], gcsafe.} setHours: proc (x: int) {.tags: [], raises: [], gcsafe.} @@ -103,7 +103,7 @@ elif defined(JS): toLocaleString: proc (): cstring {.tags: [], raises: [], gcsafe.} type - TTimeInfo* = object of TObject ## represents a time in different parts + TimeInfo* = object of RootObj ## represents a time in different parts second*: range[0..61] ## The number of seconds after the minute, ## normally in the range 0 to 59, but can ## be up to 61 to allow for leap seconds. @@ -112,9 +112,9 @@ type hour*: range[0..23] ## The number of hours past midnight, ## in the range 0 to 23. monthday*: range[1..31] ## The day of the month, in the range 1 to 31. - month*: TMonth ## The current month. + month*: Month ## The current month. year*: range[-10_000..10_000] ## The current year. - weekday*: TWeekDay ## The current day of the week. + weekday*: WeekDay ## The current day of the week. yearday*: range[0..365] ## The number of days since January 1, ## in the range 0 to 365. ## Always 0 if the target is JS. @@ -127,7 +127,7 @@ type ## I make some assumptions about the data in here. Either ## everything should be positive or everything negative. Zero is ## fine too. Mixed signs will lead to unexpected results. - TTimeInterval* {.pure.} = object ## a time interval + TimeInterval* = object ## a time interval miliseconds*: int ## The number of miliseconds seconds*: int ## The number of seconds minutes*: int ## The number of minutes @@ -136,75 +136,78 @@ type months*: int ## The number of months years*: int ## The number of years -proc getTime*(): TTime {.tags: [FTime], gcsafe.} +{.deprecated: [TMonth: Month, TWeekDay: WeekDay, TTime: Time, + TTimeInterval: TimeInterval, TTimeInfo: TimeInfo].} + +proc getTime*(): Time {.tags: [TimeEffect], gcsafe.} ## gets the current calendar time as a UNIX epoch value (number of seconds ## elapsed since 1970) with integer precission. Use epochTime for higher ## resolution. -proc getLocalTime*(t: TTime): TTimeInfo {.tags: [FTime], raises: [], gcsafe.} +proc getLocalTime*(t: Time): TimeInfo {.tags: [TimeEffect], raises: [], gcsafe.} ## converts the calendar time `t` to broken-time representation, ## expressed relative to the user's specified time zone. -proc getGMTime*(t: TTime): TTimeInfo {.tags: [FTime], raises: [], gcsafe.} +proc getGMTime*(t: Time): TimeInfo {.tags: [TimeEffect], raises: [], gcsafe.} ## converts the calendar time `t` to broken-down time representation, ## expressed in Coordinated Universal Time (UTC). -proc timeInfoToTime*(timeInfo: TTimeInfo): TTime {.tags: [], gcsafe.} +proc timeInfoToTime*(timeInfo: TimeInfo): Time {.tags: [], gcsafe.} ## converts a broken-down time structure to ## calendar time representation. The function ignores the specified ## contents of the structure members `weekday` and `yearday` and recomputes ## them from the other information in the broken-down time structure. -proc fromSeconds*(since1970: float): TTime {.tags: [], raises: [], gcsafe.} +proc fromSeconds*(since1970: float): Time {.tags: [], raises: [], gcsafe.} ## Takes a float which contains the number of seconds since the unix epoch and ## returns a time object. -proc fromSeconds*(since1970: int64): TTime {.tags: [], raises: [], gcsafe.} = +proc fromSeconds*(since1970: int64): Time {.tags: [], raises: [], gcsafe.} = ## Takes an int which contains the number of seconds since the unix epoch and ## returns a time object. fromSeconds(float(since1970)) -proc toSeconds*(time: TTime): float {.tags: [], raises: [], gcsafe.} +proc toSeconds*(time: Time): float {.tags: [], raises: [], gcsafe.} ## Returns the time in seconds since the unix epoch. -proc `$` *(timeInfo: TTimeInfo): string {.tags: [], raises: [], gcsafe.} - ## converts a `TTimeInfo` object to a string representation. -proc `$` *(time: TTime): string {.tags: [], raises: [], gcsafe.} +proc `$` *(timeInfo: TimeInfo): string {.tags: [], raises: [], gcsafe.} + ## converts a `TimeInfo` object to a string representation. +proc `$` *(time: Time): string {.tags: [], raises: [], gcsafe.} ## converts a calendar time to a string representation. -proc `-`*(a, b: TTime): int64 {. +proc `-`*(a, b: Time): int64 {. rtl, extern: "ntDiffTime", tags: [], raises: [].} ## computes the difference of two calendar times. Result is in seconds. -proc `<`*(a, b: TTime): bool {. +proc `<`*(a, b: Time): bool {. rtl, extern: "ntLtTime", tags: [], raises: [].} = ## returns true iff ``a < b``, that is iff a happened before b. result = a - b < 0 -proc `<=` * (a, b: TTime): bool {. +proc `<=` * (a, b: Time): bool {. rtl, extern: "ntLeTime", tags: [], raises: [].}= ## returns true iff ``a <= b``. result = a - b <= 0 -proc `==`*(a, b: TTime): bool {. +proc `==`*(a, b: Time): bool {. rtl, extern: "ntEqTime", tags: [], raises: [].} = ## returns true if ``a == b``, that is if both times represent the same value result = a - b == 0 when not defined(JS): - proc getTzname*(): tuple[nonDST, DST: string] {.tags: [FTime], raises: [], + proc getTzname*(): tuple[nonDST, DST: string] {.tags: [TimeEffect], raises: [], gcsafe.} ## returns the local timezone; ``nonDST`` is the name of the local non-DST ## timezone, ``DST`` is the name of the local DST timezone. -proc getTimezone*(): int {.tags: [FTime], raises: [], gcsafe.} +proc getTimezone*(): int {.tags: [TimeEffect], raises: [], gcsafe.} ## returns the offset of the local (non-DST) timezone in seconds west of UTC. -proc getStartMilsecs*(): int {.deprecated, tags: [FTime], gcsafe.} +proc getStartMilsecs*(): int {.deprecated, tags: [TimeEffect], gcsafe.} ## get the miliseconds from the start of the program. **Deprecated since ## version 0.8.10.** Use ``epochTime`` or ``cpuTime`` instead. proc initInterval*(miliseconds, seconds, minutes, hours, days, months, - years: int = 0): TTimeInterval = - ## creates a new ``TTimeInterval``. + years: int = 0): TimeInterval = + ## creates a new ``TimeInterval``. result.miliseconds = miliseconds result.seconds = seconds result.minutes = minutes @@ -225,7 +228,7 @@ proc isLeapYear*(year: int): bool = else: return false -proc getDaysInMonth*(month: TMonth, year: int): int = +proc getDaysInMonth*(month: Month, year: int): int = ## gets the amount of days in a ``month`` of a ``year`` # http://www.dispersiondesign.com/articles/time/number_of_days_in_a_month @@ -234,7 +237,7 @@ proc getDaysInMonth*(month: TMonth, year: int): int = of mApr, mJun, mSep, mNov: result = 30 else: result = 31 -proc toSeconds(a: TTimeInfo, interval: TTimeInterval): float = +proc toSeconds(a: TimeInfo, interval: TimeInterval): float = ## Calculates how many seconds the interval is worth by adding up ## all the fields @@ -257,7 +260,7 @@ proc toSeconds(a: TTimeInfo, interval: TTimeInterval): float = result += float(newinterv.seconds) result += newinterv.miliseconds / 1000 -proc `+`*(a: TTimeInfo, interval: TTimeInterval): TTimeInfo = +proc `+`*(a: TimeInfo, interval: TimeInterval): TimeInfo = ## adds ``interval`` time. ## ## **Note:** This has been only briefly tested and it may not be @@ -269,7 +272,7 @@ proc `+`*(a: TTimeInfo, interval: TTimeInterval): TTimeInfo = else: result = getLocalTime(fromSeconds(t + secs)) -proc `-`*(a: TTimeInfo, interval: TTimeInterval): TTimeInfo = +proc `-`*(a: TimeInfo, interval: TimeInterval): TimeInfo = ## subtracts ``interval`` time. ## ## **Note:** This has been only briefly tested, it is inaccurate especially @@ -282,12 +285,12 @@ proc `-`*(a: TTimeInfo, interval: TTimeInterval): TTimeInfo = result = getLocalTime(fromSeconds(t - secs)) when not defined(JS): - proc epochTime*(): float {.rtl, extern: "nt$1", tags: [FTime].} + proc epochTime*(): float {.rtl, extern: "nt$1", tags: [TimeEffect].} ## gets time after the UNIX epoch (1970) in seconds. It is a float ## because sub-second resolution is likely to be supported (depending ## on the hardware/OS). - proc cpuTime*(): float {.rtl, extern: "nt$1", tags: [FTime].} + proc cpuTime*(): float {.rtl, extern: "nt$1", tags: [TimeEffect].} ## gets time spent that the CPU spent to run the current process in ## seconds. This may be more useful for benchmarking than ``epochTime``. ## However, it may measure the real time instead (depending on the OS). @@ -295,7 +298,7 @@ when not defined(JS): ## To generate useful timing values, take the difference between ## the results of two ``cpuTime`` calls: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var t0 = cpuTime() ## doWork() ## echo "CPU time [s] ", cpuTime() - t0 @@ -314,42 +317,40 @@ when not defined(JS): yearday {.importc: "tm_yday".}, isdst {.importc: "tm_isdst".}: cint - PTimeInfo = ptr StructTM - PTime = ptr TTime - - TClock {.importc: "clock_t".} = distinct int + TimeInfoPtr = ptr StructTM + Clock {.importc: "clock_t".} = distinct int - proc localtime(timer: PTime): PTimeInfo {. + proc localtime(timer: ptr Time): TimeInfoPtr {. importc: "localtime", header: "<time.h>", tags: [].} - proc gmtime(timer: PTime): PTimeInfo {. + proc gmtime(timer: ptr Time): TimeInfoPtr {. importc: "gmtime", header: "<time.h>", tags: [].} - proc timec(timer: PTime): TTime {. + proc timec(timer: ptr Time): Time {. importc: "time", header: "<time.h>", tags: [].} - proc mktime(t: StructTM): TTime {. + proc mktime(t: StructTM): Time {. importc: "mktime", header: "<time.h>", tags: [].} proc asctime(tblock: StructTM): cstring {. importc: "asctime", header: "<time.h>", tags: [].} - proc ctime(time: PTime): cstring {. + proc ctime(time: ptr Time): cstring {. importc: "ctime", header: "<time.h>", tags: [].} # strftime(s: CString, maxsize: int, fmt: CString, t: tm): int {. # importc: "strftime", header: "<time.h>".} - proc clock(): TClock {.importc: "clock", header: "<time.h>", tags: [FTime].} - proc difftime(a, b: TTime): float {.importc: "difftime", header: "<time.h>", + proc getClock(): Clock {.importc: "clock", header: "<time.h>", tags: [TimeEffect].} + proc difftime(a, b: Time): float {.importc: "difftime", header: "<time.h>", tags: [].} var clocksPerSec {.importc: "CLOCKS_PER_SEC", nodecl.}: int # our own procs on top of that: - proc tmToTimeInfo(tm: StructTM, local: bool): TTimeInfo = + proc tmToTimeInfo(tm: StructTM, local: bool): TimeInfo = const - weekDays: array [0..6, TWeekDay] = [ + weekDays: array [0..6, WeekDay] = [ dSun, dMon, dTue, dWed, dThu, dFri, dSat] - TTimeInfo(second: int(tm.second), + TimeInfo(second: int(tm.second), minute: int(tm.minute), hour: int(tm.hour), monthday: int(tm.monthday), - month: TMonth(tm.month), + month: Month(tm.month), year: tm.year + 1900'i32, weekday: weekDays[int(tm.weekday)], yearday: int(tm.yearday), @@ -364,9 +365,9 @@ when not defined(JS): timezone: if local: getTimezone() else: 0 ) - proc timeInfoToTM(t: TTimeInfo): StructTM = + proc timeInfoToTM(t: TimeInfo): StructTM = const - weekDays: array [TWeekDay, int8] = [1'i8,2'i8,3'i8,4'i8,5'i8,6'i8,0'i8] + weekDays: array [WeekDay, int8] = [1'i8,2'i8,3'i8,4'i8,5'i8,6'i8,0'i8] result.second = t.second result.minute = t.minute result.hour = t.hour @@ -378,36 +379,36 @@ when not defined(JS): result.isdst = if t.isDST: 1 else: 0 when not defined(useNimRtl): - proc `-` (a, b: TTime): int64 = + proc `-` (a, b: Time): int64 = return toBiggestInt(difftime(a, b)) proc getStartMilsecs(): int = - #echo "clocks per sec: ", clocksPerSec, "clock: ", int(clock()) - #return clock() div (clocksPerSec div 1000) + #echo "clocks per sec: ", clocksPerSec, "clock: ", int(getClock()) + #return getClock() div (clocksPerSec div 1000) when defined(macosx): - result = toInt(toFloat(int(clock())) / (toFloat(clocksPerSec) / 1000.0)) + result = toInt(toFloat(int(getClock())) / (toFloat(clocksPerSec) / 1000.0)) else: - result = int(clock()) div (clocksPerSec div 1000) + result = int(getClock()) div (clocksPerSec div 1000) when false: - var a: Ttimeval + var a: Timeval posix_gettimeofday(a) result = a.tv_sec * 1000'i64 + a.tv_usec div 1000'i64 #echo "result: ", result - proc getTime(): TTime = return timec(nil) - proc getLocalTime(t: TTime): TTimeInfo = + proc getTime(): Time = return timec(nil) + proc getLocalTime(t: Time): TimeInfo = var a = t result = tmToTimeInfo(localtime(addr(a))[], true) # copying is needed anyway to provide reentrancity; thus # the conversion is not expensive - proc getGMTime(t: TTime): TTimeInfo = + proc getGMTime(t: Time): TimeInfo = var a = t result = tmToTimeInfo(gmtime(addr(a))[], false) # copying is needed anyway to provide reentrancity; thus # the conversion is not expensive - proc timeInfoToTime(timeInfo: TTimeInfo): TTime = + proc timeInfoToTime(timeInfo: TimeInfo): Time = var cTimeInfo = timeInfo # for C++ we have to make a copy, # because the header of mktime is broken in my version of libc return mktime(timeInfoToTM(cTimeInfo)) @@ -419,12 +420,12 @@ when not defined(JS): add(result, p[i]) inc(i) - proc `$`(timeInfo: TTimeInfo): string = + proc `$`(timeInfo: TimeInfo): string = # BUGFIX: asctime returns a newline at the end! var p = asctime(timeInfoToTM(timeInfo)) result = toStringTillNL(p) - proc `$`(time: TTime): string = + proc `$`(time: Time): string = # BUGFIX: ctime returns a newline at the end! var a = time return toStringTillNL(ctime(addr(a))) @@ -433,13 +434,13 @@ when not defined(JS): epochDiff = 116444736000000000'i64 rateDiff = 10000000'i64 # 100 nsecs - proc unixTimeToWinTime*(t: TTime): int64 = - ## converts a UNIX `TTime` (``time_t``) to a Windows file time + proc unixTimeToWinTime*(t: Time): int64 = + ## converts a UNIX `Time` (``time_t``) to a Windows file time result = int64(t) * rateDiff + epochDiff - proc winTimeToUnixTime*(t: int64): TTime = - ## converts a Windows time to a UNIX `TTime` (``time_t``) - result = TTime((t - epochDiff) div rateDiff) + proc winTimeToUnixTime*(t: int64): Time = + ## converts a Windows time to a UNIX `Time` (``time_t``) + result = Time((t - epochDiff) div rateDiff) proc getTzname(): tuple[nonDST, DST: string] = return ($tzname[0], $tzname[1]) @@ -447,18 +448,18 @@ when not defined(JS): proc getTimezone(): int = return timezone - proc fromSeconds(since1970: float): TTime = TTime(since1970) + proc fromSeconds(since1970: float): Time = Time(since1970) - proc toSeconds(time: TTime): float = float(time) + proc toSeconds(time: Time): float = float(time) when not defined(useNimRtl): proc epochTime(): float = when defined(posix): - var a: Ttimeval + var a: Timeval posix_gettimeofday(a) result = toFloat(a.tv_sec) + toFloat(a.tv_usec)*0.00_0001 elif defined(windows): - var f: winlean.TFiletime + var f: winlean.TFILETIME getSystemTimeAsFileTime(f) var i64 = rdFileTime(f) - epochDiff var secs = i64 div rateDiff @@ -468,15 +469,15 @@ when not defined(JS): {.error: "unknown OS".} proc cpuTime(): float = - result = toFloat(int(clock())) / toFloat(clocksPerSec) + result = toFloat(int(getClock())) / toFloat(clocksPerSec) elif defined(JS): - proc newDate(): TTime {.importc: "new Date".} - proc internGetTime(): TTime {.importc: "new Date", tags: [].} + proc newDate(): Time {.importc: "new Date".} + proc internGetTime(): Time {.importc: "new Date", tags: [].} - proc newDate(value: float): TTime {.importc: "new Date".} - proc newDate(value: string): TTime {.importc: "new Date".} - proc getTime(): TTime = + proc newDate(value: float): Time {.importc: "new Date".} + proc newDate(value: string): Time {.importc: "new Date".} + proc getTime(): Time = # Warning: This is something different in JS. return newDate() @@ -484,7 +485,7 @@ elif defined(JS): weekDays: array [0..6, TWeekDay] = [ dSun, dMon, dTue, dWed, dThu, dFri, dSat] - proc getLocalTime(t: TTime): TTimeInfo = + proc getLocalTime(t: Time): TimeInfo = result.second = t.getSeconds() result.minute = t.getMinutes() result.hour = t.getHours() @@ -494,7 +495,7 @@ elif defined(JS): result.weekday = weekDays[t.getDay()] result.yearday = 0 - proc getGMTime(t: TTime): TTimeInfo = + proc getGMTime(t: Time): TimeInfo = result.second = t.getUTCSeconds() result.minute = t.getUTCMinutes() result.hour = t.getUTCHours() @@ -504,7 +505,7 @@ elif defined(JS): result.weekday = weekDays[t.getUTCDay()] result.yearday = 0 - proc timeInfoToTime*(timeInfo: TTimeInfo): TTime = + proc timeInfoToTime*(timeInfo: TimeInfo): Time = result = internGetTime() result.setSeconds(timeInfo.second) result.setMinutes(timeInfo.minute) @@ -513,10 +514,10 @@ elif defined(JS): result.setFullYear(timeInfo.year) result.setDate(timeInfo.monthday) - proc `$`(timeInfo: TTimeInfo): string = return $(timeInfoToTime(timeInfo)) - proc `$`(time: TTime): string = return $time.toLocaleString() + proc `$`(timeInfo: TimeInfo): string = return $(timeInfoToTime(timeInfo)) + proc `$`(time: Time): string = return $time.toLocaleString() - proc `-` (a, b: TTime): int64 = + proc `-` (a, b: Time): int64 = return a.getTime() - b.getTime() var @@ -526,40 +527,40 @@ elif defined(JS): ## get the miliseconds from the start of the program return int(getTime() - startMilsecs) - proc valueOf(time: TTime): float {.importcpp: "getTime", tags:[]} + proc valueOf(time: Time): float {.importcpp: "getTime", tags:[]} - proc fromSeconds(since1970: float): TTime = result = newDate(since1970) + proc fromSeconds(since1970: float): Time = result = newDate(since1970) - proc toSeconds(time: TTime): float = result = time.valueOf() / 1000 + proc toSeconds(time: Time): float = result = time.valueOf() / 1000 proc getTimezone(): int = result = newDate().getTimezoneOffset() -proc getDateStr*(): string {.rtl, extern: "nt$1", tags: [FTime].} = +proc getDateStr*(): string {.rtl, extern: "nt$1", tags: [TimeEffect].} = ## gets the current date as a string of the format ``YYYY-MM-DD``. var ti = getLocalTime(getTime()) result = $ti.year & '-' & intToStr(ord(ti.month)+1, 2) & '-' & intToStr(ti.monthday, 2) -proc getClockStr*(): string {.rtl, extern: "nt$1", tags: [FTime].} = +proc getClockStr*(): string {.rtl, extern: "nt$1", tags: [TimeEffect].} = ## gets the current clock time as a string of the format ``HH:MM:SS``. var ti = getLocalTime(getTime()) result = intToStr(ti.hour, 2) & ':' & intToStr(ti.minute, 2) & ':' & intToStr(ti.second, 2) -proc `$`*(day: TWeekDay): string = - ## stingify operator for ``TWeekDay``. - const lookup: array[TWeekDay, string] = ["Monday", "Tuesday", "Wednesday", +proc `$`*(day: WeekDay): string = + ## stingify operator for ``WeekDay``. + const lookup: array[WeekDay, string] = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] return lookup[day] -proc `$`*(m: TMonth): string = +proc `$`*(m: Month): string = ## stingify operator for ``TMonth``. - const lookup: array[TMonth, string] = ["January", "February", "March", + const lookup: array[Month, string] = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] return lookup[m] -proc format_token(info: TTimeInfo, token: string, buf: var string) = +proc formatToken(info: TimeInfo, token: string, buf: var string) = ## Helper of the format proc to parse individual tokens. ## ## Pass the found token in the user input string, and the buffer where the @@ -669,10 +670,10 @@ proc format_token(info: TTimeInfo, token: string, buf: var string) = of "": discard else: - raise newException(EInvalidValue, "Invalid format string: " & token) + raise newException(ValueError, "Invalid format string: " & token) -proc format*(info: TTimeInfo, f: string): string = +proc format*(info: TimeInfo, f: string): string = ## This function formats `info` as specified by `f`. The following format ## specifiers are available: ## @@ -718,7 +719,7 @@ proc format*(info: TTimeInfo, f: string): string = while true: case f[i] of ' ', '-', '/', ':', '\'', '\0', '(', ')', '[', ']', ',': - format_token(info, currentF, result) + formatToken(info, currentF, result) currentF = "" if f[i] == '\0': break @@ -735,7 +736,7 @@ proc format*(info: TTimeInfo, f: string): string = if currentF.len < 1 or currentF[high(currentF)] == f[i]: currentF.add(f[i]) else: - format_token(info, currentF, result) + formatToken(info, currentF, result) dec(i) # Move position back to re-process the character separately. currentF = "" @@ -764,7 +765,7 @@ when isMainModule: " ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") == "27 27 Mon Monday 4 04 16 16 6 06 1 01 Jan January 29 29 P PM 5 75 975 1975 01975 0 00 00:00 UTC" - when not defined(JS) and sizeof(TTime) == 8: + when not defined(JS) and sizeof(Time) == 8: var t3 = getGMTime(fromSeconds(889067643645)) # Fri 7 Jun 19:20:45 BST 30143 assert t3.format("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" & " ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") == diff --git a/lib/pure/typetraits.nim b/lib/pure/typetraits.nim index 3203ee699..2c3d872df 100644 --- a/lib/pure/typetraits.nim +++ b/lib/pure/typetraits.nim @@ -1,7 +1,7 @@ # # -# Nimrod's Runtime Library -# (c) Copyright 2012 Nimrod Contributors +# Nim's Runtime Library +# (c) Copyright 2012 Nim Contributors # # See the file "copying.txt", included in this # distribution, for details about the copyright. diff --git a/lib/pure/unicode.nim b/lib/pure/unicode.nim index 6e73eea3f..c2eb001f6 100644 --- a/lib/pure/unicode.nim +++ b/lib/pure/unicode.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -14,13 +14,15 @@ include "system/inclrtl" type - IRune = int # underlying type of TRune - TRune* = distinct IRune ## type that can hold any Unicode character - TRune16* = distinct int16 ## 16 bit Unicode character + RuneImpl = int # underlying type of Rune + Rune* = distinct RuneImpl ## type that can hold any Unicode character + Rune16* = distinct int16 ## 16 bit Unicode character + +{.deprecated: [TRune: Rune, TRune16: Rune16].} -proc `<=%`*(a, b: TRune): bool = return int(a) <=% int(b) -proc `<%`*(a, b: TRune): bool = return int(a) <% int(b) -proc `==`*(a, b: TRune): bool = return int(a) == int(b) +proc `<=%`*(a, b: Rune): bool = return int(a) <=% int(b) +proc `<%`*(a, b: Rune): bool = return int(a) <% int(b) +proc `==`*(a, b: Rune): bool = return int(a) == int(b) template ones(n: expr): expr = ((1 shl n)-1) @@ -52,17 +54,17 @@ template fastRuneAt*(s: string, i: int, result: expr, doInc = true) = ## `i` is incremented by the number of bytes that have been processed. bind ones if ord(s[i]) <=% 127: - result = TRune(ord(s[i])) + result = Rune(ord(s[i])) when doInc: inc(i) elif ord(s[i]) shr 5 == 0b110: # assert(ord(s[i+1]) shr 6 == 0b10) - result = TRune((ord(s[i]) and (ones(5))) shl 6 or - (ord(s[i+1]) and ones(6))) + result = Rune((ord(s[i]) and (ones(5))) shl 6 or + (ord(s[i+1]) and ones(6))) when doInc: inc(i, 2) elif ord(s[i]) shr 4 == 0b1110: # assert(ord(s[i+1]) shr 6 == 0b10) # assert(ord(s[i+2]) shr 6 == 0b10) - result = TRune((ord(s[i]) and ones(4)) shl 12 or + result = Rune((ord(s[i]) and ones(4)) shl 12 or (ord(s[i+1]) and ones(6)) shl 6 or (ord(s[i+2]) and ones(6))) when doInc: inc(i, 3) @@ -70,7 +72,7 @@ template fastRuneAt*(s: string, i: int, result: expr, doInc = true) = # assert(ord(s[i+1]) shr 6 == 0b10) # assert(ord(s[i+2]) shr 6 == 0b10) # assert(ord(s[i+3]) shr 6 == 0b10) - result = TRune((ord(s[i]) and ones(3)) shl 18 or + result = Rune((ord(s[i]) and ones(3)) shl 18 or (ord(s[i+1]) and ones(6)) shl 12 or (ord(s[i+2]) and ones(6)) shl 6 or (ord(s[i+3]) and ones(6))) @@ -80,7 +82,7 @@ template fastRuneAt*(s: string, i: int, result: expr, doInc = true) = # assert(ord(s[i+2]) shr 6 == 0b10) # assert(ord(s[i+3]) shr 6 == 0b10) # assert(ord(s[i+4]) shr 6 == 0b10) - result = TRune((ord(s[i]) and ones(2)) shl 24 or + result = Rune((ord(s[i]) and ones(2)) shl 24 or (ord(s[i+1]) and ones(6)) shl 18 or (ord(s[i+2]) and ones(6)) shl 12 or (ord(s[i+3]) and ones(6)) shl 6 or @@ -92,7 +94,7 @@ template fastRuneAt*(s: string, i: int, result: expr, doInc = true) = # assert(ord(s[i+3]) shr 6 == 0b10) # assert(ord(s[i+4]) shr 6 == 0b10) # assert(ord(s[i+5]) shr 6 == 0b10) - result = TRune((ord(s[i]) and ones(1)) shl 30 or + result = Rune((ord(s[i]) and ones(1)) shl 30 or (ord(s[i+1]) and ones(6)) shl 24 or (ord(s[i+2]) and ones(6)) shl 18 or (ord(s[i+3]) and ones(6)) shl 12 or @@ -100,16 +102,16 @@ template fastRuneAt*(s: string, i: int, result: expr, doInc = true) = (ord(s[i+5]) and ones(6))) when doInc: inc(i, 6) else: - result = TRune(ord(s[i])) + result = Rune(ord(s[i])) when doInc: inc(i) -proc runeAt*(s: string, i: int): TRune = +proc runeAt*(s: string, i: int): Rune = ## returns the unicode character in `s` at byte index `i` fastRuneAt(s, i, result, false) -proc toUTF8*(c: TRune): string {.rtl, extern: "nuc$1".} = +proc toUTF8*(c: Rune): string {.rtl, extern: "nuc$1".} = ## converts a rune into its UTF8 representation - var i = IRune(c) + var i = RuneImpl(c) if i <=% 127: result = newString(1) result[0] = chr(i) @@ -132,11 +134,11 @@ proc toUTF8*(c: TRune): string {.rtl, extern: "nuc$1".} = result = newString(1) result[0] = chr(i) -proc `$`*(rune: TRune): string = +proc `$`*(rune: Rune): string = ## converts a rune to a string rune.toUTF8 -proc `$`*(runes: seq[TRune]): string = +proc `$`*(runes: seq[Rune]): string = ## converts a sequence of runes to a string result = "" for rune in runes: result.add(rune.toUTF8) @@ -1100,7 +1102,7 @@ const 0x01f1, 501, # 0x01f3, 499] # -proc binarySearch(c: IRune, tab: openArray[IRune], len, stride: int): int = +proc binarySearch(c: RuneImpl, tab: openArray[RuneImpl], len, stride: int): int = var n = len var t = 0 while n > 1: @@ -1115,41 +1117,41 @@ proc binarySearch(c: IRune, tab: openArray[IRune], len, stride: int): int = return t return -1 -proc toLower*(c: TRune): TRune {.rtl, extern: "nuc$1", procvar.} = +proc toLower*(c: Rune): Rune {.rtl, extern: "nuc$1", procvar.} = ## Converts `c` into lower case. This works for any Unicode character. ## If possible, prefer `toLower` over `toUpper`. - var c = IRune(c) + var c = RuneImpl(c) var p = binarySearch(c, tolowerRanges, len(tolowerRanges) div 3, 3) if p >= 0 and c >= tolowerRanges[p] and c <= tolowerRanges[p+1]: - return TRune(c + tolowerRanges[p+2] - 500) + return Rune(c + tolowerRanges[p+2] - 500) p = binarySearch(c, tolowerSinglets, len(tolowerSinglets) div 2, 2) if p >= 0 and c == tolowerSinglets[p]: - return TRune(c + tolowerSinglets[p+1] - 500) - return TRune(c) + return Rune(c + tolowerSinglets[p+1] - 500) + return Rune(c) -proc toUpper*(c: TRune): TRune {.rtl, extern: "nuc$1", procvar.} = +proc toUpper*(c: Rune): Rune {.rtl, extern: "nuc$1", procvar.} = ## Converts `c` into upper case. This works for any Unicode character. ## If possible, prefer `toLower` over `toUpper`. - var c = IRune(c) + var c = RuneImpl(c) var p = binarySearch(c, toupperRanges, len(toupperRanges) div 3, 3) if p >= 0 and c >= toupperRanges[p] and c <= toupperRanges[p+1]: - return TRune(c + toupperRanges[p+2] - 500) + return Rune(c + toupperRanges[p+2] - 500) p = binarySearch(c, toupperSinglets, len(toupperSinglets) div 2, 2) if p >= 0 and c == toupperSinglets[p]: - return TRune(c + toupperSinglets[p+1] - 500) - return TRune(c) + return Rune(c + toupperSinglets[p+1] - 500) + return Rune(c) -proc toTitle*(c: TRune): TRune {.rtl, extern: "nuc$1", procvar.} = - var c = IRune(c) +proc toTitle*(c: Rune): Rune {.rtl, extern: "nuc$1", procvar.} = + var c = RuneImpl(c) var p = binarySearch(c, toTitleSinglets, len(toTitleSinglets) div 2, 2) if p >= 0 and c == toTitleSinglets[p]: - return TRune(c + toTitleSinglets[p+1] - 500) - return TRune(c) + return Rune(c + toTitleSinglets[p+1] - 500) + return Rune(c) -proc isLower*(c: TRune): bool {.rtl, extern: "nuc$1", procvar.} = +proc isLower*(c: Rune): bool {.rtl, extern: "nuc$1", procvar.} = ## returns true iff `c` is a lower case Unicode character ## If possible, prefer `isLower` over `isUpper`. - var c = IRune(c) + var c = RuneImpl(c) # Note: toUpperRanges is correct here! var p = binarySearch(c, toupperRanges, len(toupperRanges) div 3, 3) if p >= 0 and c >= toupperRanges[p] and c <= toupperRanges[p+1]: @@ -1158,10 +1160,10 @@ proc isLower*(c: TRune): bool {.rtl, extern: "nuc$1", procvar.} = if p >= 0 and c == toupperSinglets[p]: return true -proc isUpper*(c: TRune): bool {.rtl, extern: "nuc$1", procvar.} = +proc isUpper*(c: Rune): bool {.rtl, extern: "nuc$1", procvar.} = ## returns true iff `c` is a upper case Unicode character ## If possible, prefer `isLower` over `isUpper`. - var c = IRune(c) + var c = RuneImpl(c) # Note: toLowerRanges is correct here! var p = binarySearch(c, tolowerRanges, len(tolowerRanges) div 3, 3) if p >= 0 and c >= tolowerRanges[p] and c <= tolowerRanges[p+1]: @@ -1170,11 +1172,11 @@ proc isUpper*(c: TRune): bool {.rtl, extern: "nuc$1", procvar.} = if p >= 0 and c == tolowerSinglets[p]: return true -proc isAlpha*(c: TRune): bool {.rtl, extern: "nuc$1", procvar.} = +proc isAlpha*(c: Rune): bool {.rtl, extern: "nuc$1", procvar.} = ## returns true iff `c` is an *alpha* Unicode character (i.e. a letter) if isUpper(c) or isLower(c): return true - var c = IRune(c) + var c = RuneImpl(c) var p = binarySearch(c, alphaRanges, len(alphaRanges) div 2, 2) if p >= 0 and c >= alphaRanges[p] and c <= alphaRanges[p+1]: return true @@ -1182,21 +1184,21 @@ proc isAlpha*(c: TRune): bool {.rtl, extern: "nuc$1", procvar.} = if p >= 0 and c == alphaSinglets[p]: return true -proc isTitle*(c: TRune): bool {.rtl, extern: "nuc$1", procvar.} = +proc isTitle*(c: Rune): bool {.rtl, extern: "nuc$1", procvar.} = return isUpper(c) and isLower(c) -proc isWhiteSpace*(c: TRune): bool {.rtl, extern: "nuc$1", procvar.} = +proc isWhiteSpace*(c: Rune): bool {.rtl, extern: "nuc$1", procvar.} = ## returns true iff `c` is a Unicode whitespace character - var c = IRune(c) + var c = RuneImpl(c) var p = binarySearch(c, spaceRanges, len(spaceRanges) div 2, 2) if p >= 0 and c >= spaceRanges[p] and c <= spaceRanges[p+1]: return true -iterator runes*(s: string): TRune = +iterator runes*(s: string): Rune = ## iterates over any unicode character of the string `s`. var i = 0 - result: TRune + result: Rune while i < len(s): fastRuneAt(s, i, result, true) yield result @@ -1209,12 +1211,12 @@ proc cmpRunesIgnoreCase*(a, b: string): int {.rtl, extern: "nuc$1", procvar.} = ## | > 0 iff a > b var i = 0 var j = 0 - var ar, br: TRune + var ar, br: Rune while i < a.len and j < b.len: # slow path: fastRuneAt(a, i, ar) fastRuneAt(b, j, br) - result = IRune(toLower(ar)) - IRune(toLower(br)) + result = RuneImpl(toLower(ar)) - RuneImpl(toLower(br)) if result != 0: return result = a.len - b.len diff --git a/lib/pure/unidecode/unidecode.nim b/lib/pure/unidecode/unidecode.nim index 1d36d11b5..798eef5d0 100644 --- a/lib/pure/unidecode/unidecode.nim +++ b/lib/pure/unidecode/unidecode.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -55,7 +55,7 @@ proc unidecode*(s: string): string = ## ## Example: ## - ## ..code-block:: nimrod + ## ..code-block:: nim ## ## unidecode("\x53\x17\x4E\xB0") ## diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim index 7cc95f0ad..fa2e30ef4 100644 --- a/lib/pure/unittest.nim +++ b/lib/pure/unittest.nim @@ -1,7 +1,7 @@ # # -# Nimrod's Runtime Library -# (c) Copyright 2012 Nimrod Contributors +# Nim's Runtime Library +# (c) Copyright 2012 Nim Contributors # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -26,19 +26,22 @@ when not defined(ECMAScript): import terminal type - TTestStatus* = enum OK, FAILED - TOutputLevel* = enum PRINT_ALL, PRINT_FAILURES, PRINT_NONE + TestStatus* = enum OK, FAILED + OutputLevel* = enum PRINT_ALL, PRINT_FAILURES, PRINT_NONE + +{.deprecated: [TTestStatus: TestStatus, TOutputLevel: OutputLevel]} var - # XXX: These better be thread-local - AbortOnError*: bool - OutputLevel*: TOutputLevel - ColorOutput*: bool + abortOnError* {.threadvar.}: bool + outputLevel* {.threadvar.}: OutputLevel + colorOutput* {.threadvar.}: bool - checkpoints: seq[string] = @[] + checkpoints {.threadvar.}: seq[string] + +checkpoints = @[] -template TestSetupIMPL*: stmt {.immediate, dirty.} = discard -template TestTeardownIMPL*: stmt {.immediate, dirty.} = discard +template testSetupIMPL*: stmt {.immediate, dirty.} = discard +template testTeardownIMPL*: stmt {.immediate, dirty.} = discard proc shouldRun(testName: string): bool = result = true @@ -46,21 +49,21 @@ proc shouldRun(testName: string): bool = template suite*(name: expr, body: stmt): stmt {.immediate, dirty.} = block: template setup*(setupBody: stmt): stmt {.immediate, dirty.} = - template TestSetupIMPL: stmt {.immediate, dirty.} = setupBody + template testSetupIMPL: stmt {.immediate, dirty.} = setupBody template teardown*(teardownBody: stmt): stmt {.immediate, dirty.} = - template TestTeardownIMPL: stmt {.immediate, dirty.} = teardownBody + template testTeardownIMPL: stmt {.immediate, dirty.} = teardownBody body -proc testDone(name: string, s: TTestStatus) = +proc testDone(name: string, s: TestStatus) = if s == FAILED: - program_result += 1 + programResult += 1 - if OutputLevel != PRINT_NONE and (OutputLevel == PRINT_ALL or s == FAILED): + if outputLevel != PRINT_NONE and (outputLevel == PRINT_ALL or s == FAILED): template rawPrint() = echo("[", $s, "] ", name, "\n") when not defined(ECMAScript): - if ColorOutput and not defined(ECMAScript): + if colorOutput and not defined(ECMAScript): var color = (if s == OK: fgGreen else: fgRed) styledEcho styleBright, color, "[", $s, "] ", fgWhite, name, "\n" else: @@ -73,10 +76,10 @@ template test*(name: expr, body: stmt): stmt {.immediate, dirty.} = if shouldRun(name): checkpoints = @[] - var TestStatusIMPL {.inject.} = OK + var testStatusIMPL {.inject.} = OK try: - TestSetupIMPL() + testSetupIMPL() body except: @@ -84,8 +87,8 @@ template test*(name: expr, body: stmt): stmt {.immediate, dirty.} = fail() finally: - TestTeardownIMPL() - testDone name, TestStatusIMPL + testTeardownIMPL() + testDone name, testStatusIMPL proc checkpoint*(msg: string) = checkpoints.add(msg) @@ -97,12 +100,12 @@ template fail* = echo msg when not defined(ECMAScript): - if AbortOnError: quit(1) + if abortOnError: quit(1) - when declared(TestStatusIMPL): - TestStatusIMPL = FAILED + when declared(testStatusIMPL): + testStatusIMPL = FAILED else: - program_result += 1 + programResult += 1 checkpoints = @[] @@ -192,15 +195,15 @@ when declared(stdout): ## Reading settings var envOutLvl = os.getEnv("NIMTEST_OUTPUT_LVL").string - AbortOnError = existsEnv("NIMTEST_ABORT_ON_ERROR") - ColorOutput = not existsEnv("NIMTEST_NO_COLOR") + abortOnError = existsEnv("NIMTEST_ABORT_ON_ERROR") + colorOutput = not existsEnv("NIMTEST_NO_COLOR") else: var envOutLvl = "" # TODO - ColorOutput = false + colorOutput = false if envOutLvl.len > 0: - for opt in countup(low(TOutputLevel), high(TOutputLevel)): + for opt in countup(low(OutputLevel), high(OutputLevel)): if $opt == envOutLvl: - OutputLevel = opt + outputLevel = opt break diff --git a/lib/pure/uri.nim b/lib/pure/uri.nim index 7ec823033..2c65d071e 100644 --- a/lib/pure/uri.nim +++ b/lib/pure/uri.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Dominik Picheta # # See the file "copying.txt", included in this @@ -11,12 +11,14 @@ import strutils, parseutils type - TUrl* = distinct string + Url* = distinct string - TUri* = object + Uri* = object scheme*, username*, password*: string hostname*, port*, path*, query*, anchor*: string +{.deprecated: [TUrl: Url, TUri: Uri].} + proc `$`*(url: TUrl): string {.deprecated.} = ## **Deprecated since 0.9.6**: Use ``TUri`` instead. return string(url) @@ -68,7 +70,7 @@ proc parsePath(uri: string, i: var int, result: var TUri) = i.inc parseUntil(uri, result.path, {'?', '#'}, i) # The 'mailto' scheme's PATH actually contains the hostname/username - if result.scheme.ToLower() == "mailto": + if result.scheme.toLower == "mailto": parseAuthority(result.path, result) result.path = "" @@ -172,7 +174,7 @@ proc combine*(base: TUri, reference: TUri): TUri = ## ## Examples: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let foo = combine(parseUri("http://example.com/foo/bar"), parseUri("/baz")) ## assert foo.path == "/baz" ## @@ -229,7 +231,7 @@ proc `/`*(x: TUri, path: string): TUri = ## ## Examples: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let foo = parseUri("http://example.com/foo/bar") / parseUri("/baz") ## assert foo.path == "/foo/bar/baz" ## diff --git a/lib/pure/xmldom.nim b/lib/pure/xmldom.nim index d63b6c5dd..660932d92 100644 --- a/lib/pure/xmldom.nim +++ b/lib/pure/xmldom.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Dominik Picheta # # See the file "copying.txt", included in this @@ -9,14 +9,15 @@ import strutils -## This module implements XML DOM Level 2 Core specification(http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html) +## This module implements XML DOM Level 2 Core +## specification (http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html) #http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html #Exceptions type - EDOMException* = object of EInvalidValue ## Base exception object for all DOM Exceptions + EDOMException* = object of ValueError ## Base exception object for all DOM Exceptions EDOMStringSizeErr* = object of EDOMException ## If the specified range of text does not fit into a DOMString ## Currently not used(Since DOMString is just string) EHierarchyRequestErr* = object of EDOMException ## If any node is inserted somewhere it doesn't belong @@ -55,24 +56,24 @@ type Feature = tuple[name: string, version: string] PDOMImplementation* = ref DOMImplementation DOMImplementation = object - Features: seq[Feature] # Read-Only + features: seq[Feature] # Read-Only PNode* = ref Node - Node = object of TObject + Node = object of RootObj attributes*: seq[PAttr] childNodes*: seq[PNode] - FLocalName: string # Read-only - FNamespaceURI: string # Read-only - FNodeName: string # Read-only + fLocalName: string # Read-only + fNamespaceURI: string # Read-only + fNodeName: string # Read-only nodeValue*: string - FNodeType: int # Read-only - FOwnerDocument: PDocument # Read-Only - FParentNode: PNode # Read-Only + fNodeType: int # Read-only + fOwnerDocument: PDocument # Read-Only + fParentNode: PNode # Read-Only prefix*: string # Setting this should change some values... TODO! PElement* = ref Element Element = object of Node - FTagName: string # Read-only + fTagName: string # Read-only PCharacterData* = ref CharacterData CharacterData = object of Node @@ -80,15 +81,15 @@ type PDocument* = ref Document Document = object of Node - FImplementation: PDOMImplementation # Read-only - FDocumentElement: PElement # Read-only + fImplementation: PDOMImplementation # Read-only + fDocumentElement: PElement # Read-only PAttr* = ref Attr Attr = object of Node - FName: string # Read-only - FSpecified: bool # Read-only + fName: string # Read-only + fSpecified: bool # Read-only value*: string - FOwnerElement: PElement # Read-only + fOwnerElement: PElement # Read-only PDocumentFragment* = ref DocumentFragment DocumentFragment = object of Node @@ -96,7 +97,7 @@ type PText* = ref Text Text = object of CharacterData - PComment* = ref comment + PComment* = ref Comment Comment = object of CharacterData PCDataSection* = ref CDataSection @@ -105,13 +106,13 @@ type PProcessingInstruction* = ref ProcessingInstruction ProcessingInstruction = object of Node data*: string - FTarget: string # Read-only + fTarget: string # Read-only # DOMImplementation proc getDOM*(): PDOMImplementation = ## Returns a DOMImplementation new(result) - result.Features = @[(name: "core", version: "2.0"), + result.features = @[(name: "core", version: "2.0"), (name: "core", version: "1.0"), (name: "XML", version: "2.0")] @@ -119,15 +120,15 @@ proc createDocument*(dom: PDOMImplementation, namespaceURI: string, qualifiedNam ## Creates an XML Document object of the specified type with its document element. var doc: PDocument new(doc) - doc.FNamespaceURI = namespaceURI - doc.FImplementation = dom + doc.fNamespaceURI = namespaceURI + doc.fImplementation = dom var elTag: PElement new(elTag) - elTag.FTagName = qualifiedName - elTag.FNodeName = qualifiedName - doc.FDocumentElement = elTag - doc.FNodeType = DocumentNode + elTag.fTagName = qualifiedName + elTag.fNodeName = qualifiedName + doc.fDocumentElement = elTag + doc.fNodeType = DocumentNode return doc @@ -137,32 +138,32 @@ proc createDocument*(dom: PDOMImplementation, n: PElement): PDocument = # This procedure is not in the specification, it's provided for the parser. var doc: PDocument new(doc) - doc.FDocumentElement = n - doc.FImplementation = dom - doc.FNodeType = DocumentNode + doc.fDocumentElement = n + doc.fImplementation = dom + doc.fNodeType = DocumentNode return doc proc hasFeature*(dom: PDOMImplementation, feature: string, version: string = ""): bool = ## Returns ``true`` if this ``version`` of the DomImplementation implements ``feature``, otherwise ``false`` - for iName, iVersion in items(dom.Features): + for iName, iVersion in items(dom.features): if iName == feature: if version == "": - return True + return true else: if iVersion == version: - return True - return False + return true + return false # Document # Attributes proc implementation*(doc: PDocument): PDOMImplementation = - return doc.FImplementation + return doc.fImplementation proc documentElement*(doc: PDocument): PElement = - return doc.FDocumentElement + return doc.fDocumentElement # Internal procedures proc findNodes(nl: PNode, name: string): seq[PNode] = @@ -172,8 +173,8 @@ proc findNodes(nl: PNode, name: string): seq[PNode] = if nl.childNodes.len() == 0: return @[] for i in items(nl.childNodes): - if i.FNodeType == ElementNode: - if i.FNodeName == name or name == "*": + if i.fNodeType == ElementNode: + if i.fNodeName == name or name == "*": r.add(i) if not isNil(i.childNodes): @@ -189,8 +190,8 @@ proc findNodesNS(nl: PNode, namespaceURI: string, localName: string): seq[PNode] if nl.childNodes.len() == 0: return @[] for i in items(nl.childNodes): - if i.FNodeType == ElementNode: - if (i.FNamespaceURI == namespaceURI or namespaceURI == "*") and (i.FLocalName == localName or localName == "*"): + if i.fNodeType == ElementNode: + if (i.fNamespaceURI == namespaceURI or namespaceURI == "*") and (i.fLocalName == localName or localName == "*"): r.add(i) if not isNil(i.childNodes): @@ -209,16 +210,16 @@ proc createAttribute*(doc: PDocument, name: string): PAttr = if illegalChars in name: raise newException(EInvalidCharacterErr, "Invalid character") - var AttrNode: PAttr - new(AttrNode) - AttrNode.FName = name - AttrNode.FNodeName = name - AttrNode.FLocalName = nil - AttrNode.prefix = nil - AttrNode.FNamespaceURI = nil - AttrNode.value = "" - AttrNode.FSpecified = False - return AttrNode + var attrNode: PAttr + new(attrNode) + attrNode.fName = name + attrNode.fNodeName = name + attrNode.fLocalName = nil + attrNode.prefix = nil + attrNode.fNamespaceURI = nil + attrNode.value = "" + attrNode.fSpecified = false + return attrNode proc createAttributeNS*(doc: PDocument, namespaceURI: string, qualifiedName: string): PAttr = ## Creates an attribute of the given qualified name and namespace URI @@ -237,48 +238,48 @@ proc createAttributeNS*(doc: PDocument, namespaceURI: string, qualifiedName: str raise newException(ENamespaceErr, "When the namespace prefix is \"xmlns\" namespaceURI has to be \"http://www.w3.org/2000/xmlns/\"") - var AttrNode: PAttr - new(AttrNode) - AttrNode.FName = qualifiedName - AttrNode.FNodeName = qualifiedName - AttrNode.FSpecified = False - AttrNode.FNamespaceURI = namespaceURI + var attrNode: PAttr + new(attrNode) + attrNode.fName = qualifiedName + attrNode.fNodeName = qualifiedName + attrNode.fSpecified = false + attrNode.fNamespaceURI = namespaceURI if qualifiedName.contains(':'): - AttrNode.prefix = qualifiedName.split(':')[0] - AttrNode.FLocalName = qualifiedName.split(':')[1] + attrNode.prefix = qualifiedName.split(':')[0] + attrNode.fLocalName = qualifiedName.split(':')[1] else: - AttrNode.prefix = nil - AttrNode.FLocalName = qualifiedName - AttrNode.value = "" + attrNode.prefix = nil + attrNode.fLocalName = qualifiedName + attrNode.value = "" - AttrNode.FNodeType = AttributeNode - return AttrNode + attrNode.fNodeType = AttributeNode + return attrNode -proc createCDATASection*(doc: PDocument, data: string): PCDATASection = +proc createCDATASection*(doc: PDocument, data: string): PCDataSection = ## Creates a CDATASection node whose value is the specified string. - var CData: PCDATASection - new(CData) - CData.data = data - CData.nodeValue = data - CData.FNodeName = "#text" # Not sure about this, but this is technically a TextNode - CData.FNodeType = CDataSectionNode - return CData + var cData: PCDataSection + new(cData) + cData.data = data + cData.nodeValue = data + cData.fNodeName = "#text" # Not sure about this, but this is technically a TextNode + cData.fNodeType = CDataSectionNode + return cData proc createComment*(doc: PDocument, data: string): PComment = ## Creates a Comment node given the specified string. - var Comm: PComment - new(Comm) - Comm.data = data - Comm.nodeValue = data + var comm: PComment + new(comm) + comm.data = data + comm.nodeValue = data - Comm.FNodeType = CommentNode - return Comm + comm.fNodeType = CommentNode + return comm proc createDocumentFragment*(doc: PDocument): PDocumentFragment = ## Creates an empty DocumentFragment object. - var DF: PDocumentFragment - new(DF) - return DF + var df: PDocumentFragment + new(df) + return df proc createElement*(doc: PDocument, tagName: string): PElement = ## Creates an element of the type specified. @@ -289,22 +290,22 @@ proc createElement*(doc: PDocument, tagName: string): PElement = var elNode: PElement new(elNode) - elNode.FTagName = tagName - elNode.FNodeName = tagName - elNode.FLocalName = nil + elNode.fTagName = tagName + elNode.fNodeName = tagName + elNode.fLocalName = nil elNode.prefix = nil - elNode.FNamespaceURI = nil + elNode.fNamespaceURI = nil elNode.childNodes = @[] elNode.attributes = @[] - elNode.FNodeType = ElementNode + elNode.fNodeType = ElementNode return elNode proc createElementNS*(doc: PDocument, namespaceURI: string, qualifiedName: string): PElement = ## Creates an element of the given qualified name and namespace URI. if qualifiedName.contains(':'): - if isNIl(namespaceURI): + if isNil(namespaceURI): raise newException(ENamespaceErr, "When qualifiedName contains a prefix namespaceURI cannot be nil") elif qualifiedName.split(':')[0].toLower() == "xml" and namespaceURI != "http://www.w3.org/XML/1998/namespace": raise newException(ENamespaceErr, @@ -316,19 +317,19 @@ proc createElementNS*(doc: PDocument, namespaceURI: string, qualifiedName: strin var elNode: PElement new(elNode) - elNode.FTagName = qualifiedName - elNode.FNodeName = qualifiedName + elNode.fTagName = qualifiedName + elNode.fNodeName = qualifiedName if qualifiedName.contains(':'): elNode.prefix = qualifiedName.split(':')[0] - elNode.FLocalName = qualifiedName.split(':')[1] + elNode.fLocalName = qualifiedName.split(':')[1] else: elNode.prefix = nil - elNode.FLocalName = qualifiedName - elNode.FNamespaceURI = namespaceURI + elNode.fLocalName = qualifiedName + elNode.fNamespaceURI = namespaceURI elNode.childNodes = @[] elNode.attributes = @[] - elNode.FNodeType = ElementNode + elNode.fNodeType = ElementNode return elNode @@ -339,12 +340,12 @@ proc createProcessingInstruction*(doc: PDocument, target: string, data: string): if illegalChars in target: raise newException(EInvalidCharacterErr, "Invalid character") - var PI: PProcessingInstruction - new(PI) - PI.FTarget = target - PI.data = data - PI.FNodeType = ProcessingInstructionNode - return PI + var pi: PProcessingInstruction + new(pi) + pi.fTarget = target + pi.data = data + pi.fNodeType = ProcessingInstructionNode + return pi proc createTextNode*(doc: PDocument, data: string): PText = #Propably TextNode ## Creates a Text node given the specified string. @@ -352,9 +353,9 @@ proc createTextNode*(doc: PDocument, data: string): PText = #Propably TextNode new(txtNode) txtNode.data = data txtNode.nodeValue = data - txtNode.FNodeName = "#text" + txtNode.fNodeName = "#text" - txtNode.FNodeType = TextNode + txtNode.fNodeType = TextNode return txtNode discard """proc getElementById*(doc: PDocument, elementId: string): PElement = @@ -365,42 +366,42 @@ proc getElementsByTagName*(doc: PDocument, tagName: string): seq[PNode] = ## Returns a NodeList of all the Elements with a given tag name in ## the order in which they are encountered in a preorder traversal of the Document tree. var result: seq[PNode] = @[] - if doc.FDocumentElement.FNodeName == tagName or tagName == "*": - result.add(doc.FDocumentElement) + if doc.fDocumentElement.fNodeName == tagName or tagName == "*": + result.add(doc.fDocumentElement) - result.add(doc.FDocumentElement.findNodes(tagName)) + result.add(doc.fDocumentElement.findNodes(tagName)) return result proc getElementsByTagNameNS*(doc: PDocument, namespaceURI: string, localName: string): seq[PNode] = ## Returns a NodeList of all the Elements with a given localName and namespaceURI ## in the order in which they are encountered in a preorder traversal of the Document tree. var result: seq[PNode] = @[] - if doc.FDocumentElement.FLocalName == localName or localName == "*": - if doc.FDocumentElement.FNamespaceURI == namespaceURI or namespaceURI == "*": - result.add(doc.FDocumentElement) + if doc.fDocumentElement.fLocalName == localName or localName == "*": + if doc.fDocumentElement.fNamespaceURI == namespaceURI or namespaceURI == "*": + result.add(doc.fDocumentElement) - result.add(doc.FDocumentElement.findNodesNS(namespaceURI, localName)) + result.add(doc.fDocumentElement.findNodesNS(namespaceURI, localName)) return result proc importNode*(doc: PDocument, importedNode: PNode, deep: bool): PNode = ## Imports a node from another document to this document - case importedNode.FNodeType + case importedNode.fNodeType of AttributeNode: var nAttr: PAttr = PAttr(importedNode) - nAttr.FOwnerDocument = doc - nAttr.FParentNode = nil - nAttr.FOwnerElement = nil - nAttr.FSpecified = True + nAttr.fOwnerDocument = doc + nAttr.fParentNode = nil + nAttr.fOwnerElement = nil + nAttr.fSpecified = true return nAttr of DocumentFragmentNode: var n: PNode new(n) n = importedNode - n.FOwnerDocument = doc - n.FParentNode = nil + n.fOwnerDocument = doc + n.fParentNode = nil - n.FOwnerDocument = doc - n.FParentNode = nil + n.fOwnerDocument = doc + n.fParentNode = nil var tmp: seq[PNode] = n.childNodes n.childNodes = @[] if deep: @@ -412,8 +413,8 @@ proc importNode*(doc: PDocument, importedNode: PNode, deep: bool): PNode = var n: PNode new(n) n = importedNode - n.FOwnerDocument = doc - n.FParentNode = nil + n.fOwnerDocument = doc + n.fParentNode = nil var tmpA: seq[PAttr] = n.attributes n.attributes = @[] @@ -432,8 +433,8 @@ proc importNode*(doc: PDocument, importedNode: PNode, deep: bool): PNode = var n: PNode new(n) n = importedNode - n.FOwnerDocument = doc - n.FParentNode = nil + n.fOwnerDocument = doc + n.fParentNode = nil return n else: raise newException(ENotSupportedErr, "The type of node being imported is not supported") @@ -461,58 +462,58 @@ proc lastChild*(n: PNode): PNode = proc localName*(n: PNode): string = ## Returns this nodes local name - return n.FLocalName + return n.fLocalName proc namespaceURI*(n: PNode): string = ## Returns this nodes namespace URI - return n.FNamespaceURI + return n.fNamespaceURI proc `namespaceURI=`*(n: PNode, value: string) = - n.FNamespaceURI = value + n.fNamespaceURI = value proc nextSibling*(n: PNode): PNode = ## Returns the next sibling of this node - if isNil(n.FParentNode) or isNil(n.FParentNode.childNodes): + if isNil(n.fParentNode) or isNil(n.fParentNode.childNodes): return nil - var nLow: int = low(n.FParentNode.childNodes) - var nHigh: int = high(n.FParentNode.childNodes) + var nLow: int = low(n.fParentNode.childNodes) + var nHigh: int = high(n.fParentNode.childNodes) for i in nLow..nHigh: - if n.FParentNode.childNodes[i] == n: - return n.FParentNode.childNodes[i + 1] + if n.fParentNode.childNodes[i] == n: + return n.fParentNode.childNodes[i + 1] return nil proc nodeName*(n: PNode): string = ## Returns the name of this node - return n.FNodeName + return n.fNodeName proc nodeType*(n: PNode): int = ## Returns the type of this node - return n.FNodeType + return n.fNodeType proc ownerDocument*(n: PNode): PDocument = ## Returns the owner document of this node - return n.FOwnerDocument + return n.fOwnerDocument proc parentNode*(n: PNode): PNode = ## Returns the parent node of this node - return n.FParentNode + return n.fParentNode proc previousSibling*(n: PNode): PNode = ## Returns the previous sibling of this node - if isNil(n.FParentNode) or isNil(n.FParentNode.childNodes): + if isNil(n.fParentNode) or isNil(n.fParentNode.childNodes): return nil - var nLow: int = low(n.FParentNode.childNodes) - var nHigh: int = high(n.FParentNode.childNodes) + var nLow: int = low(n.fParentNode.childNodes) + var nHigh: int = high(n.fParentNode.childNodes) for i in nLow..nHigh: - if n.FParentNode.childNodes[i] == n: - return n.FParentNode.childNodes[i - 1] + if n.fParentNode.childNodes[i] == n: + return n.fParentNode.childNodes[i - 1] return nil proc `prefix=`*(n: PNode, value: string) = @@ -523,25 +524,25 @@ proc `prefix=`*(n: PNode, value: string) = if illegalChars in value: raise newException(EInvalidCharacterErr, "Invalid character") - if isNil(n.FNamespaceURI): + if isNil(n.fNamespaceURI): raise newException(ENamespaceErr, "namespaceURI cannot be nil") - elif value.toLower() == "xml" and n.FNamespaceURI != "http://www.w3.org/XML/1998/namespace": + elif value.toLower() == "xml" and n.fNamespaceURI != "http://www.w3.org/XML/1998/namespace": raise newException(ENamespaceErr, "When the namespace prefix is \"xml\" namespaceURI has to be \"http://www.w3.org/XML/1998/namespace\"") - elif value.toLower() == "xmlns" and n.FNamespaceURI != "http://www.w3.org/2000/xmlns/": + elif value.toLower() == "xmlns" and n.fNamespaceURI != "http://www.w3.org/2000/xmlns/": raise newException(ENamespaceErr, "When the namespace prefix is \"xmlns\" namespaceURI has to be \"http://www.w3.org/2000/xmlns/\"") - elif value.toLower() == "xmlns" and n.FNodeType == AttributeNode: + elif value.toLower() == "xmlns" and n.fNodeType == AttributeNode: raise newException(ENamespaceErr, "An AttributeNode cannot have a prefix of \"xmlns\"") - n.FNodeName = value & ":" & n.FLocalName + n.fNodeName = value & ":" & n.fLocalName if n.nodeType == ElementNode: var el: PElement = PElement(n) - el.FTagName = value & ":" & n.FLocalName + el.fTagName = value & ":" & n.fLocalName elif n.nodeType == AttributeNode: var attr: PAttr = PAttr(n) - attr.FName = value & ":" & n.FLocalName + attr.fName = value & ":" & n.fLocalName # Procedures proc appendChild*(n: PNode, newChild: PNode) = @@ -555,7 +556,7 @@ proc appendChild*(n: PNode, newChild: PNode) = raise newException(EHierarchyRequestErr, "The node to append is already in this nodes children.") # Check if newChild is from this nodes document - if n.FOwnerDocument != newChild.FOwnerDocument: + if n.fOwnerDocument != newChild.fOwnerDocument: raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.") if n == newChild: @@ -566,7 +567,7 @@ proc appendChild*(n: PNode, newChild: PNode) = if isNil(n.childNodes): n.childNodes = @[] - newChild.FParentNode = n + newChild.fParentNode = n for i in low(n.childNodes)..high(n.childNodes): if n.childNodes[i] == newChild: n.childNodes[i] = newChild @@ -575,13 +576,13 @@ proc appendChild*(n: PNode, newChild: PNode) = proc cloneNode*(n: PNode, deep: bool): PNode = ## Returns a duplicate of this node, if ``deep`` is `true`, Element node's children are copied - case n.FNodeType + case n.fNodeType of AttributeNode: var newNode: PAttr new(newNode) newNode = PAttr(n) - newNode.FSpecified = True - newNode.FOwnerElement = nil + newNode.fSpecified = true + newNode.fOwnerElement = nil return newNode of ElementNode: var newNode: PElement @@ -613,32 +614,32 @@ proc insertBefore*(n: PNode, newChild: PNode, refChild: PNode): PNode = ## If ``refChild`` is nil, insert ``newChild`` at the end of the list of children. # Check if newChild is from this nodes document - if n.FOwnerDocument != newChild.FOwnerDocument: + if n.fOwnerDocument != newChild.fOwnerDocument: raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.") if isNil(n.childNodes): - n.ChildNodes = @[] + n.childNodes = @[] for i in low(n.childNodes)..high(n.childNodes): if n.childNodes[i] == refChild: n.childNodes.insert(newChild, i - 1) return - n.ChildNodes.add(newChild) + n.childNodes.add(newChild) proc isSupported*(n: PNode, feature: string, version: string): bool = ## Tests whether the DOM implementation implements a specific ## feature and that feature is supported by this node. - return n.FOwnerDocument.FImplementation.hasFeature(feature, version) + return n.fOwnerDocument.fImplementation.hasFeature(feature, version) proc isEmpty(s: string): bool = if isNil(s) or s == "": - return True + return true for i in items(s): if i != ' ': - return False - return True + return false + return true proc normalize*(n: PNode) = ## Merges all seperated TextNodes together, and removes any empty TextNodes @@ -646,7 +647,7 @@ proc normalize*(n: PNode) = var i: int = 0 var newChildNodes: seq[PNode] = @[] - while True: + while true: if isNil(n.childNodes) or i >= n.childNodes.len: break if n.childNodes[i].nodeType == TextNode: @@ -684,7 +685,7 @@ proc replaceChild*(n: PNode, newChild: PNode, oldChild: PNode): PNode = ## Replaces the child node ``oldChild`` with ``newChild`` in the list of children, and returns the ``oldChild`` node. # Check if newChild is from this nodes document - if n.FOwnerDocument != newChild.FOwnerDocument: + if n.fOwnerDocument != newChild.fOwnerDocument: raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.") if not isNil(n.childNodes): @@ -698,159 +699,159 @@ proc replaceChild*(n: PNode, newChild: PNode, oldChild: PNode): PNode = # NamedNodeMap -proc getNamedItem*(NList: seq[PNode], name: string): PNode = +proc getNamedItem*(nList: seq[PNode], name: string): PNode = ## Retrieves a node specified by ``name``. If this node cannot be found returns ``nil`` - for i in items(NList): + for i in items(nList): if i.nodeName() == name: return i return nil -proc getNamedItem*(NList: seq[PAttr], name: string): PAttr = +proc getNamedItem*(nList: seq[PAttr], name: string): PAttr = ## Retrieves a node specified by ``name``. If this node cannot be found returns ``nil`` - for i in items(NList): + for i in items(nList): if i.nodeName() == name: return i return nil -proc getNamedItemNS*(NList: seq[PNode], namespaceURI: string, localName: string): PNode = +proc getNamedItemNS*(nList: seq[PNode], namespaceURI: string, localName: string): PNode = ## Retrieves a node specified by ``localName`` and ``namespaceURI``. If this node cannot be found returns ``nil`` - for i in items(NList): + for i in items(nList): if i.namespaceURI() == namespaceURI and i.localName() == localName: return i return nil -proc getNamedItemNS*(NList: seq[PAttr], namespaceURI: string, localName: string): PAttr = +proc getNamedItemNS*(nList: seq[PAttr], namespaceURI: string, localName: string): PAttr = ## Retrieves a node specified by ``localName`` and ``namespaceURI``. If this node cannot be found returns ``nil`` - for i in items(NList): - if i.NamespaceURI() == namespaceURI and i.LocalName() == localName: + for i in items(nList): + if i.namespaceURI() == namespaceURI and i.localName() == localName: return i return nil -proc item*(NList: seq[PNode], index: int): PNode = +proc item*(nList: seq[PNode], index: int): PNode = ## Returns the ``index`` th item in the map. ## If ``index`` is greater than or equal to the number of nodes in this map, this returns ``nil``. - if index >= NList.len(): return nil - else: return NList[index] + if index >= nList.len(): return nil + else: return nList[index] -proc removeNamedItem*(NList: var seq[PNode], name: string): PNode = +proc removeNamedItem*(nList: var seq[PNode], name: string): PNode = ## Removes a node specified by ``name`` ## Raises the ``ENotFoundErr`` exception, if the node was not found - for i in low(NList)..high(NList): - if NList[i].FNodeName == name: - result = NList[i] - NList.delete(i) + for i in low(nList)..high(nList): + if nList[i].fNodeName == name: + result = nList[i] + nList.delete(i) return result raise newException(ENotFoundErr, "Node not found") -proc removeNamedItemNS*(NList: var seq[PNode], namespaceURI: string, localName: string): PNode = +proc removeNamedItemNS*(nList: var seq[PNode], namespaceURI: string, localName: string): PNode = ## Removes a node specified by local name and namespace URI - for i in low(NList)..high(NList): - if NList[i].FLocalName == localName and NList[i].FNamespaceURI == namespaceURI: - result = NList[i] - NList.delete(i) + for i in low(nList)..high(nList): + if nList[i].fLocalName == localName and nList[i].fNamespaceURI == namespaceURI: + result = nList[i] + nList.delete(i) return result raise newException(ENotFoundErr, "Node not found") -proc setNamedItem*(NList: var seq[PNode], arg: PNode): PNode = +proc setNamedItem*(nList: var seq[PNode], arg: PNode): PNode = ## Adds ``arg`` as a ``Node`` to the ``NList`` ## If a node with the same name is already present in this map, it is replaced by the new one. - if not isNil(NList): - if NList.len() > 0: + if not isNil(nList): + if nList.len() > 0: #Check if newChild is from this nodes document - if NList[0].FOwnerDocument != arg.FOwnerDocument: + if nList[0].fOwnerDocument != arg.fOwnerDocument: raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.") #Exceptions End - var item: PNode = NList.getNamedItem(arg.NodeName()) + var item: PNode = nList.getNamedItem(arg.nodeName()) if isNil(item): - NList.add(arg) + nList.add(arg) return nil else: # Node with the same name exists var index: int = 0 - for i in low(NList)..high(NList): - if NList[i] == item: + for i in low(nList)..high(nList): + if nList[i] == item: index = i break - NList[index] = arg + nList[index] = arg return item # Return the replaced node -proc setNamedItem*(NList: var seq[PAttr], arg: PAttr): PAttr = +proc setNamedItem*(nList: var seq[PAttr], arg: PAttr): PAttr = ## Adds ``arg`` as a ``Node`` to the ``NList`` ## If a node with the same name is already present in this map, it is replaced by the new one. - if not isNil(NList): - if NList.len() > 0: + if not isNil(nList): + if nList.len() > 0: # Check if newChild is from this nodes document - if NList[0].FOwnerDocument != arg.FOwnerDocument: + if nList[0].fOwnerDocument != arg.fOwnerDocument: raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.") - if not isNil(arg.FOwnerElement): + if not isNil(arg.fOwnerElement): raise newException(EInuseAttributeErr, "This attribute is in use by another element, use cloneNode") # Exceptions end - var item: PAttr = NList.getNamedItem(arg.nodeName()) + var item: PAttr = nList.getNamedItem(arg.nodeName()) if isNil(item): - NList.add(arg) + nList.add(arg) return nil else: # Node with the same name exists var index: int = 0 - for i in low(NList)..high(NList): - if NList[i] == item: + for i in low(nList)..high(nList): + if nList[i] == item: index = i break - NList[index] = arg + nList[index] = arg return item # Return the replaced node -proc setNamedItemNS*(NList: var seq[PNode], arg: PNode): PNode = +proc setNamedItemNS*(nList: var seq[PNode], arg: PNode): PNode = ## Adds a node using its ``namespaceURI`` and ``localName`` - if not isNil(NList): - if NList.len() > 0: + if not isNil(nList): + if nList.len() > 0: # Check if newChild is from this nodes document - if NList[0].FOwnerDocument != arg.FOwnerDocument: + if nList[0].fOwnerDocument != arg.fOwnerDocument: raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.") #Exceptions end - var item: PNode = NList.getNamedItemNS(arg.namespaceURI(), arg.localName()) + var item: PNode = nList.getNamedItemNS(arg.namespaceURI(), arg.localName()) if isNil(item): - NList.add(arg) + nList.add(arg) return nil else: # Node with the same name exists var index: int = 0 - for i in low(NList)..high(NList): - if NList[i] == item: + for i in low(nList)..high(nList): + if nList[i] == item: index = i break - NList[index] = arg + nList[index] = arg return item # Return the replaced node -proc setNamedItemNS*(NList: var seq[PAttr], arg: PAttr): PAttr = +proc setNamedItemNS*(nList: var seq[PAttr], arg: PAttr): PAttr = ## Adds a node using its ``namespaceURI`` and ``localName`` - if not isNil(NList): - if NList.len() > 0: + if not isNil(nList): + if nList.len() > 0: # Check if newChild is from this nodes document - if NList[0].FOwnerDocument != arg.FOwnerDocument: + if nList[0].fOwnerDocument != arg.fOwnerDocument: raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.") - if not isNil(arg.FOwnerElement): + if not isNil(arg.fOwnerElement): raise newException(EInuseAttributeErr, "This attribute is in use by another element, use cloneNode") # Exceptions end - var item: PAttr = NList.getNamedItemNS(arg.namespaceURI(), arg.localName()) + var item: PAttr = nList.getNamedItemNS(arg.namespaceURI(), arg.localName()) if isNil(item): - NList.add(arg) + nList.add(arg) return nil else: # Node with the same name exists var index: int = 0 - for i in low(NList)..high(NList): - if NList[i] == item: + for i in low(nList)..high(nList): + if nList[i] == item: index = i break - NList[index] = arg + nList[index] = arg return item # Return the replaced node # CharacterData - Decided to implement this, @@ -861,17 +862,17 @@ proc setNamedItemNS*(NList: var seq[PAttr], arg: PAttr): PAttr = proc name*(a: PAttr): string = ## Returns the name of the Attribute - return a.FName + return a.fName proc specified*(a: PAttr): bool = ## Specifies whether this attribute was specified in the original document - return a.FSpecified + return a.fSpecified proc ownerElement*(a: PAttr): PElement = ## Returns this Attributes owner element - return a.FOwnerElement + return a.fOwnerElement # Element # Attributes @@ -879,7 +880,7 @@ proc ownerElement*(a: PAttr): PElement = proc tagName*(el: PElement): string = ## Returns the Element Tag Name - return el.FTagName + return el.fTagName # Procedures proc getAttribute*(el: PElement, name: string): string = @@ -945,15 +946,15 @@ proc removeAttribute*(el: PElement, name: string) = ## Removes an attribute by ``name`` if not isNil(el.attributes): for i in low(el.attributes)..high(el.attributes): - if el.attributes[i].FName == name: + if el.attributes[i].fName == name: el.attributes.delete(i) proc removeAttributeNS*(el: PElement, namespaceURI: string, localName: string) = ## Removes an attribute by ``localName`` and ``namespaceURI`` if not isNil(el.attributes): for i in low(el.attributes)..high(el.attributes): - if el.attributes[i].FNamespaceURI == namespaceURI and - el.attributes[i].FLocalName == localName: + if el.attributes[i].fNamespaceURI == namespaceURI and + el.attributes[i].fLocalName == localName: el.attributes.delete(i) proc removeAttributeNode*(el: PElement, oldAttr: PAttr): PAttr = @@ -974,11 +975,11 @@ proc setAttributeNode*(el: PElement, newAttr: PAttr): PAttr = ## returned, otherwise ``nil`` is returned. # Check if newAttr is from this nodes document - if el.FOwnerDocument != newAttr.FOwnerDocument: + if el.fOwnerDocument != newAttr.fOwnerDocument: raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.") - if not isNil(newAttr.FOwnerElement): + if not isNil(newAttr.fOwnerElement): raise newException(EInuseAttributeErr, "This attribute is in use by another element, use cloneNode") # Exceptions end @@ -992,11 +993,11 @@ proc setAttributeNodeNS*(el: PElement, newAttr: PAttr): PAttr = ## and the replaced attribute is returned, otherwise ``nil`` is returned. # Check if newAttr is from this nodes document - if el.FOwnerDocument != newAttr.FOwnerDocument: + if el.fOwnerDocument != newAttr.fOwnerDocument: raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.") - if not isNil(newAttr.FOwnerElement): + if not isNil(newAttr.fOwnerElement): raise newException(EInuseAttributeErr, "This attribute is in use by another element, use cloneNode") # Exceptions end @@ -1010,17 +1011,17 @@ proc setAttribute*(el: PElement, name: string, value: string) = ## value is changed to be that of the value parameter ## Raises the EInvalidCharacterErr if the specified ``name`` contains ## illegal characters - var AttrNode = el.FOwnerDocument.createAttribute(name) + var attrNode = el.fOwnerDocument.createAttribute(name) # Check if name contains illegal characters if illegalChars in name: raise newException(EInvalidCharacterErr, "Invalid character") - discard el.setAttributeNode(AttrNode) + discard el.setAttributeNode(attrNode) # Set the info later, the setAttributeNode checks # if FOwnerElement is nil, and if it isn't it raises an exception - AttrNode.FOwnerElement = el - AttrNode.FSpecified = True - AttrNode.value = value + attrNode.fOwnerElement = el + attrNode.fSpecified = true + attrNode.value = value proc setAttributeNS*(el: PElement, namespaceURI, localName, value: string) = ## Adds a new attribute, as specified by ``namespaceURI``, ``localName`` @@ -1030,43 +1031,43 @@ proc setAttributeNS*(el: PElement, namespaceURI, localName, value: string) = if illegalChars in namespaceURI or illegalChars in localName: raise newException(EInvalidCharacterErr, "Invalid character") - var AttrNode = el.FOwnerDocument.createAttributeNS(namespaceURI, localName) + var attrNode = el.fOwnerDocument.createAttributeNS(namespaceURI, localName) - discard el.setAttributeNodeNS(AttrNode) + discard el.setAttributeNodeNS(attrNode) # Set the info later, the setAttributeNode checks # if FOwnerElement is nil, and if it isn't it raises an exception - AttrNode.FOwnerElement = el - AttrNode.FSpecified = True - AttrNode.value = value + attrNode.fOwnerElement = el + attrNode.fSpecified = true + attrNode.value = value # Text -proc splitData*(TextNode: PText, offset: int): PText = +proc splitData*(textNode: PText, offset: int): PText = ## Breaks this node into two nodes at the specified offset, ## keeping both in the tree as siblings. - if offset > TextNode.data.len(): + if offset > textNode.data.len(): raise newException(EIndexSizeErr, "Index out of bounds") - var left: string = TextNode.data.substr(0, offset) - TextNode.data = left - var right: string = TextNode.data.substr(offset, TextNode.data.len()) + var left: string = textNode.data.substr(0, offset) + textNode.data = left + var right: string = textNode.data.substr(offset, textNode.data.len()) - if not isNil(TextNode.FParentNode) and not isNil(TextNode.FParentNode.childNodes): - for i in low(TextNode.FParentNode.childNodes)..high(TextNode.FParentNode.childNodes): - if TextNode.FParentNode.childNodes[i] == TextNode: - var newNode: PText = TextNode.FOwnerDocument.createTextNode(right) - TextNode.FParentNode.childNodes.insert(newNode, i) + if not isNil(textNode.fParentNode) and not isNil(textNode.fParentNode.childNodes): + for i in low(textNode.fParentNode.childNodes)..high(textNode.fParentNode.childNodes): + if textNode.fParentNode.childNodes[i] == textNode: + var newNode: PText = textNode.fOwnerDocument.createTextNode(right) + textNode.fParentNode.childNodes.insert(newNode, i) return newNode else: - var newNode: PText = TextNode.FOwnerDocument.createTextNode(right) + var newNode: PText = textNode.fOwnerDocument.createTextNode(right) return newNode # ProcessingInstruction -proc target*(PI: PProcessingInstruction): string = +proc target*(pi: PProcessingInstruction): string = ## Returns the Processing Instructions target - return PI.FTarget + return pi.fTarget # --Other stuff-- diff --git a/lib/pure/xmldomparser.nim b/lib/pure/xmldomparser.nim index fda46bac0..7f34d72a8 100644 --- a/lib/pure/xmldomparser.nim +++ b/lib/pure/xmldomparser.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Dominik Picheta # # See the file "copying.txt", included in this @@ -15,13 +15,13 @@ import xmldom, os, streams, parsexml, strutils type # Parsing errors - EMismatchedTag* = object of EInvalidValue ## Raised when a tag is not properly closed - EParserError* = object of EInvalidValue ## Raised when an unexpected XML Parser event occurs + EMismatchedTag* = object of ValueError ## Raised when a tag is not properly closed + EParserError* = object of ValueError ## Raised when an unexpected XML Parser event occurs # For namespaces - xmlnsAttr = tuple[name, value: string, ownerElement: PElement] + XmlnsAttr = tuple[name, value: string, ownerElement: PElement] -var nsList: seq[xmlnsAttr] = @[] # Used for storing namespaces +var nsList: seq[XmlnsAttr] = @[] # Used for storing namespaces proc getNS(prefix: string): string = var defaultNS: seq[string] = @[] @@ -43,13 +43,13 @@ proc getNS(prefix: string): string = return "" -proc parseText(x: var TXmlParser, doc: var PDocument): PText = +proc parseText(x: var XmlParser, doc: var PDocument): PText = result = doc.createTextNode(x.charData()) -proc parseElement(x: var TXmlParser, doc: var PDocument): PElement = +proc parseElement(x: var XmlParser, doc: var PDocument): PElement = var n = doc.createElement("") - while True: + while true: case x.kind() of xmlEof: break @@ -102,10 +102,10 @@ proc parseElement(x: var TXmlParser, doc: var PDocument): PElement = of xmlComment: n.appendChild(doc.createComment(x.charData())) of xmlPI: - n.appendChild(doc.createProcessingInstruction(x.PIName(), x.PIRest())) + n.appendChild(doc.createProcessingInstruction(x.piName(), x.piRest())) of xmlWhitespace, xmlElementClose, xmlEntity, xmlSpecial: - # Unused 'events' + discard " Unused \'events\'" else: raise newException(EParserError, "Unexpected XML Parser event") @@ -114,30 +114,30 @@ proc parseElement(x: var TXmlParser, doc: var PDocument): PElement = raise newException(EMismatchedTag, "Mismatched tag at line " & $x.getLine() & " column " & $x.getColumn) -proc loadXMLStream*(stream: PStream): PDocument = +proc loadXMLStream*(stream: Stream): PDocument = ## Loads and parses XML from a stream specified by ``stream``, and returns ## a ``PDocument`` - var x: TXmlParser + var x: XmlParser open(x, stream, nil, {reportComments}) - var XmlDoc: PDocument - var DOM: PDOMImplementation = getDOM() + var xmlDoc: PDocument + var dom: PDOMImplementation = getDOM() - while True: + while true: x.next() case x.kind() of xmlEof: break of xmlElementStart, xmlElementOpen: - var el: PElement = parseElement(x, XmlDoc) - XmlDoc = dom.createDocument(el) + var el: PElement = parseElement(x, xmlDoc) + xmlDoc = dom.createDocument(el) of xmlWhitespace, xmlElementClose, xmlEntity, xmlSpecial: - # Unused 'events' + discard " Unused \'events\'" else: raise newException(EParserError, "Unexpected XML Parser event") - return XmlDoc + return xmlDoc proc loadXML*(xml: string): PDocument = ## Loads and parses XML from a string specified by ``xml``, and returns @@ -151,12 +151,12 @@ proc loadXMLFile*(path: string): PDocument = ## a ``PDocument`` var s = newFileStream(path, fmRead) - if s == nil: raise newException(EIO, "Unable to read file " & path) + if s == nil: raise newException(IOError, "Unable to read file " & path) return loadXMLStream(s) when isMainModule: - var xml = loadXMLFile(r"C:\Users\Dominik\Desktop\Code\Nimrod\xmldom\test.xml") + var xml = loadXMLFile("nim/xmldom/test.xml") #echo(xml.getElementsByTagName("m:test2")[0].namespaceURI) #echo(xml.getElementsByTagName("bla:test")[0].namespaceURI) #echo(xml.getElementsByTagName("test")[0].namespaceURI) diff --git a/lib/pure/xmlparser.nim b/lib/pure/xmlparser.nim index 8b8bb3b03..8591e894c 100644 --- a/lib/pure/xmlparser.nim +++ b/lib/pure/xmlparser.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this @@ -12,23 +12,25 @@ import streams, parsexml, strtabs, xmltree type - EInvalidXml* = object of EInvalidValue ## exception that is raised - ## for invalid XML - errors*: seq[string] ## all detected parsing errors + XmlError* = object of ValueError ## exception that is raised + ## for invalid XML + errors*: seq[string] ## all detected parsing errors + +{.deprecated: [EInvalidXml: XmlError].} proc raiseInvalidXml(errors: seq[string]) = - var e: ref EInvalidXml + var e: ref XmlError new(e) e.msg = errors[0] e.errors = errors raise e -proc addNode(father, son: PXmlNode) = +proc addNode(father, son: XmlNode) = if son != nil: add(father, son) -proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode +proc parse(x: var XmlParser, errors: var seq[string]): XmlNode -proc untilElementEnd(x: var TXmlParser, result: PXmlNode, +proc untilElementEnd(x: var XmlParser, result: XmlNode, errors: var seq[string]) = while true: case x.kind @@ -45,7 +47,7 @@ proc untilElementEnd(x: var TXmlParser, result: PXmlNode, else: result.addNode(parse(x, errors)) -proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode = +proc parse(x: var XmlParser, errors: var seq[string]): XmlNode = case x.kind of xmlComment: result = newComment(x.charData) @@ -98,11 +100,11 @@ proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode = next(x) of xmlEof: discard -proc parseXml*(s: PStream, filename: string, - errors: var seq[string]): PXmlNode = +proc parseXml*(s: Stream, filename: string, + errors: var seq[string]): XmlNode = ## parses the XML from stream `s` and returns a ``PXmlNode``. Every ## occured parsing error is added to the `errors` sequence. - var x: TXmlParser + var x: XmlParser open(x, s, filename, {reportComments}) while true: x.next() @@ -118,28 +120,28 @@ proc parseXml*(s: PStream, filename: string, break close(x) -proc parseXml*(s: PStream): PXmlNode = +proc parseXml*(s: Stream): XmlNode = ## parses the XTML from stream `s` and returns a ``PXmlNode``. All parsing ## errors are turned into an ``EInvalidXML`` exception. var errors: seq[string] = @[] result = parseXml(s, "unknown_html_doc", errors) - if errors.len > 0: raiseInvalidXMl(errors) + if errors.len > 0: raiseInvalidXml(errors) -proc loadXml*(path: string, errors: var seq[string]): PXmlNode = +proc loadXml*(path: string, errors: var seq[string]): XmlNode = ## Loads and parses XML from file specified by ``path``, and returns ## a ``PXmlNode``. Every occured parsing error is added to the `errors` ## sequence. var s = newFileStream(path, fmRead) - if s == nil: raise newException(EIO, "Unable to read file: " & path) + if s == nil: raise newException(IOError, "Unable to read file: " & path) result = parseXml(s, path, errors) -proc loadXml*(path: string): PXmlNode = +proc loadXml*(path: string): XmlNode = ## Loads and parses XML from file specified by ``path``, and returns ## a ``PXmlNode``. All parsing errors are turned into an ``EInvalidXML`` ## exception. var errors: seq[string] = @[] result = loadXml(path, errors) - if errors.len > 0: raiseInvalidXMl(errors) + if errors.len > 0: raiseInvalidXml(errors) when isMainModule: import os @@ -148,7 +150,7 @@ when isMainModule: var x = loadXml(paramStr(1), errors) for e in items(errors): echo e - var f: TFile + var f: File if open(f, "xmltest.txt", fmWrite): f.write($x) f.close() diff --git a/lib/pure/xmltree.nim b/lib/pure/xmltree.nim index 1af7db7d5..b84da9586 100644 --- a/lib/pure/xmltree.nim +++ b/lib/pure/xmltree.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -12,76 +12,79 @@ import macros, strtabs type - PXmlNode* = ref TXmlNode ## an XML tree consists of ``PXmlNode``'s. + XmlNode* = ref XmlNodeObj ## an XML tree consists of ``PXmlNode``'s. - TXmlNodeKind* = enum ## different kinds of ``PXmlNode``'s + XmlNodeKind* = enum ## different kinds of ``PXmlNode``'s xnText, ## a text element xnElement, ## an element with 0 or more children xnCData, ## a CDATA node xnEntity, ## an entity (like ``&thing;``) xnComment ## an XML comment - PXmlAttributes* = PStringTable ## an alias for a string to string mapping + XmlAttributes* = StringTableRef ## an alias for a string to string mapping - TXmlNode {.pure, final, acyclic.} = object - case k: TXmlNodeKind # private, use the kind() proc to read this field. + XmlNodeObj {.acyclic.} = object + case k: XmlNodeKind # private, use the kind() proc to read this field. of xnText, xnComment, xnCData, xnEntity: fText: string of xnElement: fTag: string - s: seq[PXmlNode] - fAttr: PXmlAttributes + s: seq[XmlNode] + fAttr: XmlAttributes fClientData: int ## for other clients - -proc newXmlNode(kind: TXmlNodeKind): PXmlNode = - ## creates a new ``PXmlNode``. + +{.deprecated: [PXmlNode: XmlNode, TXmlNodeKind: XmlNodeKind, PXmlAttributes: + XmlAttributes, TXmlNode: XmlNodeObj].} + +proc newXmlNode(kind: XmlNodeKind): XmlNode = + ## creates a new ``XmlNode``. new(result) result.k = kind -proc newElement*(tag: string): PXmlNode = +proc newElement*(tag: string): XmlNode = ## creates a new ``PXmlNode`` of kind ``xnText`` with the given `tag`. result = newXmlNode(xnElement) result.fTag = tag result.s = @[] # init attributes lazily to safe memory -proc newText*(text: string): PXmlNode = +proc newText*(text: string): XmlNode = ## creates a new ``PXmlNode`` of kind ``xnText`` with the text `text`. result = newXmlNode(xnText) result.fText = text -proc newComment*(comment: string): PXmlNode = +proc newComment*(comment: string): XmlNode = ## creates a new ``PXmlNode`` of kind ``xnComment`` with the text `comment`. result = newXmlNode(xnComment) result.fText = comment -proc newCData*(cdata: string): PXmlNode = +proc newCData*(cdata: string): XmlNode = ## creates a new ``PXmlNode`` of kind ``xnComment`` with the text `cdata`. result = newXmlNode(xnCData) result.fText = cdata -proc newEntity*(entity: string): PXmlNode = +proc newEntity*(entity: string): XmlNode = ## creates a new ``PXmlNode`` of kind ``xnEntity`` with the text `entity`. result = newXmlNode(xnCData) result.fText = entity -proc text*(n: PXmlNode): string {.inline.} = +proc text*(n: XmlNode): string {.inline.} = ## gets the associated text with the node `n`. `n` can be a CDATA, Text, ## comment, or entity node. assert n.k in {xnText, xnComment, xnCData, xnEntity} result = n.fText -proc rawText*(n: PXmlNode): string {.inline.} = +proc rawText*(n: XmlNode): string {.inline.} = ## returns the underlying 'text' string by reference. ## This is only used for speed hacks. shallowCopy(result, n.fText) -proc rawTag*(n: PXmlNode): string {.inline.} = +proc rawTag*(n: XmlNode): string {.inline.} = ## returns the underlying 'tag' string by reference. ## This is only used for speed hacks. shallowCopy(result, n.fTag) -proc innerText*(n: PXmlNode): string = +proc innerText*(n: XmlNode): string = ## gets the inner text of `n`. `n` has to be an ``xnElement`` node. Only ## ``xnText`` and ``xnEntity`` nodes are considered part of `n`'s inner text, ## other child nodes are silently ignored. @@ -90,55 +93,55 @@ proc innerText*(n: PXmlNode): string = for i in 0 .. n.s.len-1: if n.s[i].k in {xnText, xnEntity}: result.add(n.s[i].fText) -proc tag*(n: PXmlNode): string {.inline.} = +proc tag*(n: XmlNode): string {.inline.} = ## gets the tag name of `n`. `n` has to be an ``xnElement`` node. assert n.k == xnElement result = n.fTag -proc add*(father, son: PXmlNode) {.inline.} = +proc add*(father, son: XmlNode) {.inline.} = ## adds the child `son` to `father`. add(father.s, son) -proc len*(n: PXmlNode): int {.inline.} = +proc len*(n: XmlNode): int {.inline.} = ## returns the number `n`'s children. if n.k == xnElement: result = len(n.s) -proc kind*(n: PXmlNode): TXmlNodeKind {.inline.} = +proc kind*(n: XmlNode): XmlNodeKind {.inline.} = ## returns `n`'s kind. result = n.k -proc `[]`* (n: PXmlNode, i: int): PXmlNode {.inline.} = +proc `[]`* (n: XmlNode, i: int): XmlNode {.inline.} = ## returns the `i`'th child of `n`. assert n.k == xnElement result = n.s[i] -iterator items*(n: PXmlNode): PXmlNode {.inline.} = +iterator items*(n: XmlNode): XmlNode {.inline.} = ## iterates over any child of `n`. assert n.k == xnElement for i in 0 .. n.len-1: yield n[i] -proc attrs*(n: PXmlNode): PXmlAttributes {.inline.} = +proc attrs*(n: XmlNode): XmlAttributes {.inline.} = ## gets the attributes belonging to `n`. ## Returns `nil` if attributes have not been initialised for this node. assert n.k == xnElement result = n.fAttr -proc `attrs=`*(n: PXmlNode, attr: PXmlAttributes) {.inline.} = +proc `attrs=`*(n: XmlNode, attr: XmlAttributes) {.inline.} = ## sets the attributes belonging to `n`. assert n.k == xnElement n.fAttr = attr -proc attrsLen*(n: PXmlNode): int {.inline.} = +proc attrsLen*(n: XmlNode): int {.inline.} = ## returns the number of `n`'s attributes. assert n.k == xnElement if not isNil(n.fAttr): result = len(n.fAttr) -proc clientData*(n: PXmlNode): int {.inline.} = +proc clientData*(n: XmlNode): int {.inline.} = ## gets the client data of `n`. The client data field is used by the HTML ## parser and generator. result = n.fClientData -proc `clientData=`*(n: PXmlNode, data: int) {.inline.} = +proc `clientData=`*(n: XmlNode, data: int) {.inline.} = ## sets the client data of `n`. The client data field is used by the HTML ## parser and generator. n.fClientData = data @@ -176,13 +179,13 @@ proc addIndent(result: var string, indent: int) = result.add("\n") for i in 1..indent: result.add(' ') -proc noWhitespace(n: PXmlNode): bool = +proc noWhitespace(n: XmlNode): bool = #for i in 1..n.len-1: # if n[i].kind != n[0].kind: return true for i in 0..n.len-1: if n[i].kind in {xnText, xnEntity}: return true -proc add*(result: var string, n: PXmlNode, indent = 0, indWidth = 2) = +proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2) = ## adds the textual representation of `n` to `result`. if n == nil: return case n.k @@ -222,7 +225,7 @@ proc add*(result: var string, n: PXmlNode, indent = 0, indWidth = 2) = result.add("<!-- ") result.addEscaped(n.fText) result.add(" -->") - of xnCDATA: + of xnCData: result.add("<![CDATA[") result.add(n.fText) result.add("]]>") @@ -235,14 +238,14 @@ const xmlHeader* = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" ## header to use for complete XML output -proc `$`*(n: PXmlNode): string = +proc `$`*(n: XmlNode): string = ## converts `n` into its string representation. No ``<$xml ...$>`` declaration ## is produced, so that the produced XML fragments are composable. result = "" result.add(n) -proc newXmlTree*(tag: string, children: openArray[PXmlNode], - attributes: PXmlAttributes = nil): PXmlNode = +proc newXmlTree*(tag: string, children: openArray[XmlNode], + attributes: XmlAttributes = nil): XmlNode = ## creates a new XML tree with `tag`, `children` and `attributes` result = newXmlNode(xnElement) result.fTag = tag @@ -276,17 +279,17 @@ proc xmlConstructor(e: PNimrodNode): PNimrodNode {.compileTime.} = macro `<>`*(x: expr): expr {.immediate.} = ## Constructor macro for XML. Example usage: ## - ## .. code-block:: nimrod - ## <>a(href="http://nimrod-code.org", newText("Nimrod rules.")) + ## .. code-block:: nim + ## <>a(href="http://nim-code.org", newText("Nim rules.")) ## ## Produces an XML tree for:: ## - ## <a href="http://nimrod-code.org">Nimrod rules.</a> + ## <a href="http://nim-code.org">Nim rules.</a> ## let x = callsite() result = xmlConstructor(x) -proc child*(n: PXmlNode, name: string): PXmlNode = +proc child*(n: XmlNode, name: string): XmlNode = ## Finds the first child element of `n` with a name of `name`. ## Returns `nil` on failure. assert n.kind == xnElement @@ -295,23 +298,23 @@ proc child*(n: PXmlNode, name: string): PXmlNode = if i.tag == name: return i -proc attr*(n: PXmlNode, name: string): string = +proc attr*(n: XmlNode, name: string): string = ## Finds the first attribute of `n` with a name of `name`. ## Returns "" on failure. assert n.kind == xnElement if n.attrs == nil: return "" return n.attrs[name] -proc findAll*(n: PXmlNode, tag: string, result: var seq[PXmlNode]) = +proc findAll*(n: XmlNode, tag: string, result: var seq[XmlNode]) = ## Iterates over all the children of `n` returning those matching `tag`. ## ## Found nodes satisfying the condition will be appended to the `result` ## sequence, which can't be nil or the proc will crash. Usage example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## var - ## html: PXmlNode - ## tags: seq[PXmlNode] = @[] + ## html: XmlNode + ## tags: seq[XmlNode] = @[] ## ## html = buildHtml() ## findAll(html, "img", tags) @@ -327,11 +330,11 @@ proc findAll*(n: PXmlNode, tag: string, result: var seq[PXmlNode]) = elif child.k == xnElement: child.findAll(tag, result) -proc findAll*(n: PXmlNode, tag: string): seq[PXmlNode] = +proc findAll*(n: XmlNode, tag: string): seq[XmlNode] = ## Shortcut version to assign in let blocks. Example: ## - ## .. code-block:: nimrod - ## var html: PXmlNode + ## .. code-block:: + ## var html: XmlNode ## ## html = buildHtml(html) ## for imgTag in html.findAll("img"): @@ -340,5 +343,5 @@ proc findAll*(n: PXmlNode, tag: string): seq[PXmlNode] = findAll(n, tag, result) when isMainModule: - assert """<a href="http://nimrod-code.org">Nimrod rules.</a>""" == - $(<>a(href="http://nimrod-code.org", newText("Nimrod rules."))) + assert """<a href="http://nim-code.org">Nim rules.</a>""" == + $(<>a(href="http://nim-code.org", newText("Nim rules."))) diff --git a/lib/stdlib.babel b/lib/stdlib.nimble index f22598aba..0805ead54 100644 --- a/lib/stdlib.babel +++ b/lib/stdlib.nimble @@ -2,5 +2,5 @@ name = "stdlib" version = "0.9.0" author = "Dominik Picheta" -description = "Nimrod's standard library." +description = "Nim's standard library." license = "MIT" diff --git a/lib/system.nim b/lib/system.nim index 0df8849f5..a9b4da77a 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1,7 +1,7 @@ # # -# Nimrod's Runtime Library -# (c) Copyright 2013 Andreas Rumpf +# Nim's Runtime Library +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -77,44 +77,53 @@ type auto* = expr any* = distinct auto - TSignedInt* = int|int8|int16|int32|int64 + SomeSignedInt* = int|int8|int16|int32|int64 ## type class matching all signed integer types - TUnsignedInt* = uint|uint8|uint16|uint32|uint64 + SomeUnsignedInt* = uint|uint8|uint16|uint32|uint64 ## type class matching all unsigned integer types - TInteger* = TSignedInt|TUnsignedInt + SomeInteger* = SomeSignedInt|SomeUnsignedInt ## type class matching all integer types - TOrdinal* = int|int8|int16|int32|int64|bool|enum|uint8|uint16|uint32 + SomeOrdinal* = int|int8|int16|int32|int64|bool|enum|uint8|uint16|uint32 ## type class matching all ordinal types; however this includes enums with ## holes. - TReal* = float|float32|float64 + SomeReal* = float|float32|float64 ## type class matching all floating point number types - TNumber* = TInteger|TReal + SomeNumber* = SomeInteger|SomeReal ## type class matching all number types proc defined*(x: expr): bool {.magic: "Defined", noSideEffect.} ## Special compile-time procedure that checks whether `x` is ## defined. ## `x` is an external symbol introduced through the compiler's - ## `-d:x switch <nimrodc.html#compile-time-symbols>`_ to enable build time + ## `-d:x switch <nimc.html#compile-time-symbols>`_ to enable build time ## conditionals: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## when not defined(release): ## # Do here programmer friendly expensive sanity checks. ## # Put here the normal code +when defined(nimalias): + {.deprecated: [ + TSignedInt: SomeSignedInt, + TUnsignedInt: SomeUnsignedInt, + TInteger: SomeInteger, + TReal: SomeReal, + TNumber: SomeNumber, + TOrdinal: SomeOrdinal].} + proc declared*(x: expr): bool {.magic: "Defined", noSideEffect.} ## Special compile-time procedure that checks whether `x` is ## declared. `x` has to be an identifier or a qualified identifier. ## This can be used to check whether a library provides a certain ## feature or not: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## when not defined(strutils.toUpper): ## # provide our own toUpper proc here, because strutils is ## # missing it. @@ -183,6 +192,7 @@ proc high*[T](x: T): T {.magic: "High", noSideEffect.} ## returns the highest possible index of an array, a sequence, a string or ## the highest possible value of an ordinal value `x`. As a special ## semantic rule, `x` may also be a type identifier. + ## ``high(int)`` is Nim's way of writing `INT_MAX`:idx: or `MAX_INT`:idx:. proc low*[T](x: T): T {.magic: "Low", noSideEffect.} ## returns the lowest possible index of an array, a sequence, a string or @@ -202,10 +212,13 @@ type set*{.magic: "Set".}[T] ## Generic type to construct bit sets. type - TSlice* {.final, pure.}[T] = object ## builtin slice type - a*, b*: T ## the bounds + Slice* {.final, pure.}[T] = object ## builtin slice type + a*, b*: T ## the bounds + +when defined(nimalias): + {.deprecated: [TSlice: Slice].} -proc `..`*[T](a, b: T): TSlice[T] {.noSideEffect, inline.} = +proc `..`*[T](a, b: T): Slice[T] {.noSideEffect, inline.} = ## `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 @@ -213,7 +226,7 @@ proc `..`*[T](a, b: T): TSlice[T] {.noSideEffect, inline.} = result.a = a result.b = b -proc `..`*[T](b: T): TSlice[T] {.noSideEffect, inline.} = +proc `..`*[T](b: T): Slice[T] {.noSideEffect, inline.} = ## `slice`:idx: operator that constructs an interval ``[default(T), b]`` result.b = b @@ -296,7 +309,7 @@ when not defined(JS) and not defined(NimrodVM): include "system/hti" type - Byte* = uint8 ## this is an alias for ``uint8``, that is an unsigned + byte* = uint8 ## this is an alias for ``uint8``, that is an unsigned ## int 8 bits wide. Natural* = range[0..high(int)] @@ -307,29 +320,29 @@ type ## is an int type ranging from one to the maximum value ## of an int. This type is often useful for documentation and debugging. - TObject* {.exportc: "TNimObject", inheritable.} = - object ## the root of Nimrod's object hierarchy. Objects should + RootObj* {.exportc: "TNimObject", inheritable.} = + object ## the root of Nim's object hierarchy. Objects should ## inherit from TObject or one of its descendants. However, ## objects that have no ancestor are allowed. - PObject* = ref TObject ## reference to TObject + RootRef* = ref RootObj ## reference to RootObj - TEffect* {.compilerproc.} = object of TObject ## \ + RootEffect* {.compilerproc.} = object of RootObj ## \ ## base effect class; each effect should ## inherit from `TEffect` unless you know what ## you doing. - FTime* = object of TEffect ## Time effect. - FIO* = object of TEffect ## IO effect. - FReadIO* = object of FIO ## Effect describing a read IO operation. - FWriteIO* = object of FIO ## Effect describing a write IO operation. - FExecIO* = object of FIO ## Effect describing an executing IO operation. + TimeEffect* = object of RootEffect ## Time effect. + IOEffect* = object of RootEffect ## IO effect. + ReadIOEffect* = object of IOEffect ## Effect describing a read IO operation. + WriteIOEffect* = object of IOEffect ## Effect describing a write IO operation. + ExecIOEffect* = object of IOEffect ## Effect describing an executing IO operation. - E_Base* {.compilerproc.} = object of TObject ## \ + Exception* {.compilerproc.} = object of RootObj ## \ ## Base exception class. ## - ## Each exception has to inherit from `E_Base`. See the full `exception + ## Each exception has to inherit from `Exception`. See the full `exception ## hierarchy`_. - parent: ref E_Base ## parent exception (can be used as a stack) - name: cstring ## The exception's name is its Nimrod identifier. + parent: ref Exception ## parent exception (can be used as a stack) + name: cstring ## The exception's name is its Nim identifier. ## This field is filled automatically in the ## ``raise`` statement. msg* {.exportc: "message".}: string ## the exception's message. Not @@ -337,143 +350,156 @@ type ## is bad style. trace: string - EAsynch* = object of E_Base ## \ - ## Abstract exception class for *asynchronous exceptions* (interrupts). - ## - ## This is rarely needed: most exception types inherit from `ESynch - ## <#ESynch>`_. See the full `exception hierarchy`_. - EControlC* = object of EAsynch ## \ - ## Raised for Ctrl+C key presses in console applications. - ## - ## See the full `exception hierarchy`_. - ESynch* = object of E_Base ## \ - ## Abstract exception class for *synchronous exceptions*. - ## - ## Most exceptions should be inherited (directly or indirectly) from - ## `ESynch` instead of from `EAsynch <#EAsynch>`_. See the full `exception - ## hierarchy`_. - ESystem* = object of ESynch ## \ + SystemError* = object of Exception ## \ ## Abstract class for exceptions that the runtime system raises. ## ## See the full `exception hierarchy`_. - EIO* = object of ESystem ## \ + IOError* = object of SystemError ## \ ## Raised if an IO error occured. ## ## See the full `exception hierarchy`_. - EOS* = object of ESystem ## \ + OSError* = object of SystemError ## \ ## Raised if an operating system service failed. ## ## See the full `exception hierarchy`_. errorCode*: int32 ## OS-defined error code describing this error. - EInvalidLibrary* = object of EOS ## \ + LibraryError* = object of OSError ## \ ## Raised if a dynamic library could not be loaded. ## ## See the full `exception hierarchy`_. - EResourceExhausted* = object of ESystem ## \ + ResourceExhaustedError* = object of SystemError ## \ ## Raised if a resource request could not be fullfilled. ## ## See the full `exception hierarchy`_. - EArithmetic* = object of ESynch ## \ + ArithmeticError* = object of Exception ## \ ## Raised if any kind of arithmetic error occured. ## ## See the full `exception hierarchy`_. - EDivByZero* {.compilerproc.} = object of EArithmetic ## \ + DivByZeroError* = object of ArithmeticError ## \ ## Raised for runtime integer divide-by-zero errors. ## ## See the full `exception hierarchy`_. - EOverflow* {.compilerproc.} = object of EArithmetic ## \ + + OverflowError* = object of ArithmeticError ## \ ## Raised for runtime integer overflows. ## ## This happens for calculations whose results are too large to fit in the ## provided bits. See the full `exception hierarchy`_. - EAccessViolation* {.compilerproc.} = object of ESynch ## \ + AccessViolationError* = object of Exception ## \ ## Raised for invalid memory access errors ## ## See the full `exception hierarchy`_. - EAssertionFailed* {.compilerproc.} = object of ESynch ## \ + AssertionError* = object of Exception ## \ ## Raised when assertion is proved wrong. ## ## Usually the result of using the `assert() template <#assert>`_. See the ## full `exception hierarchy`_. - EInvalidValue* = object of ESynch ## \ + ValueError* = object of Exception ## \ ## Raised for string and object conversion errors. - EInvalidKey* = object of EInvalidValue ## \ + KeyError* = object of ValueError ## \ ## Raised if a key cannot be found in a table. ## ## Mostly used by the `tables <tables.html>`_ module, it can also be raised ## by other collection modules like `sets <sets.html>`_ or `strtabs ## <strtabs.html>`_. See the full `exception hierarchy`_. - EOutOfMemory* = object of ESystem ## \ + OutOfMemError* = object of SystemError ## \ ## Raised for unsuccessful attempts to allocate memory. ## ## See the full `exception hierarchy`_. - EInvalidIndex* = object of ESynch ## \ + IndexError* = object of Exception ## \ ## Raised if an array index is out of bounds. ## ## See the full `exception hierarchy`_. - EInvalidField* = object of ESynch ## \ + + FieldError* = object of Exception ## \ ## Raised if a record field is not accessible because its dicriminant's ## value does not fit. ## ## See the full `exception hierarchy`_. - EOutOfRange* = object of ESynch ## \ + RangeError* = object of Exception ## \ ## Raised if a range check error occurred. ## ## See the full `exception hierarchy`_. - EStackOverflow* = object of ESystem ## \ + StackOverflowError* = object of SystemError ## \ ## Raised if the hardware stack used for subroutine calls overflowed. ## ## See the full `exception hierarchy`_. - ENoExceptionToReraise* = object of ESynch ## \ + ReraiseError* = object of Exception ## \ ## Raised if there is no exception to reraise. ## ## See the full `exception hierarchy`_. - EInvalidObjectAssignment* = object of ESynch ## \ + ObjectAssignmentError* = object of Exception ## \ ## Raised if an object gets assigned to its parent's object. ## ## See the full `exception hierarchy`_. - EInvalidObjectConversion* = object of ESynch ## \ + ObjectConversionError* = object of Exception ## \ ## Raised if an object is converted to an incompatible object type. ## ## See the full `exception hierarchy`_. - EFloatingPoint* = object of ESynch ## \ + FloatingPointError* = object of Exception ## \ ## Base class for floating point exceptions. ## ## See the full `exception hierarchy`_. - EFloatInvalidOp* {.compilerproc.} = object of EFloatingPoint ## \ + FloatInvalidOpError* = object of FloatingPointError ## \ ## Raised by invalid operations according to IEEE. ## ## Raised by ``0.0/0.0``, for example. See the full `exception ## hierarchy`_. - EFloatDivByZero* {.compilerproc.} = object of EFloatingPoint ## \ + FloatDivByZeroError* = object of FloatingPointError ## \ ## Raised by division by zero. ## ## Divisor is zero and dividend is a finite nonzero number. See the full ## `exception hierarchy`_. - EFloatOverflow* {.compilerproc.} = object of EFloatingPoint ## \ + FloatOverflowError* = object of FloatingPointError ## \ ## Raised for overflows. ## ## The operation produced a result that exceeds the range of the exponent. ## See the full `exception hierarchy`_. - EFloatUnderflow* {.compilerproc.} = object of EFloatingPoint ## \ + FloatUnderflowError* = object of FloatingPointError ## \ ## Raised for underflows. ## ## The operation produced a result that is too small to be represented as a ## normal number. See the full `exception hierarchy`_. - EFloatInexact* {.compilerproc.} = object of EFloatingPoint ## \ + FloatInexactError* = object of FloatingPointError ## \ ## Raised for inexact results. ## ## The operation produced a result that cannot be represented with infinite ## precision -- for example: ``2.0 / 3.0, log(1.1)`` ## - ## **NOTE**: Nimrod currently does not detect these! See the full + ## **NOTE**: Nim currently does not detect these! See the full ## `exception hierarchy`_. - EDeadThread* = object of ESynch ## \ + DeadThreadError* = object of Exception ## \ ## Raised if it is attempted to send a message to a dead thread. ## ## See the full `exception hierarchy`_. - TResult* = enum Failure, Success + TResult* {.deprecated.} = enum Failure, Success + +{.deprecated: [TObject: RootObj, PObject: RootRef, TEffect: RootEffect, + FTime: TimeEffect, FIO: IOEffect, FReadIO: ReadIOEffect, + FWriteIO: WriteIOEffect, FExecIO: ExecIOEffect, + + E_Base: Exception, ESystem: SystemError, EIO: IOError, + EOS: OSError, EInvalidLibrary: LibraryError, + EResourceExhausted: ResourceExhaustedError, + EArithmetic: ArithmeticError, EDivByZero: DivByZeroError, + EOverflow: OverflowError, EAccessViolation: AccessViolationError, + EAssertionFailed: AssertionError, EInvalidValue: ValueError, + EInvalidKey: KeyError, EOutOfMemory: OutOfMemError, + EInvalidIndex: IndexError, EInvalidField: FieldError, + EOutOfRange: RangeError, EStackOverflow: StackOverflowError, + ENoExceptionToReraise: ReraiseError, + EInvalidObjectAssignment: ObjectAssignmentError, + EInvalidObjectConversion: ObjectConversionError, + EDeadThread: DeadThreadError, + EFloatInexact: FloatInexactError, + EFloatUnderflow: FloatUnderflowError, + EFloatingPoint: FloatingPointError, + EFloatInvalidOp: FloatInvalidOpError, + EFloatDivByZero: FloatDivByZeroError, + EFloatOverflow: FloatOverflowError, + ESynch: Exception +].} proc sizeof*[T](x: T): Natural {.magic: "SizeOf", noSideEffect.} ## returns the size of ``x`` in bytes. Since this is a low-level proc, @@ -484,7 +510,7 @@ proc sizeof*[T](x: T): Natural {.magic: "SizeOf", noSideEffect.} proc `<`*[T](x: Ordinal[T]): T {.magic: "UnaryLt", noSideEffect.} ## unary ``<`` that can be used for nice looking excluding ranges: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for i in 0 .. <10: echo i ## ## Semantically this is the same as ``pred``. @@ -519,7 +545,7 @@ proc newSeq*[T](s: var seq[T], len: int) {.magic: "NewSeq", noSideEffect.} ## ``nil``. After the creation of the sequence you should assign entries to ## the sequence instead of adding them. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var inputStrings : seq[string] ## newSeq(inputStrings, 3) ## inputStrings[0] = "The fourth" @@ -535,7 +561,7 @@ proc newSeq*[T](len = 0): seq[T] = ## ``nil``. After the creation of the sequence you should assign entries to ## the sequence instead of adding them. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var inputStrings = newSeq[string](3) ## inputStrings[0] = "The fourth" ## inputStrings[1] = "assignment" @@ -666,7 +692,7 @@ proc `div` *(x, y: int32): int32 {.magic: "DivI", noSideEffect.} proc `div` *(x, y: int64): int64 {.magic: "DivI64", noSideEffect.} ## computes the integer division. This is roughly the same as ## ``floor(x/y)``. - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## 1 div 2 == 0 ## 2 div 2 == 1 ## 3 div 2 == 1 @@ -685,7 +711,7 @@ proc `shr` *(x, y: int16): int16 {.magic: "ShrI", noSideEffect.} proc `shr` *(x, y: int32): int32 {.magic: "ShrI", noSideEffect.} proc `shr` *(x, y: int64): int64 {.magic: "ShrI64", noSideEffect.} ## computes the `shift right` operation of `x` and `y`. - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## 0b0001_0000'i8 shr 2 == 0b0100_0000'i8 ## 0b1000_0000'i8 shr 2 == 0b0000_0000'i8 ## 0b0000_0001'i8 shr 9 == 0b0000_0000'i8 @@ -824,12 +850,12 @@ proc contains*[T](x: set[T], y: T): bool {.magic: "InSet", noSideEffect.} ## One should overload this proc if one wants to overload the ``in`` operator. ## The parameters are in reverse order! ``a in b`` is a template for ## ``contains(b, a)``. - ## This is because the unification algorithm that Nimrod uses for overload + ## This is because the unification algorithm that Nim uses for overload ## resolution works from left to right. ## But for the ``in`` operator that would be the wrong direction for this ## piece of code: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## var s: set[range['a'..'z']] = {'a'..'c'} ## writeln(stdout, 'b' in s) ## @@ -839,11 +865,11 @@ 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: TSlice[T], value: T): bool {.noSideEffect, inline.} = +proc contains*[T](s: Slice[T], value: T): bool {.noSideEffect, inline.} = ## Checks if `value` is withing the range of `s`; returns true iff ## `value >= s.a and value <= s.b` ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert((1..3).contains(1) == true) ## assert((1..3).contains(2) == true) ## assert((1..3).contains(4) == false) @@ -852,20 +878,20 @@ proc contains*[T](s: TSlice[T], value: T): bool {.noSideEffect, inline.} = template `in` * (x, y: expr): expr {.immediate, dirty.} = contains(y, x) ## Sugar for contains ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert(1 in (1..3) == true) ## assert(5 in (1..3) == false) template `notin` * (x, y: expr): expr {.immediate, dirty.} = not contains(y, x) ## Sugar for not containing ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert(1 notin (1..3) == false) ## assert(5 notin (1..3) == true) proc `is` *[T, S](x: T, y: S): bool {.magic: "Is", noSideEffect.} ## Checks if T is of the same type as S ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## proc test[T](a: T): int = ## when (T is int): ## return a @@ -880,7 +906,7 @@ template `isnot` *(x, y: expr): expr {.immediate.} = not (x is y) proc `of` *[T, S](x: T, y: S): bool {.magic: "Of", noSideEffect.} ## Checks if `x` has a type of `y` ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert(EFloatingPoint of EBase) ## assert(EIO of ESystem) ## assert(EDivByZero of EBase) @@ -936,25 +962,25 @@ proc `&` * (x: string, y: char): string {. magic: "ConStrStr", noSideEffect, merge.} ## Concatenates `x` with `y` ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert("ab" & 'c' == "abc") proc `&` * (x: char, y: char): string {. magic: "ConStrStr", noSideEffect, merge.} ## Concatenates `x` and `y` into a string ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert('a' & 'b' == "ab") proc `&` * (x, y: string): string {. magic: "ConStrStr", noSideEffect, merge.} ## Concatenates `x` and `y` ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert("ab" & "cd" == "abcd") proc `&` * (x: char, y: string): string {. magic: "ConStrStr", noSideEffect, merge.} ## Concatenates `x` with `y` ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert('a' & "bc" == "abc") # implementation note: These must all have the same magic value "ConStrStr" so @@ -963,7 +989,7 @@ proc `&` * (x: char, y: string): string {. proc add*(x: var string, y: char) {.magic: "AppendStrCh", noSideEffect.} ## Appends `y` to `x` in place ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## var tmp = "" ## tmp.add('a') ## tmp.add('b') @@ -971,14 +997,14 @@ proc add*(x: var string, y: char) {.magic: "AppendStrCh", noSideEffect.} proc add*(x: var string, y: string) {.magic: "AppendStrStr", noSideEffect.} ## Concatenates `x` and `y` in place ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## var tmp = "" ## tmp.add("ab") ## tmp.add("cd") ## assert(tmp == "abcd") type - TEndian* = enum ## is a type describing the endianness of a processor. + Endianness* = enum ## is a type describing the endianness of a processor. littleEndian, bigEndian const @@ -994,23 +1020,23 @@ const ## is the time of compilation as a string of the form ## ``HH:MM:SS``. This works thanks to compiler magic. - NimrodVersion* {.magic: "NimrodVersion"}: string = "0.0.0" - ## is the version of Nimrod as a string. + NimVersion* {.magic: "NimrodVersion"}: string = "0.0.0" + ## is the version of Nim as a string. ## This works thanks to compiler magic. - NimrodMajor* {.magic: "NimrodMajor"}: int = 0 - ## is the major number of Nimrod's version. + NimMajor* {.magic: "NimrodMajor"}: int = 0 + ## is the major number of Nim's version. ## This works thanks to compiler magic. - NimrodMinor* {.magic: "NimrodMinor"}: int = 0 - ## is the minor number of Nimrod's version. + NimMinor* {.magic: "NimrodMinor"}: int = 0 + ## is the minor number of Nim's version. ## This works thanks to compiler magic. - NimrodPatch* {.magic: "NimrodPatch"}: int = 0 - ## is the patch number of Nimrod's version. + NimPatch* {.magic: "NimrodPatch"}: int = 0 + ## is the patch number of Nim's version. ## This works thanks to compiler magic. - cpuEndian* {.magic: "CpuEndian"}: TEndian = littleEndian + cpuEndian* {.magic: "CpuEndian"}: Endianness = littleEndian ## is the endianness of the target CPU. This is a valuable piece of ## information for low-level code only. This works thanks to compiler ## magic. @@ -1025,12 +1051,15 @@ const ## "i386", "alpha", "powerpc", "sparc", "amd64", "mips", "arm". seqShallowFlag = low(int) - + +{.deprecated: [TEndian: Endianness, NimrodVersion: NimVersion, + NimrodMajor: NimMajor, NimrodMinor: NimMinor, NimrodPatch: NimPatch].} + proc compileOption*(option: string): bool {. magic: "CompileOption", noSideEffect.} ## can be used to determine an on|off compile-time option. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## when compileOption("floatchecks"): ## echo "compiled with floating point NaN and Inf checks" @@ -1038,7 +1067,7 @@ proc compileOption*(option, arg: string): bool {. magic: "CompileOptionArg", noSideEffect.} ## can be used to determine an enum compile-time option. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## when compileOption("opt", "size") and compileOption("gc", "boehm"): ## echo "compiled with optimization for size and uses Boehm's GC" @@ -1095,7 +1124,7 @@ proc quit*(errorcode: int = QuitSuccess) {. ## procedures. It does *not* call the garbage collector to free all the ## memory, unless a quit procedure calls ``GC_collect``. ## - ## The proc ``quit(QuitSuccess)`` is called implicitly when your nimrod + ## The proc ``quit(QuitSuccess)`` is called implicitly when your nim ## program finishes without incident. A raised unhandled exception is ## equivalent to calling ``quit(QuitFailure)``. ## @@ -1117,7 +1146,7 @@ proc add *[T](x: var seq[T], y: openArray[T]) {.noSideEffect.} = ## Generic proc for adding a data item `y` to a container `x`. ## For containers that have an order, `add` means *append*. New generic ## containers should also call their adding proc `add` for consistency. - ## Generic code becomes much easier to write if the Nimrod naming scheme is + ## Generic code becomes much easier to write if the Nim naming scheme is ## respected. let xl = x.len setLen(x, xl + y.len) @@ -1155,25 +1184,27 @@ proc insert*[T](x: var seq[T], item: T, i = 0) {.noSideEffect.} = x[i] = item proc repr*[T](x: T): string {.magic: "Repr", noSideEffect.} - ## takes any Nimrod variable and returns its string representation. It + ## takes any Nim variable and returns its string representation. It ## works even for complex data graphs with cycles. This is a great ## debugging tool. type - TAddress* = int + ByteAddress* = int ## is the signed integer type that should be used for converting ## pointers to integer addresses for readability. BiggestInt* = int64 - ## is an alias for the biggest signed integer type the Nimrod compiler + ## is an alias for the biggest signed integer type the Nim compiler ## supports. Currently this is ``int64``, but it is platform-dependant ## in general. BiggestFloat* = float64 - ## is an alias for the biggest floating point type the Nimrod + ## is an alias for the biggest floating point type the Nim ## compiler supports. Currently this is ``float64``, but it is ## platform-dependant in general. +{.deprecated: [TAddress: ByteAddress].} + when defined(windows): type clong* {.importc: "long", nodecl.} = int32 @@ -1206,7 +1237,7 @@ type # these work for most platforms: ## This is the same as the type ``double`` in *C*. clongdouble* {.importc: "long double", nodecl.} = BiggestFloat ## This is the same as the type ``long double`` in *C*. - ## This C type is not supported by Nimrod's code generator + ## This C type is not supported by Nim's code generator cuchar* {.importc: "unsigned char", nodecl.} = char ## This is the same as the type ``unsigned char`` in *C*. @@ -1287,20 +1318,20 @@ proc substr*(s: string, first, last: int): string {. ## or `limit`:idx: a string's length. when not defined(nimrodVM): - proc zeroMem*(p: pointer, size: int) {.importc, noDecl, gcsafe.} + proc zeroMem*(p: pointer, size: int) {.importc, noDecl, benign.} ## overwrites the contents of the memory at ``p`` with the value 0. ## Exactly ``size`` bytes will be overwritten. Like any procedure ## dealing with raw memory this is *unsafe*. proc copyMem*(dest, source: pointer, size: int) {. - importc: "memcpy", header: "<string.h>", gcsafe.} + importc: "memcpy", header: "<string.h>", benign.} ## copies the contents from the memory at ``source`` to the memory ## at ``dest``. Exactly ``size`` bytes will be copied. The memory ## regions may not overlap. Like any procedure dealing with raw ## memory this is *unsafe*. proc moveMem*(dest, source: pointer, size: int) {. - importc: "memmove", header: "<string.h>", gcsafe.} + importc: "memmove", header: "<string.h>", benign.} ## copies the contents from the memory at ``source`` to the memory ## at ``dest``. Exactly ``size`` bytes will be copied. The memory ## regions may overlap, ``moveMem`` handles this case appropriately @@ -1315,14 +1346,14 @@ when not defined(nimrodVM): ## *unsafe*. when hostOS != "standalone": - proc alloc*(size: int): pointer {.noconv, rtl, tags: [], gcsafe.} + proc alloc*(size: int): pointer {.noconv, rtl, tags: [], benign.} ## allocates a new memory block with at least ``size`` bytes. The ## block has to be freed with ``realloc(block, 0)`` or ## ``dealloc(block)``. The block is not initialized, so reading ## from it before writing to it is undefined behaviour! ## The allocated memory belongs to its allocating thread! ## Use `allocShared` to allocate from a shared heap. - proc createU*(T: typedesc, size = 1.Positive): ptr T {.inline, gcsafe.} = + proc createU*(T: typedesc, size = 1.Positive): ptr T {.inline, benign.} = ## allocates a new memory block with at least ``T.sizeof * size`` ## bytes. The block has to be freed with ``resize(block, 0)`` or ## ``free(block)``. The block is not initialized, so reading @@ -1330,14 +1361,14 @@ when not defined(nimrodVM): ## The allocated memory belongs to its allocating thread! ## Use `createSharedU` to allocate from a shared heap. cast[ptr T](alloc(T.sizeof * size)) - proc alloc0*(size: int): pointer {.noconv, rtl, tags: [], gcsafe.} + proc alloc0*(size: int): pointer {.noconv, rtl, tags: [], benign.} ## allocates a new memory block with at least ``size`` bytes. The ## block has to be freed with ``realloc(block, 0)`` or ## ``dealloc(block)``. The block is initialized with all bytes ## containing zero, so it is somewhat safer than ``alloc``. ## The allocated memory belongs to its allocating thread! ## Use `allocShared0` to allocate from a shared heap. - proc create*(T: typedesc, size = 1.Positive): ptr T {.inline, gcsafe.} = + proc create*(T: typedesc, size = 1.Positive): ptr T {.inline, benign.} = ## allocates a new memory block with at least ``T.sizeof * size`` ## bytes. The block has to be freed with ``resize(block, 0)`` or ## ``free(block)``. The block is initialized with all bytes @@ -1346,7 +1377,7 @@ when not defined(nimrodVM): ## Use `createShared` to allocate from a shared heap. cast[ptr T](alloc0(T.sizeof * size)) proc realloc*(p: pointer, newSize: int): pointer {.noconv, rtl, tags: [], - gcsafe.} + benign.} ## grows or shrinks a given memory block. If p is **nil** then a new ## memory block is returned. In either way the block has at least ## ``newSize`` bytes. If ``newSize == 0`` and p is not **nil** @@ -1354,7 +1385,7 @@ when not defined(nimrodVM): ## be freed with ``dealloc``. ## The allocated memory belongs to its allocating thread! ## Use `reallocShared` to reallocate from a shared heap. - proc resize*[T](p: ptr T, newSize: Natural): ptr T {.inline, gcsafe.} = + proc resize*[T](p: ptr T, newSize: Natural): ptr T {.inline, benign.} = ## grows or shrinks a given memory block. If p is **nil** then a new ## memory block is returned. In either way the block has at least ## ``T.sizeof * newSize`` bytes. If ``newSize == 0`` and p is not @@ -1363,7 +1394,7 @@ when not defined(nimrodVM): ## its allocating thread! ## Use `resizeShared` to reallocate from a shared heap. cast[ptr T](realloc(p, T.sizeof * newSize)) - proc dealloc*(p: pointer) {.noconv, rtl, tags: [], gcsafe.} + proc dealloc*(p: pointer) {.noconv, rtl, tags: [], benign.} ## frees the memory allocated with ``alloc``, ``alloc0`` or ## ``realloc``. This procedure is dangerous! If one forgets to ## free the memory a leak occurs; if one tries to access freed @@ -1371,23 +1402,23 @@ when not defined(nimrodVM): ## or other memory may be corrupted. ## The freed memory must belong to its allocating thread! ## Use `deallocShared` to deallocate from a shared heap. - proc free*[T](p: ptr T) {.inline, gcsafe.} = + proc free*[T](p: ptr T) {.inline, benign.} = dealloc(p) - proc allocShared*(size: int): pointer {.noconv, rtl, gcsafe.} + proc allocShared*(size: int): pointer {.noconv, rtl, benign.} ## allocates a new memory block on the shared heap with at ## least ``size`` bytes. The block has to be freed with ## ``reallocShared(block, 0)`` or ``deallocShared(block)``. The block ## is not initialized, so reading from it before writing to it is ## undefined behaviour! proc createSharedU*(T: typedesc, size = 1.Positive): ptr T {.inline, - gcsafe.} = + benign.} = ## allocates a new memory block on the shared heap with at ## least ``T.sizeof * size`` bytes. The block has to be freed with ## ``resizeShared(block, 0)`` or ``freeShared(block)``. The block ## is not initialized, so reading from it before writing to it is ## undefined behaviour! cast[ptr T](allocShared(T.sizeof * size)) - proc allocShared0*(size: int): pointer {.noconv, rtl, gcsafe.} + proc allocShared0*(size: int): pointer {.noconv, rtl, benign.} ## allocates a new memory block on the shared heap with at ## least ``size`` bytes. The block has to be freed with ## ``reallocShared(block, 0)`` or ``deallocShared(block)``. @@ -1401,7 +1432,7 @@ when not defined(nimrodVM): ## containing zero, so it is somewhat safer than ``createSharedU``. cast[ptr T](allocShared0(T.sizeof * size)) proc reallocShared*(p: pointer, newSize: int): pointer {.noconv, rtl, - gcsafe.} + benign.} ## grows or shrinks a given memory block on the heap. If p is **nil** ## then a new memory block is returned. In either way the block has at ## least ``newSize`` bytes. If ``newSize == 0`` and p is not **nil** @@ -1414,13 +1445,13 @@ when not defined(nimrodVM): ## not **nil** ``resizeShared`` calls ``freeShared(p)``. In other ## cases the block has to be freed with ``freeShared``. cast[ptr T](reallocShared(p, T.sizeof * newSize)) - proc deallocShared*(p: pointer) {.noconv, rtl, gcsafe.} + proc deallocShared*(p: pointer) {.noconv, rtl, benign.} ## frees the memory allocated with ``allocShared``, ``allocShared0`` or ## ``reallocShared``. This procedure is dangerous! If one forgets to ## free the memory a leak occurs; if one tries to access freed ## memory (or just freeing it twice!) a core dump may happen ## or other memory may be corrupted. - proc freeShared*[T](p: ptr T) {.inline, gcsafe.} = + proc freeShared*[T](p: ptr T) {.inline, benign.} = ## frees the memory allocated with ``createShared``, ``createSharedU`` or ## ``resizeShared``. This procedure is dangerous! If one forgets to ## free the memory a leak occurs; if one tries to access freed @@ -1560,7 +1591,7 @@ iterator `||`*[S, T](a: S, b: T, annotation=""): T {. ## Note that the compiler maps that to ## the ``#pragma omp parallel for`` construct of `OpenMP`:idx: and as ## such isn't aware of the parallelism in your code! Be careful! Later - ## versions of ``||`` will get proper support by Nimrod's code generator + ## versions of ``||`` will get proper support by Nim's code generator ## and GC. discard @@ -1612,7 +1643,7 @@ proc max*(x, y: float): float {.magic: "MaxF64", noSideEffect.} = proc clamp*[T](x, a, b: T): T = ## limits the value ``x`` within the interval [a, b] ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert((1.4).clamp(0.0, 1.0) == 1.0) ## assert((0.5).clamp(0.0, 1.0) == 0.5) if x < a: return a @@ -1716,7 +1747,7 @@ proc `&` *[T](x, y: seq[T]): seq[T] {.noSideEffect.} = ## Concatenates two sequences. ## Requires copying of the sequences. ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert(@[1, 2, 3, 4] & @[5, 6] == @[1, 2, 3, 4, 5, 6]) newSeq(result, x.len + y.len) for i in 0..x.len-1: @@ -1728,7 +1759,7 @@ proc `&` *[T](x: seq[T], y: T): seq[T] {.noSideEffect.} = ## Appends element y to the end of the sequence. ## Requires copying of the sequence ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert(@[1, 2, 3] & 4 == @[1, 2, 3, 4]) newSeq(result, x.len + 1) for i in 0..x.len-1: @@ -1739,7 +1770,7 @@ proc `&` *[T](x: T, y: seq[T]): seq[T] {.noSideEffect.} = ## Prepends the element x to the beginning of the sequence. ## Requires copying of the sequence ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert(1 & @[2, 3, 4] == @[1, 2, 3, 4]) newSeq(result, y.len + 1) result[0] = x @@ -1810,7 +1841,7 @@ proc map*[T, S](data: openArray[T], op: proc (x: T): S {.closure.}): seq[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: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## let ## a = @[1, 2, 3, 4] ## b = map(a, proc(x: int): string = $x) @@ -1824,7 +1855,7 @@ proc map*[T](data: var openArray[T], op: proc (x: var T) {.closure.}) = ## Note that this version of ``map`` requires your input and output types to ## be the same, since they are modified in-place. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var a = @["1", "2", "3", "4"] ## echo repr(a) ## # --> ["1", "2", "3", "4"] @@ -1833,7 +1864,7 @@ proc map*[T](data: var openArray[T], op: proc (x: var T) {.closure.}) = ## # --> ["142", "242", "342", "442"] for i in 0..data.len-1: op(data[i]) -iterator fields*[T: tuple|object](x: T): TObject {. +iterator fields*[T: tuple|object](x: T): RootObj {. magic: "Fields", noSideEffect.} ## iterates over every field of `x`. Warning: This really transforms ## the 'for' and unrolls the loop. The current implementation also has a bug @@ -1844,7 +1875,7 @@ iterator fields*[S:tuple|object, T:tuple|object](x: S, y: T): tuple[a,b: expr] { ## Warning: This is really transforms the 'for' and unrolls the loop. ## The current implementation also has a bug that affects symbol binding ## in the loop body. -iterator fieldPairs*[T: tuple|object](x: T): TObject {. +iterator fieldPairs*[T: tuple|object](x: T): RootObj {. magic: "FieldPairs", noSideEffect.} ## Iterates over every field of `x` returning their name and value. ## @@ -1853,7 +1884,7 @@ iterator fieldPairs*[T: tuple|object](x: T): TObject {. ## you want to run for each type. To perform the comparison use the `is ## operator <manual.html#is-operator>`_. Example: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## ## type ## Custom = object @@ -1915,7 +1946,7 @@ proc `$`*[T: tuple|object](x: T): string = ## generic ``$`` operator for tuples that is lifted from the components ## of `x`. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## $(23, 45) == "(23, 45)" ## $() == "()" result = "(" @@ -1941,7 +1972,7 @@ proc `$`*[T](x: set[T]): string = ## generic ``$`` operator for sets that is lifted from the components ## of `x`. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ${23, 45} == "{23, 45}" collectionToString(x, "{", "}") @@ -1949,7 +1980,7 @@ proc `$`*[T](x: seq[T]): string = ## generic ``$`` operator for seqs that is lifted from the components ## of `x`. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## $(@[23, 45]) == "@[23, 45]" collectionToString(x, "@[", "]") @@ -1962,41 +1993,44 @@ when false: # ----------------- GC interface --------------------------------------------- when not defined(nimrodVM) and hostOS != "standalone": - proc GC_disable*() {.rtl, inl.} + proc GC_disable*() {.rtl, inl, benign.} ## disables the GC. If called n-times, n calls to `GC_enable` are needed to ## reactivate the GC. Note that in most circumstances one should only disable ## the mark and sweep phase with `GC_disableMarkAndSweep`. - proc GC_enable*() {.rtl, inl.} + proc GC_enable*() {.rtl, inl, benign.} ## enables the GC again. - proc GC_fullCollect*() {.rtl.} + proc GC_fullCollect*() {.rtl, benign.} ## forces a full garbage collection pass. ## Ordinary code does not need to call this (and should not). type - TGC_Strategy* = enum ## the strategy the GC should use for the application + GC_Strategy* = enum ## the strategy the GC should use for the application gcThroughput, ## optimize for throughput gcResponsiveness, ## optimize for responsiveness (default) gcOptimizeTime, ## optimize for speed gcOptimizeSpace ## optimize for memory footprint - proc GC_setStrategy*(strategy: TGC_Strategy) {.rtl, deprecated.} + {.deprecated: [TGC_Strategy: GC_Strategy].} + + proc GC_setStrategy*(strategy: GC_Strategy) {.rtl, deprecated, benign.} ## tells the GC the desired strategy for the application. ## **Deprecated** since version 0.8.14. This has always been a nop. - proc GC_enableMarkAndSweep*() {.rtl.} - proc GC_disableMarkAndSweep*() {.rtl.} + proc GC_enableMarkAndSweep*() {.rtl, benign.} + proc GC_disableMarkAndSweep*() {.rtl, benign.} ## the current implementation uses a reference counting garbage collector ## with a seldomly run mark and sweep phase to free cycles. The mark and ## sweep phase may take a long time and is not needed if the application ## does not create cycles. Thus the mark and sweep phase can be deactivated ## and activated separately from the rest of the GC. - proc GC_getStatistics*(): string {.rtl.} + proc GC_getStatistics*(): string {.rtl, benign.} ## returns an informative string about the GC's activity. This may be useful ## for tweaking. + # XXX mark these as 'locks: 0' once 0.10.0 has been released proc GC_ref*[T](x: ref T) {.magic: "GCref", gcsafe.} proc GC_ref*[T](x: seq[T]) {.magic: "GCref", gcsafe.} proc GC_ref*(x: string) {.magic: "GCref", gcsafe.} @@ -2015,7 +2049,7 @@ template accumulateResult*(iter: expr) = for x in iter: add(result, x) # we have to compute this here before turning it off in except.nim anyway ... -const nimrodStackTrace = compileOption("stacktrace") +const NimStackTrace = compileOption("stacktrace") {.push checks: off.} # obviously we cannot generate checking operations here :-) @@ -2024,7 +2058,7 @@ const nimrodStackTrace = compileOption("stacktrace") # of the code var - globalRaiseHook*: proc (e: ref E_Base): bool {.nimcall, gcsafe.} + globalRaiseHook*: proc (e: ref Exception): bool {.nimcall, benign.} ## with this hook you can influence exception handling on a global level. ## If not nil, every 'raise' statement ends up calling this hook. Ordinary ## application code should never set this hook! You better know what you @@ -2032,7 +2066,7 @@ var ## exception is caught and does not propagate further through the call ## stack. - localRaiseHook* {.threadvar.}: proc (e: ref E_Base): bool {.nimcall, gcsafe.} + localRaiseHook* {.threadvar.}: proc (e: ref Exception): bool {.nimcall, benign.} ## with this hook you can influence exception handling on a ## thread local level. ## If not nil, every 'raise' statement ends up calling this hook. Ordinary @@ -2040,13 +2074,13 @@ var ## do when setting this. If ``localRaiseHook`` returns false, the exception ## is caught and does not propagate further through the call stack. - outOfMemHook*: proc () {.nimcall, tags: [], gcsafe.} + outOfMemHook*: proc () {.nimcall, tags: [], benign.} ## set this variable to provide a procedure that should be called ## in case of an `out of memory`:idx: event. The standard handler ## writes an error message and terminates the program. `outOfMemHook` can ## be used to raise an exception in case of OOM like so: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## var gOutOfMem: ref EOutOfMemory ## new(gOutOfMem) # need to be allocated *before* OOM really happened! @@ -2092,7 +2126,7 @@ elif hostOS != "standalone": inc(i) {.pop.} -proc echo*[T](x: varargs[T, `$`]) {.magic: "Echo", tags: [FWriteIO], gcsafe.} +proc echo*[T](x: varargs[T, `$`]) {.magic: "Echo", tags: [WriteIOEffect], benign.} ## Writes and flushes the parameters to the standard output. ## ## Special built-in that takes a variable number of arguments. Each argument @@ -2145,9 +2179,14 @@ when not declared(sysFatal): e.msg = message & arg raise e -proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo", gcsafe.} - ## get type information for `x`. Ordinary code should not use this, but - ## the `typeinfo` module instead. +when defined(nimlocks): + proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo", gcsafe, locks: 0.} + ## get type information for `x`. Ordinary code should not use this, but + ## the `typeinfo` module instead. +else: + proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo", gcsafe.} + ## get type information for `x`. Ordinary code should not use this, but + ## the `typeinfo` module instead. {.push stackTrace: off.} proc abs*(x: int): int {.magic: "AbsI", noSideEffect.} = @@ -2224,9 +2263,9 @@ when not defined(JS): #and not defined(NimrodVM): type CFile {.importc: "FILE", header: "<stdio.h>", final, incompletestruct.} = object - TFile* = ptr CFile ## The type representing a file handle. + File* = ptr CFile ## The type representing a file handle. - TFileMode* = enum ## The file mode when opening a file. + FileMode* = enum ## The file mode when opening a file. fmRead, ## Open the file for read access only. fmWrite, ## Open the file for write access only. fmReadWrite, ## Open the file for read and write access. @@ -2238,103 +2277,105 @@ when not defined(JS): #and not defined(NimrodVM): fmAppend ## Open the file for writing only; append data ## at the end. - TFileHandle* = cint ## type that represents an OS file handle; this is - ## useful for low-level file access + FileHandle* = cint ## type that represents an OS file handle; this is + ## useful for low-level file access + + {.deprecated: [TFile: File, TFileHandle: FileHandle, TFileMode: FileMode].} # text file handling: var - stdin* {.importc: "stdin", header: "<stdio.h>".}: TFile + stdin* {.importc: "stdin", header: "<stdio.h>".}: File ## The standard input stream. - stdout* {.importc: "stdout", header: "<stdio.h>".}: TFile + stdout* {.importc: "stdout", header: "<stdio.h>".}: File ## The standard output stream. - stderr* {.importc: "stderr", header: "<stdio.h>".}: TFile + stderr* {.importc: "stderr", header: "<stdio.h>".}: File ## The standard error stream. when defined(useStdoutAsStdmsg): - template stdmsg*: TFile = stdout + template stdmsg*: File = stdout else: - template stdmsg*: TFile = stderr + template stdmsg*: File = stderr ## Template which expands to either stdout or stderr depending on ## `useStdoutAsStdmsg` compile-time switch. - proc open*(f: var TFile, filename: string, - mode: TFileMode = fmRead, bufSize: int = -1): bool {.tags: [], - gcsafe.} + proc open*(f: var File, filename: string, + mode: FileMode = fmRead, bufSize: int = -1): bool {.tags: [], + benign.} ## Opens a file named `filename` with given `mode`. ## ## Default mode is readonly. Returns true iff the file could be opened. ## This throws no exception if the file could not be opened. - proc open*(f: var TFile, filehandle: TFileHandle, - mode: TFileMode = fmRead): bool {.tags: [], gcsafe.} + proc open*(f: var File, filehandle: FileHandle, + mode: FileMode = fmRead): bool {.tags: [], benign.} ## Creates a ``TFile`` from a `filehandle` with given `mode`. ## ## Default mode is readonly. Returns true iff the file could be opened. proc open*(filename: string, - mode: TFileMode = fmRead, bufSize: int = -1): TFile = + mode: FileMode = fmRead, bufSize: int = -1): File = ## Opens a file named `filename` with given `mode`. ## ## Default mode is readonly. Raises an ``IO`` exception if the file ## could not be opened. if not open(result, filename, mode, bufSize): - sysFatal(EIO, "cannot open: ", filename) + sysFatal(IOError, "cannot open: ", filename) - proc reopen*(f: TFile, filename: string, mode: TFileMode = fmRead): bool {. - tags: [], gcsafe.} + proc reopen*(f: File, filename: string, mode: FileMode = fmRead): bool {. + tags: [], benign.} ## reopens the file `f` with given `filename` and `mode`. This ## is often used to redirect the `stdin`, `stdout` or `stderr` ## file variables. ## ## Default mode is readonly. Returns true iff the file could be reopened. - proc close*(f: TFile) {.importc: "fclose", header: "<stdio.h>", tags: [].} + proc close*(f: File) {.importc: "fclose", header: "<stdio.h>", tags: [].} ## Closes the file. - proc endOfFile*(f: TFile): bool {.tags: [], gcsafe.} + proc endOfFile*(f: File): bool {.tags: [], benign.} ## Returns true iff `f` is at the end. - proc readChar*(f: TFile): char {. - importc: "fgetc", header: "<stdio.h>", tags: [FReadIO].} + proc readChar*(f: File): char {. + importc: "fgetc", header: "<stdio.h>", tags: [ReadIOEffect].} ## Reads a single character from the stream `f`. - proc flushFile*(f: TFile) {. - importc: "fflush", header: "<stdio.h>", tags: [FWriteIO].} + proc flushFile*(f: File) {. + importc: "fflush", header: "<stdio.h>", tags: [WriteIOEffect].} ## Flushes `f`'s buffer. - proc readAll*(file: TFile): TaintedString {.tags: [FReadIO], gcsafe.} + proc readAll*(file: File): TaintedString {.tags: [ReadIOEffect], benign.} ## Reads all data from the stream `file`. ## ## Raises an IO exception in case of an error. It is an error if the ## current file position is not at the beginning of the file. - proc readFile*(filename: string): TaintedString {.tags: [FReadIO], gcsafe.} + proc readFile*(filename: string): TaintedString {.tags: [ReadIOEffect], benign.} ## Opens a file named `filename` for reading. Then calls `readAll` ## and closes the file afterwards. Returns the string. ## Raises an IO exception in case of an error. - proc writeFile*(filename, content: string) {.tags: [FWriteIO], gcsafe.} + proc writeFile*(filename, content: string) {.tags: [WriteIOEffect], benign.} ## Opens a file named `filename` for writing. Then writes the ## `content` completely to the file and closes the file afterwards. ## Raises an IO exception in case of an error. - proc write*(f: TFile, r: float32) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, i: int) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, i: BiggestInt) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, r: BiggestFloat) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, s: string) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, b: bool) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, c: char) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, c: cstring) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, a: varargs[string, `$`]) {.tags: [FWriteIO], gcsafe.} + proc write*(f: File, r: float32) {.tags: [WriteIOEffect], benign.} + proc write*(f: File, i: int) {.tags: [WriteIOEffect], benign.} + proc write*(f: File, i: BiggestInt) {.tags: [WriteIOEffect], benign.} + proc write*(f: File, r: BiggestFloat) {.tags: [WriteIOEffect], benign.} + proc write*(f: File, s: string) {.tags: [WriteIOEffect], benign.} + proc write*(f: File, b: bool) {.tags: [WriteIOEffect], benign.} + proc write*(f: File, c: char) {.tags: [WriteIOEffect], benign.} + proc write*(f: File, c: cstring) {.tags: [WriteIOEffect], benign.} + proc write*(f: File, a: varargs[string, `$`]) {.tags: [WriteIOEffect], benign.} ## Writes a value to the file `f`. May throw an IO exception. - proc readLine*(f: TFile): TaintedString {.tags: [FReadIO], gcsafe.} + proc readLine*(f: File): TaintedString {.tags: [ReadIOEffect], benign.} ## reads a line of text from the file `f`. May throw an IO exception. ## A line of text may be delimited by ``CR``, ``LF`` or ## ``CRLF``. The newline character(s) are not part of the returned string. - proc readLine*(f: TFile, line: var TaintedString): bool {.tags: [FReadIO], - gcsafe.} + proc readLine*(f: File, line: var TaintedString): bool {.tags: [ReadIOEffect], + benign.} ## reads a line of text from the file `f` into `line`. `line` must not be ## ``nil``! May throw an IO exception. ## A line of text may be delimited by ``CR``, ``LF`` or @@ -2343,66 +2384,69 @@ when not defined(JS): #and not defined(NimrodVM): ## otherwise. If ``false`` is returned `line` contains no new data. when not defined(booting): - proc writeln*[Ty](f: TFile, x: varargs[Ty, `$`]) {.inline, - tags: [FWriteIO], gcsafe.} + proc writeln*[Ty](f: File, x: varargs[Ty, `$`]) {.inline, + tags: [WriteIOEffect], gcsafe, locks: 0.} ## writes the values `x` to `f` and then writes "\n". ## May throw an IO exception. else: - proc writeln*[Ty](f: TFile, x: varargs[Ty, `$`]) {.inline, - tags: [FWriteIO].} + proc writeln*[Ty](f: File, x: varargs[Ty, `$`]) {.inline, + tags: [WriteIOEffect].} - proc getFileSize*(f: TFile): int64 {.tags: [FReadIO], gcsafe.} + proc getFileSize*(f: File): int64 {.tags: [ReadIOEffect], benign.} ## retrieves the file size (in bytes) of `f`. - proc readBytes*(f: TFile, a: var openArray[int8], start, len: int): int {. - tags: [FReadIO], gcsafe.} + proc readBytes*(f: File, a: var openArray[int8], start, len: int): int {. + tags: [ReadIOEffect], benign.} ## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns ## the actual number of bytes that have been read which may be less than ## `len` (if not as many bytes are remaining), but not greater. - proc readChars*(f: TFile, a: var openArray[char], start, len: int): int {. - tags: [FReadIO], gcsafe.} + proc readChars*(f: File, a: var openArray[char], start, len: int): int {. + tags: [ReadIOEffect], benign.} ## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns ## the actual number of bytes that have been read which may be less than ## `len` (if not as many bytes are remaining), but not greater. - proc readBuffer*(f: TFile, buffer: pointer, len: int): int {. - tags: [FReadIO], gcsafe.} + proc readBuffer*(f: File, buffer: pointer, len: int): int {. + tags: [ReadIOEffect], benign.} ## reads `len` bytes into the buffer pointed to by `buffer`. Returns ## the actual number of bytes that have been read which may be less than ## `len` (if not as many bytes are remaining), but not greater. - proc writeBytes*(f: TFile, a: openArray[int8], start, len: int): int {. - tags: [FWriteIO], gcsafe.} + proc writeBytes*(f: File, a: openArray[int8], start, len: int): int {. + tags: [WriteIOEffect], benign.} ## writes the bytes of ``a[start..start+len-1]`` to the file `f`. Returns ## the number of actual written bytes, which may be less than `len` in case ## of an error. - proc writeChars*(f: TFile, a: openArray[char], start, len: int): int {. - tags: [FWriteIO], gcsafe.} + proc writeChars*(f: File, a: openArray[char], start, len: int): int {. + tags: [WriteIOEffect], benign.} ## writes the bytes of ``a[start..start+len-1]`` to the file `f`. Returns ## the number of actual written bytes, which may be less than `len` in case ## of an error. - proc writeBuffer*(f: TFile, buffer: pointer, len: int): int {. - tags: [FWriteIO], gcsafe.} + proc writeBuffer*(f: File, buffer: pointer, len: int): int {. + tags: [WriteIOEffect], benign.} ## writes the bytes of buffer pointed to by the parameter `buffer` to the ## file `f`. Returns the number of actual written bytes, which may be less ## than `len` in case of an error. - proc setFilePos*(f: TFile, pos: int64) {.gcsafe.} + proc setFilePos*(f: File, pos: int64) {.benign.} ## sets the position of the file pointer that is used for read/write ## operations. The file's first byte has the index zero. - proc getFilePos*(f: TFile): int64 {.gcsafe.} + proc getFilePos*(f: File): int64 {.benign.} ## retrieves the current position of the file pointer that is used to ## read from the file `f`. The file's first byte has the index zero. - proc fileHandle*(f: TFile): TFileHandle {.importc: "fileno", - header: "<stdio.h>"} + proc getFileHandle*(f: File): FileHandle {.importc: "fileno", + header: "<stdio.h>"} ## returns the OS file handle of the file ``f``. This is only useful for ## platform specific programming. + when not defined(nimfix): + {.deprecated: [fileHandle: getFileHandle].} + proc cstringArrayToSeq*(a: cstringArray, len: int): seq[string] = ## converts a ``cstringArray`` to a ``seq[string]``. `a` is supposed to be ## of length ``len``. @@ -2438,11 +2482,11 @@ when not defined(JS): #and not defined(NimrodVM): when not defined(NimrodVM): proc atomicInc*(memLoc: var int, x: int = 1): int {.inline, - discardable, gcsafe.} + discardable, benign.} ## atomic increment of `memLoc`. Returns the value after the operation. proc atomicDec*(memLoc: var int, x: int = 1): int {.inline, - discardable, gcsafe.} + discardable, benign.} ## atomic decrement of `memLoc`. Returns the value after the operation. include "system/atomics" @@ -2454,7 +2498,7 @@ when not defined(JS): #and not defined(NimrodVM): status: int context: C_JmpBuf hasRaiseAction: bool - raiseAction: proc (e: ref E_Base): bool {.closure.} + raiseAction: proc (e: ref Exception): bool {.closure.} when declared(initAllocator): initAllocator() @@ -2470,14 +2514,14 @@ when not defined(JS): #and not defined(NimrodVM): ## allows you to override the behaviour of your application when CTRL+C ## is pressed. Only one such hook is supported. - proc writeStackTrace*() {.tags: [FWriteIO].} + proc writeStackTrace*() {.tags: [WriteIOEffect].} ## writes the current stack trace to ``stderr``. This is only works ## for debug builds. when hostOS != "standalone": proc getStackTrace*(): string ## gets the current stack trace. This only works for debug builds. - proc getStackTrace*(e: ref E_Base): string + proc getStackTrace*(e: ref Exception): string ## gets the stack trace associated with `e`, which is the stack that ## lead to the ``raise`` statement. This only works for debug builds. @@ -2505,7 +2549,7 @@ when not defined(JS): #and not defined(NimrodVM): proc getDiscriminant(aa: pointer, n: ptr TNimNode): int = sysAssert(n.kind == nkCase, "getDiscriminant: node != nkCase") var d: int - var a = cast[TAddress](aa) + var a = cast[ByteAddress](aa) case n.typ.size of 1: d = ze(cast[ptr int8](a +% n.offset)[]) of 2: d = ze(cast[ptr int16](a +% n.offset)[]) @@ -2534,13 +2578,13 @@ when not defined(JS): #and not defined(NimrodVM): include "system/sysio" when hostOS != "standalone": - iterator lines*(filename: string): TaintedString {.tags: [FReadIO].} = + iterator lines*(filename: string): TaintedString {.tags: [ReadIOEffect].} = ## Iterates over any line in the file named `filename`. ## ## If the file does not exist `EIO` is raised. The trailing newline ## character(s) are removed from the iterated lines. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## import strutils ## ## proc transformLetters(filename: string) = @@ -2553,14 +2597,14 @@ when not defined(JS): #and not defined(NimrodVM): while f.readLine(res): yield res close(f) - iterator lines*(f: TFile): TaintedString {.tags: [FReadIO].} = + iterator lines*(f: File): TaintedString {.tags: [ReadIOEffect].} = ## Iterate over any line in the file `f`. ## ## The trailing newline character(s) are removed from the iterated lines. ## Example: ## - ## .. code-block:: nimrod - ## proc countZeros(filename: TFile): tuple[lines, zeros: int] = + ## .. code-block:: nim + ## proc countZeros(filename: File): tuple[lines, zeros: int] = ## for line in filename.lines: ## for letter in line: ## if letter == '0': @@ -2573,17 +2617,17 @@ when not defined(JS): #and not defined(NimrodVM): include "system/assign" include "system/repr" - proc getCurrentException*(): ref E_Base {.compilerRtl, inl, gcsafe.} = + proc getCurrentException*(): ref Exception {.compilerRtl, inl, benign.} = ## retrieves the current exception; if there is none, nil is returned. result = currException - proc getCurrentExceptionMsg*(): string {.inline, gcsafe.} = + proc getCurrentExceptionMsg*(): string {.inline, benign.} = ## retrieves the error message that was attached to the current ## exception; if there is none, "" is returned. var e = getCurrentException() return if e == nil: "" else: e.msg - proc onRaise*(action: proc(e: ref E_Base): bool{.closure.}) = + proc onRaise*(action: proc(e: ref Exception): bool{.closure.}) = ## can be used in a ``try`` statement to setup a Lisp-like ## `condition system`:idx:\: This prevents the 'raise' statement to ## raise an exception but instead calls ``action``. @@ -2593,6 +2637,12 @@ when not defined(JS): #and not defined(NimrodVM): excHandler.hasRaiseAction = true excHandler.raiseAction = action + proc setCurrentException*(exc: ref Exception) {.inline, benign.} = + ## sets the current exception. + ## + ## **Warning**: Only use this if you know what you are doing. + currException = exc + {.push stack_trace: off, profiler:off.} when defined(endb) and not defined(NimrodVM): include "system/debugger" @@ -2609,7 +2659,7 @@ when not defined(JS): #and not defined(NimrodVM): ## platforms this can help the processor predict better which branch is ## going to be run. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for value in inputValues: ## if likely(value <= 100): ## process(value) @@ -2623,7 +2673,7 @@ when not defined(JS): #and not defined(NimrodVM): ## platforms this can help the processor predict better which branch is ## going to be run. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for value in inputValues: ## if unlikely(value > 100): ## echo "Value too big!" @@ -2657,7 +2707,7 @@ elif defined(JS): proc GC_disable() = discard proc GC_enable() = discard proc GC_fullCollect() = discard - proc GC_setStrategy(strategy: TGC_Strategy) = discard + proc GC_setStrategy(strategy: GC_Strategy) = discard proc GC_enableMarkAndSweep() = discard proc GC_disableMarkAndSweep() = discard proc GC_getStatistics(): string = return "" @@ -2669,7 +2719,7 @@ elif defined(JS): proc dealloc(p: pointer) = discard proc alloc(size: int): pointer = discard proc alloc0(size: int): pointer = discard - proc realloc(p: Pointer, newsize: int): pointer = discard + proc realloc(p: pointer, newsize: int): pointer = discard proc allocShared(size: int): pointer = discard proc allocShared0(size: int): pointer = discard @@ -2721,16 +2771,16 @@ template spliceImpl(s, a, L, b: expr): stmt {.immediate.} = for i in 0 .. <b.len: s[i+a] = b[i] when hostOS != "standalone": - proc `[]`*(s: string, x: TSlice[int]): string {.inline.} = + proc `[]`*(s: string, x: Slice[int]): string {.inline.} = ## slice operation for strings. Negative indexes are supported. result = s.substr(x.a-|s, x.b-|s) - proc `[]=`*(s: var string, x: TSlice[int], b: string) = + proc `[]=`*(s: var string, x: Slice[int], b: string) = ## slice assignment for strings. Negative indexes are supported. If ## ``b.len`` is not exactly the number of elements that are referred to ## by `x`, a `splice`:idx: is performed: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var s = "abcdef" ## s[1 .. -2] = "xyz" ## assert s == "axyzf" @@ -2741,7 +2791,7 @@ when hostOS != "standalone": else: spliceImpl(s, a, L, b) -proc `[]`*[Idx, T](a: array[Idx, T], x: TSlice[int]): seq[T] = +proc `[]`*[Idx, T](a: array[Idx, T], x: Slice[int]): seq[T] = ## slice operation for arrays. Negative indexes are **not** supported ## because the array might have negative bounds. when low(a) < 0: @@ -2750,7 +2800,7 @@ proc `[]`*[Idx, T](a: array[Idx, T], x: TSlice[int]): seq[T] = newSeq(result, L) for i in 0.. <L: result[i] = a[i + x.a] -proc `[]=`*[Idx, T](a: var array[Idx, T], x: TSlice[int], b: openArray[T]) = +proc `[]=`*[Idx, T](a: var array[Idx, T], x: Slice[int], b: openArray[T]) = ## slice assignment for arrays. Negative indexes are **not** supported ## because the array might have negative bounds. when low(a) < 0: @@ -2759,9 +2809,9 @@ proc `[]=`*[Idx, T](a: var array[Idx, T], x: TSlice[int], b: openArray[T]) = if L == b.len: for i in 0 .. <L: a[i+x.a] = b[i] else: - sysFatal(EOutOfRange, "different lengths for slice assignment") + sysFatal(RangeError, "different lengths for slice assignment") -proc `[]`*[Idx, T](a: array[Idx, T], x: TSlice[Idx]): seq[T] = +proc `[]`*[Idx, T](a: array[Idx, T], x: Slice[Idx]): seq[T] = ## slice operation for arrays. Negative indexes are **not** supported ## because the array might have negative bounds. var L = ord(x.b) - ord(x.a) + 1 @@ -2771,7 +2821,7 @@ proc `[]`*[Idx, T](a: array[Idx, T], x: TSlice[Idx]): seq[T] = result[i] = a[j] inc(j) -proc `[]=`*[Idx, T](a: var array[Idx, T], x: TSlice[Idx], b: openArray[T]) = +proc `[]=`*[Idx, T](a: var array[Idx, T], x: Slice[Idx], b: openArray[T]) = ## slice assignment for arrays. Negative indexes are **not** supported ## because the array might have negative bounds. var L = ord(x.b) - ord(x.a) + 1 @@ -2781,16 +2831,16 @@ proc `[]=`*[Idx, T](a: var array[Idx, T], x: TSlice[Idx], b: openArray[T]) = a[j] = b[i] inc(j) else: - sysFatal(EOutOfRange, "different lengths for slice assignment") + sysFatal(RangeError, "different lengths for slice assignment") -proc `[]`*[T](s: seq[T], x: TSlice[int]): seq[T] = +proc `[]`*[T](s: seq[T], x: Slice[int]): seq[T] = ## slice operation for sequences. Negative indexes are supported. var a = x.a-|s var L = x.b-|s - a + 1 newSeq(result, L) for i in 0.. <L: result[i] = s[i + a] -proc `[]=`*[T](s: var seq[T], x: TSlice[int], b: openArray[T]) = +proc `[]=`*[T](s: var seq[T], x: Slice[int], b: openArray[T]) = ## slice assignment for sequences. Negative indexes are supported. If ## ``b.len`` is not exactly the number of elements that are referred to ## by `x`, a `splice`:idx: is performed. @@ -2807,7 +2857,7 @@ proc slurp*(filename: string): string {.magic: "Slurp".} proc staticRead*(filename: string): string {.magic: "Slurp".} ## Compile-time ``readFile`` proc for easy `resource`:idx: embedding: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## const myResource = staticRead"mydatafile.bin" ## ## ``slurp`` is an alias for ``staticRead``. @@ -2822,21 +2872,21 @@ proc staticExec*(command: string, input = ""): string {. ## if `input` is not an empty string, it will be passed as a standard input ## to the executed program. ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## const buildInfo = "Revision " & staticExec("git rev-parse HEAD") & ## "\nCompiled on " & staticExec("uname -v") ## ## ``gorge`` is an alias for ``staticExec``. Note that you can use this proc - ## inside a pragma like `passC <nimrodc.html#passc-pragma>`_ or `passL - ## <nimrodc.html#passl-pragma>`_. + ## inside a pragma like `passC <nimc.html#passc-pragma>`_ or `passL + ## <nimc.html#passl-pragma>`_. -proc `+=`*[T: TOrdinal|uint|uint64](x: var T, y: T) {.magic: "Inc", noSideEffect.} +proc `+=`*[T: SomeOrdinal|uint|uint64](x: var T, y: T) {.magic: "Inc", noSideEffect.} ## Increments an ordinal -proc `-=`*[T: TOrdinal|uint|uint64](x: var T, y: T) {.magic: "Dec", noSideEffect.} +proc `-=`*[T: SomeOrdinal|uint|uint64](x: var T, y: T) {.magic: "Dec", noSideEffect.} ## Decrements an ordinal -proc `*=`*[T: TOrdinal|uint|uint64](x: var T, y: T) {.inline, noSideEffect.} = +proc `*=`*[T: SomeOrdinal|uint|uint64](x: var T, y: T) {.inline, noSideEffect.} = ## Binary `*=` operator for ordinals x = x * y @@ -2870,7 +2920,7 @@ proc instantiationInfo*(index = -1, fullPaths = false): tuple[ ## to retrieve information about the current filename and line number. ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## import strutils ## ## template testException(exception, code: expr): stmt = @@ -2897,7 +2947,7 @@ template currentSourcePath*: string = instantiationInfo(-1, true).filename ## returns the full file-system path of the current source proc raiseAssert*(msg: string) {.noinline.} = - sysFatal(EAssertionFailed, msg) + sysFatal(AssertionError, msg) when true: proc failedAssertImpl*(msg: string) {.raises: [], tags: [].} = @@ -2910,12 +2960,12 @@ when true: template assert*(cond: bool, msg = "") = ## Raises ``EAssertionFailure`` with `msg` if `cond` is false. ## - ## Provides a means to implement `programming by contracts`:idx: in Nimrod. + ## Provides a means to implement `programming by contracts`:idx: in Nim. ## ``assert`` evaluates expression ``cond`` and if ``cond`` is false, it ## raises an ``EAssertionFailure`` exception. However, the compiler may not ## generate any code at all for ``assert`` if it is advised to do so through ## the ``-d:release`` or ``--assertions:off`` `command line switches - ## <nimrodc.html#command-line-switches>`_. + ## <nimc.html#command-line-switches>`_. ## ## Use ``assert`` for debugging purposes only. bind instantiationInfo @@ -2958,7 +3008,7 @@ template onFailedAssert*(msg: expr, code: stmt): stmt {.dirty, immediate.} = ## statements following `onFailedAssert` in the current lexical scope. ## Can be defined multiple times in a single function. ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## proc example(x: int): TErrorCode = ## onFailedAssert(msg): @@ -2995,7 +3045,7 @@ proc shallow*(s: var string) {.noSideEffect, inline.} = type TNimrodNode {.final.} = object PNimrodNode* {.magic: "PNimrodNode".} = ref TNimrodNode - ## represents a Nimrod AST node. Macros operate on this type. + ## represents a Nim AST node. Macros operate on this type. when false: template eval*(blk: stmt): stmt = @@ -3024,7 +3074,7 @@ proc compiles*(x): bool {.magic: "Compiles", noSideEffect.} = ## without any semantic error. ## This can be used to check whether a type supports some operation: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## when not compiles(3 + 4): ## echo "'+' for integers is available" discard @@ -3046,14 +3096,14 @@ when hostOS != "standalone": if x == nil: x = y else: x.add(y) -proc locals*(): TObject {.magic: "Locals", noSideEffect.} = +proc locals*(): RootObj {.magic: "Locals", noSideEffect.} = ## generates a tuple constructor expression listing all the local variables ## in the current scope. This is quite fast as it does not rely ## on any debug or runtime information. Note that in constrast to what ## the official signature says, the return type is not ``TObject`` but a ## tuple of a structure that depends on the current scope. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## proc testLocals() = ## var ## a = "something" diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim index 602e5c7fa..fd3ced832 100644 --- a/lib/system/alloc.nim +++ b/lib/system/alloc.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -# Low level allocator for Nimrod. Has been designed to support the GC. +# Low level allocator for Nim. Has been designed to support the GC. # TODO: # - eliminate "used" field # - make searching for block O(1) @@ -218,7 +218,7 @@ proc llAlloc(a: var TMemRegion, size: int): pointer = a.llmem.size = PageSize - sizeof(TLLChunk) a.llmem.acc = sizeof(TLLChunk) a.llmem.next = old - result = cast[pointer](cast[TAddress](a.llmem) + a.llmem.acc) + result = cast[pointer](cast[ByteAddress](a.llmem) + a.llmem.acc) dec(a.llmem.size, size) inc(a.llmem.acc, size) zeroMem(result, size) @@ -321,7 +321,7 @@ iterator allObjects(m: TMemRegion): pointer {.inline.} = var c = cast[PSmallChunk](c) let size = c.size - var a = cast[TAddress](addr(c.data)) + var a = cast[ByteAddress](addr(c.data)) let limit = a + c.acc while a <% limit: yield cast[pointer](a) @@ -335,27 +335,27 @@ proc isCell(p: pointer): bool {.inline.} = # ------------- chunk management ---------------------------------------------- proc pageIndex(c: PChunk): int {.inline.} = - result = cast[TAddress](c) shr PageShift + result = cast[ByteAddress](c) shr PageShift proc pageIndex(p: pointer): int {.inline.} = - result = cast[TAddress](p) shr PageShift + result = cast[ByteAddress](p) shr PageShift proc pageAddr(p: pointer): PChunk {.inline.} = - result = cast[PChunk](cast[TAddress](p) and not PageMask) + result = cast[PChunk](cast[ByteAddress](p) and not PageMask) #sysAssert(Contains(allocator.chunkStarts, pageIndex(result))) proc requestOsChunks(a: var TMemRegion, size: int): PBigChunk = incCurrMem(a, size) inc(a.freeMem, size) result = cast[PBigChunk](osAllocPages(size)) - sysAssert((cast[TAddress](result) and PageMask) == 0, "requestOsChunks 1") + sysAssert((cast[ByteAddress](result) and PageMask) == 0, "requestOsChunks 1") #zeroMem(result, size) result.next = nil result.prev = nil result.used = false result.size = size # update next.prevSize: - var nxt = cast[TAddress](result) +% size + var nxt = cast[ByteAddress](result) +% size sysAssert((nxt and PageMask) == 0, "requestOsChunks 2") var next = cast[PChunk](nxt) if pageIndex(next) in a.chunkStarts: @@ -363,7 +363,7 @@ proc requestOsChunks(a: var TMemRegion, size: int): PBigChunk = next.prevSize = size # set result.prevSize: var lastSize = if a.lastSize != 0: a.lastSize else: PageSize - var prv = cast[TAddress](result) -% lastSize + var prv = cast[ByteAddress](result) -% lastSize sysAssert((nxt and PageMask) == 0, "requestOsChunks 3") var prev = cast[PChunk](prv) if pageIndex(prev) in a.chunkStarts and prev.size == lastSize: @@ -376,7 +376,7 @@ proc requestOsChunks(a: var TMemRegion, size: int): PBigChunk = proc freeOsChunks(a: var TMemRegion, p: pointer, size: int) = # update next.prevSize: var c = cast[PChunk](p) - var nxt = cast[TAddress](p) +% c.size + var nxt = cast[ByteAddress](p) +% c.size sysAssert((nxt and PageMask) == 0, "freeOsChunks") var next = cast[PChunk](nxt) if pageIndex(next) in a.chunkStarts: @@ -429,8 +429,8 @@ proc listRemove[T](head: var T, c: T) {.inline.} = proc updatePrevSize(a: var TMemRegion, c: PBigChunk, prevSize: int) {.inline.} = - var ri = cast[PChunk](cast[TAddress](c) +% c.size) - sysAssert((cast[TAddress](ri) and PageMask) == 0, "updatePrevSize") + var ri = cast[PChunk](cast[ByteAddress](c) +% c.size) + sysAssert((cast[ByteAddress](ri) and PageMask) == 0, "updatePrevSize") if isAccessible(a, ri): ri.prevSize = prevSize @@ -439,8 +439,8 @@ proc freeBigChunk(a: var TMemRegion, c: PBigChunk) = sysAssert(c.size >= PageSize, "freeBigChunk") inc(a.freeMem, c.size) when coalescRight: - var ri = cast[PChunk](cast[TAddress](c) +% c.size) - sysAssert((cast[TAddress](ri) and PageMask) == 0, "freeBigChunk 2") + var ri = cast[PChunk](cast[ByteAddress](c) +% c.size) + sysAssert((cast[ByteAddress](ri) and PageMask) == 0, "freeBigChunk 2") if isAccessible(a, ri) and chunkUnused(ri): sysAssert(not isSmallChunk(ri), "freeBigChunk 3") if not isSmallChunk(ri): @@ -449,8 +449,8 @@ proc freeBigChunk(a: var TMemRegion, c: PBigChunk) = excl(a.chunkStarts, pageIndex(ri)) when coalescLeft: if c.prevSize != 0: - var le = cast[PChunk](cast[TAddress](c) -% c.prevSize) - sysAssert((cast[TAddress](le) and PageMask) == 0, "freeBigChunk 4") + var le = cast[PChunk](cast[ByteAddress](c) -% c.prevSize) + sysAssert((cast[ByteAddress](le) and PageMask) == 0, "freeBigChunk 4") if isAccessible(a, le) and chunkUnused(le): sysAssert(not isSmallChunk(le), "freeBigChunk 5") if not isSmallChunk(le): @@ -468,7 +468,7 @@ proc freeBigChunk(a: var TMemRegion, c: PBigChunk) = freeOsChunks(a, c, c.size) proc splitChunk(a: var TMemRegion, c: PBigChunk, size: int) = - var rest = cast[PBigChunk](cast[TAddress](c) +% size) + var rest = cast[PBigChunk](cast[ByteAddress](c) +% size) sysAssert(rest notin a.freeChunksList, "splitChunk") rest.size = c.size - size rest.used = false @@ -514,7 +514,7 @@ proc getSmallChunk(a: var TMemRegion): PSmallChunk = result = cast[PSmallChunk](res) # ----------------------------------------------------------------------------- -proc isAllocatedPtr(a: TMemRegion, p: pointer): bool +proc isAllocatedPtr(a: TMemRegion, p: pointer): bool {.benign.} proc allocInv(a: TMemRegion): bool = ## checks some (not all yet) invariants of the allocator's data structures. @@ -559,7 +559,7 @@ proc rawAlloc(a: var TMemRegion, requestedSize: int): pointer = c.prev = nil listAdd(a.freeSmallChunks[s], c) result = addr(c.data) - sysAssert((cast[TAddress](result) and (MemAlign-1)) == 0, "rawAlloc 4") + sysAssert((cast[ByteAddress](result) and (MemAlign-1)) == 0, "rawAlloc 4") else: sysAssert(allocInv(a), "rawAlloc: begin c != nil") sysAssert c.next != c, "rawAlloc 5" @@ -569,21 +569,21 @@ proc rawAlloc(a: var TMemRegion, requestedSize: int): pointer = if c.freeList == nil: sysAssert(c.acc + smallChunkOverhead() + size <= SmallChunkSize, "rawAlloc 7") - result = cast[pointer](cast[TAddress](addr(c.data)) +% c.acc) + result = cast[pointer](cast[ByteAddress](addr(c.data)) +% c.acc) inc(c.acc, size) else: result = c.freeList sysAssert(c.freeList.zeroField == 0, "rawAlloc 8") c.freeList = c.freeList.next dec(c.free, size) - sysAssert((cast[TAddress](result) and (MemAlign-1)) == 0, "rawAlloc 9") + sysAssert((cast[ByteAddress](result) and (MemAlign-1)) == 0, "rawAlloc 9") sysAssert(allocInv(a), "rawAlloc: end c != nil") sysAssert(allocInv(a), "rawAlloc: before c.free < size") if c.free < size: sysAssert(allocInv(a), "rawAlloc: before listRemove test") listRemove(a.freeSmallChunks[s], c) sysAssert(allocInv(a), "rawAlloc: end listRemove test") - sysAssert(((cast[TAddress](result) and PageMask) - smallChunkOverhead()) %% + sysAssert(((cast[ByteAddress](result) and PageMask) - smallChunkOverhead()) %% size == 0, "rawAlloc 21") sysAssert(allocInv(a), "rawAlloc: end small size") else: @@ -594,9 +594,9 @@ proc rawAlloc(a: var TMemRegion, requestedSize: int): pointer = sysAssert c.next == nil, "rawAlloc 11" sysAssert c.size == size, "rawAlloc 12" result = addr(c.data) - sysAssert((cast[TAddress](result) and (MemAlign-1)) == 0, "rawAlloc 13") + sysAssert((cast[ByteAddress](result) and (MemAlign-1)) == 0, "rawAlloc 13") if a.root == nil: a.root = bottom - add(a, a.root, cast[TAddress](result), cast[TAddress](result)+%size) + add(a, a.root, cast[ByteAddress](result), cast[ByteAddress](result)+%size) sysAssert(isAccessible(a, result), "rawAlloc 14") sysAssert(allocInv(a), "rawAlloc: end") when logAlloc: cprintf("rawAlloc: %ld %p\n", requestedSize, result) @@ -613,7 +613,7 @@ proc rawDealloc(a: var TMemRegion, p: pointer) = # `p` is within a small chunk: var c = cast[PSmallChunk](c) var s = c.size - sysAssert(((cast[TAddress](p) and PageMask) - smallChunkOverhead()) %% + sysAssert(((cast[ByteAddress](p) and PageMask) - smallChunkOverhead()) %% s == 0, "rawDealloc 3") var f = cast[ptr TFreeCell](p) #echo("setting to nil: ", $cast[TAddress](addr(f.zeroField))) @@ -636,7 +636,7 @@ proc rawDealloc(a: var TMemRegion, p: pointer) = listRemove(a.freeSmallChunks[s div MemAlign], c) c.size = SmallChunkSize freeBigChunk(a, cast[PBigChunk](c)) - sysAssert(((cast[TAddress](p) and PageMask) - smallChunkOverhead()) %% + sysAssert(((cast[ByteAddress](p) and PageMask) - smallChunkOverhead()) %% s == 0, "rawDealloc 2") else: # set to 0xff to check for usage after free bugs: @@ -655,7 +655,7 @@ proc isAllocatedPtr(a: TMemRegion, p: pointer): bool = if not chunkUnused(c): if isSmallChunk(c): var c = cast[PSmallChunk](c) - var offset = (cast[TAddress](p) and (PageSize-1)) -% + var offset = (cast[ByteAddress](p) and (PageSize-1)) -% smallChunkOverhead() result = (c.acc >% offset) and (offset %% c.size == 0) and (cast[ptr TFreeCell](p).zeroField >% 1) @@ -673,12 +673,12 @@ proc interiorAllocatedPtr(a: TMemRegion, p: pointer): pointer = if not chunkUnused(c): if isSmallChunk(c): var c = cast[PSmallChunk](c) - var offset = (cast[TAddress](p) and (PageSize-1)) -% + var offset = (cast[ByteAddress](p) and (PageSize-1)) -% smallChunkOverhead() if c.acc >% offset: - sysAssert(cast[TAddress](addr(c.data)) +% offset == - cast[TAddress](p), "offset is not what you think it is") - var d = cast[ptr TFreeCell](cast[TAddress](addr(c.data)) +% + sysAssert(cast[ByteAddress](addr(c.data)) +% offset == + cast[ByteAddress](p), "offset is not what you think it is") + var d = cast[ptr TFreeCell](cast[ByteAddress](addr(c.data)) +% offset -% (offset %% c.size)) if d.zeroField >% 1: result = d @@ -704,7 +704,7 @@ proc interiorAllocatedPtr(a: TMemRegion, p: pointer): pointer = sysAssert isAllocatedPtr(a, result), " result wrong pointer!" proc ptrSize(p: pointer): int = - var x = cast[pointer](cast[TAddress](p) -% sizeof(TFreeCell)) + var x = cast[pointer](cast[ByteAddress](p) -% sizeof(TFreeCell)) var c = pageAddr(p) sysAssert(not chunkUnused(c), "ptrSize") result = c.size -% sizeof(TFreeCell) @@ -715,7 +715,7 @@ proc alloc(allocator: var TMemRegion, size: int): pointer = result = rawAlloc(allocator, size+sizeof(TFreeCell)) cast[ptr TFreeCell](result).zeroField = 1 # mark it as used sysAssert(not isAllocatedPtr(allocator, result), "alloc") - result = cast[pointer](cast[TAddress](result) +% sizeof(TFreeCell)) + result = cast[pointer](cast[ByteAddress](result) +% sizeof(TFreeCell)) proc alloc0(allocator: var TMemRegion, size: int): pointer = result = alloc(allocator, size) @@ -723,7 +723,7 @@ proc alloc0(allocator: var TMemRegion, size: int): pointer = proc dealloc(allocator: var TMemRegion, p: pointer) = sysAssert(p != nil, "dealloc 0") - var x = cast[pointer](cast[TAddress](p) -% sizeof(TFreeCell)) + var x = cast[pointer](cast[ByteAddress](p) -% sizeof(TFreeCell)) sysAssert(x != nil, "dealloc 1") sysAssert(isAccessible(allocator, x), "is not accessible") sysAssert(cast[ptr TFreeCell](x).zeroField == 1, "dealloc 2") @@ -769,7 +769,7 @@ template instantiateForRegion(allocator: expr) = result = interiorAllocatedPtr(allocator, p) proc isAllocatedPtr*(p: pointer): bool = - let p = cast[pointer](cast[TAddress](p)-%TAddress(sizeof(TCell))) + let p = cast[pointer](cast[ByteAddress](p)-%ByteAddress(sizeof(TCell))) result = isAllocatedPtr(allocator, p) proc deallocOsPages = deallocOsPages(allocator) @@ -784,7 +784,7 @@ template instantiateForRegion(allocator: expr) = dealloc(allocator, p) proc realloc(p: pointer, newsize: int): pointer = - result = realloc(allocator, p, newsize) + result = realloc(allocator, p, newSize) when false: proc countFreeMem(): int = @@ -833,7 +833,7 @@ template instantiateForRegion(allocator: expr) = result = realloc(sharedHeap, p, newsize) releaseSys(heapLock) else: - result = realloc(p, newsize) + result = realloc(p, newSize) when hasThreadSupport: diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim index 673d55582..6bc44719f 100644 --- a/lib/system/ansi_c.nim +++ b/lib/system/ansi_c.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -8,7 +8,7 @@ # # This include file contains headers of Ansi C procs -# and definitions of Ansi C types in Nimrod syntax +# and definitions of Ansi C types in Nim syntax # All symbols are prefixed with 'c_' to avoid ambiguities {.push hints:off} diff --git a/lib/system/arithm.nim b/lib/system/arithm.nim index 7672947cd..c4df287cf 100644 --- a/lib/system/arithm.nim +++ b/lib/system/arithm.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -12,10 +12,10 @@ proc raiseOverflow {.compilerproc, noinline, noreturn.} = # a single proc to reduce code size to a minimum - sysFatal(EOverflow, "over- or underflow") + sysFatal(OverflowError, "over- or underflow") proc raiseDivByZero {.compilerproc, noinline, noreturn.} = - sysFatal(EDivByZero, "divison by zero") + sysFatal(DivByZeroError, "divison by zero") proc addInt64(a, b: int64): int64 {.compilerProc, inline.} = result = a +% b @@ -328,16 +328,16 @@ when not declared(mulInt): # written in other languages. proc raiseFloatInvalidOp {.noinline, noreturn.} = - sysFatal(EFloatInvalidOp, "FPU operation caused a NaN result") + sysFatal(FloatInvalidOpError, "FPU operation caused a NaN result") proc nanCheck(x: float64) {.compilerProc, inline.} = if x != x: raiseFloatInvalidOp() proc raiseFloatOverflow(x: float64) {.noinline, noreturn.} = if x > 0.0: - sysFatal(EFloatOverflow, "FPU operation caused an overflow") + sysFatal(FloatOverflowError, "FPU operation caused an overflow") else: - sysFatal(EFloatUnderflow, "FPU operations caused an underflow") + sysFatal(FloatUnderflowError, "FPU operations caused an underflow") proc infCheck(x: float64) {.compilerProc, inline.} = if x != 0.0 and x*0.5 == x: raiseFloatOverflow(x) diff --git a/lib/system/assign.nim b/lib/system/assign.nim index 0e27eb57f..8d53e127c 100644 --- a/lib/system/assign.nim +++ b/lib/system/assign.nim @@ -1,20 +1,20 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -proc genericResetAux(dest: pointer, n: ptr TNimNode) {.gcsafe.} +proc genericResetAux(dest: pointer, n: ptr TNimNode) {.benign.} -proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) {.gcsafe.} +proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) {.benign.} proc genericAssignAux(dest, src: pointer, n: ptr TNimNode, - shallow: bool) {.gcsafe.} = + shallow: bool) {.benign.} = var - d = cast[TAddress](dest) - s = cast[TAddress](src) + d = cast[ByteAddress](dest) + s = cast[ByteAddress](src) case n.kind of nkSlot: genericAssignAux(cast[pointer](d +% n.offset), @@ -40,8 +40,8 @@ proc genericAssignAux(dest, src: pointer, n: ptr TNimNode, proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) = var - d = cast[TAddress](dest) - s = cast[TAddress](src) + d = cast[ByteAddress](dest) + s = cast[ByteAddress](src) sysAssert(mt != nil, "genericAssignAux 2") case mt.kind of tyString: @@ -62,11 +62,11 @@ proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) = return sysAssert(dest != nil, "genericAssignAux 3") unsureAsgnRef(x, newSeq(mt, seq.len)) - var dst = cast[TAddress](cast[PPointer](dest)[]) + var dst = cast[ByteAddress](cast[PPointer](dest)[]) for i in 0..seq.len-1: genericAssignAux( cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize), - cast[pointer](cast[TAddress](s2) +% i *% mt.base.size +% + cast[pointer](cast[ByteAddress](s2) +% i *% mt.base.size +% GenericSeqSize), mt.base, shallow) of tyObject: @@ -130,15 +130,15 @@ proc genericSeqAssign(dest, src: pointer, mt: PNimType) {.compilerProc.} = proc genericAssignOpenArray(dest, src: pointer, len: int, mt: PNimType) {.compilerproc.} = var - d = cast[TAddress](dest) - s = cast[TAddress](src) + d = cast[ByteAddress](dest) + s = cast[ByteAddress](src) for i in 0..len-1: genericAssign(cast[pointer](d +% i*% mt.base.size), cast[pointer](s +% i*% mt.base.size), mt.base) -proc objectInit(dest: pointer, typ: PNimType) {.compilerProc, gcsafe.} -proc objectInitAux(dest: pointer, n: ptr TNimNode) {.gcsafe.} = - var d = cast[TAddress](dest) +proc objectInit(dest: pointer, typ: PNimType) {.compilerProc, benign.} +proc objectInitAux(dest: pointer, n: ptr TNimNode) {.benign.} = + var d = cast[ByteAddress](dest) case n.kind of nkNone: sysAssert(false, "objectInitAux") of nkSlot: objectInit(cast[pointer](d +% n.offset), n.typ) @@ -152,7 +152,7 @@ proc objectInitAux(dest: pointer, n: ptr TNimNode) {.gcsafe.} = proc objectInit(dest: pointer, typ: PNimType) = # the generic init proc that takes care of initialization of complex # objects on the stack or heap - var d = cast[TAddress](dest) + var d = cast[ByteAddress](dest) case typ.kind of tyObject: # iterate over any structural type @@ -182,9 +182,9 @@ else: mixin destroy for i in countup(0, r.len - 1): destroy(r[i]) -proc genericReset(dest: pointer, mt: PNimType) {.compilerProc, gcsafe.} +proc genericReset(dest: pointer, mt: PNimType) {.compilerProc, benign.} proc genericResetAux(dest: pointer, n: ptr TNimNode) = - var d = cast[TAddress](dest) + var d = cast[ByteAddress](dest) case n.kind of nkNone: sysAssert(false, "genericResetAux") of nkSlot: genericReset(cast[pointer](d +% n.offset), n.typ) @@ -196,7 +196,7 @@ proc genericResetAux(dest: pointer, n: ptr TNimNode) = zeroMem(cast[pointer](d +% n.offset), n.typ.size) proc genericReset(dest: pointer, mt: PNimType) = - var d = cast[TAddress](dest) + var d = cast[ByteAddress](dest) sysAssert(mt != nil, "genericReset 2") case mt.kind of tyString, tyRef, tySequence: @@ -223,4 +223,4 @@ proc FieldDiscriminantCheck(oldDiscVal, newDiscVal: int, var oldBranch = selectBranch(oldDiscVal, L, a) var newBranch = selectBranch(newDiscVal, L, a) if newBranch != oldBranch and oldDiscVal != 0: - sysFatal(EInvalidField, "assignment to discriminant changes object branch") + sysFatal(FieldError, "assignment to discriminant changes object branch") diff --git a/lib/system/atomics.nim b/lib/system/atomics.nim index 3ef9d00ec..5e5c72fae 100644 --- a/lib/system/atomics.nim +++ b/lib/system/atomics.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -# Atomic operations for Nimrod. +# Atomic operations for Nim. {.push stackTrace:off.} const someGcc = defined(gcc) or defined(llvm_gcc) or defined(clang) @@ -165,6 +165,7 @@ when someGcc and hasThreadSupport: elif defined(vcc) and hasThreadSupport: proc addAndFetch*(p: ptr int, val: int): int {. importc: "NimXadd", nodecl.} + proc fence*() {.importc: "_ReadWriteBarrier", header: "<intrin.h>".} else: proc addAndFetch*(p: ptr int, val: int): int {.inline.} = diff --git a/lib/system/avltree.nim b/lib/system/avltree.nim index bced15d6a..292097062 100644 --- a/lib/system/avltree.nim +++ b/lib/system/avltree.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -51,7 +51,7 @@ proc split(t: var PAvlNode) = t.link[0] = temp inc t.level -proc add(a: var TMemRegion, t: var PAvlNode, key, upperBound: int) {.gcsafe.} = +proc add(a: var TMemRegion, t: var PAvlNode, key, upperBound: int) {.benign.} = if t == bottom: t = allocAvlNode(a, key, upperBound) else: @@ -64,7 +64,7 @@ proc add(a: var TMemRegion, t: var PAvlNode, key, upperBound: int) {.gcsafe.} = skew(t) split(t) -proc del(a: var TMemRegion, t: var PAvlNode, x: int) {.gcsafe.} = +proc del(a: var TMemRegion, t: var PAvlNode, x: int) {.benign.} = if t == bottom: return a.last = t if x <% t.key: diff --git a/lib/system/cellsets.nim b/lib/system/cellsets.nim index 3825e5b47..0e3a01eba 100644 --- a/lib/system/cellsets.nim +++ b/lib/system/cellsets.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -27,7 +27,7 @@ type TBitIndex = range[0..UnitsPerPage-1] TPageDesc {.final, pure.} = object next: PPageDesc # all nodes are connected with this pointer - key: TAddress # start address at bit 0 + key: ByteAddress # start address at bit 0 bits: array[TBitIndex, int] # a bit vector PPageDescArray = ptr array[0..1000_000, PPageDesc] @@ -98,7 +98,7 @@ proc nextTry(h, maxHash: int): int {.inline.} = # generates each int in range(maxHash) exactly once (see any text on # random-number generation for proof). -proc cellSetGet(t: TCellSet, key: TAddress): PPageDesc = +proc cellSetGet(t: TCellSet, key: ByteAddress): PPageDesc = var h = cast[int](key) and t.max while t.data[h] != nil: if t.data[h].key == key: return t.data[h] @@ -123,7 +123,7 @@ proc cellSetEnlarge(t: var TCellSet) = dealloc(t.data) t.data = n -proc cellSetPut(t: var TCellSet, key: TAddress): PPageDesc = +proc cellSetPut(t: var TCellSet, key: ByteAddress): PPageDesc = var h = cast[int](key) and t.max while true: var x = t.data[h] @@ -147,7 +147,7 @@ proc cellSetPut(t: var TCellSet, key: TAddress): PPageDesc = # ---------- slightly higher level procs -------------------------------------- proc contains(s: TCellSet, cell: PCell): bool = - var u = cast[TAddress](cell) + var u = cast[ByteAddress](cell) var t = cellSetGet(s, u shr PageShift) if t != nil: u = (u %% PageSize) /% MemAlign @@ -156,13 +156,13 @@ proc contains(s: TCellSet, cell: PCell): bool = result = false proc incl(s: var TCellSet, cell: PCell) {.noinline.} = - var u = cast[TAddress](cell) + var u = cast[ByteAddress](cell) var t = cellSetPut(s, u shr PageShift) u = (u %% PageSize) /% MemAlign t.bits[u shr IntShift] = t.bits[u shr IntShift] or (1 shl (u and IntMask)) proc excl(s: var TCellSet, cell: PCell) = - var u = cast[TAddress](cell) + var u = cast[ByteAddress](cell) var t = cellSetGet(s, u shr PageShift) if t != nil: u = (u %% PageSize) /% MemAlign @@ -170,7 +170,7 @@ proc excl(s: var TCellSet, cell: PCell) = not (1 shl (u and IntMask))) proc containsOrIncl(s: var TCellSet, cell: PCell): bool = - var u = cast[TAddress](cell) + var u = cast[ByteAddress](cell) var t = cellSetGet(s, u shr PageShift) if t != nil: u = (u %% PageSize) /% MemAlign diff --git a/lib/system/cgprocs.nim b/lib/system/cgprocs.nim index d483c61bd..089846578 100644 --- a/lib/system/cgprocs.nim +++ b/lib/system/cgprocs.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -9,7 +9,7 @@ # Headers for procs that the code generator depends on ("compilerprocs") -proc addChar(s: NimString, c: char): NimString {.compilerProc, gcsafe.} +proc addChar(s: NimString, c: char): NimString {.compilerProc, benign.} type TLibHandle = pointer # private type @@ -21,5 +21,5 @@ proc nimGetProcAddr(lib: TLibHandle, name: cstring): TProcAddr {.compilerproc.} proc nimLoadLibraryError(path: string) {.compilerproc, noinline.} -proc setStackBottom(theStackBottom: pointer) {.compilerRtl, noinline, gcsafe.} +proc setStackBottom(theStackBottom: pointer) {.compilerRtl, noinline, benign.} diff --git a/lib/system/channels.nim b/lib/system/channels.nim index a5d5c0802..3e5ca0795 100644 --- a/lib/system/channels.nim +++ b/lib/system/channels.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -13,9 +13,9 @@ ## ## **Note:** The current implementation of message passing is slow and does ## not work with cyclic data structures. - -when not declared(NimString): - {.error: "You must not import this module explicitly".} + +when not declared(NimString): + {.error: "You must not import this module explicitly".} type pbytes = ptr array[0.. 0xffff, byte] @@ -49,12 +49,12 @@ proc deinitRawChannel(p: pointer) = deinitSysCond(c.cond) proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, - mode: TLoadStoreMode) {.gcsafe.} + mode: TLoadStoreMode) {.benign.} proc storeAux(dest, src: pointer, n: ptr TNimNode, t: PRawChannel, - mode: TLoadStoreMode) {.gcsafe.} = + mode: TLoadStoreMode) {.benign.} = var - d = cast[TAddress](dest) - s = cast[TAddress](src) + d = cast[ByteAddress](dest) + s = cast[ByteAddress](src) case n.kind of nkSlot: storeAux(cast[pointer](d +% n.offset), cast[pointer](s +% n.offset), n.typ, t, mode) @@ -70,14 +70,14 @@ proc storeAux(dest, src: pointer, n: ptr TNimNode, t: PRawChannel, proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, mode: TLoadStoreMode) = var - d = cast[TAddress](dest) - s = cast[TAddress](src) + d = cast[ByteAddress](dest) + s = cast[ByteAddress](src) sysAssert(mt != nil, "mt == nil") - case mt.Kind + case mt.kind of tyString: if mode == mStore: - var x = cast[ppointer](dest) - var s2 = cast[ppointer](s)[] + var x = cast[PPointer](dest) + var s2 = cast[PPointer](s)[] if s2 == nil: x[] = nil else: @@ -86,17 +86,17 @@ proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, copyMem(ns, ss, ss.len+1 + GenericSeqSize) x[] = ns else: - var x = cast[ppointer](dest) - var s2 = cast[ppointer](s)[] + var x = cast[PPointer](dest) + var s2 = cast[PPointer](s)[] if s2 == nil: unsureAsgnRef(x, s2) else: unsureAsgnRef(x, copyString(cast[NimString](s2))) dealloc(t.region, s2) of tySequence: - var s2 = cast[ppointer](src)[] + var s2 = cast[PPointer](src)[] var seq = cast[PGenericSeq](s2) - var x = cast[ppointer](dest) + var x = cast[PPointer](dest) if s2 == nil: if mode == mStore: x[] = nil @@ -108,13 +108,13 @@ proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, x[] = alloc(t.region, seq.len *% mt.base.size +% GenericSeqSize) else: unsureAsgnRef(x, newObj(mt, seq.len * mt.base.size + GenericSeqSize)) - var dst = cast[taddress](cast[ppointer](dest)[]) + var dst = cast[ByteAddress](cast[PPointer](dest)[]) for i in 0..seq.len-1: storeAux( cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize), - cast[pointer](cast[TAddress](s2) +% i *% mt.base.size +% + cast[pointer](cast[ByteAddress](s2) +% i *% mt.base.size +% GenericSeqSize), - mt.Base, t, mode) + mt.base, t, mode) var dstseq = cast[PGenericSeq](dst) dstseq.len = seq.len dstseq.reserved = seq.len @@ -123,8 +123,8 @@ proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, # copy type field: var pint = cast[ptr PNimType](dest) # XXX use dynamic type here! - pint[] = mt - if mt.base != nil: + pint[] = mt + if mt.base != nil: storeAux(dest, src, mt.base, t, mode) storeAux(dest, src, mt.node, t, mode) of tyTuple: @@ -134,8 +134,8 @@ proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, storeAux(cast[pointer](d +% i*% mt.base.size), cast[pointer](s +% i*% mt.base.size), mt.base, t, mode) of tyRef: - var s = cast[ppointer](src)[] - var x = cast[ppointer](dest) + var s = cast[PPointer](src)[] + var x = cast[PPointer](dest) if s == nil: if mode == mStore: x[] = nil @@ -192,7 +192,7 @@ template lockChannel(q: expr, action: stmt) {.immediate.} = template sendImpl(q: expr) {.immediate.} = if q.mask == ChannelDeadMask: - sysFatal(EDeadThread, "cannot send message; thread died") + sysFatal(DeadThreadError, "cannot send message; thread died") acquireSys(q.lock) var m: TMsg shallowCopy(m, msg) @@ -215,7 +215,7 @@ proc llRecv(q: PRawChannel, res: pointer, typ: PNimType) = q.ready = false if typ != q.elemType: releaseSys(q.lock) - sysFatal(EInvalidValue, "cannot receive message of wrong type") + sysFatal(ValueError, "cannot receive message of wrong type") rawRecv(q, res, typ) proc recv*[TMsg](c: var TChannel[TMsg]): TMsg = @@ -225,21 +225,21 @@ proc recv*[TMsg](c: var TChannel[TMsg]): TMsg = acquireSys(q.lock) llRecv(q, addr(result), cast[PNimType](getTypeInfo(result))) releaseSys(q.lock) - -proc tryRecv*[TMsg](c: var TChannel[TMsg]): tuple[dataAvailable: bool, - msg: TMsg] = - ## try to receives a message from the channel `c` if available. Otherwise - ## it returns ``(false, default(msg))``. + +proc tryRecv*[TMsg](c: var TChannel[TMsg]): tuple[dataAvailable: bool, + msg: TMsg] = + ## try to receives a message from the channel `c` if available. Otherwise + ## it returns ``(false, default(msg))``. var q = cast[PRawChannel](addr(c)) - if q.mask != ChannelDeadMask: + if q.mask != ChannelDeadMask: if tryAcquireSys(q.lock): - llRecv(q, addr(result.msg), cast[PNimType](getTypeInfo(result.msg))) + llRecv(q, addr(result.msg), cast[PNimType](getTypeInfo(result.msg))) result.dataAvailable = true releaseSys(q.lock) proc peek*[TMsg](c: var TChannel[TMsg]): int = ## returns the current number of messages in the channel `c`. Returns -1 - ## if the channel has been closed. **Note**: This is dangerous to use + ## if the channel has been closed. **Note**: This is dangerous to use ## as it encourages races. It's much better to use ``tryRecv`` instead. var q = cast[PRawChannel](addr(c)) if q.mask != ChannelDeadMask: diff --git a/lib/system/chcks.nim b/lib/system/chcks.nim index 387b54ef1..5c32a307a 100644 --- a/lib/system/chcks.nim +++ b/lib/system/chcks.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -13,13 +13,13 @@ proc raiseRangeError(val: BiggestInt) {.compilerproc, noreturn, noinline.} = when hostOS == "standalone": sysFatal(EOutOfRange, "value out of range") else: - sysFatal(EOutOfRange, "value out of range: ", $val) + sysFatal(RangeError, "value out of range: ", $val) proc raiseIndexError() {.compilerproc, noreturn, noinline.} = - sysFatal(EInvalidIndex, "index out of bounds") + sysFatal(IndexError, "index out of bounds") proc raiseFieldError(f: string) {.compilerproc, noreturn, noinline.} = - sysFatal(EInvalidField, f, " is not accessible") + sysFatal(FieldError, f, " is not accessible") proc chckIndx(i, a, b: int): int = if i >= a and i <= b: @@ -46,11 +46,11 @@ proc chckRangeF(x, a, b: float): float = when hostOS == "standalone": sysFatal(EOutOfRange, "value out of range") else: - sysFatal(EOutOfRange, "value out of range: ", $x) + sysFatal(RangeError, "value out of range: ", $x) proc chckNil(p: pointer) = if p == nil: - sysFatal(EInvalidValue, "attempt to write to a nil address") + sysFatal(ValueError, "attempt to write to a nil address") #c_raise(SIGSEGV) proc chckObj(obj, subclass: PNimType) {.compilerproc.} = @@ -59,13 +59,13 @@ proc chckObj(obj, subclass: PNimType) {.compilerproc.} = if x == subclass: return # optimized fast path while x != subclass: if x == nil: - sysFatal(EInvalidObjectConversion, "invalid object conversion") + sysFatal(ObjectConversionError, "invalid object conversion") break x = x.base proc chckObjAsgn(a, b: PNimType) {.compilerproc, inline.} = if a != b: - sysFatal(EInvalidObjectAssignment, "invalid object assignment") + sysFatal(ObjectAssignmentError, "invalid object assignment") type ObjCheckCache = array[0..1, PNimType] diff --git a/lib/system/debugger.nim b/lib/system/debugger.nim index af7b6d515..7b5169344 100644 --- a/lib/system/debugger.nim +++ b/lib/system/debugger.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -157,8 +157,8 @@ type oldValue: THash var - Watchpoints: array [0..99, TWatchpoint] - WatchpointsLen: int + watchpoints: array [0..99, TWatchpoint] + watchpointsLen: int proc `!&`(h: THash, val: int): THash {.inline.} = result = h +% val @@ -189,7 +189,7 @@ proc genericHashAux(dest: pointer, mt: PNimType, shallow: bool, h: THash): THash proc genericHashAux(dest: pointer, n: ptr TNimNode, shallow: bool, h: THash): THash = - var d = cast[TAddress](dest) + var d = cast[ByteAddress](dest) case n.kind of nkSlot: result = genericHashAux(cast[pointer](d +% n.offset), n.typ, shallow, h) @@ -206,9 +206,9 @@ proc genericHashAux(dest: pointer, n: ptr TNimNode, shallow: bool, proc genericHashAux(dest: pointer, mt: PNimType, shallow: bool, h: THash): THash = sysAssert(mt != nil, "genericHashAux 2") - case mt.Kind + case mt.kind of tyString: - var x = cast[ppointer](dest)[] + var x = cast[PPointer](dest)[] result = h if x != nil: let s = cast[NimString](x) @@ -217,29 +217,29 @@ proc genericHashAux(dest: pointer, mt: PNimType, shallow: bool, else: result = result !& hash(x, s.len) of tySequence: - var x = cast[ppointer](dest) - var dst = cast[taddress](cast[ppointer](dest)[]) + var x = cast[PPointer](dest) + var dst = cast[ByteAddress](cast[PPointer](dest)[]) result = h if dst != 0: when defined(trackGcHeaders): - result = result !& hashGcHeader(cast[ppointer](dest)[]) + result = result !& hashGcHeader(cast[PPointer](dest)[]) else: - for i in 0..cast[pgenericseq](dst).len-1: + for i in 0..cast[PGenericSeq](dst).len-1: result = result !& genericHashAux( cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize), - mt.Base, shallow, result) + mt.base, shallow, result) of tyObject, tyTuple: # we don't need to copy m_type field for tyObject, as they are equal anyway result = genericHashAux(dest, mt.node, shallow, h) of tyArray, tyArrayConstr: - let d = cast[TAddress](dest) + let d = cast[ByteAddress](dest) result = h for i in 0..(mt.size div mt.base.size)-1: result = result !& genericHashAux(cast[pointer](d +% i*% mt.base.size), mt.base, shallow, result) of tyRef: when defined(trackGcHeaders): - var s = cast[ppointer](dest)[] + var s = cast[PPointer](dest)[] if s != nil: result = result !& hashGcHeader(s) else: @@ -247,7 +247,7 @@ proc genericHashAux(dest: pointer, mt: PNimType, shallow: bool, result = h !& hash(dest, mt.size) else: result = h - var s = cast[ppointer](dest)[] + var s = cast[PPointer](dest)[] if s != nil: result = result !& genericHashAux(s, mt.base, shallow, result) else: @@ -258,23 +258,23 @@ proc genericHash(dest: pointer, mt: PNimType): int = proc dbgRegisterWatchpoint(address: pointer, name: cstring, typ: PNimType) {.compilerproc.} = - let L = WatchpointsLen + let L = watchPointsLen for i in 0.. <L: - if Watchpoints[i].name == name: + if watchPoints[i].name == name: # address may have changed: - Watchpoints[i].address = address + watchPoints[i].address = address return if L >= watchPoints.high: #debugOut("[Warning] cannot register watchpoint") return - Watchpoints[L].name = name - Watchpoints[L].address = address - Watchpoints[L].typ = typ - Watchpoints[L].oldValue = genericHash(address, typ) - inc WatchpointsLen + watchPoints[L].name = name + watchPoints[L].address = address + watchPoints[L].typ = typ + watchPoints[L].oldValue = genericHash(address, typ) + inc watchPointsLen proc dbgUnregisterWatchpoints*() = - WatchpointsLen = 0 + watchPointsLen = 0 var dbgLineHook*: proc () {.nimcall.} @@ -285,15 +285,15 @@ var dbgWatchpointHook*: proc (watchpointName: cstring) {.nimcall.} proc checkWatchpoints = - let L = WatchpointsLen + let L = watchPointsLen for i in 0.. <L: - let newHash = genericHash(Watchpoints[i].address, Watchpoints[i].typ) - if newHash != Watchpoints[i].oldValue: - dbgWatchpointHook(Watchpoints[i].name) - Watchpoints[i].oldValue = newHash + let newHash = genericHash(watchPoints[i].address, watchPoints[i].typ) + if newHash != watchPoints[i].oldValue: + dbgWatchpointHook(watchPoints[i].name) + watchPoints[i].oldValue = newHash proc endb(line: int, file: cstring) {.compilerproc, noinline.} = - # This proc is called before every Nimrod code line! + # This proc is called before every Nim code line! if framePtr == nil: return if dbgWatchpointHook != nil: checkWatchpoints() framePtr.line = line # this is done here for smaller code size! diff --git a/lib/system/deepcopy.nim b/lib/system/deepcopy.nim index e7eb1cdb4..fbebb17a8 100644 --- a/lib/system/deepcopy.nim +++ b/lib/system/deepcopy.nim @@ -1,17 +1,17 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) {.gcsafe.} -proc genericDeepCopyAux(dest, src: pointer, n: ptr TNimNode) {.gcsafe.} = +proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) {.benign.} +proc genericDeepCopyAux(dest, src: pointer, n: ptr TNimNode) {.benign.} = var - d = cast[TAddress](dest) - s = cast[TAddress](src) + d = cast[ByteAddress](dest) + s = cast[ByteAddress](src) case n.kind of nkSlot: genericDeepCopyAux(cast[pointer](d +% n.offset), @@ -40,8 +40,8 @@ proc copyDeepString(src: NimString): NimString {.inline.} = proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) = var - d = cast[TAddress](dest) - s = cast[TAddress](src) + d = cast[ByteAddress](dest) + s = cast[ByteAddress](src) sysAssert(mt != nil, "genericDeepCopyAux 2") case mt.kind of tyString: @@ -60,11 +60,11 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) = return sysAssert(dest != nil, "genericDeepCopyAux 3") unsureAsgnRef(x, newSeq(mt, seq.len)) - var dst = cast[TAddress](cast[PPointer](dest)[]) + var dst = cast[ByteAddress](cast[PPointer](dest)[]) for i in 0..seq.len-1: genericDeepCopyAux( cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize), - cast[pointer](cast[TAddress](s2) +% i *% mt.base.size +% + cast[pointer](cast[ByteAddress](s2) +% i *% mt.base.size +% GenericSeqSize), mt.base) of tyObject: @@ -82,17 +82,16 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) = genericDeepCopyAux(cast[pointer](d +% i*% mt.base.size), cast[pointer](s +% i*% mt.base.size), mt.base) of tyRef: - if mt.base.deepCopy != nil: - let z = mt.base.deepCopy(cast[PPointer](src)[]) + let s2 = cast[PPointer](src)[] + if s2 == nil: + unsureAsgnRef(cast[PPointer](dest), s2) + elif mt.base.deepcopy != nil: + let z = mt.base.deepcopy(s2) unsureAsgnRef(cast[PPointer](dest), z) else: # we modify the header of the cell temporarily; instead of the type # field we store a forwarding pointer. XXX This is bad when the cloning # fails due to OOM etc. - let s2 = cast[PPointer](src)[] - if s2 == nil: - unsureAsgnRef(cast[PPointer](dest), s2) - return when declared(usrToCell): # unfortunately we only have cycle detection for our native GCs. let x = usrToCell(s2) @@ -116,10 +115,11 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) = genericDeepCopyAux(z, s2, realType.base) of tyPtr: # no cycle check here, but also not really required - if mt.base.deepCopy != nil: - cast[PPointer](dest)[] = mt.base.deepCopy(cast[PPointer](s)[]) + let s2 = cast[PPointer](src)[] + if s2 != nil and mt.base.deepcopy != nil: + cast[PPointer](dest)[] = mt.base.deepcopy(s2) else: - cast[PPointer](dest)[] = cast[PPointer](s)[] + cast[PPointer](dest)[] = s2 else: copyMem(dest, src, mt.size) @@ -134,8 +134,8 @@ proc genericSeqDeepCopy(dest, src: pointer, mt: PNimType) {.compilerProc.} = proc genericDeepCopyOpenArray(dest, src: pointer, len: int, mt: PNimType) {.compilerproc.} = var - d = cast[TAddress](dest) - s = cast[TAddress](src) + d = cast[ByteAddress](dest) + s = cast[ByteAddress](src) for i in 0..len-1: genericDeepCopy(cast[pointer](d +% i*% mt.base.size), cast[pointer](s +% i*% mt.base.size), mt.base) diff --git a/lib/system/dyncalls.nim b/lib/system/dyncalls.nim index 9ef1a99ca..e0d99cf88 100644 --- a/lib/system/dyncalls.nim +++ b/lib/system/dyncalls.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -17,7 +17,7 @@ const NilLibHandle: TLibHandle = nil -proc rawWrite(f: TFile, s: string) = +proc rawWrite(f: File, s: string) = # we cannot throw an exception here! discard writeBuffer(f, cstring(s), s.len) diff --git a/lib/system/embedded.nim b/lib/system/embedded.nim index 661992e81..9bb25b8dd 100644 --- a/lib/system/embedded.nim +++ b/lib/system/embedded.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -21,7 +21,7 @@ proc popFrame {.compilerRtl, inl.} = discard proc setFrame(s: PFrame) {.compilerRtl, inl.} = discard proc pushSafePoint(s: PSafePoint) {.compilerRtl, inl.} = discard proc popSafePoint {.compilerRtl, inl.} = discard -proc pushCurrentException(e: ref E_Base) {.compilerRtl, inl.} = discard +proc pushCurrentException(e: ref Exception) {.compilerRtl, inl.} = discard proc popCurrentException {.compilerRtl, inl.} = discard # some platforms have native support for stack traces: @@ -32,7 +32,7 @@ const proc quitOrDebug() {.inline.} = quit(1) -proc raiseException(e: ref E_Base, ename: CString) {.compilerRtl.} = +proc raiseException(e: ref Exception, ename: cstring) {.compilerRtl.} = sysFatal(ENoExceptionToReraise, "exception handling is not available") proc reraiseException() {.compilerRtl.} = diff --git a/lib/system/endb.nim b/lib/system/endb.nim index f7e95e216..003698421 100644 --- a/lib/system/endb.nim +++ b/lib/system/endb.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -11,7 +11,7 @@ # with the application. Mostly we do not use dynamic memory here as that # would interfere with the GC and trigger ON/OFF errors if the # user program corrupts memory. Unfortunately, for dispaying -# variables we use the ``system.repr()`` proc which uses Nimrod +# variables we use the ``system.repr()`` proc which uses Nim # strings and thus allocates memory from the heap. Pity, but # I do not want to implement ``repr()`` twice. @@ -152,7 +152,7 @@ proc debugOut(msg: cstring) = proc dbgFatal(msg: cstring) = debugOut(msg) - dbgAborting = True # the debugger wants to abort + dbgAborting = true # the debugger wants to abort quit(1) proc dbgShowCurrentProc(dbgFramePointer: PFrame) = @@ -176,7 +176,7 @@ proc scanAndAppendWord(src: cstring, a: var TStaticStr, start: int): int = result = start # skip whitespace: while src[result] in {'\t', ' '}: inc(result) - while True: + while true: case src[result] of 'a'..'z', '0'..'9': add(a, src[result]) of '_': discard # just skip it @@ -280,7 +280,7 @@ proc breakpointToggle(s: cstring, start: int) = else: debugOut("[Warning] unknown breakpoint ") proc dbgEvaluate(stream: TFile, s: cstring, start: int, f: PFrame) = - var dbgTemp: tstaticstr + var dbgTemp: TStaticStr var i = scanWord(s, dbgTemp, start) while s[i] in {' ', '\t'}: inc(i) var v: TVarSlot @@ -299,10 +299,10 @@ proc dbgEvaluate(stream: TFile, s: cstring, start: int, f: PFrame) = writeVariable(stream, v) proc dbgOut(s: cstring, start: int, currFrame: PFrame) = - var dbgTemp: tstaticstr + var dbgTemp: TStaticStr var i = scanFilename(s, dbgTemp, start) if dbgTemp.len == 0: - InvalidCommand() + invalidCommand() return var stream = openAppend(dbgTemp.data) if stream == nil: @@ -326,7 +326,7 @@ proc dbgStackFrame(s: cstring, start: int, currFrame: PFrame) = close(stream) proc readLine(f: TFile, line: var TStaticStr): bool = - while True: + while true: var c = fgetc(f) if c < 0'i32: if line.len > 0: break @@ -355,7 +355,7 @@ proc dbgWriteStackTrace(f: PFrame) proc commandPrompt() = # if we return from this routine, user code executes again var - again = True + again = true dbgFramePtr = framePtr # for going down and up the stack dbgDown = 0 # how often we did go down dbgTemp: TStaticStr @@ -390,7 +390,7 @@ proc commandPrompt() = dbgHelp() elif ?"q" or ?"quit": dbgState = dbQuiting - dbgAborting = True + dbgAborting = true again = false quit(1) # BUGFIX: quit with error code > 0 elif ?"e" or ?"eval": @@ -402,9 +402,9 @@ proc commandPrompt() = elif ?"w" or ?"where": dbgShowExecutionPoint() elif ?"l" or ?"locals": - ListLocals(stdout, dbgFramePtr) + listLocals(stdout, dbgFramePtr) elif ?"g" or ?"globals": - ListGlobals(stdout) + listGlobals(stdout) elif ?"u" or ?"up": if dbgDown <= 0: debugOut("[Warning] cannot go up any further ") diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index 3c5436afb..e21eeca6a 100644 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -11,7 +11,7 @@ # use the heap (and nor exceptions) do not include the GC or memory allocator. var - errorMessageWriter*: (proc(msg: string) {.tags: [FWriteIO], gcsafe.}) + errorMessageWriter*: (proc(msg: string) {.tags: [WriteIOEffect], benign.}) ## Function that will be called ## instead of stdmsg.write when printing stacktrace. ## Unstable API. @@ -32,17 +32,17 @@ proc showErrorMessage(data: cstring) = else: writeToStdErr(data) -proc chckIndx(i, a, b: int): int {.inline, compilerproc, gcsafe.} -proc chckRange(i, a, b: int): int {.inline, compilerproc, gcsafe.} -proc chckRangeF(x, a, b: float): float {.inline, compilerproc, gcsafe.} -proc chckNil(p: pointer) {.noinline, compilerproc, gcsafe.} +proc chckIndx(i, a, b: int): int {.inline, compilerproc, benign.} +proc chckRange(i, a, b: int): int {.inline, compilerproc, benign.} +proc chckRangeF(x, a, b: float): float {.inline, compilerproc, benign.} +proc chckNil(p: pointer) {.noinline, compilerproc, benign.} var framePtr {.threadvar.}: PFrame excHandler {.threadvar.}: PSafePoint # list of exception handlers # a global variable for the root of all try blocks - currException {.threadvar.}: ref E_Base + currException {.threadvar.}: ref Exception proc popFrame {.compilerRtl, inl.} = framePtr = framePtr.prev @@ -58,7 +58,7 @@ proc pushSafePoint(s: PSafePoint) {.compilerRtl, inl.} = proc popSafePoint {.compilerRtl, inl.} = excHandler = excHandler.prev -proc pushCurrentException(e: ref E_Base) {.compilerRtl, inl.} = +proc pushCurrentException(e: ref Exception) {.compilerRtl, inl.} = e.parent = currException currException = e @@ -68,8 +68,8 @@ proc popCurrentException {.compilerRtl, inl.} = # some platforms have native support for stack traces: const nativeStackTraceSupported* = (defined(macosx) or defined(linux)) and - not nimrodStackTrace - hasSomeStackTrace = nimrodStackTrace or + not NimStackTrace + hasSomeStackTrace = NimStackTrace or defined(nativeStackTrace) and nativeStackTraceSupported when defined(nativeStacktrace) and nativeStackTraceSupported: @@ -177,7 +177,7 @@ proc auxWriteStackTrace(f: PFrame, s: var string) = when hasSomeStackTrace: proc rawWriteStackTrace(s: var string) = - when nimrodStackTrace: + when NimStackTrace: if framePtr == nil: add(s, "No stack traceback available\n") else: @@ -195,7 +195,7 @@ proc quitOrDebug() {.inline.} = else: endbStep() # call the debugger -proc raiseExceptionAux(e: ref E_Base) = +proc raiseExceptionAux(e: ref Exception) = if localRaiseHook != nil: if not localRaiseHook(e): return if globalRaiseHook != nil: @@ -204,7 +204,7 @@ proc raiseExceptionAux(e: ref E_Base) = if not excHandler.hasRaiseAction or excHandler.raiseAction(e): pushCurrentException(e) c_longjmp(excHandler.context, 1) - elif e[] of EOutOfMemory: + elif e[] of OutOfMemError: showErrorMessage(e.name) quitOrDebug() else: @@ -236,7 +236,7 @@ proc raiseExceptionAux(e: ref E_Base) = showErrorMessage(buf) quitOrDebug() -proc raiseException(e: ref E_Base, ename: cstring) {.compilerRtl.} = +proc raiseException(e: ref Exception, ename: cstring) {.compilerRtl.} = e.name = ename when hasSomeStackTrace: e.trace = "" @@ -245,7 +245,7 @@ proc raiseException(e: ref E_Base, ename: cstring) {.compilerRtl.} = proc reraiseException() {.compilerRtl.} = if currException == nil: - sysFatal(ENoExceptionToReraise, "no exception to reraise") + sysFatal(ReraiseError, "no exception to reraise") else: raiseExceptionAux(currException) @@ -264,7 +264,7 @@ proc getStackTrace(): string = else: result = "No stack traceback available\n" -proc getStackTrace(e: ref E_Base): string = +proc getStackTrace(e: ref Exception): string = if not isNil(e) and not isNil(e.trace): result = e.trace else: @@ -318,7 +318,7 @@ when not defined(noSignalHandler): GC_disable() var buf = newStringOfCap(2000) rawWriteStackTrace(buf) - processSignal(sig, buf.add) # nice hu? currying a la nimrod :-) + processSignal(sig, buf.add) # nice hu? currying a la Nim :-) showErrorMessage(buf) GC_enable() else: @@ -326,7 +326,7 @@ when not defined(noSignalHandler): template asgn(y: expr) = msg = y processSignal(sig, asgn) showErrorMessage(msg) - when defined(endb): dbgAborting = True + when defined(endb): dbgAborting = true quit(1) # always quit when SIGABRT proc registerSignalHandler() = @@ -343,5 +343,5 @@ when not defined(noSignalHandler): proc setControlCHook(hook: proc () {.noconv.}) = # ugly cast, but should work on all architectures: - type TSignalHandler = proc (sig: cint) {.noconv, gcsafe.} + type TSignalHandler = proc (sig: cint) {.noconv, benign.} c_signal(SIGINT, cast[TSignalHandler](hook)) diff --git a/lib/system/gc.nim b/lib/system/gc.nim index 0c1fc7748..fe4b40903 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -51,7 +51,7 @@ type waZctDecRef, waPush, waCycleDecRef, waMarkGray, waScan, waScanBlack, waCollectWhite, - TFinalizer {.compilerproc.} = proc (self: pointer) {.nimcall, gcsafe.} + TFinalizer {.compilerproc.} = proc (self: pointer) {.nimcall, benign.} # A ref type can have a finalizer that is called before the object's # storage is freed. @@ -111,11 +111,11 @@ proc addZCT(s: var TCellSeq, c: PCell) {.noinline.} = proc cellToUsr(cell: PCell): pointer {.inline.} = # convert object (=pointer to refcount) to pointer to userdata - result = cast[pointer](cast[TAddress](cell)+%TAddress(sizeof(TCell))) + result = cast[pointer](cast[ByteAddress](cell)+%ByteAddress(sizeof(TCell))) proc usrToCell(usr: pointer): PCell {.inline.} = # convert pointer to userdata to object (=pointer to refcount) - result = cast[PCell](cast[TAddress](usr)-%TAddress(sizeof(TCell))) + result = cast[PCell](cast[ByteAddress](usr)-%ByteAddress(sizeof(TCell))) proc canbeCycleRoot(c: PCell): bool {.inline.} = result = ntfAcyclic notin c.typ.flags @@ -152,11 +152,11 @@ template gcTrace(cell, state: expr): stmt {.immediate.} = when traceGC: traceCell(cell, state) # forward declarations: -proc collectCT(gch: var TGcHeap) {.gcsafe.} -proc isOnStack*(p: pointer): bool {.noinline, gcsafe.} -proc forAllChildren(cell: PCell, op: TWalkOp) {.gcsafe.} -proc doOperation(p: pointer, op: TWalkOp) {.gcsafe.} -proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) {.gcsafe.} +proc collectCT(gch: var TGcHeap) {.benign.} +proc isOnStack*(p: pointer): bool {.noinline, benign.} +proc forAllChildren(cell: PCell, op: TWalkOp) {.benign.} +proc doOperation(p: pointer, op: TWalkOp) {.benign.} +proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) {.benign.} # we need the prototype here for debugging purposes when hasThreadSupport and hasSharedHeap: @@ -294,7 +294,7 @@ proc initGC() = when useMarkForDebug or useBackupGc: type - TGlobalMarkerProc = proc () {.nimcall, gcsafe.} + TGlobalMarkerProc = proc () {.nimcall, benign.} var globalMarkersLen: int globalMarkers: array[0.. 7_000, TGlobalMarkerProc] @@ -311,8 +311,8 @@ proc cellsetReset(s: var TCellSet) = deinit(s) init(s) -proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.gcsafe.} = - var d = cast[TAddress](dest) +proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.benign.} = + var d = cast[ByteAddress](dest) case n.kind of nkSlot: forAllChildrenAux(cast[pointer](d +% n.offset), n.typ, op) of nkList: @@ -332,7 +332,7 @@ proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.gcsafe.} = of nkNone: sysAssert(false, "forAllSlotsAux") proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) = - var d = cast[TAddress](dest) + var d = cast[ByteAddress](dest) if dest == nil: return # nothing to do if ntfNoRefs notin mt.flags: case mt.kind @@ -358,7 +358,7 @@ proc forAllChildren(cell: PCell, op: TWalkOp) = of tyRef: # common case forAllChildrenAux(cellToUsr(cell), cell.typ.base, op) of tySequence: - var d = cast[TAddress](cellToUsr(cell)) + var d = cast[ByteAddress](cellToUsr(cell)) var s = cast[PGenericSeq](d) if s != nil: for i in 0..s.len-1: @@ -424,7 +424,7 @@ proc rawNewObj(typ: PNimType, size: int, gch: var TGcHeap): pointer = gcAssert(typ.kind in {tyRef, tyString, tySequence}, "newObj: 1") collectCT(gch) var res = cast[PCell](rawAlloc(gch.region, size + sizeof(TCell))) - gcAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "newObj: 2") + gcAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "newObj: 2") # now it is buffered in the ZCT res.typ = typ when leakDetector and not hasThreadSupport: @@ -470,7 +470,7 @@ proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} = var res = cast[PCell](rawAlloc(gch.region, size + sizeof(TCell))) sysAssert(allocInv(gch.region), "newObjRC1 after rawAlloc") - sysAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "newObj: 2") + sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "newObj: 2") # now it is buffered in the ZCT res.typ = typ when leakDetector and not hasThreadSupport: @@ -511,9 +511,9 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer = var oldsize = cast[PGenericSeq](old).len*elemSize + GenericSeqSize copyMem(res, ol, oldsize + sizeof(TCell)) - zeroMem(cast[pointer](cast[TAddress](res)+% oldsize +% sizeof(TCell)), + zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)), newsize-oldsize) - sysAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "growObj: 3") + sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3") sysAssert(res.refcount shr rcShift <=% 1, "growObj: 4") #if res.refcount <% rcIncrement: # add(gch.zct, res) @@ -680,11 +680,11 @@ proc doOperation(p: pointer, op: TWalkOp) = proc nimGCvisit(d: pointer, op: int) {.compilerRtl.} = doOperation(d, TWalkOp(op)) -proc collectZCT(gch: var TGcHeap): bool {.gcsafe.} +proc collectZCT(gch: var TGcHeap): bool {.benign.} when useMarkForDebug or useBackupGc: proc markStackAndRegistersForSweep(gch: var TGcHeap) {.noinline, cdecl, - gcsafe.} + benign.} proc collectRoots(gch: var TGcHeap) = for s in elements(gch.cycleRoots): @@ -728,7 +728,7 @@ proc gcMark(gch: var TGcHeap, p: pointer) {.inline.} = # the addresses are not as cells on the stack, so turn them to cells: sysAssert(allocInv(gch.region), "gcMark begin") var cell = usrToCell(p) - var c = cast[TAddress](cell) + var c = cast[ByteAddress](cell) if c >% PageSize: # fast check: does it look like a cell? var objStart = cast[PCell](interiorAllocatedPtr(gch.region, cell)) @@ -778,8 +778,8 @@ when not defined(useNimRtl): # the first init must be the one that defines the stack bottom: if gch.stackBottom == nil: gch.stackBottom = theStackBottom else: - var a = cast[TAddress](theStackBottom) # and not PageMask - PageSize*2 - var b = cast[TAddress](gch.stackBottom) + var a = cast[ByteAddress](theStackBottom) # and not PageMask - PageSize*2 + var b = cast[ByteAddress](gch.stackBottom) #c_fprintf(c_stdout, "old: %p new: %p;\n",gch.stackBottom,theStackBottom) when stackIncreases: gch.stackBottom = cast[pointer](min(a, b)) @@ -854,9 +854,9 @@ else: proc isOnStack(p: pointer): bool = var stackTop {.volatile.}: pointer stackTop = addr(stackTop) - var b = cast[TAddress](gch.stackBottom) - var a = cast[TAddress](stackTop) - var x = cast[TAddress](p) + var b = cast[ByteAddress](gch.stackBottom) + var a = cast[ByteAddress](stackTop) + var x = cast[ByteAddress](p) result = a <=% x and x <=% b template forEachStackSlot(gch, gcMark: expr) {.immediate, dirty.} = @@ -866,8 +866,8 @@ else: type PStackSlice = ptr array [0..7, pointer] var registers {.noinit.}: C_JmpBuf if c_setjmp(registers) == 0'i32: # To fill the C stack with registers. - var max = cast[TAddress](gch.stackBottom) - var sp = cast[TAddress](addr(registers)) + var max = cast[ByteAddress](gch.stackBottom) + var sp = cast[ByteAddress](addr(registers)) # loop unrolled: while sp <% max - 8*sizeof(pointer): gcMark(gch, cast[PStackSlice](sp)[0]) @@ -1040,7 +1040,7 @@ when not defined(useNimRtl): else: dec(gch.recGcLock) - proc GC_setStrategy(strategy: TGC_Strategy) = + proc GC_setStrategy(strategy: GC_Strategy) = discard proc GC_enableMarkAndSweep() = diff --git a/lib/system/gc2.nim b/lib/system/gc2.nim index 132da9885..ee52b54f5 100644 --- a/lib/system/gc2.nim +++ b/lib/system/gc2.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/gc_ms.nim b/lib/system/gc_ms.nim index 05bcdcc82..242ca1608 100644 --- a/lib/system/gc_ms.nim +++ b/lib/system/gc_ms.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -# A simple mark&sweep garbage collector for Nimrod. Define the +# A simple mark&sweep garbage collector for Nim. Define the # symbol ``gcUseBitvectors`` to generate a variant of this GC. {.push profiler:off.} @@ -32,11 +32,11 @@ type # local waMarkPrecise # fast precise marking - TFinalizer {.compilerproc.} = proc (self: pointer) {.nimcall, gcsafe.} + TFinalizer {.compilerproc.} = proc (self: pointer) {.nimcall, benign.} # A ref type can have a finalizer that is called before the object's # storage is freed. - TGlobalMarkerProc = proc () {.nimcall, gcsafe.} + TGlobalMarkerProc = proc () {.nimcall, benign.} TGcStat = object collections: int # number of performed full collections @@ -80,11 +80,11 @@ template gcAssert(cond: bool, msg: string) = proc cellToUsr(cell: PCell): pointer {.inline.} = # convert object (=pointer to refcount) to pointer to userdata - result = cast[pointer](cast[TAddress](cell)+%TAddress(sizeof(TCell))) + result = cast[pointer](cast[ByteAddress](cell)+%ByteAddress(sizeof(TCell))) proc usrToCell(usr: pointer): PCell {.inline.} = # convert pointer to userdata to object (=pointer to refcount) - result = cast[PCell](cast[TAddress](usr)-%TAddress(sizeof(TCell))) + result = cast[PCell](cast[ByteAddress](usr)-%ByteAddress(sizeof(TCell))) proc canbeCycleRoot(c: PCell): bool {.inline.} = result = ntfAcyclic notin c.typ.flags @@ -116,11 +116,11 @@ when BitsPerPage mod (sizeof(int)*8) != 0: {.error: "(BitsPerPage mod BitsPerUnit) should be zero!".} # forward declarations: -proc collectCT(gch: var TGcHeap) {.gcsafe.} -proc isOnStack*(p: pointer): bool {.noinline, gcsafe.} -proc forAllChildren(cell: PCell, op: TWalkOp) {.gcsafe.} -proc doOperation(p: pointer, op: TWalkOp) {.gcsafe.} -proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) {.gcsafe.} +proc collectCT(gch: var TGcHeap) {.benign.} +proc isOnStack*(p: pointer): bool {.noinline, benign.} +proc forAllChildren(cell: PCell, op: TWalkOp) {.benign.} +proc doOperation(p: pointer, op: TWalkOp) {.benign.} +proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) {.benign.} # we need the prototype here for debugging purposes proc prepareDealloc(cell: PCell) = @@ -168,8 +168,8 @@ proc initGC() = Init(gch.allocated) init(gch.marked) -proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.gcsafe.} = - var d = cast[TAddress](dest) +proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.benign.} = + var d = cast[ByteAddress](dest) case n.kind of nkSlot: forAllChildrenAux(cast[pointer](d +% n.offset), n.typ, op) of nkList: @@ -181,7 +181,7 @@ proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.gcsafe.} = of nkNone: sysAssert(false, "forAllSlotsAux") proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) = - var d = cast[TAddress](dest) + var d = cast[ByteAddress](dest) if dest == nil: return # nothing to do if ntfNoRefs notin mt.flags: case mt.kind @@ -206,7 +206,7 @@ proc forAllChildren(cell: PCell, op: TWalkOp) = of tyRef: # common case forAllChildrenAux(cellToUsr(cell), cell.typ.base, op) of tySequence: - var d = cast[TAddress](cellToUsr(cell)) + var d = cast[ByteAddress](cellToUsr(cell)) var s = cast[PGenericSeq](d) if s != nil: for i in 0..s.len-1: @@ -220,7 +220,7 @@ proc rawNewObj(typ: PNimType, size: int, gch: var TGcHeap): pointer = gcAssert(typ.kind in {tyRef, tyString, tySequence}, "newObj: 1") collectCT(gch) var res = cast[PCell](rawAlloc(gch.region, size + sizeof(TCell))) - gcAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "newObj: 2") + gcAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "newObj: 2") # now it is buffered in the ZCT res.typ = typ when leakDetector and not hasThreadSupport: @@ -280,9 +280,9 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer = var oldsize = cast[PGenericSeq](old).len*elemSize + GenericSeqSize copyMem(res, ol, oldsize + sizeof(TCell)) - zeroMem(cast[pointer](cast[TAddress](res)+% oldsize +% sizeof(TCell)), + zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)), newsize-oldsize) - sysAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "growObj: 3") + sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3") when withBitvectors: excl(gch.allocated, ol) when reallyDealloc: rawDealloc(gch.region, ol) else: @@ -379,7 +379,7 @@ proc markGlobals(gch: var TGcHeap) = proc gcMark(gch: var TGcHeap, p: pointer) {.inline.} = # the addresses are not as cells on the stack, so turn them to cells: var cell = usrToCell(p) - var c = cast[TAddress](cell) + var c = cast[ByteAddress](cell) if c >% PageSize: # fast check: does it look like a cell? var objStart = cast[PCell](interiorAllocatedPtr(gch.region, cell)) @@ -404,8 +404,8 @@ when not defined(useNimRtl): # the first init must be the one that defines the stack bottom: if gch.stackBottom == nil: gch.stackBottom = theStackBottom else: - var a = cast[TAddress](theStackBottom) # and not PageMask - PageSize*2 - var b = cast[TAddress](gch.stackBottom) + var a = cast[ByteAddress](theStackBottom) # and not PageMask - PageSize*2 + var b = cast[ByteAddress](gch.stackBottom) #c_fprintf(c_stdout, "old: %p new: %p;\n",gch.stackBottom,theStackBottom) when stackIncreases: gch.stackBottom = cast[pointer](min(a, b)) @@ -421,9 +421,9 @@ when defined(sparc): # For SPARC architecture. proc isOnStack(p: pointer): bool = var stackTop {.volatile.}: pointer stackTop = addr(stackTop) - var b = cast[TAddress](gch.stackBottom) - var a = cast[TAddress](stackTop) - var x = cast[TAddress](p) + var b = cast[ByteAddress](gch.stackBottom) + var a = cast[ByteAddress](stackTop) + var x = cast[ByteAddress](p) result = a <=% x and x <=% b proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} = @@ -440,7 +440,7 @@ when defined(sparc): # For SPARC architecture. # Addresses decrease as the stack grows. while sp <= max: gcMark(gch, sp[]) - sp = cast[ppointer](cast[TAddress](sp) +% sizeof(pointer)) + sp = cast[ppointer](cast[ByteAddress](sp) +% sizeof(pointer)) elif defined(ELATE): {.error: "stack marking code is to be written for this architecture".} @@ -452,9 +452,9 @@ elif stackIncreases: proc isOnStack(p: pointer): bool = var stackTop {.volatile.}: pointer stackTop = addr(stackTop) - var a = cast[TAddress](gch.stackBottom) - var b = cast[TAddress](stackTop) - var x = cast[TAddress](p) + var a = cast[ByteAddress](gch.stackBottom) + var b = cast[ByteAddress](stackTop) + var x = cast[ByteAddress](p) result = a <=% x and x <=% b var @@ -465,8 +465,8 @@ elif stackIncreases: proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} = var registers: C_JmpBuf if c_setjmp(registers) == 0'i32: # To fill the C stack with registers. - var max = cast[TAddress](gch.stackBottom) - var sp = cast[TAddress](addr(registers)) +% jmpbufSize -% sizeof(pointer) + var max = cast[ByteAddress](gch.stackBottom) + var sp = cast[ByteAddress](addr(registers)) +% jmpbufSize -% sizeof(pointer) # sp will traverse the JMP_BUF as well (jmp_buf size is added, # otherwise sp would be below the registers structure). while sp >=% max: @@ -480,9 +480,9 @@ else: proc isOnStack(p: pointer): bool = var stackTop {.volatile.}: pointer stackTop = addr(stackTop) - var b = cast[TAddress](gch.stackBottom) - var a = cast[TAddress](stackTop) - var x = cast[TAddress](p) + var b = cast[ByteAddress](gch.stackBottom) + var a = cast[ByteAddress](stackTop) + var x = cast[ByteAddress](p) result = a <=% x and x <=% b proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} = @@ -492,8 +492,8 @@ else: type PStackSlice = ptr array [0..7, pointer] var registers {.noinit.}: C_JmpBuf if c_setjmp(registers) == 0'i32: # To fill the C stack with registers. - var max = cast[TAddress](gch.stackBottom) - var sp = cast[TAddress](addr(registers)) + var max = cast[ByteAddress](gch.stackBottom) + var sp = cast[ByteAddress](addr(registers)) # loop unrolled: while sp <% max - 8*sizeof(pointer): gcMark(gch, cast[PStackSlice](sp)[0]) @@ -546,7 +546,7 @@ when not defined(useNimRtl): else: dec(gch.recGcLock) - proc GC_setStrategy(strategy: TGC_Strategy) = discard + proc GC_setStrategy(strategy: GC_Strategy) = discard proc GC_enableMarkAndSweep() = gch.cycleThreshold = InitialThreshold diff --git a/lib/system/hti.nim b/lib/system/hti.nim index ef8f50831..e599668a7 100644 --- a/lib/system/hti.nim +++ b/lib/system/hti.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -85,8 +85,8 @@ type base: ptr TNimType node: ptr TNimNode # valid for tyRecord, tyObject, tyTuple, tyEnum finalizer: pointer # the finalizer for the type - marker: proc (p: pointer, op: int) {.nimcall, gcsafe.} # marker proc for GC - deepcopy: proc (p: pointer): pointer {.nimcall, gcsafe.} + marker: proc (p: pointer, op: int) {.nimcall, benign.} # marker proc for GC + deepcopy: proc (p: pointer): pointer {.nimcall, benign.} PNimType = ptr TNimType # node.len may be the ``first`` element of a set diff --git a/lib/system/inclrtl.nim b/lib/system/inclrtl.nim index 5c82db4da..aac802229 100644 --- a/lib/system/inclrtl.nim +++ b/lib/system/inclrtl.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -46,3 +46,8 @@ else: when not defined(nimsuperops): {.pragma: operator.} + +when defined(nimlocks): + {.pragma: benign, gcsafe, locks: 0.} +else: + {.pragma: benign, gcsafe.} diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim index 423f63e2a..9b4a7d556 100644 --- a/lib/system/jssys.nim +++ b/lib/system/jssys.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -18,7 +18,7 @@ type PSafePoint = ptr TSafePoint TSafePoint {.compilerproc, final.} = object prev: PSafePoint # points to next safe point - exc: ref E_Base + exc: ref Exception PCallFrame = ptr TCallFrame TCallFrame {.importc, nodecl, final.} = object @@ -97,13 +97,13 @@ proc rawWriteStackTrace(): string = else: result = "No stack traceback available\n" -proc raiseException(e: ref E_Base, ename: cstring) {. +proc raiseException(e: ref Exception, ename: cstring) {. compilerproc, asmNoStackFrame.} = e.name = ename if excHandler != nil: excHandler.exc = e else: - when nimrodStackTrace: + when NimStackTrace: var buf = rawWriteStackTrace() else: var buf = "" @@ -120,24 +120,24 @@ proc raiseException(e: ref E_Base, ename: cstring) {. proc reraiseException() {.compilerproc, asmNoStackFrame.} = if excHandler == nil: - raise newException(ENoExceptionToReraise, "no exception to reraise") + raise newException(ReraiseError, "no exception to reraise") else: asm """throw excHandler.exc;""" proc raiseOverflow {.exportc: "raiseOverflow", noreturn.} = - raise newException(EOverflow, "over- or underflow") + raise newException(OverflowError, "over- or underflow") proc raiseDivByZero {.exportc: "raiseDivByZero", noreturn.} = - raise newException(EDivByZero, "divison by zero") + raise newException(DivByZeroError, "divison by zero") proc raiseRangeError() {.compilerproc, noreturn.} = - raise newException(EOutOfRange, "value out of range") + raise newException(RangeError, "value out of range") proc raiseIndexError() {.compilerproc, noreturn.} = - raise newException(EInvalidIndex, "index out of bounds") + raise newException(IndexError, "index out of bounds") proc raiseFieldError(f: string) {.compilerproc, noreturn.} = - raise newException(EInvalidField, f & " is not accessible") + raise newException(FieldError, f & " is not accessible") proc SetConstr() {.varargs, asmNoStackFrame, compilerproc.} = asm """ @@ -260,7 +260,7 @@ proc eqStrings(a, b: string): bool {.asmNoStackFrame, compilerProc.} = """ type - TDocument {.importc.} = object of TObject + TDocument {.importc.} = object of RootObj write: proc (text: cstring) {.nimcall.} writeln: proc (text: cstring) {.nimcall.} createAttribute: proc (identifier: cstring): ref TNode {.nimcall.} @@ -283,7 +283,7 @@ type DocumentTypeNode, DocumentFragmentNode, NotationNode - TNode* {.importc.} = object of TObject + TNode* {.importc.} = object of RootObj attributes*: seq[ref TNode] childNodes*: seq[ref TNode] data*: cstring @@ -345,11 +345,12 @@ else: node.appendChild(document.createTextNode(x)) node.appendChild(document.createElement("br")) else: - raise newException(EInvalidValue, "<body> element does not exist yet!") + raise newException(ValueError, "<body> element does not exist yet!") proc rawEcho {.compilerproc.} = var node = document.getElementsByTagName("body")[0] - if node == nil: raise newException(EIO, "<body> element does not exist yet!") + if node == nil: + raise newException(IOError, "<body> element does not exist yet!") asm """ for (var i = 0; i < arguments.length; ++i) { var x = `toJSStr`(arguments[i]); @@ -621,7 +622,7 @@ proc chckObj(obj, subclass: PNimType) {.compilerproc.} = if x == subclass: return # optimized fast path while x != subclass: if x == nil: - raise newException(EInvalidObjectConversion, "invalid object conversion") + raise newException(ObjectConversionError, "invalid object conversion") x = x.base proc isObj(obj, subclass: PNimType): bool {.compilerproc.} = diff --git a/lib/system/mmdisp.nim b/lib/system/mmdisp.nim index 606743f51..e091c0889 100644 --- a/lib/system/mmdisp.nim +++ b/lib/system/mmdisp.nim @@ -1,14 +1,14 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -# Nimrod high-level memory manager: It supports Boehm's GC, no GC and the -# native Nimrod GC. The native Nimrod GC is the default. +# Nim high-level memory manager: It supports Boehm's GC, no GC and the +# native Nim GC. The native Nim GC is the default. #{.push checks:on, assertions:on.} {.push checks:off.} @@ -34,7 +34,7 @@ const type PPointer = ptr pointer - TByteArray = array[0..1000_0000, Byte] + TByteArray = array[0..1000_0000, byte] PByte = ptr TByteArray PString = ptr string @@ -267,7 +267,7 @@ elif defined(nogc) and defined(useMalloc): elif defined(nogc): # Even though we don't want the GC, we cannot simply use C's memory manager - # because Nimrod's runtime wants ``realloc`` to zero out the additional + # because Nim's runtime wants ``realloc`` to zero out the additional # space which C's ``realloc`` does not. And we cannot get the old size of an # object, because C does not support this operation... Even though every # possible implementation has to have a way to determine the object's size. @@ -308,7 +308,7 @@ elif defined(nogc): dest[] = src var allocator {.rtlThreadVar.}: TMemRegion - InstantiateForRegion(allocator) + instantiateForRegion(allocator) include "system/cellsets" diff --git a/lib/system/profiler.nim b/lib/system/profiler.nim index 8e4c51dd9..96ab6abc7 100644 --- a/lib/system/profiler.nim +++ b/lib/system/profiler.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -# This file implements the Nimrod profiler. The profiler needs support by the +# This file implements the Nim profiler. The profiler needs support by the # code generator. The idea is to inject the instruction stream # with 'nimProfile()' calls. These calls are injected at every loop end # (except perhaps loops that have no side-effects). At every Nth call a diff --git a/lib/system/repr.nim b/lib/system/repr.nim index 8e1bc5f26..2de603cea 100644 --- a/lib/system/repr.nim +++ b/lib/system/repr.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -155,7 +155,7 @@ when not defined(useNimRtl): var bs = typ.base.size for i in 0..typ.size div bs - 1: if i > 0: add result, ", " - reprAux(result, cast[pointer](cast[TAddress](p) + i*bs), typ.base, cl) + reprAux(result, cast[pointer](cast[ByteAddress](p) + i*bs), typ.base, cl) add result, "]" proc reprSequence(result: var string, p: pointer, typ: PNimType, @@ -167,7 +167,7 @@ when not defined(useNimRtl): var bs = typ.base.size for i in 0..cast[PGenericSeq](p).len-1: if i > 0: add result, ", " - reprAux(result, cast[pointer](cast[TAddress](p) + GenericSeqSize + i*bs), + reprAux(result, cast[pointer](cast[ByteAddress](p) + GenericSeqSize + i*bs), typ.base, cl) add result, "]" @@ -178,14 +178,14 @@ when not defined(useNimRtl): of nkSlot: add result, $n.name add result, " = " - reprAux(result, cast[pointer](cast[TAddress](p) + n.offset), n.typ, cl) + reprAux(result, cast[pointer](cast[ByteAddress](p) + n.offset), n.typ, cl) of nkList: for i in 0..n.len-1: if i > 0: add result, ",\n" reprRecordAux(result, p, n.sons[i], cl) of nkCase: var m = selectBranch(p, n) - reprAux(result, cast[pointer](cast[TAddress](p) + n.offset), n.typ, cl) + reprAux(result, cast[pointer](cast[ByteAddress](p) + n.offset), n.typ, cl) if m != nil: reprRecordAux(result, p, m, cl) proc reprRecord(result: var string, p: pointer, typ: PNimType, @@ -265,7 +265,7 @@ proc reprOpenArray(p: pointer, length: int, elemtyp: PNimType): string {. var bs = elemtyp.size for i in 0..length - 1: if i > 0: add result, ", " - reprAux(result, cast[pointer](cast[TAddress](p) + i*bs), elemtyp, cl) + reprAux(result, cast[pointer](cast[ByteAddress](p) + i*bs), elemtyp, cl) add result, "]" deinitReprClosure(cl) diff --git a/lib/system/reprjs.nim b/lib/system/reprjs.nim index fd1cb5c8b..57237cfff 100644 --- a/lib/system/reprjs.nim +++ b/lib/system/reprjs.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/sets.nim b/lib/system/sets.nim index 794c65cb8..626d43c33 100644 --- a/lib/system/sets.nim +++ b/lib/system/sets.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim index 32d4c3e91..7908fbe4d 100644 --- a/lib/system/sysio.nim +++ b/lib/system/sysio.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -8,7 +8,7 @@ # -# Nimrod's standard IO library. It contains high-performance +# Nim's standard IO library. It contains high-performance # routines for reading and writing data to (buffered) files or # TTYs. @@ -16,33 +16,33 @@ # of the standard library! -proc fputs(c: cstring, f: TFile) {.importc: "fputs", header: "<stdio.h>", - tags: [FWriteIO].} -proc fgets(c: cstring, n: int, f: TFile): cstring {. - importc: "fgets", header: "<stdio.h>", tags: [FReadIO].} -proc fgetc(stream: TFile): cint {.importc: "fgetc", header: "<stdio.h>", - tags: [FReadIO].} -proc ungetc(c: cint, f: TFile) {.importc: "ungetc", header: "<stdio.h>", +proc fputs(c: cstring, f: File) {.importc: "fputs", header: "<stdio.h>", + tags: [WriteIOEffect].} +proc fgets(c: cstring, n: int, f: File): cstring {. + importc: "fgets", header: "<stdio.h>", tags: [ReadIOEffect].} +proc fgetc(stream: File): cint {.importc: "fgetc", header: "<stdio.h>", + tags: [ReadIOEffect].} +proc ungetc(c: cint, f: File) {.importc: "ungetc", header: "<stdio.h>", tags: [].} -proc putc(c: char, stream: TFile) {.importc: "putc", header: "<stdio.h>", - tags: [FWriteIO].} -proc fprintf(f: TFile, frmt: cstring) {.importc: "fprintf", - header: "<stdio.h>", varargs, tags: [FWriteIO].} +proc putc(c: char, stream: File) {.importc: "putc", header: "<stdio.h>", + tags: [WriteIOEffect].} +proc fprintf(f: File, frmt: cstring) {.importc: "fprintf", + header: "<stdio.h>", varargs, tags: [WriteIOEffect].} proc strlen(c: cstring): int {. importc: "strlen", header: "<string.h>", tags: [].} # C routine that is used here: -proc fread(buf: pointer, size, n: int, f: TFile): int {. - importc: "fread", header: "<stdio.h>", tags: [FReadIO].} -proc fseek(f: TFile, offset: clong, whence: int): int {. +proc fread(buf: pointer, size, n: int, f: File): int {. + importc: "fread", header: "<stdio.h>", tags: [ReadIOEffect].} +proc fseek(f: File, offset: clong, whence: int): int {. importc: "fseek", header: "<stdio.h>", tags: [].} -proc ftell(f: TFile): int {.importc: "ftell", header: "<stdio.h>", tags: [].} -proc setvbuf(stream: TFile, buf: pointer, typ, size: cint): cint {. +proc ftell(f: File): int {.importc: "ftell", header: "<stdio.h>", tags: [].} +proc setvbuf(stream: File, buf: pointer, typ, size: cint): cint {. importc, header: "<stdio.h>", tags: [].} {.push stackTrace:off, profiler:off.} -proc write(f: TFile, c: cstring) = fputs(c, f) +proc write(f: File, c: cstring) = fputs(c, f) {.pop.} when NoFakeVars: @@ -65,9 +65,9 @@ const BufSize = 4000 proc raiseEIO(msg: string) {.noinline, noreturn.} = - sysFatal(EIO, msg) + sysFatal(IOError, msg) -proc readLine(f: TFile, line: var TaintedString): bool = +proc readLine(f: File, line: var TaintedString): bool = # of course this could be optimized a bit; but IO is slow anyway... # and it was difficult to get this CORRECT with Ansi C's methods setLen(line.string, 0) # reuse the buffer! @@ -84,34 +84,34 @@ proc readLine(f: TFile, line: var TaintedString): bool = add line.string, chr(int(c)) result = true -proc readLine(f: TFile): TaintedString = +proc readLine(f: File): TaintedString = result = TaintedString(newStringOfCap(80)) if not readLine(f, result): raiseEIO("EOF reached") -proc write(f: TFile, i: int) = +proc write(f: File, i: int) = when sizeof(int) == 8: fprintf(f, "%lld", i) else: fprintf(f, "%ld", i) -proc write(f: TFile, i: BiggestInt) = +proc write(f: File, i: BiggestInt) = when sizeof(BiggestInt) == 8: fprintf(f, "%lld", i) else: fprintf(f, "%ld", i) -proc write(f: TFile, b: bool) = +proc write(f: File, b: bool) = if b: write(f, "true") else: write(f, "false") -proc write(f: TFile, r: float32) = fprintf(f, "%g", r) -proc write(f: TFile, r: BiggestFloat) = fprintf(f, "%g", r) +proc write(f: File, r: float32) = fprintf(f, "%g", r) +proc write(f: File, r: BiggestFloat) = fprintf(f, "%g", r) -proc write(f: TFile, c: char) = putc(c, f) -proc write(f: TFile, a: varargs[string, `$`]) = +proc write(f: File, c: char) = putc(c, f) +proc write(f: File, a: varargs[string, `$`]) = for x in items(a): write(f, x) -proc readAllBuffer(file: TFile): string = - # This proc is for TFile we want to read but don't know how many +proc readAllBuffer(file: File): string = + # This proc is for File we want to read but don't know how many # bytes we need to read before the buffer is empty. result = "" var buffer = newString(BufSize) @@ -124,27 +124,27 @@ proc readAllBuffer(file: TFile): string = result.add(buffer) break -proc rawFileSize(file: TFile): int = +proc rawFileSize(file: File): int = # this does not raise an error opposed to `getFileSize` var oldPos = ftell(file) discard fseek(file, 0, 2) # seek the end of the file result = ftell(file) discard fseek(file, clong(oldPos), 0) -proc readAllFile(file: TFile, len: int): string = +proc readAllFile(file: File, len: int): string = # We aquire the filesize beforehand and hope it doesn't change. # Speeds things up. result = newString(int(len)) if readBuffer(file, addr(result[0]), int(len)) != len: raiseEIO("error while reading from file") -proc readAllFile(file: TFile): string = +proc readAllFile(file: File): string = var len = rawFileSize(file) result = readAllFile(file, len) -proc readAll(file: TFile): TaintedString = +proc readAll(file: File): TaintedString = # Separate handling needed because we need to buffer when we - # don't know the overall length of the TFile. + # don't know the overall length of the File. var len = rawFileSize(file) if len >= 0: result = readAllFile(file, len).TaintedString @@ -165,13 +165,13 @@ proc writeFile(filename, content: string) = finally: close(f) -proc endOfFile(f: TFile): bool = +proc endOfFile(f: File): bool = # do not blame me; blame the ANSI C standard this is so brain-damaged var c = fgetc(f) ungetc(c, f) return c < 0'i32 -proc writeln[Ty](f: TFile, x: varargs[Ty, `$`]) = +proc writeln[Ty](f: File, x: varargs[Ty, `$`]) = for i in items(x): write(f, i) write(f, "\n") @@ -186,7 +186,7 @@ when (defined(windows) and not defined(useWinAnsi)) or defined(nimdoc): when defined(windows) and not defined(useWinAnsi): proc wfopen(filename, mode: WideCString): pointer {. importc: "_wfopen", nodecl.} - proc wfreopen(filename, mode: WideCString, stream: TFile): TFile {. + proc wfreopen(filename, mode: WideCString, stream: File): File {. importc: "_wfreopen", nodecl.} proc fopen(filename, mode: cstring): pointer = @@ -194,82 +194,82 @@ when defined(windows) and not defined(useWinAnsi): var m = newWideCString(mode) result = wfopen(f, m) - proc freopen(filename, mode: cstring, stream: TFile): TFile = + proc freopen(filename, mode: cstring, stream: File): File = var f = newWideCString(filename) var m = newWideCString(mode) result = wfreopen(f, m, stream) else: proc fopen(filename, mode: cstring): pointer {.importc: "fopen", noDecl.} - proc freopen(filename, mode: cstring, stream: TFile): TFile {. + proc freopen(filename, mode: cstring, stream: File): File {. importc: "freopen", nodecl.} const - FormatOpen: array [TFileMode, string] = ["rb", "wb", "w+b", "r+b", "ab"] + FormatOpen: array [FileMode, string] = ["rb", "wb", "w+b", "r+b", "ab"] #"rt", "wt", "w+t", "r+t", "at" - # we always use binary here as for Nimrod the OS line ending + # we always use binary here as for Nim the OS line ending # should not be translated. -proc open(f: var TFile, filename: string, - mode: TFileMode = fmRead, +proc open(f: var File, filename: string, + mode: FileMode = fmRead, bufSize: int = -1): bool = var p: pointer = fopen(filename, FormatOpen[mode]) - result = (p != nil) - f = cast[TFile](p) - if bufSize > 0 and bufSize <= high(cint).int: - if setvbuf(f, nil, IOFBF, bufSize.cint) != 0'i32: - sysFatal(EOutOfMemory, "out of memory") - elif bufSize == 0: - discard setvbuf(f, nil, IONBF, 0) - -proc reopen(f: TFile, filename: string, mode: TFileMode = fmRead): bool = + if p != nil: + result = true + f = cast[File](p) + if bufSize > 0 and bufSize <= high(cint).int: + discard setvbuf(f, nil, IOFBF, bufSize.cint) + elif bufSize == 0: + discard setvbuf(f, nil, IONBF, 0) + +proc reopen(f: File, filename: string, mode: FileMode = fmRead): bool = var p: pointer = freopen(filename, FormatOpen[mode], f) result = p != nil -proc fdopen(filehandle: TFileHandle, mode: cstring): TFile {. +proc fdopen(filehandle: FileHandle, mode: cstring): File {. importc: pccHack & "fdopen", header: "<stdio.h>".} -proc open(f: var TFile, filehandle: TFileHandle, mode: TFileMode): bool = +proc open(f: var File, filehandle: FileHandle, mode: FileMode): bool = f = fdopen(filehandle, FormatOpen[mode]) result = f != nil -proc fwrite(buf: pointer, size, n: int, f: TFile): int {. +proc fwrite(buf: pointer, size, n: int, f: File): int {. importc: "fwrite", noDecl.} -proc readBuffer(f: TFile, buffer: pointer, len: int): int = +proc readBuffer(f: File, buffer: pointer, len: int): int = result = fread(buffer, 1, len, f) -proc readBytes(f: TFile, a: var openArray[int8], start, len: int): int = +proc readBytes(f: File, a: var openArray[int8], start, len: int): int = result = readBuffer(f, addr(a[start]), len) -proc readChars(f: TFile, a: var openArray[char], start, len: int): int = +proc readChars(f: File, a: var openArray[char], start, len: int): int = result = readBuffer(f, addr(a[start]), len) {.push stackTrace:off, profiler:off.} -proc writeBytes(f: TFile, a: openArray[int8], start, len: int): int = +proc writeBytes(f: File, a: openArray[int8], start, len: int): int = var x = cast[ptr array[0..1000_000_000, int8]](a) result = writeBuffer(f, addr(x[start]), len) -proc writeChars(f: TFile, a: openArray[char], start, len: int): int = +proc writeChars(f: File, a: openArray[char], start, len: int): int = var x = cast[ptr array[0..1000_000_000, int8]](a) result = writeBuffer(f, addr(x[start]), len) -proc writeBuffer(f: TFile, buffer: pointer, len: int): int = +proc writeBuffer(f: File, buffer: pointer, len: int): int = result = fwrite(buffer, 1, len, f) -proc write(f: TFile, s: string) = +proc write(f: File, s: string) = if writeBuffer(f, cstring(s), s.len) != s.len: raiseEIO("cannot write string to file") {.pop.} -proc setFilePos(f: TFile, pos: int64) = +proc setFilePos(f: File, pos: int64) = if fseek(f, clong(pos), 0) != 0: raiseEIO("cannot set file position") -proc getFilePos(f: TFile): int64 = +proc getFilePos(f: File): int64 = result = ftell(f) if result < 0: raiseEIO("cannot retrieve file position") -proc getFileSize(f: TFile): int64 = +proc getFileSize(f: File): int64 = var oldPos = getFilePos(f) discard fseek(f, 0, 2) # seek the end of the file result = getFilePos(f) diff --git a/lib/system/syslocks.nim b/lib/system/syslocks.nim index b8ed29cfc..8b38f34f3 100644 --- a/lib/system/syslocks.nim +++ b/lib/system/syslocks.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -31,7 +31,7 @@ when defined(Windows): ## Tries to acquire the lock `L`. proc tryAcquireSys(L: var TSysLock): bool {.inline.} = - result = TryAcquireSysAux(L) != 0'i32 + result = tryAcquireSysAux(L) != 0'i32 proc acquireSys(L: var TSysLock) {.stdcall, noSideEffect, dynlib: "kernel32", importc: "EnterCriticalSection".} diff --git a/lib/system/sysspawn.nim b/lib/system/sysspawn.nim index 5161104a9..04f30872d 100644 --- a/lib/system/sysspawn.nim +++ b/lib/system/sysspawn.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## Implements Nimrod's 'spawn'. +## Implements Nim's 'spawn'. when not declared(NimString): {.error: "You must not import this module explicitly".} diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim index bc79bb254..ba973e9b5 100644 --- a/lib/system/sysstr.nim +++ b/lib/system/sysstr.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -119,7 +119,7 @@ proc addChar(s: NimString, c: char): NimString = inc(result.len) # These routines should be used like following: -# <Nimrod code> +# <Nim code> # s &= "Hello " & name & ", how do you feel?" # # <generated C code> @@ -130,7 +130,7 @@ proc addChar(s: NimString, c: char): NimString = # appendString(s, strLit3); # } # -# <Nimrod code> +# <Nim code> # s = "Hello " & name & ", how do you feel?" # # <generated C code> @@ -143,7 +143,7 @@ proc addChar(s: NimString, c: char): NimString = # s = tmp0; # } # -# <Nimrod code> +# <Nim code> # s = "" # # <generated C code> @@ -217,7 +217,7 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {. gch.tempStack.len = len0 else: for i in newLen..result.len-1: - forAllChildrenAux(cast[pointer](cast[TAddress](result) +% + forAllChildrenAux(cast[pointer](cast[ByteAddress](result) +% GenericSeqSize +% (i*%elemSize)), extGetCellType(result).base, waZctDecRef) @@ -227,7 +227,7 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {. # presense of user defined destructors, the user will expect the cell to be # "destroyed" thus creating the same problem. We can destoy the cell in the # finalizer of the sequence, but this makes destruction non-deterministic. - zeroMem(cast[pointer](cast[TAddress](result) +% GenericSeqSize +% + zeroMem(cast[pointer](cast[ByteAddress](result) +% GenericSeqSize +% (newLen*%elemSize)), (result.len-%newLen) *% elemSize) result.len = newLen diff --git a/lib/system/threads.nim b/lib/system/threads.nim index c30c57fb9..7dac9d9aa 100644 --- a/lib/system/threads.nim +++ b/lib/system/threads.nim @@ -353,8 +353,7 @@ when hostOS == "windows": t.sys = createThread(nil, ThreadStackSize, threadProcWrapper[TArg], addr(t), 0'i32, dummyThreadId) if t.sys <= 0: - raise newException(EResourceExhausted, "cannot create thread") - + raise newException(ResourceExhaustedError, "cannot create thread") else: proc createThread*[TArg](t: var TThread[TArg], tp: proc (arg: TArg) {.thread.}, @@ -369,7 +368,7 @@ else: pthread_attr_init(a) pthread_attr_setstacksize(a, ThreadStackSize) if pthread_create(t.sys, a, threadProcWrapper[TArg], addr(t)) != 0: - raise newException(EResourceExhausted, "cannot create thread") + raise newException(ResourceExhaustedError, "cannot create thread") proc threadId*[TArg](t: var TThread[TArg]): TThreadId[TArg] {.inline.} = ## returns the thread ID of `t`. diff --git a/lib/system/timers.nim b/lib/system/timers.nim index fa1a13a5f..e58ff7adc 100644 --- a/lib/system/timers.nim +++ b/lib/system/timers.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/widestrs.nim b/lib/system/widestrs.nim index cd64ff410..1e8bc6791 100644 --- a/lib/system/widestrs.nim +++ b/lib/system/widestrs.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -# Nimrod support for C/C++'s `wide strings`:idx:. This is part of the system +# Nim support for C/C++'s `wide strings`:idx:. This is part of the system # module! Do not import it directly! when not declared(NimString): diff --git a/lib/windows/mmsystem.nim b/lib/windows/mmsystem.nim index 91279a5ef..45613d8e2 100644 --- a/lib/windows/mmsystem.nim +++ b/lib/windows/mmsystem.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2006 Andreas Rumpf # # See the file "copying.txt", included in this @@ -27,15 +27,15 @@ import windows type - MMRESULT* = UINT - MMVERSION* = UINT + MMRESULT* = uint32 + MMVERSION* = uint32 HWAVEOUT* = THandle LPHWAVEOUT* = ptr HWAVEOUT HWAVEIN* = THandle LPHWAVEIN* = ptr HWAVEOUT HWAVE* = THandle LPHWAVE* = ptr THandle - LPUINT* = ptr UINT + LPUINT* = ptr uint32 const MAXPNAMELEN* = 32 @@ -178,18 +178,18 @@ const DRV_MCI_LAST* = (DRV_RESERVED + 0x00000FFF) type - PDRVCALLBACK* = proc (hdrvr: tHandle, uMsg: UINT, dwUser, dw1, dw2: DWORD){. + PDRVCALLBACK* = proc (hdrvr: THandle, uMsg: uint32, dwUser, dw1, dw2: DWORD){. stdcall.} -proc sndPlaySoundA*(Name: LPCSTR, flags: UINT): BOOL{.stdcall, +proc sndPlaySoundA*(Name: LPCSTR, flags: uint32): bool{.stdcall, dynlib: "winmm.dll", importc: "sndPlaySoundA".} -proc sndPlaySoundW*(Name: LPCWSTR, flags: UINT): BOOL{.stdcall, +proc sndPlaySoundW*(Name: LPCWSTR, flags: uint32): bool{.stdcall, dynlib: "winmm.dll", importc: "sndPlaySoundW".} when defined(winUNICODE): - proc sndPlaySound*(Name: cstring, flags: UINT): BOOL{.stdcall, + proc sndPlaySound*(Name: cstring, flags: uint32): bool{.stdcall, dynlib: "winmm.dll", importc: "sndPlaySoundW".} else: - proc sndPlaySound*(Name: cstring, flags: UINT): BOOL{.stdcall, + proc sndPlaySound*(Name: cstring, flags: uint32): bool{.stdcall, dynlib: "winmm.dll", importc: "sndPlaySoundA".} const SND_NODEFAULT* = 2 @@ -225,12 +225,12 @@ const WIM_OPEN* = MM_WIM_OPEN WIM_CLOSE* = MM_WIM_CLOSE WIM_DATA* = MM_WIM_DATA - WAVE_MAPPER* = UINT(- 1) + WAVE_MAPPER* = uint32(- 1) WAVE_FORMAT_QUERY* = 1 WAVE_ALLOWSYNC* = 2 WAVE_MAPPED* = 4 WAVE_FORMAT_DIRECT* = 8 - WAVE_FORMAT_DIRECT_QUERY* = (WAVE_FORMAT_QUERY Or WAVE_FORMAT_DIRECT) + WAVE_FORMAT_DIRECT_QUERY* = (WAVE_FORMAT_QUERY or WAVE_FORMAT_DIRECT) MIM_OPEN* = MM_MIM_OPEN MIM_CLOSE* = MM_MIM_CLOSE MIM_DATA* = MM_MIM_DATA @@ -242,7 +242,7 @@ const MOM_DONE* = MM_MOM_DONE MIM_MOREDATA* = MM_MIM_MOREDATA MOM_POSITIONCB* = MM_MOM_POSITIONCB - MIDIMAPPER* = UINT(- 1) + MIDIMAPPER* = uint32(- 1) MIDI_IO_STATUS* = 32 MIDI_CACHE_ALL* = 1 MIDI_CACHE_BESTFIT* = 2 @@ -364,53 +364,53 @@ const MIXERCONTROL_CT_UNITS_DECIBELS* = 0x00040000 MIXERCONTROL_CT_UNITS_PERCENT* = 0x00050000 MIXERCONTROL_CONTROLTYPE_CUSTOM* = ( - MIXERCONTROL_CT_CLASS_CUSTOM Or MIXERCONTROL_CT_UNITS_CUSTOM) - MIXERCONTROL_CONTROLTYPE_BOOLEANMETER* = (MIXERCONTROL_CT_CLASS_METER Or - MIXERCONTROL_CT_SC_METER_POLLED Or MIXERCONTROL_CT_UNITS_BOOLEAN) - MIXERCONTROL_CONTROLTYPE_SIGNEDMETER* = (MIXERCONTROL_CT_CLASS_METER Or - MIXERCONTROL_CT_SC_METER_POLLED Or MIXERCONTROL_CT_UNITS_SIGNED) + MIXERCONTROL_CT_CLASS_CUSTOM or MIXERCONTROL_CT_UNITS_CUSTOM) + MIXERCONTROL_CONTROLTYPE_BOOLEANMETER* = (MIXERCONTROL_CT_CLASS_METER or + MIXERCONTROL_CT_SC_METER_POLLED or MIXERCONTROL_CT_UNITS_BOOLEAN) + MIXERCONTROL_CONTROLTYPE_SIGNEDMETER* = (MIXERCONTROL_CT_CLASS_METER or + MIXERCONTROL_CT_SC_METER_POLLED or MIXERCONTROL_CT_UNITS_SIGNED) MIXERCONTROL_CONTROLTYPE_PEAKMETER* = ( MIXERCONTROL_CONTROLTYPE_SIGNEDMETER + 1) - MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER* = (MIXERCONTROL_CT_CLASS_METER Or - MIXERCONTROL_CT_SC_METER_POLLED Or MIXERCONTROL_CT_UNITS_UNSIGNED) - MIXERCONTROL_CONTROLTYPE_BOOLEAN* = (MIXERCONTROL_CT_CLASS_SWITCH Or - MIXERCONTROL_CT_SC_SWITCH_BOOLEAN Or MIXERCONTROL_CT_UNITS_BOOLEAN) + MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER* = (MIXERCONTROL_CT_CLASS_METER or + MIXERCONTROL_CT_SC_METER_POLLED or MIXERCONTROL_CT_UNITS_UNSIGNED) + MIXERCONTROL_CONTROLTYPE_BOOLEAN* = (MIXERCONTROL_CT_CLASS_SWITCH or + MIXERCONTROL_CT_SC_SWITCH_BOOLEAN or MIXERCONTROL_CT_UNITS_BOOLEAN) MIXERCONTROL_CONTROLTYPE_ONOFF* = (MIXERCONTROL_CONTROLTYPE_BOOLEAN + 1) MIXERCONTROL_CONTROLTYPE_MUTE* = (MIXERCONTROL_CONTROLTYPE_BOOLEAN + 2) MIXERCONTROL_CONTROLTYPE_MONO* = (MIXERCONTROL_CONTROLTYPE_BOOLEAN + 3) MIXERCONTROL_CONTROLTYPE_LOUDNESS* = (MIXERCONTROL_CONTROLTYPE_BOOLEAN + 4) MIXERCONTROL_CONTROLTYPE_STEREOENH* = (MIXERCONTROL_CONTROLTYPE_BOOLEAN + 5) - MIXERCONTROL_CONTROLTYPE_BUTTON* = (MIXERCONTROL_CT_CLASS_SWITCH Or - MIXERCONTROL_CT_SC_SWITCH_BUTTON Or MIXERCONTROL_CT_UNITS_BOOLEAN) + MIXERCONTROL_CONTROLTYPE_BUTTON* = (MIXERCONTROL_CT_CLASS_SWITCH or + MIXERCONTROL_CT_SC_SWITCH_BUTTON or MIXERCONTROL_CT_UNITS_BOOLEAN) MIXERCONTROL_CONTROLTYPE_DECIBELS* = ( - MIXERCONTROL_CT_CLASS_NUMBER Or MIXERCONTROL_CT_UNITS_DECIBELS) + MIXERCONTROL_CT_CLASS_NUMBER or MIXERCONTROL_CT_UNITS_DECIBELS) MIXERCONTROL_CONTROLTYPE_SIGNED* = ( - MIXERCONTROL_CT_CLASS_NUMBER Or MIXERCONTROL_CT_UNITS_SIGNED) + MIXERCONTROL_CT_CLASS_NUMBER or MIXERCONTROL_CT_UNITS_SIGNED) MIXERCONTROL_CONTROLTYPE_UNSIGNED* = ( - MIXERCONTROL_CT_CLASS_NUMBER Or MIXERCONTROL_CT_UNITS_UNSIGNED) + MIXERCONTROL_CT_CLASS_NUMBER or MIXERCONTROL_CT_UNITS_UNSIGNED) MIXERCONTROL_CONTROLTYPE_PERCENT* = ( - MIXERCONTROL_CT_CLASS_NUMBER Or MIXERCONTROL_CT_UNITS_PERCENT) + MIXERCONTROL_CT_CLASS_NUMBER or MIXERCONTROL_CT_UNITS_PERCENT) MIXERCONTROL_CONTROLTYPE_SLIDER* = ( - MIXERCONTROL_CT_CLASS_SLIDER Or MIXERCONTROL_CT_UNITS_SIGNED) + MIXERCONTROL_CT_CLASS_SLIDER or MIXERCONTROL_CT_UNITS_SIGNED) MIXERCONTROL_CONTROLTYPE_PAN* = (MIXERCONTROL_CONTROLTYPE_SLIDER + 1) MIXERCONTROL_CONTROLTYPE_QSOUNDPAN* = (MIXERCONTROL_CONTROLTYPE_SLIDER + 2) MIXERCONTROL_CONTROLTYPE_FADER* = ( - MIXERCONTROL_CT_CLASS_FADER Or MIXERCONTROL_CT_UNITS_UNSIGNED) + MIXERCONTROL_CT_CLASS_FADER or MIXERCONTROL_CT_UNITS_UNSIGNED) MIXERCONTROL_CONTROLTYPE_VOLUME* = (MIXERCONTROL_CONTROLTYPE_FADER + 1) MIXERCONTROL_CONTROLTYPE_BASS* = (MIXERCONTROL_CONTROLTYPE_FADER + 2) MIXERCONTROL_CONTROLTYPE_TREBLE* = (MIXERCONTROL_CONTROLTYPE_FADER + 3) MIXERCONTROL_CONTROLTYPE_EQUALIZER* = (MIXERCONTROL_CONTROLTYPE_FADER + 4) - MIXERCONTROL_CONTROLTYPE_SINGLESELECT* = (MIXERCONTROL_CT_CLASS_LIST Or - MIXERCONTROL_CT_SC_LIST_SINGLE Or MIXERCONTROL_CT_UNITS_BOOLEAN) + MIXERCONTROL_CONTROLTYPE_SINGLESELECT* = (MIXERCONTROL_CT_CLASS_LIST or + MIXERCONTROL_CT_SC_LIST_SINGLE or MIXERCONTROL_CT_UNITS_BOOLEAN) MIXERCONTROL_CONTROLTYPE_MUX* = (MIXERCONTROL_CONTROLTYPE_SINGLESELECT + 1) - MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT* = (MIXERCONTROL_CT_CLASS_LIST Or - MIXERCONTROL_CT_SC_LIST_MULTIPLE Or MIXERCONTROL_CT_UNITS_BOOLEAN) + MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT* = (MIXERCONTROL_CT_CLASS_LIST or + MIXERCONTROL_CT_SC_LIST_MULTIPLE or MIXERCONTROL_CT_UNITS_BOOLEAN) MIXERCONTROL_CONTROLTYPE_MIXER* = (MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT + 1) - MIXERCONTROL_CONTROLTYPE_MICROTIME* = (MIXERCONTROL_CT_CLASS_TIME Or - MIXERCONTROL_CT_SC_TIME_MICROSECS Or MIXERCONTROL_CT_UNITS_UNSIGNED) - MIXERCONTROL_CONTROLTYPE_MILLITIME* = (MIXERCONTROL_CT_CLASS_TIME Or - MIXERCONTROL_CT_SC_TIME_MILLISECS Or MIXERCONTROL_CT_UNITS_UNSIGNED) + MIXERCONTROL_CONTROLTYPE_MICROTIME* = (MIXERCONTROL_CT_CLASS_TIME or + MIXERCONTROL_CT_SC_TIME_MICROSECS or MIXERCONTROL_CT_UNITS_UNSIGNED) + MIXERCONTROL_CONTROLTYPE_MILLITIME* = (MIXERCONTROL_CT_CLASS_TIME or + MIXERCONTROL_CT_SC_TIME_MILLISECS or MIXERCONTROL_CT_UNITS_UNSIGNED) MIXER_SHORT_NAME_CHARS* = 16 MIXER_LONG_NAME_CHARS* = 64 MIXERR_INVALLINE* = (MIXERR_BASE + 0) @@ -419,15 +419,15 @@ const MIXERR_LASTERROR* = (MIXERR_BASE + 2) MIXER_OBJECTF_HANDLE* = 0x80000000 MIXER_OBJECTF_MIXER* = 0 - MIXER_OBJECTF_HMIXER* = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_MIXER) + MIXER_OBJECTF_HMIXER* = (MIXER_OBJECTF_HANDLE or MIXER_OBJECTF_MIXER) MIXER_OBJECTF_WAVEOUT* = 0x10000000 - MIXER_OBJECTF_HWAVEOUT* = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_WAVEOUT) + MIXER_OBJECTF_HWAVEOUT* = (MIXER_OBJECTF_HANDLE or MIXER_OBJECTF_WAVEOUT) MIXER_OBJECTF_WAVEIN* = 0x20000000 - MIXER_OBJECTF_HWAVEIN* = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_WAVEIN) + MIXER_OBJECTF_HWAVEIN* = (MIXER_OBJECTF_HANDLE or MIXER_OBJECTF_WAVEIN) MIXER_OBJECTF_MIDIOUT* = 0x30000000 - MIXER_OBJECTF_HMIDIOUT* = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_MIDIOUT) + MIXER_OBJECTF_HMIDIOUT* = (MIXER_OBJECTF_HANDLE or MIXER_OBJECTF_MIDIOUT) MIXER_OBJECTF_MIDIIN* = 0x40000000 - MIXER_OBJECTF_HMIDIIN* = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_MIDIIN) + MIXER_OBJECTF_HMIDIIN* = (MIXER_OBJECTF_HANDLE or MIXER_OBJECTF_MIDIIN) MIXER_OBJECTF_AUX* = 0x50000000 MIXER_GETCONTROLDETAILSF_VALUE* = 0 MIXER_GETCONTROLDETAILSF_LISTTEXT* = 1 @@ -492,8 +492,8 @@ const JOY_RETURNPOVCTS* = 512 JOY_RETURNCENTERED* = 0x00000400 JOY_USEDEADZONE* = 0x00000800 - JOY_RETURNALL* = (JOY_RETURNX Or JOY_RETURNY Or JOY_RETURNZ Or JOY_RETURNR Or - JOY_RETURNU Or JOY_RETURNV Or JOY_RETURNPOV Or JOY_RETURNBUTTONS) + JOY_RETURNALL* = (JOY_RETURNX or JOY_RETURNY or JOY_RETURNZ or JOY_RETURNR or + JOY_RETURNU or JOY_RETURNV or JOY_RETURNPOV or JOY_RETURNBUTTONS) JOY_CAL_READALWAYS* = 0x00010000 JOY_CAL_READXYONLY* = 0x00020000 JOY_CAL_READ3* = 0x00040000 @@ -982,17 +982,17 @@ const #///////////////////////////////////////////////////////// type - mmtime* {.final.} = object - wType*: UINT + MMTIME* {.final.} = object + wType*: uint32 hour*, min*, sec*, frame*, fps*, dummy*: int8 pad*: array[0..1, int8] - PMMTIME* = ptr mmtime - NPMMTIME* = ptr mmtime - LPMMTIME* = ptr mmtime - PWAVEHDR* = ptr wavehdr - TMMTime* = mmtime - wavehdr* {.final.} = object + PMMTIME* = ptr MMTIME + NPMMTIME* = ptr MMTIME + LPMMTIME* = ptr MMTIME + PWAVEHDR* = ptr WAVEHDR + TMMTime* = MMTIME + WAVEHDR* {.final.} = object lpData*: cstring dwBufferLength*: DWORD dwBytesRecorded*: DWORD @@ -1003,13 +1003,13 @@ type reserved*: DWORD TWAVEHDR* = WAVEHDR - NPWAVEHDR* = ptr wavehdr - LPWAVEHDR* = ptr wavehdr + NPWAVEHDR* = ptr WAVEHDR + LPWAVEHDR* = ptr WAVEHDR WAVEOUTCAPSA* {.final.} = object wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), CHAR] + szPname*: array[0..pred(MAXPNAMELEN), char] dwFormats*: DWORD wChannels*: int16 wReserved1*: int16 @@ -1023,7 +1023,7 @@ type wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), WCHAR] + szPname*: array[0..pred(MAXPNAMELEN), WCHAR] dwFormats*: DWORD wChannels*: int16 wReserved1*: int16 @@ -1052,7 +1052,7 @@ type wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), CHAR] + szPname*: array[0..pred(MAXPNAMELEN), char] dwFormats*: DWORD wChannels*: int16 wReserved1*: int16 @@ -1065,7 +1065,7 @@ type wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), WCHAR] + szPname*: array[0..pred(MAXPNAMELEN), WCHAR] dwFormats*: DWORD wChannels*: int16 wReserved1*: int16 @@ -1089,29 +1089,29 @@ else: LPWAVEINCAPS* = LPWAVEINCAPSA type TWAVEINCAPS* = WAVEINCAPS - waveformat* {.final.} = object + WAVEFORMAT* {.final.} = object wFormatTag*: int16 nChannels*: int16 nSamplesPerSec*: DWORD nAvgBytesPerSec*: DWORD nBlockAlign*: int16 - PWAVEFORMAT* = ptr waveformat - NPWAVEFORMAT* = ptr waveformat - LPWAVEFORMAT* = ptr waveformat - TWAVEFORMAT* = waveformat + PWAVEFORMAT* = ptr WAVEFORMAT + NPWAVEFORMAT* = ptr WAVEFORMAT + LPWAVEFORMAT* = ptr WAVEFORMAT + TWAVEFORMAT* = WAVEFORMAT const WAVE_FORMAT_PCM* = 1 type - pcmwaveformat* {.final.} = object + PCMWAVEFORMAT* {.final.} = object wf*: WAVEFORMAT wBitsPerSample*: int16 - PPCMWAVEFORMAT* = ptr pcmwaveformat - NPPCMWAVEFORMAT* = ptr pcmwaveformat - LPPCMWAVEFORMAT* = ptr pcmwaveformat + PPCMWAVEFORMAT* = ptr PCMWAVEFORMAT + NPPCMWAVEFORMAT* = ptr PCMWAVEFORMAT + LPPCMWAVEFORMAT* = ptr PCMWAVEFORMAT TPCMWAVEFORMAT* = PCMWAVEFORMAT WAVEFORMATEX* {.final.} = object wFormatTag*: int16 @@ -1141,15 +1141,15 @@ const MIDIPATCHSIZE* = 128 type - PATCHARRAY* = array[0..Pred(MIDIPATCHSIZE), int16] + PATCHARRAY* = array[0..pred(MIDIPATCHSIZE), int16] LPPATCHARRAY* = ptr int16 - KEYARRAY* = array[0..Pred(MIDIPATCHSIZE), int16] + KEYARRAY* = array[0..pred(MIDIPATCHSIZE), int16] LPKEYARRAY* = ptr int16 MIDIOUTCAPSA* {.final.} = object wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), CHAR] + szPname*: array[0..pred(MAXPNAMELEN), char] wTechnology*: int16 wVoices*: int16 wNotes*: int16 @@ -1164,7 +1164,7 @@ type wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), WCHAR] + szPname*: array[0..pred(MAXPNAMELEN), Wchar] wTechnology*: int16 wVoices*: int16 wNotes*: int16 @@ -1179,7 +1179,7 @@ type wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), CHAR] + szPname*: array[0..pred(MAXPNAMELEN), char] dwSupport*: DWORD PMIDIINCAPSA* = ptr MIDIINCAPSA @@ -1190,7 +1190,7 @@ type wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), WCHAR] + szPname*: array[0..pred(MAXPNAMELEN), Wchar] dwSupport*: DWORD PMIDIINCAPSW* = ptr MIDIINCAPSW @@ -1220,8 +1220,8 @@ else: LPMIDIINCAPS* = LPMIDIINCAPSA type TMIDIINCAPS* = MIDIINCAPS - PMIDIHDR* = ptr midihdr - midihdr* {.final.} = object + PMIDIHDR* = ptr MIDIHDR + MIDIHDR* {.final.} = object lpData*: cstring dwBufferLength*: DWORD dwBytesRecorded*: DWORD @@ -1230,19 +1230,19 @@ type lpNext*: PMIDIHDR reserved*: DWORD dwOffset*: DWORD - dwReserved*: array[0..Pred(8), DWORD] + dwReserved*: array[0..pred(8), DWORD] - NPMIDIHDR* = ptr midihdr - LPMIDIHDR* = ptr midihdr + NPMIDIHDR* = ptr MIDIHDR + LPMIDIHDR* = ptr MIDIHDR TMIDIHDR* = MIDIHDR - midievent* {.final.} = object + MIDIEVENT* {.final.} = object dwDeltaTime*: DWORD dwStreamID*: DWORD dwEvent*: DWORD - dwParms*: array[0..Pred(1), DWORD] + dwParms*: array[0..pred(1), DWORD] TMIDIEVENT* = MIDIEVENT - midistrmbuffver* {.final.} = object + MIDISTRMBUFFVER* {.final.} = object dwVersion*: DWORD dwMid*: DWORD dwOEMVersion*: DWORD @@ -1262,7 +1262,7 @@ type wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), CHAR] + szPname*: array[0..pred(MAXPNAMELEN), char] wTechnology*: int16 wReserved1*: int16 dwSupport*: DWORD @@ -1275,7 +1275,7 @@ type wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), WCHAR] + szPname*: array[0..pred(MAXPNAMELEN), Wchar] wTechnology*: int16 wReserved1*: int16 dwSupport*: DWORD @@ -1304,14 +1304,14 @@ type HMIXER* = THandle LPHMIXER* = ptr HMIXER -proc mixerGetNumDevs*(): UINT{.stdcall, dynlib: "winmm.dll", +proc mixerGetNumDevs*(): uint32{.stdcall, dynlib: "winmm.dll", importc: "mixerGetNumDevs".} type MIXERCAPSA* {.final.} = object wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), CHAR] + szPname*: array[0..pred(MAXPNAMELEN), char] fdwSupport*: DWORD cDestinations*: DWORD @@ -1322,7 +1322,7 @@ type wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), WCHAR] + szPname*: array[0..pred(MAXPNAMELEN), Wchar] fdwSupport*: DWORD cDestinations*: DWORD @@ -1353,12 +1353,12 @@ type cChannels*: DWORD cConnections*: DWORD cControls*: DWORD - szShortName*: array[0..Pred(MIXER_SHORT_NAME_CHARS), CHAR] - szName*: array[0..Pred(MIXER_LONG_NAME_CHARS), CHAR] + szShortName*: array[0..pred(MIXER_SHORT_NAME_CHARS), char] + szName*: array[0..pred(MIXER_LONG_NAME_CHARS), char] dwType*, dwDeviceID*: DWORD wMid*, wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..pred(MAXPNAMELEN), Char] + szPname*: array[0..pred(MAXPNAMELEN), char] PMIXERLINEA* = ptr MIXERLINEA LPMIXERLINEA* = ptr MIXERLINEA @@ -1374,8 +1374,8 @@ type cChannels*: DWORD cConnections*: DWORD cControls*: DWORD - szShortName*: array[0..Pred(MIXER_SHORT_NAME_CHARS), WCHAR] - szName*: array[0..Pred(MIXER_LONG_NAME_CHARS), WCHAR] + szShortName*: array[0..pred(MIXER_SHORT_NAME_CHARS), WCHAR] + szName*: array[0..pred(MIXER_LONG_NAME_CHARS), WCHAR] dwType*, dwDeviceID*: DWORD wMid*, wPid*: int16 vDriverVersion*: MMVERSION @@ -1403,8 +1403,8 @@ type dwControlType*: DWORD fdwControl*: DWORD cMultipleItems*: DWORD - szShortName*: array[0..Pred(MIXER_SHORT_NAME_CHARS), CHAR] - szName*: array[0..Pred(MIXER_LONG_NAME_CHARS), CHAR] + szShortName*: array[0..pred(MIXER_SHORT_NAME_CHARS), char] + szName*: array[0..pred(MIXER_LONG_NAME_CHARS), char] dwMinimum*, dwMaximum*: DWORD dwReserved*: array[0..3, DWORD] cSteps*: DWORD @@ -1419,8 +1419,8 @@ type dwControlType*: DWORD fdwControl*: DWORD cMultipleItems*: DWORD - szShortName*: array[0..Pred(MIXER_SHORT_NAME_CHARS), WCHAR] - szName*: array[0..Pred(MIXER_LONG_NAME_CHARS), WCHAR] + szShortName*: array[0..pred(MIXER_SHORT_NAME_CHARS), WCHAR] + szName*: array[0..pred(MIXER_LONG_NAME_CHARS), WCHAR] dwMinimum*, dwMaximum*: DWORD dwReserved*: array[0..3, DWORD] cSteps*: DWORD @@ -1478,15 +1478,15 @@ type dwControlID*: DWORD cChannels*: DWORD cMultipleItems*, cbDetails*: DWORD - paDetails*: Pointer + paDetails*: pointer - MIXERCONTROLDETAILS* = tMIXERCONTROLDETAILS - PMIXERCONTROLDETAILS* = ptr tMIXERCONTROLDETAILS - LPMIXERCONTROLDETAILS* = ptr tMIXERCONTROLDETAILS + MIXERCONTROLDETAILS* = TMIXERCONTROLDETAILS + PMIXERCONTROLDETAILS* = ptr TMIXERCONTROLDETAILS + LPMIXERCONTROLDETAILS* = ptr TMIXERCONTROLDETAILS MIXERCONTROLDETAILS_LISTTEXTA* {.final.} = object dwParam1*: DWORD dwParam2*: DWORD - szName*: array[0..Pred(MIXER_LONG_NAME_CHARS), CHAR] + szName*: array[0..pred(MIXER_LONG_NAME_CHARS), char] PMIXERCONTROLDETAILS_LISTTEXTA* = ptr MIXERCONTROLDETAILS_LISTTEXTA LPMIXERCONTROLDETAILS_LISTTEXTA* = ptr MIXERCONTROLDETAILS_LISTTEXTA @@ -1494,7 +1494,7 @@ type MIXERCONTROLDETAILS_LISTTEXTW* {.final.} = object dwParam1*: DWORD dwParam2*: DWORD - szName*: array[0..Pred(MIXER_LONG_NAME_CHARS), WCHAR] + szName*: array[0..pred(MIXER_LONG_NAME_CHARS), WCHAR] PMIXERCONTROLDETAILS_LISTTEXTW* = ptr MIXERCONTROLDETAILS_LISTTEXTW LPMIXERCONTROLDETAILS_LISTTEXTW* = ptr MIXERCONTROLDETAILS_LISTTEXTW @@ -1530,42 +1530,42 @@ type PMIXERCONTROLDETAILS_UNSIGNED* = ptr MIXERCONTROLDETAILS_UNSIGNED LPMIXERCONTROLDETAILS_UNSIGNED* = ptr MIXERCONTROLDETAILS_UNSIGNED TMIXERCONTROLDETAILS_UNSIGNED* = MIXERCONTROLDETAILS_UNSIGNED - LPTIMECALLBACK* = proc (uTimerID, uMsg: UINT, dwUser, dw1, dw2: DWORD){. + LPTIMECALLBACK* = proc (uTimerID, uMsg: uint32, dwUser, dw1, dw2: DWORD){. stdcall.} TTIMECALLBACK* = LPTIMECALLBACK - timecaps* {.final.} = object - wPeriodMin*: UINT - wPeriodMax*: UINT + TIMECAPS* {.final.} = object + wPeriodMin*: uint32 + wPeriodMax*: uint32 - PTIMECAPS* = ptr timecaps - NPTIMECAPS* = ptr timecaps - LPTIMECAPS* = ptr timecaps + PTIMECAPS* = ptr TIMECAPS + NPTIMECAPS* = ptr TIMECAPS + LPTIMECAPS* = ptr TIMECAPS TTIMECAS* = TIMECAPS JOYCAPSA* {.final.} = object wMid*: int16 wPid*: int16 - szPname*: array[0..Pred(MAXPNAMELEN), CHAR] - wXmin*: UINT - wXmax*: UINT - wYmin*: UINT - wYmax*: UINT - wZmin*: UINT - wZmax*: UINT - wNumButtons*: UINT - wPeriodMin*: UINT - wPeriodMax*: UINT - wRmin*: UINT - wRmax*: UINT - wUmin*: UINT - wUmax*: UINT - wVmin*: UINT - wVmax*: UINT - wCaps*: UINT - wMaxAxes*: UINT - wNumAxes*: UINT - wMaxButtons*: UINT - szRegKey*: array[0..Pred(MAXPNAMELEN), CHAR] - szOEMVxD*: array[0..Pred(MAX_JOYSTICKOEMVXDNAME), CHAR] + szPname*: array[0..pred(MAXPNAMELEN), char] + wXmin*: uint32 + wXmax*: uint32 + wYmin*: uint32 + wYmax*: uint32 + wZmin*: uint32 + wZmax*: uint32 + wNumButtons*: uint32 + wPeriodMin*: uint32 + wPeriodMax*: uint32 + wRmin*: uint32 + wRmax*: uint32 + wUmin*: uint32 + wUmax*: uint32 + wVmin*: uint32 + wVmax*: uint32 + wCaps*: uint32 + wMaxAxes*: uint32 + wNumAxes*: uint32 + wMaxButtons*: uint32 + szRegKey*: array[0..pred(MAXPNAMELEN), char] + szOEMVxD*: array[0..pred(MAX_JOYSTICKOEMVXDNAME), char] PJOYCAPSA* = ptr JOYCAPSA NPJOYCAPSA* = ptr JOYCAPSA @@ -1574,28 +1574,28 @@ type JOYCAPSW* {.final.} = object wMid*: int16 wPid*: int16 - szPname*: array[0..Pred(MAXPNAMELEN), WCHAR] - wXmin*: UINT - wXmax*: UINT - wYmin*: UINT - wYmax*: UINT - wZmin*: UINT - wZmax*: UINT - wNumButtons*: UINT - wPeriodMin*: UINT - wPeriodMax*: UINT - wRmin*: UINT - wRmax*: UINT - wUmin*: UINT - wUmax*: UINT - wVmin*: UINT - wVmax*: UINT - wCaps*: UINT - wMaxAxes*: UINT - wNumAxes*: UINT - wMaxButtons*: UINT - szRegKey*: array[0..Pred(MAXPNAMELEN), WCHAR] - szOEMVxD*: array[0..Pred(MAX_JOYSTICKOEMVXDNAME), WCHAR] + szPname*: array[0..pred(MAXPNAMELEN), WCHAR] + wXmin*: uint32 + wXmax*: uint32 + wYmin*: uint32 + wYmax*: uint32 + wZmin*: uint32 + wZmax*: uint32 + wNumButtons*: uint32 + wPeriodMin*: uint32 + wPeriodMax*: uint32 + wRmin*: uint32 + wRmax*: uint32 + wUmin*: uint32 + wUmax*: uint32 + wVmin*: uint32 + wVmax*: uint32 + wCaps*: uint32 + wMaxAxes*: uint32 + wNumAxes*: uint32 + wMaxButtons*: uint32 + szRegKey*: array[0..pred(MAXPNAMELEN), WCHAR] + szOEMVxD*: array[0..pred(MAX_JOYSTICKOEMVXDNAME), WCHAR] PJOYCAPSW* = ptr JOYCAPSW NPJOYCAPSW* = ptr JOYCAPSW @@ -1616,45 +1616,45 @@ else: LPJOYCAPS* = LPJOYCAPSA type TJOYCAPS* = JOYCAPS - joyinfo* {.final.} = object - wXpos*: UINT - wYpos*: UINT - wZpos*: UINT - wButtons*: UINT - - PJOYINFO* = ptr joyinfo - NPJOYINFO* = ptr joyinfo - LPJOYINFO* = ptr joyinfo + JOYINFO* {.final.} = object + wXpos*: uint32 + wYpos*: uint32 + wZpos*: uint32 + wButtons*: uint32 + + PJOYINFO* = ptr JOYINFO + NPJOYINFO* = ptr JOYINFO + LPJOYINFO* = ptr JOYINFO TJOYINFO* = JOYINFO - joyinfoex* {.final.} = object + JOYINFOEX* {.final.} = object dwSize*: DWORD dwFlags*: DWORD - wXpos*: UINT - wYpos*: UINT - wZpos*: UINT + wXpos*: uint32 + wYpos*: uint32 + wZpos*: uint32 dwRpos*: DWORD dwUpos*: DWORD dwVpos*: DWORD - wButtons*: UINT + wButtons*: uint32 dwButtonNumber*: DWORD dwPOV*: DWORD dwReserved1*: DWORD dwReserved2*: DWORD - PJOYINFOEX* = ptr joyinfoex - NPJOYINFOEX* = ptr joyinfoex - LPJOYINFOEX* = ptr joyinfoex + PJOYINFOEX* = ptr JOYINFOEX + NPJOYINFOEX* = ptr JOYINFOEX + LPJOYINFOEX* = ptr JOYINFOEX TJOYINFOEX* = JOYINFOEX FOURCC* = DWORD HPSTR* = cstring HMMIO* = THandle - LPMMIOPROC* = proc (x1: LPSTR, x2: UINT, x3, x4: LPARAM): LRESULT{.stdcall.} + LPMMIOPROC* = proc (x1: LPSTR, x2: uint32, x3, x4: LPARAM): LRESULT{.stdcall.} TMMIOPROC* = LPMMIOPROC MMIOINFO* {.final.} = object dwFlags*: DWORD fccIOProc*: FOURCC pIOProc*: LPMMIOPROC - wErrorRet*: UINT + wErrorRet*: uint32 htask*: HTASK cchBuffer*: int32 pchBuffer*: HPSTR @@ -1663,7 +1663,7 @@ type pchEndWrite*: HPSTR lBufOffset*: int32 lDiskOffset*: int32 - adwInfo*: array[0..Pred(3), DWORD] + adwInfo*: array[0..pred(3), DWORD] dwReserved1*: DWORD dwReserved2*: DWORD hmmio*: HMMIO @@ -1686,8 +1686,8 @@ type LPCMMCKINFO* = ptr MMCKINFO TMMCKINFO* = MMCKINFO MCIERROR* = DWORD - MCIDEVICEID* = UINT - YIELDPROC* = proc (mciId: MCIDEVICEID, dwYieldData: DWORD): UINT{.stdcall.} + MCIDEVICEID* = uint32 + YIELDPROC* = proc (mciId: MCIDEVICEID, dwYieldData: DWORD): uint32{.stdcall.} TYIELDPROC* = YIELDPROC MCI_GENERIC_PARMS* {.final.} = object dwCallback*: DWORD @@ -1790,7 +1790,7 @@ type lpstrReturn*: cstring dwRetSize*: DWORD dwNumber*: DWORD - wDeviceType*: UINT + wDeviceType*: uint32 PMCI_SYSINFO_PARMSA* = ptr MCI_SYSINFO_PARMSA LPMCI_SYSINFO_PARMSA* = ptr MCI_SYSINFO_PARMSA @@ -1800,7 +1800,7 @@ type lpstrReturn*: LPWSTR dwRetSize*: DWORD dwNumber*: DWORD - wDeviceType*: UINT + wDeviceType*: uint32 PMCI_SYSINFO_PARMSW* = ptr MCI_SYSINFO_PARMSW LPMCI_SYSINFO_PARMSW* = ptr MCI_SYSINFO_PARMSW @@ -1984,8 +1984,8 @@ type dwCallback*: DWORD dwTimeFormat*: DWORD dwAudio*: DWORD - wInput*: UINT - wOutput*: UINT + wInput*: uint32 + wOutput*: uint32 wFormatTag*: int16 wReserved2*: int16 nChannels*: int16 @@ -2052,7 +2052,7 @@ type MCI_ANIM_WINDOW_PARMSW* {.final.} = object dwCallback*: DWORD hWnd*: HWND - nCmdShow*: UINT + nCmdShow*: uint32 lpstrText*: LPCWSTR PMCI_ANIM_WINDOW_PARMSW* = ptr MCI_ANIM_WINDOW_PARMSW @@ -2068,7 +2068,7 @@ type MCI_ANIM_WINDOW_PARMSA* {.final.} = object dwCallback*: DWORD hWnd*: HWND - nCmdShow*: UINT + nCmdShow*: uint32 lpstrText*: LPCSTR PMCI_ANIM_WINDOW_PARMSA* = ptr MCI_ANIM_WINDOW_PARMSA @@ -2149,7 +2149,7 @@ type MCI_OVLY_WINDOW_PARMSA* {.final.} = object dwCallback*: DWORD hWnd*: HWND - nCmdShow*: UINT + nCmdShow*: uint32 lpstrText*: LPCSTR PMCI_OVLY_WINDOW_PARMSA* = ptr MCI_OVLY_WINDOW_PARMSA @@ -2158,7 +2158,7 @@ type MCI_OVLY_WINDOW_PARMSW* {.final.} = object dwCallback*: DWORD hWnd*: HWND - nCmdShow*: UINT + nCmdShow*: uint32 lpstrText*: LPCWSTR PMCI_OVLY_WINDOW_PARMSW* = ptr MCI_OVLY_WINDOW_PARMSW @@ -2243,14 +2243,11 @@ else: type TMCI_OVLY_LOAD_PARMS* = MCI_OVLY_LOAD_PARMS -type - pcmwaveformat_tag* = PCMWAVEFORMAT - -proc mmioStringToFOURCCA*(x1: LPCSTR, x2: UINT): FOURCC{.stdcall, +proc mmioStringToFOURCCA*(x1: LPCSTR, x2: uint32): FOURCC{.stdcall, dynlib: "winmm.dll", importc: "mmioStringToFOURCCA".} -proc mmioStringToFOURCCW*(x1: LPCWSTR, x2: UINT): FOURCC{.stdcall, +proc mmioStringToFOURCCW*(x1: LPCWSTR, x2: uint32): FOURCC{.stdcall, dynlib: "winmm.dll", importc: "mmioStringToFOURCCW".} -proc mmioStringToFOURCC*(x1: cstring, x2: UINT): FOURCC{.stdcall, +proc mmioStringToFOURCC*(x1: cstring, x2: uint32): FOURCC{.stdcall, dynlib: "winmm.dll", importc: "mmioStringToFOURCCA".} proc mmioInstallIOProcA*(x1: FOURCC, x2: LPMMIOPROC, x3: DWORD): LPMMIOPROC{. stdcall, dynlib: "winmm.dll", importc: "mmioInstallIOProcA".} @@ -2270,7 +2267,7 @@ proc mmioRenameW*(x1: LPCWSTR, x2: LPCWSTR, x3: LPCMMIOINFO, x4: DWORD): MMRESUL stdcall, dynlib: "winmm.dll", importc: "mmioRenameW".} proc mmioRename*(x1: cstring, x2: cstring, x3: LPCMMIOINFO, x4: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "mmioRenameA".} -proc mmioClose*(x1: HMMIO, x2: UINT): MMRESULT{.stdcall, dynlib: "winmm.dll", +proc mmioClose*(x1: HMMIO, x2: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mmioClose".} proc mmioRead*(x1: HMMIO, x2: HPSTR, x3: LONG): LONG{.stdcall, dynlib: "winmm.dll", importc: "mmioRead".} @@ -2278,35 +2275,35 @@ proc mmioWrite*(x1: HMMIO, x2: cstring, x3: LONG): LONG{.stdcall, dynlib: "winmm.dll", importc: "mmioWrite".} proc mmioSeek*(x1: HMMIO, x2: LONG, x3: WINT): LONG{.stdcall, dynlib: "winmm.dll", importc: "mmioSeek".} -proc mmioGetInfo*(x1: HMMIO, x2: LPMMIOINFO, x3: UINT): MMRESULT{.stdcall, +proc mmioGetInfo*(x1: HMMIO, x2: LPMMIOINFO, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mmioGetInfo".} -proc mmioSetInfo*(x1: HMMIO, x2: LPCMMIOINFO, x3: UINT): MMRESULT{.stdcall, +proc mmioSetInfo*(x1: HMMIO, x2: LPCMMIOINFO, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mmioSetInfo".} -proc mmioSetBuffer*(x1: HMMIO, x2: LPSTR, x3: LONG, x4: UINT): MMRESULT{. +proc mmioSetBuffer*(x1: HMMIO, x2: LPSTR, x3: LONG, x4: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "mmioSetBuffer".} -proc mmioFlush*(x1: HMMIO, x2: UINT): MMRESULT{.stdcall, dynlib: "winmm.dll", +proc mmioFlush*(x1: HMMIO, x2: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mmioFlush".} -proc mmioAdvance*(x1: HMMIO, x2: LPMMIOINFO, x3: UINT): MMRESULT{.stdcall, +proc mmioAdvance*(x1: HMMIO, x2: LPMMIOINFO, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mmioAdvance".} -proc mmioSendMessage*(x1: HMMIO, x2: UINT, x3: LPARAM, x4: LPARAM): LRESULT{. +proc mmioSendMessage*(x1: HMMIO, x2: uint32, x3: LPARAM, x4: LPARAM): LRESULT{. stdcall, dynlib: "winmm.dll", importc: "mmioSendMessage".} -proc mmioDescend*(x1: HMMIO, x2: LPMMCKINFO, x3: PMMCKINFO, x4: UINT): MMRESULT{. +proc mmioDescend*(x1: HMMIO, x2: LPMMCKINFO, x3: PMMCKINFO, x4: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "mmioDescend".} -proc mmioAscend*(x1: HMMIO, x2: LPMMCKINFO, x3: UINT): MMRESULT{.stdcall, +proc mmioAscend*(x1: HMMIO, x2: LPMMCKINFO, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mmioAscend".} -proc mmioCreateChunk*(x1: HMMIO, x2: LPMMCKINFO, x3: UINT): MMRESULT{.stdcall, +proc mmioCreateChunk*(x1: HMMIO, x2: LPMMCKINFO, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mmioCreateChunk".} -proc mciSendCommandA*(x1: MCIDEVICEID, x2: UINT, x3: DWORD, x4: DWORD): MCIERROR{. +proc mciSendCommandA*(x1: MCIDEVICEID, x2: uint32, x3: DWORD, x4: DWORD): MCIERROR{. stdcall, dynlib: "winmm.dll", importc: "mciSendCommandA".} -proc mciSendCommandW*(x1: MCIDEVICEID, x2: UINT, x3: DWORD, x4: DWORD): MCIERROR{. +proc mciSendCommandW*(x1: MCIDEVICEID, x2: uint32, x3: DWORD, x4: DWORD): MCIERROR{. stdcall, dynlib: "winmm.dll", importc: "mciSendCommandW".} -proc mciSendCommand*(x1: MCIDEVICEID, x2: UINT, x3: DWORD, x4: DWORD): MCIERROR{. +proc mciSendCommand*(x1: MCIDEVICEID, x2: uint32, x3: DWORD, x4: DWORD): MCIERROR{. stdcall, dynlib: "winmm.dll", importc: "mciSendCommandA".} -proc mciSendStringA*(x1: LPCSTR, x2: LPSTR, x3: UINT, x4: HWND): MCIERROR{. +proc mciSendStringA*(x1: LPCSTR, x2: LPSTR, x3: uint32, x4: HWND): MCIERROR{. stdcall, dynlib: "winmm.dll", importc: "mciSendStringA".} -proc mciSendStringW*(x1: LPCWSTR, x2: LPWSTR, x3: UINT, x4: HWND): MCIERROR{. +proc mciSendStringW*(x1: LPCWSTR, x2: LPWSTR, x3: uint32, x4: HWND): MCIERROR{. stdcall, dynlib: "winmm.dll", importc: "mciSendStringW".} -proc mciSendString*(x1: cstring, x2: cstring, x3: UINT, x4: HWND): MCIERROR{. +proc mciSendString*(x1: cstring, x2: cstring, x3: uint32, x4: HWND): MCIERROR{. stdcall, dynlib: "winmm.dll", importc: "mciSendStringA".} proc mciGetDeviceIDA*(x1: LPCSTR): MCIDEVICEID{.stdcall, dynlib: "winmm.dll", importc: "mciGetDeviceIDA".} @@ -2320,60 +2317,60 @@ proc mciGetDeviceIDFromElementIDW*(x1: DWORD, x2: LPCWSTR): MCIDEVICEID{. stdcall, dynlib: "winmm.dll", importc: "mciGetDeviceIDFromElementIDW".} proc mciGetDeviceIDFromElementID*(x1: DWORD, x2: cstring): MCIDEVICEID{.stdcall, dynlib: "winmm.dll", importc: "mciGetDeviceIDFromElementIDA".} -proc mciGetErrorStringA*(x1: MCIERROR, x2: LPSTR, x3: UINT): BOOL{.stdcall, +proc mciGetErrorStringA*(x1: MCIERROR, x2: LPSTR, x3: uint32): bool{.stdcall, dynlib: "winmm.dll", importc: "mciGetErrorStringA".} -proc mciGetErrorStringW*(x1: MCIERROR, x2: LPWSTR, x3: UINT): BOOL{.stdcall, +proc mciGetErrorStringW*(x1: MCIERROR, x2: LPWSTR, x3: uint32): bool{.stdcall, dynlib: "winmm.dll", importc: "mciGetErrorStringW".} -proc mciGetErrorString*(x1: MCIERROR, x2: cstring, x3: UINT): BOOL{.stdcall, +proc mciGetErrorString*(x1: MCIERROR, x2: cstring, x3: uint32): bool{.stdcall, dynlib: "winmm.dll", importc: "mciGetErrorStringA".} -proc mciSetYieldProc*(x1: MCIDEVICEID, x2: YIELDPROC, x3: DWORD): BOOL{.stdcall, +proc mciSetYieldProc*(x1: MCIDEVICEID, x2: YIELDPROC, x3: DWORD): bool{.stdcall, dynlib: "winmm.dll", importc: "mciSetYieldProc".} proc mciGetCreatorTask*(x1: MCIDEVICEID): HTASK{.stdcall, dynlib: "winmm.dll", importc: "mciGetCreatorTask".} proc mciGetYieldProc*(x1: MCIDEVICEID, x2: LPDWORD): YIELDPROC{.stdcall, dynlib: "winmm.dll", importc: "mciGetYieldProc".} -proc mciExecute*(x1: LPCSTR): BOOL{.stdcall, dynlib: "winmm.dll", +proc mciExecute*(x1: LPCSTR): bool{.stdcall, dynlib: "winmm.dll", importc: "mciExecute".} -proc joyGetPos*(x1: UINT, x2: LPJOYINFO): MMRESULT{.stdcall, +proc joyGetPos*(x1: uint32, x2: LPJOYINFO): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "joyGetPos".} -proc joyGetPosEx*(x1: UINT, x2: LPJOYINFOEX): MMRESULT{.stdcall, +proc joyGetPosEx*(x1: uint32, x2: LPJOYINFOEX): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "joyGetPosEx".} -proc joyGetThreshold*(x1: UINT, x2: LPUINT): MMRESULT{.stdcall, +proc joyGetThreshold*(x1: uint32, x2: LPUINT): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "joyGetThreshold".} -proc joyReleaseCapture*(x1: UINT): MMRESULT{.stdcall, dynlib: "winmm.dll", +proc joyReleaseCapture*(x1: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "joyReleaseCapture".} -proc joySetCapture*(x1: HWND, x2: UINT, x3: UINT, x4: BOOL): MMRESULT{.stdcall, +proc joySetCapture*(x1: HWND, x2: uint32, x3: uint32, x4: bool): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "joySetCapture".} -proc joySetThreshold*(x1: UINT, x2: UINT): MMRESULT{.stdcall, +proc joySetThreshold*(x1: uint32, x2: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "joySetThreshold".} -proc waveOutGetNumDevs*(): UINT{.stdcall, dynlib: "winmm.dll", +proc waveOutGetNumDevs*(): uint32{.stdcall, dynlib: "winmm.dll", importc: "waveOutGetNumDevs".} -proc waveOutGetDevCapsA*(x1: UINT, x2: LPWAVEOUTCAPSA, x3: UINT): MMRESULT{. +proc waveOutGetDevCapsA*(x1: uint32, x2: LPWAVEOUTCAPSA, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveOutGetDevCapsA".} -proc waveOutGetDevCapsW*(x1: UINT, x2: LPWAVEOUTCAPSW, x3: UINT): MMRESULT{. +proc waveOutGetDevCapsW*(x1: uint32, x2: LPWAVEOUTCAPSW, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveOutGetDevCapsW".} -proc waveOutGetDevCaps*(x1: UINT, x2: LPWAVEOUTCAPS, x3: UINT): MMRESULT{. +proc waveOutGetDevCaps*(x1: uint32, x2: LPWAVEOUTCAPS, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveOutGetDevCapsA".} proc waveOutGetVolume*(x1: HWAVEOUT, x2: LPDWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveOutGetVolume".} proc waveOutSetVolume*(x1: HWAVEOUT, x2: DWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveOutSetVolume".} -proc waveOutGetErrorTextA*(x1: MMRESULT, x2: LPSTR, x3: UINT): MMRESULT{. +proc waveOutGetErrorTextA*(x1: MMRESULT, x2: LPSTR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveOutGetErrorTextA".} -proc waveOutGetErrorTextW*(x1: MMRESULT, x2: LPWSTR, x3: UINT): MMRESULT{. +proc waveOutGetErrorTextW*(x1: MMRESULT, x2: LPWSTR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveOutGetErrorTextW".} -proc waveOutGetErrorText*(x1: MMRESULT, x2: cstring, x3: UINT): MMRESULT{. +proc waveOutGetErrorText*(x1: MMRESULT, x2: cstring, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveOutGetErrorTextA".} -proc waveOutOpen*(x1: LPHWAVEOUT, x2: UINT, x3: LPCWAVEFORMATEX, x4: DWORD, +proc waveOutOpen*(x1: LPHWAVEOUT, x2: uint32, x3: LPCWAVEFORMATEX, x4: DWORD, x5: DWORD, x6: DWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveOutOpen".} proc waveOutClose*(x1: HWAVEOUT): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveOutClose".} -proc waveOutPrepareHeader*(x1: HWAVEOUT, x2: LPWAVEHDR, x3: UINT): MMRESULT{. +proc waveOutPrepareHeader*(x1: HWAVEOUT, x2: LPWAVEHDR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveOutPrepareHeader".} -proc waveOutUnprepareHeader*(x1: HWAVEOUT, x2: LPWAVEHDR, x3: UINT): MMRESULT{. +proc waveOutUnprepareHeader*(x1: HWAVEOUT, x2: LPWAVEHDR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveOutUnprepareHeader".} -proc waveOutWrite*(x1: HWAVEOUT, x2: LPWAVEHDR, x3: UINT): MMRESULT{.stdcall, +proc waveOutWrite*(x1: HWAVEOUT, x2: LPWAVEHDR, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveOutWrite".} proc waveOutPause*(x1: HWAVEOUT): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveOutPause".} @@ -2383,7 +2380,7 @@ proc waveOutReset*(x1: HWAVEOUT): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveOutReset".} proc waveOutBreakLoop*(x1: HWAVEOUT): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveOutBreakLoop".} -proc waveOutGetPosition*(x1: HWAVEOUT, x2: LPMMTIME, x3: UINT): MMRESULT{. +proc waveOutGetPosition*(x1: HWAVEOUT, x2: LPMMTIME, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveOutGetPosition".} proc waveOutGetPitch*(x1: HWAVEOUT, x2: LPDWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveOutGetPitch".} @@ -2395,32 +2392,32 @@ proc waveOutSetPlaybackRate*(x1: HWAVEOUT, x2: DWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveOutSetPlaybackRate".} proc waveOutGetID*(x1: HWAVEOUT, x2: LPUINT): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveOutGetID".} -proc waveOutMessage*(x1: HWAVEOUT, x2: UINT, x3: DWORD, x4: DWORD): MMRESULT{. +proc waveOutMessage*(x1: HWAVEOUT, x2: uint32, x3: DWORD, x4: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveOutMessage".} -proc waveInGetNumDevs*(): UINT{.stdcall, dynlib: "winmm.dll", +proc waveInGetNumDevs*(): uint32{.stdcall, dynlib: "winmm.dll", importc: "waveInGetNumDevs".} -proc waveInGetDevCapsA*(x1: UINT, x2: LPWAVEINCAPSA, x3: UINT): MMRESULT{. +proc waveInGetDevCapsA*(x1: uint32, x2: LPWAVEINCAPSA, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveInGetDevCapsA".} -proc waveInGetDevCapsW*(x1: UINT, x2: LPWAVEINCAPSW, x3: UINT): MMRESULT{. +proc waveInGetDevCapsW*(x1: uint32, x2: LPWAVEINCAPSW, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveInGetDevCapsW".} -proc waveInGetDevCaps*(x1: UINT, x2: LPWAVEINCAPS, x3: UINT): MMRESULT{.stdcall, +proc waveInGetDevCaps*(x1: uint32, x2: LPWAVEINCAPS, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveInGetDevCapsA".} -proc waveInGetErrorTextA*(x1: MMRESULT, x2: LPSTR, x3: UINT): MMRESULT{.stdcall, +proc waveInGetErrorTextA*(x1: MMRESULT, x2: LPSTR, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveInGetErrorTextA".} -proc waveInGetErrorTextW*(x1: MMRESULT, x2: LPWSTR, x3: UINT): MMRESULT{. +proc waveInGetErrorTextW*(x1: MMRESULT, x2: LPWSTR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveInGetErrorTextW".} -proc waveInGetErrorText*(x1: MMRESULT, x2: cstring, x3: UINT): MMRESULT{. +proc waveInGetErrorText*(x1: MMRESULT, x2: cstring, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveInGetErrorTextA".} -proc waveInOpen*(x1: LPHWAVEIN, x2: UINT, x3: LPCWAVEFORMATEX, x4: DWORD, +proc waveInOpen*(x1: LPHWAVEIN, x2: uint32, x3: LPCWAVEFORMATEX, x4: DWORD, x5: DWORD, x6: DWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveInOpen".} proc waveInClose*(x1: HWAVEIN): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveInClose".} -proc waveInPrepareHeader*(x1: HWAVEIN, x2: LPWAVEHDR, x3: UINT): MMRESULT{. +proc waveInPrepareHeader*(x1: HWAVEIN, x2: LPWAVEHDR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveInPrepareHeader".} -proc waveInUnprepareHeader*(x1: HWAVEIN, x2: LPWAVEHDR, x3: UINT): MMRESULT{. +proc waveInUnprepareHeader*(x1: HWAVEIN, x2: LPWAVEHDR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveInUnprepareHeader".} -proc waveInAddBuffer*(x1: HWAVEIN, x2: LPWAVEHDR, x3: UINT): MMRESULT{.stdcall, +proc waveInAddBuffer*(x1: HWAVEIN, x2: LPWAVEHDR, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveInAddBuffer".} proc waveInStart*(x1: HWAVEIN): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveInStart".} @@ -2428,11 +2425,11 @@ proc waveInStop*(x1: HWAVEIN): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveInStop".} proc waveInReset*(x1: HWAVEIN): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveInReset".} -proc waveInGetPosition*(x1: HWAVEIN, x2: LPMMTIME, x3: UINT): MMRESULT{.stdcall, +proc waveInGetPosition*(x1: HWAVEIN, x2: LPMMTIME, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveInGetPosition".} proc waveInGetID*(x1: HWAVEIN, x2: LPUINT): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveInGetID".} -proc waveInMessage*(x1: HWAVEIN, x2: UINT, x3: DWORD, x4: DWORD): MMRESULT{. +proc waveInMessage*(x1: HWAVEIN, x2: uint32, x3: DWORD, x4: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveInMessage".} proc mixerGetLineControlsA*(x1: HMIXEROBJ, x2: LPMIXERLINECONTROLSA, x3: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "mixerGetLineControlsA".} @@ -2440,13 +2437,13 @@ proc mixerGetLineControlsW*(x1: HMIXEROBJ, x2: LPMIXERLINECONTROLSW, x3: DWORD): stdcall, dynlib: "winmm.dll", importc: "mixerGetLineControlsW".} proc mixerGetLineControls*(x1: HMIXEROBJ, x2: LPMIXERLINECONTROLS, x3: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "mixerGetLineControlsA".} -proc joyGetNumDevs*(): UINT{.stdcall, dynlib: "winmm.dll", +proc joyGetNumDevs*(): uint32{.stdcall, dynlib: "winmm.dll", importc: "joyGetNumDevs".} -proc joyGetDevCapsA*(x1: UINT, x2: LPJOYCAPSA, x3: UINT): MMRESULT{.stdcall, +proc joyGetDevCapsA*(x1: uint32, x2: LPJOYCAPSA, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "joyGetDevCapsA".} -proc joyGetDevCapsW*(x1: UINT, x2: LPJOYCAPSW, x3: UINT): MMRESULT{.stdcall, +proc joyGetDevCapsW*(x1: uint32, x2: LPJOYCAPSW, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "joyGetDevCapsW".} -proc joyGetDevCaps*(x1: UINT, x2: LPJOYCAPS, x3: UINT): MMRESULT{.stdcall, +proc joyGetDevCaps*(x1: uint32, x2: LPJOYCAPS, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "joyGetDevCapsA".} proc mixerGetControlDetailsA*(x1: HMIXEROBJ, x2: LPMIXERCONTROLDETAILS, x3: DWORD): MMRESULT{.stdcall, @@ -2456,46 +2453,46 @@ proc mixerGetControlDetailsW*(x1: HMIXEROBJ, x2: LPMIXERCONTROLDETAILS, dynlib: "winmm.dll", importc: "mixerGetControlDetailsW".} proc mixerGetControlDetails*(x1: HMIXEROBJ, x2: LPMIXERCONTROLDETAILS, x3: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "mixerGetControlDetailsA".} -proc timeGetSystemTime*(x1: LPMMTIME, x2: UINT): MMRESULT{.stdcall, +proc timeGetSystemTime*(x1: LPMMTIME, x2: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "timeGetSystemTime".} proc timeGetTime*(): DWORD{.stdcall, dynlib: "winmm.dll", importc: "timeGetTime".} -proc timeSetEvent*(x1: UINT, x2: UINT, x3: LPTIMECALLBACK, x4: DWORD, x5: UINT): MMRESULT{. +proc timeSetEvent*(x1: uint32, x2: uint32, x3: LPTIMECALLBACK, x4: DWORD, x5: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "timeSetEvent".} -proc timeKillEvent*(x1: UINT): MMRESULT{.stdcall, dynlib: "winmm.dll", +proc timeKillEvent*(x1: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "timeKillEvent".} -proc timeGetDevCaps*(x1: LPTIMECAPS, x2: UINT): MMRESULT{.stdcall, +proc timeGetDevCaps*(x1: LPTIMECAPS, x2: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "timeGetDevCaps".} -proc timeBeginPeriod*(x1: UINT): MMRESULT{.stdcall, dynlib: "winmm.dll", +proc timeBeginPeriod*(x1: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "timeBeginPeriod".} -proc timeEndPeriod*(x1: UINT): MMRESULT{.stdcall, dynlib: "winmm.dll", +proc timeEndPeriod*(x1: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "timeEndPeriod".} -proc mixerGetDevCapsA*(x1: UINT, x2: LPMIXERCAPSA, x3: UINT): MMRESULT{.stdcall, +proc mixerGetDevCapsA*(x1: uint32, x2: LPMIXERCAPSA, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mixerGetDevCapsA".} -proc mixerGetDevCapsW*(x1: UINT, x2: LPMIXERCAPSW, x3: UINT): MMRESULT{.stdcall, +proc mixerGetDevCapsW*(x1: uint32, x2: LPMIXERCAPSW, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mixerGetDevCapsW".} -proc mixerGetDevCaps*(x1: UINT, x2: LPMIXERCAPS, x3: UINT): MMRESULT{.stdcall, +proc mixerGetDevCaps*(x1: uint32, x2: LPMIXERCAPS, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mixerGetDevCapsA".} -proc mixerOpen*(x1: LPHMIXER, x2: UINT, x3: DWORD, x4: DWORD, x5: DWORD): MMRESULT{. +proc mixerOpen*(x1: LPHMIXER, x2: uint32, x3: DWORD, x4: DWORD, x5: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "mixerOpen".} proc mixerClose*(x1: HMIXER): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mixerClose".} -proc mixerMessage*(x1: HMIXER, x2: UINT, x3: DWORD, x4: DWORD): DWORD{.stdcall, +proc mixerMessage*(x1: HMIXER, x2: uint32, x3: DWORD, x4: DWORD): DWORD{.stdcall, dynlib: "winmm.dll", importc: "mixerMessage".} -proc auxGetNumDevs*(): UINT{.stdcall, dynlib: "winmm.dll", +proc auxGetNumDevs*(): uint32{.stdcall, dynlib: "winmm.dll", importc: "auxGetNumDevs".} -proc auxGetDevCapsA*(x1: UINT, x2: LPAUXCAPSA, x3: UINT): MMRESULT{.stdcall, +proc auxGetDevCapsA*(x1: uint32, x2: LPAUXCAPSA, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "auxGetDevCapsA".} -proc auxGetDevCapsW*(x1: UINT, x2: LPAUXCAPSW, x3: UINT): MMRESULT{.stdcall, +proc auxGetDevCapsW*(x1: uint32, x2: LPAUXCAPSW, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "auxGetDevCapsW".} -proc auxGetDevCaps*(x1: UINT, x2: LPAUXCAPS, x3: UINT): MMRESULT{.stdcall, +proc auxGetDevCaps*(x1: uint32, x2: LPAUXCAPS, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "auxGetDevCapsA".} -proc auxSetVolume*(x1: UINT, x2: DWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", +proc auxSetVolume*(x1: uint32, x2: DWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "auxSetVolume".} -proc auxGetVolume*(x1: UINT, x2: LPDWORD): MMRESULT{.stdcall, +proc auxGetVolume*(x1: uint32, x2: LPDWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "auxGetVolume".} -proc auxOutMessage*(x1: UINT, x2: UINT, x3: DWORD, x4: DWORD): MMRESULT{. +proc auxOutMessage*(x1: uint32, x2: uint32, x3: DWORD, x4: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "auxOutMessage".} -proc midiOutGetNumDevs*(): UINT{.stdcall, dynlib: "winmm.dll", +proc midiOutGetNumDevs*(): uint32{.stdcall, dynlib: "winmm.dll", importc: "midiOutGetNumDevs".} proc midiStreamOpen*(x1: LPHMIDISTRM, x2: LPUINT, x3: DWORD, x4: DWORD, x5: DWORD, x6: DWORD): MMRESULT{.stdcall, @@ -2504,9 +2501,9 @@ proc midiStreamClose*(x1: HMIDISTRM): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiStreamClose".} proc midiStreamProperty*(x1: HMIDISTRM, x2: LPBYTE, x3: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiStreamProperty".} -proc midiStreamPosition*(x1: HMIDISTRM, x2: LPMMTIME, x3: UINT): MMRESULT{. +proc midiStreamPosition*(x1: HMIDISTRM, x2: LPMMTIME, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiStreamPosition".} -proc midiStreamOut*(x1: HMIDISTRM, x2: LPMIDIHDR, x3: UINT): MMRESULT{.stdcall, +proc midiStreamOut*(x1: HMIDISTRM, x2: LPMIDIHDR, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiStreamOut".} proc midiStreamPause*(x1: HMIDISTRM): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiStreamPause".} @@ -2518,67 +2515,67 @@ proc midiConnect*(x1: HMIDI, x2: HMIDIOUT, x3: pointer): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiConnect".} proc midiDisconnect*(x1: HMIDI, x2: HMIDIOUT, x3: pointer): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiDisconnect".} -proc midiOutGetDevCapsA*(x1: UINT, x2: LPMIDIOUTCAPSA, x3: UINT): MMRESULT{. +proc midiOutGetDevCapsA*(x1: uint32, x2: LPMIDIOUTCAPSA, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutGetDevCapsA".} -proc midiOutGetDevCapsW*(x1: UINT, x2: LPMIDIOUTCAPSW, x3: UINT): MMRESULT{. +proc midiOutGetDevCapsW*(x1: uint32, x2: LPMIDIOUTCAPSW, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutGetDevCapsW".} -proc midiOutGetDevCaps*(x1: UINT, x2: LPMIDIOUTCAPS, x3: UINT): MMRESULT{. +proc midiOutGetDevCaps*(x1: uint32, x2: LPMIDIOUTCAPS, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutGetDevCapsA".} proc midiOutGetVolume*(x1: HMIDIOUT, x2: LPDWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiOutGetVolume".} proc midiOutSetVolume*(x1: HMIDIOUT, x2: DWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiOutSetVolume".} -proc midiOutGetErrorTextA*(x1: MMRESULT, x2: LPSTR, x3: UINT): MMRESULT{. +proc midiOutGetErrorTextA*(x1: MMRESULT, x2: LPSTR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutGetErrorTextA".} -proc midiOutGetErrorTextW*(x1: MMRESULT, x2: LPWSTR, x3: UINT): MMRESULT{. +proc midiOutGetErrorTextW*(x1: MMRESULT, x2: LPWSTR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutGetErrorTextW".} -proc midiOutGetErrorText*(x1: MMRESULT, x2: cstring, x3: UINT): MMRESULT{. +proc midiOutGetErrorText*(x1: MMRESULT, x2: cstring, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutGetErrorTextA".} -proc midiOutOpen*(x1: LPHMIDIOUT, x2: UINT, x3: DWORD, x4: DWORD, x5: DWORD): MMRESULT{. +proc midiOutOpen*(x1: LPHMIDIOUT, x2: uint32, x3: DWORD, x4: DWORD, x5: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutOpen".} proc midiOutClose*(x1: HMIDIOUT): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiOutClose".} -proc midiOutPrepareHeader*(x1: HMIDIOUT, x2: LPMIDIHDR, x3: UINT): MMRESULT{. +proc midiOutPrepareHeader*(x1: HMIDIOUT, x2: LPMIDIHDR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutPrepareHeader".} -proc midiOutUnprepareHeader*(x1: HMIDIOUT, x2: LPMIDIHDR, x3: UINT): MMRESULT{. +proc midiOutUnprepareHeader*(x1: HMIDIOUT, x2: LPMIDIHDR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutUnprepareHeader".} proc midiOutShortMsg*(x1: HMIDIOUT, x2: DWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiOutShortMsg".} -proc midiOutLongMsg*(x1: HMIDIOUT, x2: LPMIDIHDR, x3: UINT): MMRESULT{.stdcall, +proc midiOutLongMsg*(x1: HMIDIOUT, x2: LPMIDIHDR, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiOutLongMsg".} proc midiOutReset*(x1: HMIDIOUT): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiOutReset".} -proc midiOutCachePatches*(x1: HMIDIOUT, x2: UINT, x3: LPWORD, x4: UINT): MMRESULT{. +proc midiOutCachePatches*(x1: HMIDIOUT, x2: uint32, x3: LPWORD, x4: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutCachePatches".} -proc midiOutCacheDrumPatches*(x1: HMIDIOUT, x2: UINT, x3: LPWORD, x4: UINT): MMRESULT{. +proc midiOutCacheDrumPatches*(x1: HMIDIOUT, x2: uint32, x3: LPWORD, x4: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutCacheDrumPatches".} proc midiOutGetID*(x1: HMIDIOUT, x2: LPUINT): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiOutGetID".} -proc midiOutMessage*(x1: HMIDIOUT, x2: UINT, x3: DWORD, x4: DWORD): MMRESULT{. +proc midiOutMessage*(x1: HMIDIOUT, x2: uint32, x3: DWORD, x4: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutMessage".} -proc midiInGetNumDevs*(): UINT{.stdcall, dynlib: "winmm.dll", +proc midiInGetNumDevs*(): uint32{.stdcall, dynlib: "winmm.dll", importc: "midiInGetNumDevs".} -proc midiInGetDevCapsA*(x1: UINT, x2: LPMIDIINCAPSA, x3: UINT): MMRESULT{. +proc midiInGetDevCapsA*(x1: uint32, x2: LPMIDIINCAPSA, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiInGetDevCapsA".} -proc midiInGetDevCapsW*(x1: UINT, x2: LPMIDIINCAPSW, x3: UINT): MMRESULT{. +proc midiInGetDevCapsW*(x1: uint32, x2: LPMIDIINCAPSW, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiInGetDevCapsW".} -proc midiInGetDevCaps*(x1: UINT, x2: LPMIDIINCAPS, x3: UINT): MMRESULT{.stdcall, +proc midiInGetDevCaps*(x1: uint32, x2: LPMIDIINCAPS, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiInGetDevCapsA".} -proc midiInGetErrorTextA*(x1: MMRESULT, x2: LPSTR, x3: UINT): MMRESULT{.stdcall, +proc midiInGetErrorTextA*(x1: MMRESULT, x2: LPSTR, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiInGetErrorTextA".} -proc midiInGetErrorTextW*(x1: MMRESULT, x2: LPWSTR, x3: UINT): MMRESULT{. +proc midiInGetErrorTextW*(x1: MMRESULT, x2: LPWSTR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiInGetErrorTextW".} -proc midiInGetErrorText*(x1: MMRESULT, x2: cstring, x3: UINT): MMRESULT{. +proc midiInGetErrorText*(x1: MMRESULT, x2: cstring, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiInGetErrorTextA".} -proc midiInOpen*(x1: LPHMIDIIN, x2: UINT, x3: DWORD, x4: DWORD, x5: DWORD): MMRESULT{. +proc midiInOpen*(x1: LPHMIDIIN, x2: uint32, x3: DWORD, x4: DWORD, x5: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiInOpen".} proc midiInClose*(x1: HMIDIIN): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiInClose".} -proc midiInPrepareHeader*(x1: HMIDIIN, x2: LPMIDIHDR, x3: UINT): MMRESULT{. +proc midiInPrepareHeader*(x1: HMIDIIN, x2: LPMIDIHDR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiInPrepareHeader".} -proc midiInUnprepareHeader*(x1: HMIDIIN, x2: LPMIDIHDR, x3: UINT): MMRESULT{. +proc midiInUnprepareHeader*(x1: HMIDIIN, x2: LPMIDIHDR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiInUnprepareHeader".} -proc midiInAddBuffer*(x1: HMIDIIN, x2: LPMIDIHDR, x3: UINT): MMRESULT{.stdcall, +proc midiInAddBuffer*(x1: HMIDIIN, x2: LPMIDIHDR, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiInAddBuffer".} proc midiInStart*(x1: HMIDIIN): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiInStart".} @@ -2588,7 +2585,7 @@ proc midiInReset*(x1: HMIDIIN): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiInReset".} proc midiInGetID*(x1: HMIDIIN, x2: LPUINT): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiInGetID".} -proc midiInMessage*(x1: HMIDIIN, x2: UINT, x3: DWORD, x4: DWORD): MMRESULT{. +proc midiInMessage*(x1: HMIDIIN, x2: uint32, x3: DWORD, x4: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiInMessage".} proc mixerGetLineInfoA*(x1: HMIXEROBJ, x2: LPMIXERLINEA, x3: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "mixerGetLineInfoA".} @@ -2596,13 +2593,13 @@ proc mixerGetLineInfoW*(x1: HMIXEROBJ, x2: LPMIXERLINEW, x3: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "mixerGetLineInfoW".} proc mixerGetLineInfo*(x1: HMIXEROBJ, x2: LPMIXERLINE, x3: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "mixerGetLineInfoA".} -proc mixerGetID*(x1: HMIXEROBJ, x2: var UINT, x3: DWORD): MMRESULT{.stdcall, +proc mixerGetID*(x1: HMIXEROBJ, x2: var uint32, x3: DWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mixerGetID".} -proc PlaySoundA*(x1: LPCSTR, x2: HMODULE, x3: DWORD): BOOL{.stdcall, +proc PlaySoundA*(x1: LPCSTR, x2: HMODULE, x3: DWORD): bool{.stdcall, dynlib: "winmm.dll", importc: "PlaySoundA".} -proc PlaySoundW*(x1: LPCWSTR, x2: HMODULE, x3: DWORD): BOOL{.stdcall, +proc PlaySoundW*(x1: LPCWSTR, x2: HMODULE, x3: DWORD): bool{.stdcall, dynlib: "winmm.dll", importc: "PlaySoundW".} -proc PlaySound*(x1: cstring, x2: HMODULE, x3: DWORD): BOOL{.stdcall, +proc PlaySound*(x1: cstring, x2: HMODULE, x3: DWORD): bool{.stdcall, dynlib: "winmm.dll", importc: "PlaySoundA".} # implementation @@ -2610,7 +2607,7 @@ proc MEVT_EVENTTYPE(x: int8): int8 = result = toU8(x shr 24) proc MEVT_EVENTPARM(x: DWORD): DWORD = - result = x And 0x00FFFFFF + result = x and 0x00FFFFFF proc MCI_MSF_MINUTE(msf: int32): int8 = result = toU8(msf and 0xff) @@ -2648,8 +2645,8 @@ proc MCI_MAKE_HMS(h, m, s: int8): int32 = proc MCI_TMSF_FRAME(tmsf: int32): int8 = result = toU8(tmsf shr 24) -proc mci_Make_TMSF(t, m, s, f: int8): int32 = +proc MCI_MAKE_TMSF(t, m, s, f: int8): int32 = result = (ze(t) or ze(m) shl 8 or ze(s) shl 16 or ze(f) shl 24).int32 proc DIBINDEX(n: int32): int32 = - result = n Or 0x000010FF'i32 shl 16'i32 + result = n or 0x000010FF'i32 shl 16'i32 diff --git a/lib/windows/nb30.nim b/lib/windows/nb30.nim index a7fd526aa..2e0c679ae 100644 --- a/lib/windows/nb30.nim +++ b/lib/windows/nb30.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2006 Andreas Rumpf # # See the file "copying.txt", included in this @@ -13,7 +13,7 @@ {.deadCodeElim: on.} import # Data structure templates - Windows + windows const NCBNAMSZ* = 16 # absolute length of a net name @@ -24,20 +24,20 @@ type # Network Control Block TNCBPostProc* = proc (P: PNCB) {.stdcall.} TNCB* {.final.} = object # Structure returned to the NCB command NCBASTAT is ADAPTER_STATUS followed # by an array of NAME_BUFFER structures. - ncb_command*: Char # command code - ncb_retcode*: Char # return code - ncb_lsn*: Char # local session number - ncb_num*: Char # number of our network name + ncb_command*: char # command code + ncb_retcode*: char # return code + ncb_lsn*: char # local session number + ncb_num*: char # number of our network name ncb_buffer*: cstring # address of message buffer ncb_length*: int16 # size of message buffer ncb_callname*: array[0..NCBNAMSZ - 1, char] # blank-padded name of remote ncb_name*: array[0..NCBNAMSZ - 1, char] # our blank-padded netname - ncb_rto*: Char # rcv timeout/retry count - ncb_sto*: Char # send timeout/sys timeout + ncb_rto*: char # rcv timeout/retry count + ncb_sto*: char # send timeout/sys timeout ncb_post*: TNCBPostProc # POST routine address - ncb_lana_num*: Char # lana (adapter) number - ncb_cmd_cplt*: Char # 0xff => commmand pending - ncb_reserve*: array[0..9, Char] # reserved, used by BIOS + ncb_lana_num*: char # lana (adapter) number + ncb_cmd_cplt*: char # 0xff => commmand pending + ncb_reserve*: array[0..9, char] # reserved, used by BIOS ncb_event*: THandle # HANDLE to Win32 event which # will be set to the signalled # state when an ASYNCH command @@ -45,11 +45,11 @@ type # Network Control Block PAdapterStatus* = ptr TAdapterStatus TAdapterStatus* {.final.} = object - adapter_address*: array[0..5, Char] - rev_major*: Char - reserved0*: Char - adapter_type*: Char - rev_minor*: Char + adapter_address*: array[0..5, char] + rev_major*: char + reserved0*: char + adapter_type*: char + rev_minor*: char duration*: int16 frmr_recv*: int16 frmr_xmit*: int16 @@ -75,9 +75,9 @@ type # Network Control Block PNameBuffer* = ptr TNameBuffer TNameBuffer* {.final.} = object - name*: array[0..NCBNAMSZ - 1, Char] - name_num*: Char - name_flags*: Char + name*: array[0..NCBNAMSZ - 1, char] + name_num*: char + name_flags*: char const # values for name_flags bits. @@ -96,19 +96,19 @@ type # Structure returned to the NCB command NCBSSTAT is SESSION_HEADER followed # status for all names. PSessionHeader* = ptr TSessionHeader TSessionHeader* {.final.} = object - sess_name*: Char - num_sess*: Char - rcv_dg_outstanding*: Char - rcv_any_outstanding*: Char + sess_name*: char + num_sess*: char + rcv_dg_outstanding*: char + rcv_any_outstanding*: char PSessionBuffer* = ptr TSessionBuffer TSessionBuffer* {.final.} = object - lsn*: Char - state*: Char - local_name*: array[0..NCBNAMSZ - 1, Char] - remote_name*: array[0..NCBNAMSZ - 1, Char] - rcvs_outstanding*: Char - sends_outstanding*: Char + lsn*: char + state*: char + local_name*: array[0..NCBNAMSZ - 1, char] + remote_name*: array[0..NCBNAMSZ - 1, char] + rcvs_outstanding*: char + sends_outstanding*: char const # Values for state @@ -125,24 +125,24 @@ type # Structure returned to the NCB command NCBENUM. PLanaEnum* = ptr TLanaEnum TLanaEnum* {.final.} = object # Structure returned to the NCB command NCBFINDNAME is FIND_NAME_HEADER followed # by an array of FIND_NAME_BUFFER structures. - len*: Char # Number of valid entries in lana[] - lana*: array[0..MAX_LANA, Char] + len*: char # Number of valid entries in lana[] + lana*: array[0..MAX_LANA, char] PFindNameHeader* = ptr TFindNameHeader TFindNameHeader* {.final.} = object node_count*: int16 - reserved*: Char - unique_group*: Char + reserved*: char + unique_group*: char PFindNameBuffer* = ptr TFindNameBuffer TFindNameBuffer* {.final.} = object # Structure provided with NCBACTION. The purpose of NCBACTION is to provide # transport specific extensions to netbios. - len*: Char - access_control*: Char - frame_control*: Char - destination_addr*: array[0..5, Char] - source_addr*: array[0..5, Char] - routing_info*: array[0..17, Char] + len*: char + access_control*: char + frame_control*: char + destination_addr*: array[0..5, char] + source_addr*: array[0..5, char] + routing_info*: array[0..17, char] PActionHeader* = ptr TActionHeader TActionHeader* {.final.} = object @@ -227,6 +227,6 @@ const # NCB Command codes # main user entry point for NetBIOS 3.0 # Usage: Result = Netbios( pncb ); -proc Netbios*(P: PNCB): Char{.stdcall, dynlib: "netapi32.dll", +proc Netbios*(P: PNCB): char{.stdcall, dynlib: "netapi32.dll", importc: "Netbios".} # implementation diff --git a/lib/windows/psapi.nim b/lib/windows/psapi.nim index 7d53cf7ca..fd1dcada8 100644 --- a/lib/windows/psapi.nim +++ b/lib/windows/psapi.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2009 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/windows/shellapi.nim b/lib/windows/shellapi.nim index 41f2a60d5..079257680 100644 --- a/lib/windows/shellapi.nim +++ b/lib/windows/shellapi.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2006 Andreas Rumpf # # See the file "copying.txt", included in this @@ -28,14 +28,14 @@ # Copyright (c) Microsoft Corporation. All rights reserved. import - Windows + windows type HDROP* = THandle - UINT_PTR* = ptr UINT + UINT_PTR* = ptr uint32 DWORD_PTR* = ptr DWORD - pHICON* = ptr HICON - pBool* = ptr BOOL + PHICON* = ptr HICON + PBool* = ptr bool STARTUPINFOW* {.final.} = object # a guess. Omission should get fixed in Windows. cb*: DWORD lpReserved*: LPTSTR @@ -60,27 +60,27 @@ type TSTARTUPINFOW* = STARTUPINFOW PSTARTUPINFOW* = ptr STARTUPINFOW #unicode -proc DragQueryFileA*(arg1: HDROP, arg2: UINT, arg3: LPSTR, arg4: UINT): UINT{. +proc DragQueryFileA*(arg1: HDROP, arg2: uint32, arg3: LPSTR, arg4: uint32): uint32{. stdcall, dynlib: "shell32.dll", importc: "DragQueryFileA".} -proc DragQueryFileW*(arg1: HDROP, arg2: UINT, arg3: LPWSTR, arg4: UINT): UINT{. +proc DragQueryFileW*(arg1: HDROP, arg2: uint32, arg3: LPWSTR, arg4: uint32): uint32{. stdcall, dynlib: "shell32.dll", importc: "DragQueryFileW".} -proc DragQueryFile*(arg1: HDROP, arg2: UINT, arg3: LPSTR, arg4: UINT): UINT{. +proc DragQueryFile*(arg1: HDROP, arg2: uint32, arg3: LPSTR, arg4: uint32): uint32{. stdcall, dynlib: "shell32.dll", importc: "DragQueryFileA".} -proc DragQueryFile*(arg1: HDROP, arg2: UINT, arg3: LPWSTR, arg4: UINT): UINT{. +proc DragQueryFile*(arg1: HDROP, arg2: uint32, arg3: LPWSTR, arg4: uint32): uint32{. stdcall, dynlib: "shell32.dll", importc: "DragQueryFileW".} -proc DragQueryPoint*(arg1: HDROP, arg2: LPPOINT): BOOL{.stdcall, +proc DragQueryPoint*(arg1: HDROP, arg2: LPPOINT): bool{.stdcall, dynlib: "shell32.dll", importc: "DragQueryPoint".} proc DragFinish*(arg1: HDROP){.stdcall, dynlib: "shell32.dll", importc: "DragFinish".} -proc DragAcceptFiles*(hwnd: HWND, arg2: BOOL){.stdcall, dynlib: "shell32.dll", +proc DragAcceptFiles*(hwnd: HWND, arg2: bool){.stdcall, dynlib: "shell32.dll", importc: "DragAcceptFiles".} -proc ShellExecuteA*(HWND: hwnd, lpOperation: LPCSTR, lpFile: LPCSTR, +proc ShellExecuteA*(hwnd: HWND, lpOperation: LPCSTR, lpFile: LPCSTR, lpParameters: LPCSTR, lpDirectory: LPCSTR, nShowCmd: int32): HInst{. stdcall, dynlib: "shell32.dll", importc: "ShellExecuteA".} proc ShellExecuteW*(hwnd: HWND, lpOperation: LPCWSTR, lpFile: LPCWSTR, lpParameters: LPCWSTR, lpDirectory: LPCWSTR, nShowCmd: int32): HInst{. stdcall, dynlib: "shell32.dll", importc: "ShellExecuteW".} -proc ShellExecute*(HWND: hwnd, lpOperation: LPCSTR, lpFile: LPCSTR, +proc ShellExecute*(hwnd: HWND, lpOperation: LPCSTR, lpFile: LPCSTR, lpParameters: LPCSTR, lpDirectory: LPCSTR, nShowCmd: int32): HInst{. stdcall, dynlib: "shell32.dll", importc: "ShellExecuteA".} proc ShellExecute*(hwnd: HWND, lpOperation: LPCWSTR, lpFile: LPCWSTR, @@ -94,16 +94,16 @@ proc FindExecutable*(lpFile: LPCSTR, lpDirectory: LPCSTR, lpResult: LPSTR): HIns stdcall, dynlib: "shell32.dll", importc: "FindExecutableA".} proc FindExecutable*(lpFile: LPCWSTR, lpDirectory: LPCWSTR, lpResult: LPWSTR): HInst{. stdcall, dynlib: "shell32.dll", importc: "FindExecutableW".} -proc CommandLineToArgvW*(lpCmdLine: LPCWSTR, pNumArgs: ptr int32): pLPWSTR{. +proc CommandLineToArgvW*(lpCmdLine: LPCWSTR, pNumArgs: ptr int32): PLPWSTR{. stdcall, dynlib: "shell32.dll", importc: "CommandLineToArgvW".} -proc ShellAboutA*(HWND: hWnd, szApp: LPCSTR, szOtherStuff: LPCSTR, HICON: hIcon): int32{. +proc ShellAboutA*(hwnd: HWND, szApp: LPCSTR, szOtherStuff: LPCSTR, hIcon: HICON): int32{. stdcall, dynlib: "shell32.dll", importc: "ShellAboutA".} -proc ShellAboutW*(HWND: hWnd, szApp: LPCWSTR, szOtherStuff: LPCWSTR, - HICON: hIcon): int32{.stdcall, dynlib: "shell32.dll", +proc ShellAboutW*(hwnd: HWND, szApp: LPCWSTR, szOtherStuff: LPCWSTR, + hIcon: HICON): int32{.stdcall, dynlib: "shell32.dll", importc: "ShellAboutW".} -proc ShellAbout*(HWND: hWnd, szApp: LPCSTR, szOtherStuff: LPCSTR, HICON: hIcon): int32{. +proc ShellAbout*(hwnd: HWND, szApp: LPCSTR, szOtherStuff: LPCSTR, hIcon: HICON): int32{. stdcall, dynlib: "shell32.dll", importc: "ShellAboutA".} -proc ShellAbout*(HWND: hWnd, szApp: LPCWSTR, szOtherStuff: LPCWSTR, HICON: hIcon): int32{. +proc ShellAbout*(hwnd: HWND, szApp: LPCWSTR, szOtherStuff: LPCWSTR, hIcon: HICON): int32{. stdcall, dynlib: "shell32.dll", importc: "ShellAboutW".} proc DuplicateIcon*(inst: HINST, icon: HICON): HIcon{.stdcall, dynlib: "shell32.dll", importc: "DuplicateIcon".} @@ -115,29 +115,29 @@ proc ExtractAssociatedIcon*(hInst: HINST, lpIconPath: LPSTR, lpiIcon: LPWORD): H stdcall, dynlib: "shell32.dll", importc: "ExtractAssociatedIconA".} proc ExtractAssociatedIcon*(hInst: HINST, lpIconPath: LPWSTR, lpiIcon: LPWORD): HICON{. stdcall, dynlib: "shell32.dll", importc: "ExtractAssociatedIconW".} -proc ExtractIconA*(hInst: HINST, lpszExeFileName: LPCSTR, nIconIndex: UINT): HICON{. +proc ExtractIconA*(hInst: HINST, lpszExeFileName: LPCSTR, nIconIndex: uint32): HICON{. stdcall, dynlib: "shell32.dll", importc: "ExtractIconA".} -proc ExtractIconW*(hInst: HINST, lpszExeFileName: LPCWSTR, nIconIndex: UINT): HICON{. +proc ExtractIconW*(hInst: HINST, lpszExeFileName: LPCWSTR, nIconIndex: uint32): HICON{. stdcall, dynlib: "shell32.dll", importc: "ExtractIconW".} -proc ExtractIcon*(hInst: HINST, lpszExeFileName: LPCSTR, nIconIndex: UINT): HICON{. +proc ExtractIcon*(hInst: HINST, lpszExeFileName: LPCSTR, nIconIndex: uint32): HICON{. stdcall, dynlib: "shell32.dll", importc: "ExtractIconA".} -proc ExtractIcon*(hInst: HINST, lpszExeFileName: LPCWSTR, nIconIndex: UINT): HICON{. +proc ExtractIcon*(hInst: HINST, lpszExeFileName: LPCWSTR, nIconIndex: uint32): HICON{. stdcall, dynlib: "shell32.dll", importc: "ExtractIconW".} # if(WINVER >= 0x0400) type # init with sizeof(DRAGINFO) DRAGINFOA* {.final.} = object - uSize*: UINT + uSize*: uint32 pt*: POINT - fNC*: BOOL + fNC*: bool lpFileList*: LPSTR grfKeyState*: DWORD TDRAGINFOA* = DRAGINFOA LPDRAGINFOA* = ptr DRAGINFOA # init with sizeof(DRAGINFO) DRAGINFOW* {.final.} = object - uSize*: UINT + uSize*: uint32 pt*: POINT - fNC*: BOOL + fNC*: bool lpFileList*: LPWSTR grfKeyState*: DWORD @@ -184,8 +184,8 @@ type AppBarData* {.final.} = object cbSize*: DWORD hWnd*: HWND - uCallbackMessage*: UINT - uEdge*: UINT + uCallbackMessage*: uint32 + uEdge*: uint32 rc*: RECT lParam*: LPARAM # message specific @@ -197,41 +197,41 @@ proc SHAppBarMessage*(dwMessage: DWORD, pData: APPBARDATA): UINT_PTR{.stdcall, # # EndAppBar # -proc DoEnvironmentSubstA*(szString: LPSTR, cchString: UINT): DWORD{.stdcall, +proc DoEnvironmentSubstA*(szString: LPSTR, cchString: uint32): DWORD{.stdcall, dynlib: "shell32.dll", importc: "DoEnvironmentSubstA".} -proc DoEnvironmentSubstW*(szString: LPWSTR, cchString: UINT): DWORD{.stdcall, +proc DoEnvironmentSubstW*(szString: LPWSTR, cchString: uint32): DWORD{.stdcall, dynlib: "shell32.dll", importc: "DoEnvironmentSubstW".} -proc DoEnvironmentSubst*(szString: LPSTR, cchString: UINT): DWORD{.stdcall, +proc DoEnvironmentSubst*(szString: LPSTR, cchString: uint32): DWORD{.stdcall, dynlib: "shell32.dll", importc: "DoEnvironmentSubstA".} -proc DoEnvironmentSubst*(szString: LPWSTR, cchString: UINT): DWORD{.stdcall, +proc DoEnvironmentSubst*(szString: LPWSTR, cchString: uint32): DWORD{.stdcall, dynlib: "shell32.dll", importc: "DoEnvironmentSubstW".} #Macro proc EIRESID*(x: int32): int32 -proc ExtractIconExA*(lpszFile: LPCSTR, nIconIndex: int32, phiconLarge: pHICON, - phiconSmall: pHIcon, nIcons: UINT): UINT{.stdcall, +proc ExtractIconExA*(lpszFile: LPCSTR, nIconIndex: int32, phiconLarge: PHICON, + phiconSmall: PHICON, nIcons: uint32): uint32{.stdcall, dynlib: "shell32.dll", importc: "ExtractIconExA".} -proc ExtractIconExW*(lpszFile: LPCWSTR, nIconIndex: int32, phiconLarge: pHICON, - phiconSmall: pHIcon, nIcons: UINT): UINT{.stdcall, +proc ExtractIconExW*(lpszFile: LPCWSTR, nIconIndex: int32, phiconLarge: PHICON, + phiconSmall: PHICON, nIcons: uint32): uint32{.stdcall, dynlib: "shell32.dll", importc: "ExtractIconExW".} proc ExtractIconExA*(lpszFile: LPCSTR, nIconIndex: int32, phiconLarge: var HICON, phiconSmall: var HIcon, - nIcons: UINT): UINT{.stdcall, dynlib: "shell32.dll", + nIcons: uint32): uint32{.stdcall, dynlib: "shell32.dll", importc: "ExtractIconExA".} proc ExtractIconExW*(lpszFile: LPCWSTR, nIconIndex: int32, phiconLarge: var HICON, phiconSmall: var HIcon, - nIcons: UINT): UINT{.stdcall, dynlib: "shell32.dll", + nIcons: uint32): uint32{.stdcall, dynlib: "shell32.dll", importc: "ExtractIconExW".} -proc ExtractIconEx*(lpszFile: LPCSTR, nIconIndex: int32, phiconLarge: pHICON, - phiconSmall: pHIcon, nIcons: UINT): UINT{.stdcall, +proc ExtractIconEx*(lpszFile: LPCSTR, nIconIndex: int32, phiconLarge: PHICON, + phiconSmall: PHICON, nIcons: uint32): uint32{.stdcall, dynlib: "shell32.dll", importc: "ExtractIconExA".} -proc ExtractIconEx*(lpszFile: LPCWSTR, nIconIndex: int32, phiconLarge: pHICON, - phiconSmall: pHIcon, nIcons: UINT): UINT{.stdcall, +proc ExtractIconEx*(lpszFile: LPCWSTR, nIconIndex: int32, phiconLarge: PHICON, + phiconSmall: PHICON, nIcons: uint32): uint32{.stdcall, dynlib: "shell32.dll", importc: "ExtractIconExW".} proc ExtractIconEx*(lpszFile: LPCSTR, nIconIndex: int32, phiconLarge: var HICON, - phiconSmall: var HIcon, nIcons: UINT): UINT{.stdcall, + phiconSmall: var HIcon, nIcons: uint32): uint32{.stdcall, dynlib: "shell32.dll", importc: "ExtractIconExA".} proc ExtractIconEx*(lpszFile: LPCWSTR, nIconIndex: int32, - phiconLarge: var HICON, phiconSmall: var HIcon, nIcons: UINT): UINT{. + phiconLarge: var HICON, phiconSmall: var HIcon, nIcons: uint32): uint32{. stdcall, dynlib: "shell32.dll", importc: "ExtractIconExW".} # # Shell File Operations @@ -291,11 +291,11 @@ type type SHFILEOPSTRUCTA* {.final.} = object hwnd*: HWND - wFunc*: UINT + wFunc*: uint32 pFrom*: LPCSTR pTo*: LPCSTR fFlags*: FILEOP_FLAGS - fAnyOperationsAborted*: BOOL + fAnyOperationsAborted*: bool hNameMappings*: LPVOID lpszProgressTitle*: LPCSTR # only used if FOF_SIMPLEPROGRESS @@ -303,11 +303,11 @@ type LPSHFILEOPSTRUCTA* = ptr SHFILEOPSTRUCTA SHFILEOPSTRUCTW* {.final.} = object hwnd*: HWND - wFunc*: UINT + wFunc*: uint32 pFrom*: LPCWSTR pTo*: LPCWSTR fFlags*: FILEOP_FLAGS - fAnyOperationsAborted*: BOOL + fAnyOperationsAborted*: bool hNameMappings*: LPVOID lpszProgressTitle*: LPCWSTR @@ -430,10 +430,10 @@ type cbSize*: DWORD fMask*: ULONG hwnd*: HWND - lpVerb*: lpcwstr - lpFile*: lpcwstr - lpParameters*: lpcwstr - lpDirectory*: lpcwstr + lpVerb*: LPCWSTR + lpFile*: LPCWSTR + lpParameters*: LPCWSTR + lpDirectory*: LPCWSTR nShow*: int32 hInstApp*: HINST lpIDList*: LPVOID @@ -456,24 +456,24 @@ else: SHELLEXECUTEINFO* = SHELLEXECUTEINFOA TSHELLEXECUTEINFO* = SHELLEXECUTEINFOA LPSHELLEXECUTEINFO* = LPSHELLEXECUTEINFOA -proc ShellExecuteExA*(lpExecInfo: LPSHELLEXECUTEINFOA): Bool{.stdcall, +proc ShellExecuteExA*(lpExecInfo: LPSHELLEXECUTEINFOA): bool{.stdcall, dynlib: "shell32.dll", importc: "ShellExecuteExA".} -proc ShellExecuteExW*(lpExecInfo: LPSHELLEXECUTEINFOW): Bool{.stdcall, +proc ShellExecuteExW*(lpExecInfo: LPSHELLEXECUTEINFOW): bool{.stdcall, dynlib: "shell32.dll", importc: "ShellExecuteExW".} -proc ShellExecuteEx*(lpExecInfo: LPSHELLEXECUTEINFOA): Bool{.stdcall, +proc ShellExecuteEx*(lpExecInfo: LPSHELLEXECUTEINFOA): bool{.stdcall, dynlib: "shell32.dll", importc: "ShellExecuteExA".} -proc ShellExecuteEx*(lpExecInfo: LPSHELLEXECUTEINFOW): Bool{.stdcall, +proc ShellExecuteEx*(lpExecInfo: LPSHELLEXECUTEINFOW): bool{.stdcall, dynlib: "shell32.dll", importc: "ShellExecuteExW".} -proc WinExecErrorA*(HWND: hwnd, error: int32, lpstrFileName: LPCSTR, +proc WinExecErrorA*(hwnd: HWND, error: int32, lpstrFileName: LPCSTR, lpstrTitle: LPCSTR){.stdcall, dynlib: "shell32.dll", importc: "WinExecErrorA".} -proc WinExecErrorW*(HWND: hwnd, error: int32, lpstrFileName: LPCWSTR, +proc WinExecErrorW*(hwnd: HWND, error: int32, lpstrFileName: LPCWSTR, lpstrTitle: LPCWSTR){.stdcall, dynlib: "shell32.dll", importc: "WinExecErrorW".} -proc WinExecError*(HWND: hwnd, error: int32, lpstrFileName: LPCSTR, +proc WinExecError*(hwnd: HWND, error: int32, lpstrFileName: LPCSTR, lpstrTitle: LPCSTR){.stdcall, dynlib: "shell32.dll", importc: "WinExecErrorA".} -proc WinExecError*(HWND: hwnd, error: int32, lpstrFileName: LPCWSTR, +proc WinExecError*(hwnd: HWND, error: int32, lpstrFileName: LPCWSTR, lpstrTitle: LPCWSTR){.stdcall, dynlib: "shell32.dll", importc: "WinExecErrorW".} type @@ -487,7 +487,7 @@ type hUserToken*: HANDLE lpProcessAttributes*: LPSECURITY_ATTRIBUTES lpThreadAttributes*: LPSECURITY_ATTRIBUTES - bInheritHandles*: BOOL + bInheritHandles*: bool dwCreationFlags*: DWORD lpStartupInfo*: LPSTARTUPINFOW lpProcessInformation*: LPPROCESS_INFORMATION @@ -495,7 +495,7 @@ type TSHCREATEPROCESSINFOW* = SHCREATEPROCESSINFOW PSHCREATEPROCESSINFOW* = ptr SHCREATEPROCESSINFOW -proc SHCreateProcessAsUserW*(pscpi: PSHCREATEPROCESSINFOW): Bool{.stdcall, +proc SHCreateProcessAsUserW*(pscpi: PSHCREATEPROCESSINFOW): bool{.stdcall, dynlib: "shell32.dll", importc: "SHCreateProcessAsUserW".} # # End ShellExecuteEx and family } @@ -544,16 +544,16 @@ type NOTIFYICONDATAA* {.final.} = object cbSize*: DWORD hWnd*: HWND - uID*: UINT - uFlags*: UINT - uCallbackMessage*: UINT + uID*: uint32 + uFlags*: uint32 + uCallbackMessage*: uint32 hIcon*: HICON - szTip*: array[0..127, CHAR] + szTip*: array[0..127, char] dwState*: DWORD dwStateMask*: DWORD - szInfo*: array[0..255, CHAR] - uTimeout*: UINT # also: uVersion - szInfoTitle*: array[0..63, CHAR] + szInfo*: array[0..255, char] + uTimeout*: uint32 # also: uVersion + szInfoTitle*: array[0..63, char] dwInfoFlags*: DWORD guidItem*: TGUID @@ -562,16 +562,16 @@ type NOTIFYICONDATAW* {.final.} = object cbSize*: DWORD hWnd*: HWND - uID*: UINT - uFlags*: UINT - uCallbackMessage*: UINT + uID*: uint32 + uFlags*: uint32 + uCallbackMessage*: uint32 hIcon*: HICON - szTip*: array[0..127, WCHAR] + szTip*: array[0..127, Wchar] dwState*: DWORD dwStateMask*: DWORD - szInfo*: array[0..255, WCHAR] - uTimeout*: UINT # also uVersion : UINT - szInfoTitle*: array[0..63, CHAR] + szInfo*: array[0..255, Wchar] + uTimeout*: uint32 # also uVersion : UINT + szInfoTitle*: array[0..63, char] dwInfoFlags*: DWORD guidItem*: TGUID @@ -619,13 +619,13 @@ const NIIF_ICON_MASK* = 0x0000000F NIIF_NOSOUND* = 0x00000010 -proc Shell_NotifyIconA*(dwMessage: Dword, lpData: PNOTIFYICONDATAA): Bool{. +proc Shell_NotifyIconA*(dwMessage: Dword, lpData: PNOTIFYICONDATAA): bool{. stdcall, dynlib: "shell32.dll", importc: "Shell_NotifyIconA".} -proc Shell_NotifyIconW*(dwMessage: Dword, lpData: PNOTIFYICONDATAW): Bool{. +proc Shell_NotifyIconW*(dwMessage: Dword, lpData: PNOTIFYICONDATAW): bool{. stdcall, dynlib: "shell32.dll", importc: "Shell_NotifyIconW".} -proc Shell_NotifyIcon*(dwMessage: Dword, lpData: PNOTIFYICONDATAA): Bool{. +proc Shell_NotifyIcon*(dwMessage: Dword, lpData: PNOTIFYICONDATAA): bool{. stdcall, dynlib: "shell32.dll", importc: "Shell_NotifyIconA".} -proc Shell_NotifyIcon*(dwMessage: Dword, lpData: PNOTIFYICONDATAW): Bool{. +proc Shell_NotifyIcon*(dwMessage: Dword, lpData: PNOTIFYICONDATAW): bool{. stdcall, dynlib: "shell32.dll", importc: "Shell_NotifyIconW".} # # The SHGetFileInfo API provides an easy way to get attributes @@ -652,20 +652,20 @@ type hIcon*: HICON # out: icon iIcon*: int32 # out: icon index dwAttributes*: DWORD # out: SFGAO_ flags - szDisplayName*: array[0..(MAX_PATH) - 1, CHAR] # out: display name (or path) - szTypeName*: array[0..79, CHAR] # out: type name + szDisplayName*: array[0..(MAX_PATH) - 1, char] # out: display name (or path) + szTypeName*: array[0..79, char] # out: type name TSHFILEINFOA* = SHFILEINFOA - pSHFILEINFOA* = ptr SHFILEINFOA + PSHFILEINFOA* = ptr SHFILEINFOA SHFILEINFOW* {.final.} = object hIcon*: HICON # out: icon iIcon*: int32 # out: icon index dwAttributes*: DWORD # out: SFGAO_ flags - szDisplayName*: array[0..(MAX_PATH) - 1, WCHAR] # out: display name (or path) - szTypeName*: array[0..79, WCHAR] # out: type name + szDisplayName*: array[0..(MAX_PATH) - 1, Wchar] # out: display name (or path) + szTypeName*: array[0..79, Wchar] # out: type name TSHFILEINFOW* = SHFILEINFOW - pSHFILEINFOW* = ptr SHFILEINFOW + PSHFILEINFOW* = ptr SHFILEINFOW when defined(UNICODE): type @@ -701,67 +701,67 @@ const # in the upper 8 bits of the iIcon proc SHGetFileInfoA*(pszPath: LPCSTR, dwFileAttributes: DWORD, - psfi: pSHFILEINFOA, cbFileInfo, UFlags: UINT): DWORD{. + psfi: PSHFILEINFOA, cbFileInfo, UFlags: uint32): DWORD{. stdcall, dynlib: "shell32.dll", importc: "SHGetFileInfoA".} proc SHGetFileInfoW*(pszPath: LPCWSTR, dwFileAttributes: DWORD, - psfi: pSHFILEINFOW, cbFileInfo, UFlags: UINT): DWORD{. + psfi: PSHFILEINFOW, cbFileInfo, UFlags: uint32): DWORD{. stdcall, dynlib: "shell32.dll", importc: "SHGetFileInfoW".} proc SHGetFileInfo*(pszPath: LPCSTR, dwFileAttributes: DWORD, - psfi: pSHFILEINFOA, cbFileInfo, UFlags: UINT): DWORD{. + psfi: PSHFILEINFOA, cbFileInfo, UFlags: uint32): DWORD{. stdcall, dynlib: "shell32.dll", importc: "SHGetFileInfoA".} proc SHGetFileInfoA*(pszPath: LPCSTR, dwFileAttributes: DWORD, - psfi: var TSHFILEINFOA, cbFileInfo, UFlags: UINT): DWORD{. + psfi: var TSHFILEINFOA, cbFileInfo, UFlags: uint32): DWORD{. stdcall, dynlib: "shell32.dll", importc: "SHGetFileInfoA".} proc SHGetFileInfoW*(pszPath: LPCWSTR, dwFileAttributes: DWORD, - psfi: var TSHFILEINFOW, cbFileInfo, UFlags: UINT): DWORD{. + psfi: var TSHFILEINFOW, cbFileInfo, UFlags: uint32): DWORD{. stdcall, dynlib: "shell32.dll", importc: "SHGetFileInfoW".} proc SHGetFileInfo*(pszPath: LPCSTR, dwFileAttributes: DWORD, - psfi: var TSHFILEINFOA, cbFileInfo, UFlags: UINT): DWORD{. + psfi: var TSHFILEINFOA, cbFileInfo, UFlags: uint32): DWORD{. stdcall, dynlib: "shell32.dll", importc: "SHGetFileInfoA".} proc SHGetFileInfo*(pszPath: LPCWSTR, dwFileAttributes: DWORD, - psfi: var TSHFILEINFOW, cbFileInfo, UFlags: UINT): DWORD{. + psfi: var TSHFILEINFOW, cbFileInfo, UFlags: uint32): DWORD{. stdcall, dynlib: "shell32.dll", importc: "SHGetFileInfoW".} proc SHGetDiskFreeSpaceExA*(pszDirectoryName: LPCSTR, - pulFreeBytesAvailableToCaller: pULARGE_INTEGER, - pulTotalNumberOfBytes: pULARGE_INTEGER, - pulTotalNumberOfFreeBytes: pULARGE_INTEGER): Bool{. + pulFreeBytesAvailableToCaller: PULARGE_INTEGER, + pulTotalNumberOfBytes: PULARGE_INTEGER, + pulTotalNumberOfFreeBytes: PULARGE_INTEGER): bool{. stdcall, dynlib: "shell32.dll", importc: "SHGetDiskFreeSpaceExA".} proc SHGetDiskFreeSpaceExW*(pszDirectoryName: LPCWSTR, - pulFreeBytesAvailableToCaller: pULARGE_INTEGER, - pulTotalNumberOfBytes: pULARGE_INTEGER, - pulTotalNumberOfFreeBytes: pULARGE_INTEGER): Bool{. + pulFreeBytesAvailableToCaller: PULARGE_INTEGER, + pulTotalNumberOfBytes: PULARGE_INTEGER, + pulTotalNumberOfFreeBytes: PULARGE_INTEGER): bool{. stdcall, dynlib: "shell32.dll", importc: "SHGetDiskFreeSpaceExW".} proc SHGetDiskFreeSpaceEx*(pszDirectoryName: LPCSTR, - pulFreeBytesAvailableToCaller: pULARGE_INTEGER, - pulTotalNumberOfBytes: pULARGE_INTEGER, - pulTotalNumberOfFreeBytes: pULARGE_INTEGER): Bool{. + pulFreeBytesAvailableToCaller: PULARGE_INTEGER, + pulTotalNumberOfBytes: PULARGE_INTEGER, + pulTotalNumberOfFreeBytes: PULARGE_INTEGER): bool{. stdcall, dynlib: "shell32.dll", importc: "SHGetDiskFreeSpaceExA".} proc SHGetDiskFreeSpace*(pszDirectoryName: LPCSTR, - pulFreeBytesAvailableToCaller: pULARGE_INTEGER, - pulTotalNumberOfBytes: pULARGE_INTEGER, - pulTotalNumberOfFreeBytes: pULARGE_INTEGER): Bool{. + pulFreeBytesAvailableToCaller: PULARGE_INTEGER, + pulTotalNumberOfBytes: PULARGE_INTEGER, + pulTotalNumberOfFreeBytes: PULARGE_INTEGER): bool{. stdcall, dynlib: "shell32.dll", importc: "SHGetDiskFreeSpaceExA".} proc SHGetDiskFreeSpaceEx*(pszDirectoryName: LPCWSTR, - pulFreeBytesAvailableToCaller: pULARGE_INTEGER, - pulTotalNumberOfBytes: pULARGE_INTEGER, - pulTotalNumberOfFreeBytes: pULARGE_INTEGER): Bool{. + pulFreeBytesAvailableToCaller: PULARGE_INTEGER, + pulTotalNumberOfBytes: PULARGE_INTEGER, + pulTotalNumberOfFreeBytes: PULARGE_INTEGER): bool{. stdcall, dynlib: "shell32.dll", importc: "SHGetDiskFreeSpaceExW".} proc SHGetDiskFreeSpace*(pszDirectoryName: LPCWSTR, - pulFreeBytesAvailableToCaller: pULARGE_INTEGER, - pulTotalNumberOfBytes: pULARGE_INTEGER, - pulTotalNumberOfFreeBytes: pULARGE_INTEGER): Bool{. + pulFreeBytesAvailableToCaller: PULARGE_INTEGER, + pulTotalNumberOfBytes: PULARGE_INTEGER, + pulTotalNumberOfFreeBytes: PULARGE_INTEGER): bool{. stdcall, dynlib: "shell32.dll", importc: "SHGetDiskFreeSpaceExW".} proc SHGetNewLinkInfoA*(pszLinkTo: LPCSTR, pszDir: LPCSTR, pszName: LPSTR, - pfMustCopy: pBool, uFlags: UINT): Bool{.stdcall, + pfMustCopy: PBool, uFlags: uint32): bool{.stdcall, dynlib: "shell32.dll", importc: "SHGetNewLinkInfoA".} proc SHGetNewLinkInfoW*(pszLinkTo: LPCWSTR, pszDir: LPCWSTR, pszName: LPWSTR, - pfMustCopy: pBool, uFlags: UINT): Bool{.stdcall, + pfMustCopy: PBool, uFlags: uint32): bool{.stdcall, dynlib: "shell32.dll", importc: "SHGetNewLinkInfoW".} proc SHGetNewLinkInfo*(pszLinkTo: LPCSTR, pszDir: LPCSTR, pszName: LPSTR, - pfMustCopy: pBool, uFlags: UINT): Bool{.stdcall, + pfMustCopy: PBool, uFlags: uint32): bool{.stdcall, dynlib: "shell32.dll", importc: "SHGetNewLinkInfoA".} proc SHGetNewLinkInfo*(pszLinkTo: LPCWSTR, pszDir: LPCWSTR, pszName: LPWSTR, - pfMustCopy: pBool, uFlags: UINT): Bool{.stdcall, + pfMustCopy: PBool, uFlags: uint32): bool{.stdcall, dynlib: "shell32.dll", importc: "SHGetNewLinkInfoW".} const SHGNLI_PIDL* = 0x00000001 # pszLinkTo is a pidl @@ -777,17 +777,17 @@ const PRINTACTION_DOCUMENTDEFAULTS* = 6 PRINTACTION_SERVERPROPERTIES* = 7 -proc SHInvokePrinterCommandA*(HWND: hwnd, uAction: UINT, lpBuf1: LPCSTR, - lpBuf2: LPCSTR, fModal: Bool): Bool{.stdcall, +proc SHInvokePrinterCommandA*(hwnd: HWND, uAction: uint32, lpBuf1: LPCSTR, + lpBuf2: LPCSTR, fModal: bool): bool{.stdcall, dynlib: "shell32.dll", importc: "SHInvokePrinterCommandA".} -proc SHInvokePrinterCommandW*(HWND: hwnd, uAction: UINT, lpBuf1: LPCWSTR, - lpBuf2: LPCWSTR, fModal: Bool): Bool{.stdcall, +proc SHInvokePrinterCommandW*(hwnd: HWND, uAction: uint32, lpBuf1: LPCWSTR, + lpBuf2: LPCWSTR, fModal: bool): bool{.stdcall, dynlib: "shell32.dll", importc: "SHInvokePrinterCommandW".} -proc SHInvokePrinterCommand*(HWND: hwnd, uAction: UINT, lpBuf1: LPCSTR, - lpBuf2: LPCSTR, fModal: Bool): Bool{.stdcall, +proc SHInvokePrinterCommand*(hwnd: HWND, uAction: uint32, lpBuf1: LPCSTR, + lpBuf2: LPCSTR, fModal: bool): bool{.stdcall, dynlib: "shell32.dll", importc: "SHInvokePrinterCommandA".} -proc SHInvokePrinterCommand*(HWND: hwnd, uAction: UINT, lpBuf1: LPCWSTR, - lpBuf2: LPCWSTR, fModal: Bool): Bool{.stdcall, +proc SHInvokePrinterCommand*(hwnd: HWND, uAction: uint32, lpBuf1: LPCWSTR, + lpBuf2: LPCWSTR, fModal: bool): bool{.stdcall, dynlib: "shell32.dll", importc: "SHInvokePrinterCommandW".} proc SHLoadNonloadedIconOverlayIdentifiers*(): HResult{.stdcall, dynlib: "shell32.dll", importc: "SHInvokePrinterCommandW".} diff --git a/lib/windows/shfolder.nim b/lib/windows/shfolder.nim index 253b1c77a..886d757eb 100644 --- a/lib/windows/shfolder.nim +++ b/lib/windows/shfolder.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2006 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/windows/windows.nim b/lib/windows/windows.nim index 5fd9127b3..9008d63e3 100644 --- a/lib/windows/windows.nim +++ b/lib/windows/windows.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this @@ -49,15 +49,15 @@ type # BaseTsd.h -- Type definitions for the basic sized types DWORD64* = int64 PDWORD64* = ptr DWORD64 # int32 on Win32, int64 on Win64 - INT_PTR* = TAddress - UINT_PTR* = TAddress - LONG_PTR* = TAddress - ULONG_PTR* = TAddress - SIZE_T* = TAddress - SSIZE_T* = TAddress - DWORD_PTR* = TAddress + INT_PTR* = ByteAddress + UINT_PTR* = ByteAddress + LONG_PTR* = ByteAddress + ULONG_PTR* = ByteAddress + SIZE_T* = ByteAddress + SSIZE_T* = ByteAddress + DWORD_PTR* = ByteAddress # Thread affinity - KAFFINITY* = TAddress + KAFFINITY* = ByteAddress PKAFFINITY* = ptr KAFFINITY type # WinDef.h -- Basic Windows Type Definitions @@ -74,8 +74,8 @@ type # WinDef.h -- Basic Windows Type Definitions DWORD* = int32 WINBOOL* = int32 WORD* = int16 - # FLOAT* = float - PFLOAT* = ptr FLOAT + #FLOAT* = float + PFLOAT* = ptr float32 PWINBOOL* = ptr WINBOOL LPWINBOOL* = ptr WINBOOL PBYTE* = ptr int8 @@ -383,7 +383,7 @@ type stdcall.} LPCFHOOKPROC* = proc (para1: HWND, para2: WINUINT, para3: WPARAM, para4: LPARAM): WINUINT{. stdcall.} - PTHREAD_START_ROUTINE* = Pointer + PTHREAD_START_ROUTINE* = pointer LPTHREAD_START_ROUTINE* = PTHREAD_START_ROUTINE EDITSTREAMCALLBACK* = proc (para1: DWORD, para2: LPBYTE, para3: LONG, para4: LONG): DWORD{.stdcall.} @@ -8415,34 +8415,34 @@ type # dmDisplayFixedOutput: DWORD; LPDEVMODE* = ptr DEVMODE - devicemode* = DEVMODE - tdevicemode* = DEVMODE - tdevicemodeA* = DEVMODE + Devicemode* = DEVMODE + TDevicemode* = DEVMODE + TDevicemodeA* = DEVMODE PDeviceModeA* = LPDEVMODE PDeviceMode* = LPDEVMODE TDEVMODE* = DEVMODE PDEVMODE* = LPDEVMODE - devmodeW* {.final, pure.} = object + DEVMODEW* {.final, pure.} = object dmDeviceName*: array[0..CCHDEVICENAME - 1, WCHAR] dmSpecVersion*: int16 dmDriverVersion*: int16 dmSize*: int16 dmDriverExtra*: int16 dmFields*: DWORD - dmOrientation*: short - dmPaperSize*: short - dmPaperLength*: short - dmPaperWidth*: short - dmScale*: short - dmCopies*: short - dmDefaultSource*: short - dmPrintQuality*: short - dmColor*: short - dmDuplex*: short - dmYResolution*: short - dmTTOption*: short - dmCollate*: short - dmFormName*: array[0..CCHFORMNAME - 1, wchar] + dmOrientation*: SHORT + dmPaperSize*: SHORT + dmPaperLength*: SHORT + dmPaperWidth*: SHORT + dmScale*: SHORT + dmCopies*: SHORT + dmDefaultSource*: SHORT + dmPrintQuality*: SHORT + dmColor*: SHORT + dmDuplex*: SHORT + dmYResolution*: SHORT + dmTTOption*: SHORT + dmCollate*: SHORT + dmFormName*: array[0..CCHFORMNAME - 1, WCHAR] dmLogPixels*: int16 dmBitsPerPel*: DWORD dmPelsWidth*: DWORD @@ -8459,7 +8459,7 @@ type dmPanningHeight*: DWORD LPDEVMODEW* = ptr DEVMODEW - devicemodeW* = DEVMODEW + DevicemodeW* = DEVMODEW TDeviceModeW* = DEVMODEW PDeviceModeW* = LPDEVMODEW TDEVMODEW* = DEVMODEW @@ -8497,7 +8497,7 @@ type LARGE_INTEGER* = int64 ULARGE_INTEGER* = int64 PLARGE_INTEGER* = ptr LARGE_INTEGER - TLargeInteger* = Int64 + TLargeInteger* = int64 PULARGE_INTEGER* = ptr ULARGE_INTEGER TULargeInteger* = int64 DISK_GEOMETRY* {.final, pure.} = object @@ -10469,7 +10469,7 @@ type ncb_name*: array[0..(NCBNAMSZ) - 1, UCHAR] ncb_rto*: UCHAR ncb_sto*: UCHAR - ncb_post*: proc (para1: p_NCB){.CDECL.} + ncb_post*: proc (para1: p_NCB){.cdecl.} ncb_lana_num*: UCHAR ncb_cmd_cplt*: UCHAR ncb_reserve*: array[0..9, UCHAR] @@ -10681,7 +10681,7 @@ type nErrCode*: int16 Reserved1*: int16 Reserved2*: int16 - szPathName*: array[0..(OFS_MAXPATHNAME) - 1, CHAR] + szPathName*: array[0..(OFS_MAXPATHNAME) - 1, char] LPOFSTRUCT* = ptr OFSTRUCT TOFSTRUCT* = OFSTRUCT @@ -10725,7 +10725,7 @@ type nMaxFileTitle*: DWORD lpstrInitialDir*: LPCTSTR lpstrTitle*: LPCTSTR - Flags*: DWORD + flags*: DWORD nFileOffset*: int16 nFileExtension*: int16 lpstrDefExt*: LPCTSTR @@ -10733,8 +10733,8 @@ type lpfnHook*: LPOFNHOOKPROC lpTemplateName*: LPCTSTR pvReserved*: pointer - dwreserved*: dword - FlagsEx*: dword + dwreserved*: DWORD + FlagsEx*: DWORD LPOPENFILENAME* = ptr TOPENFILENAME POPENFILENAME* = ptr TOPENFILENAME @@ -11280,8 +11280,8 @@ type dwSize*: DWORD hrasconn*: HRASCONN szEntryName*: array[0..(RAS_MaxEntryName + 1) - 1, TCHAR] - szDeviceType*: array[0..(RAS_MaxDeviceType + 1) - 1, CHAR] - szDeviceName*: array[0..(RAS_MaxDeviceName + 1) - 1, CHAR] + szDeviceType*: array[0..(RAS_MaxDeviceType + 1) - 1, char] + szDeviceName*: array[0..(RAS_MaxDeviceName + 1) - 1, char] TRASCONN* = RASCONN PRASCONN* = ptr RASCONN @@ -11344,9 +11344,9 @@ type TRASPPPNBF* = RASPPPNBF PRASPPPNBF* = ptr RASPPPNBF RASTERIZER_STATUS* {.final, pure.} = object - nSize*: short - wFlags*: short - nLanguageID*: short + nSize*: SHORT + wFlags*: SHORT + nLanguageID*: SHORT LPRASTERIZER_STATUS* = ptr RASTERIZER_STATUS TRASTERIZERSTATUS* = RASTERIZER_STATUS @@ -11592,7 +11592,7 @@ type PSTRRET* = ptr STRRET STYLEBUF* {.final, pure.} = object dwStyle*: DWORD - szDescription*: array[0..31, CHAR] + szDescription*: array[0..31, char] LPSTYLEBUF* = ptr STYLEBUF TSTYLEBUF* = STYLEBUF @@ -11801,7 +11801,7 @@ type TTOGGLEKEYS* = TOGGLEKEYS PTOGGLEKEYS* = ptr TOGGLEKEYS TTOKEN_SOURCE* {.final, pure.} = object - SourceName*: array[0..7, CHAR] + SourceName*: array[0..7, char] SourceIdentifier*: LUID PTOKENSOURCE* = ptr TTOKEN_SOURCE @@ -12366,7 +12366,7 @@ type uFlags*: WINUINT uCallbackMessage*: WINUINT hIcon*: HICON - szTip*: array[0..63, Char] + szTip*: array[0..63, char] NOTIFYICONDATA* = NOTIFYICONDATAA NOTIFYICONDATAW* {.final, pure.} = object @@ -13575,7 +13575,7 @@ type TWMSysKeyUp* = TWMKey TWMMenuChar* {.final, pure.} = object Msg*: WINUINT - User*: Char + User*: char MenuFlag*: int16 Menu*: HMENU Result*: LRESULT @@ -14432,19 +14432,19 @@ proc CharNextA*(lpsz: LPCSTR): LPSTR{.stdcall, dynlib: "user32", importc: "CharNextA".} proc CharPrevA*(lpszStart: LPCSTR, lpszCurrent: LPCSTR): LPSTR{.stdcall, dynlib: "user32", importc: "CharPrevA".} -proc IsCharAlphaA*(ch: CHAR): WINBOOL{.stdcall, dynlib: "user32", +proc IsCharAlphaA*(ch: char): WINBOOL{.stdcall, dynlib: "user32", importc: "IsCharAlphaA".} -proc IsCharAlphaNumericA*(ch: CHAR): WINBOOL{.stdcall, dynlib: "user32", +proc IsCharAlphaNumericA*(ch: char): WINBOOL{.stdcall, dynlib: "user32", importc: "IsCharAlphaNumericA".} -proc IsCharUpperA*(ch: CHAR): WINBOOL{.stdcall, dynlib: "user32", +proc IsCharUpperA*(ch: char): WINBOOL{.stdcall, dynlib: "user32", importc: "IsCharUpperA".} -proc IsCharLowerA*(ch: CHAR): WINBOOL{.stdcall, dynlib: "user32", +proc IsCharLowerA*(ch: char): WINBOOL{.stdcall, dynlib: "user32", importc: "IsCharLowerA".} proc GetKeyNameTextA*(lParam: LONG, lpString: LPSTR, nSize: int32): int32{. stdcall, dynlib: "user32", importc: "GetKeyNameTextA".} -proc VkKeyScanA*(ch: CHAR): SHORT{.stdcall, dynlib: "user32", +proc VkKeyScanA*(ch: char): SHORT{.stdcall, dynlib: "user32", importc: "VkKeyScanA".} -proc VkKeyScanExA*(ch: CHAR, dwhkl: HKL): SHORT{.stdcall, dynlib: "user32", +proc VkKeyScanExA*(ch: char, dwhkl: HKL): SHORT{.stdcall, dynlib: "user32", importc: "VkKeyScanExA".} proc MapVirtualKeyA*(uCode: WINUINT, uMapType: WINUINT): WINUINT{.stdcall, dynlib: "user32", importc: "MapVirtualKeyA".} @@ -14772,7 +14772,7 @@ proc DialogBoxA*(hInstance: HINST, lpTemplateName: LPCSTR, hWndParent: HWND, lpDialogFunc: DLGPROC): int32 proc DialogBoxIndirectA*(hInstance: HINST, hDialogTemplate: LPCDLGTEMPLATE, hWndParent: HWND, lpDialogFunc: DLGPROC): int32 -proc CreateDCA*(para1: LPCSTR, para2: LPCSTR, para3: LPCSTR, para4: pDEVMODE): HDC{. +proc CreateDCA*(para1: LPCSTR, para2: LPCSTR, para3: LPCSTR, para4: PDEVMODE): HDC{. stdcall, dynlib: "gdi32", importc: "CreateDCA".} proc VerInstallFileA*(uFlags: DWORD, szSrcFileName: LPSTR, szDestFileName: LPSTR, szSrcDir: LPSTR, szDestDir: LPSTR, @@ -14933,7 +14933,7 @@ proc WriteConsoleOutputCharacterA*(hConsoleOutput: HANDLE, lpCharacter: LPCSTR, nLength: DWORD, dwWriteCoord: COORD, lpNumberOfCharsWritten: LPDWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WriteConsoleOutputCharacterA".} -proc FillConsoleOutputCharacterA*(hConsoleOutput: HANDLE, cCharacter: CHAR, +proc FillConsoleOutputCharacterA*(hConsoleOutput: HANDLE, cCharacter: char, nLength: DWORD, dwWriteCoord: COORD, lpNumberOfCharsWritten: LPDWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "FillConsoleOutputCharacterA".} @@ -15896,7 +15896,7 @@ proc DialogBoxW*(hInstance: HINST, lpTemplate: LPCWSTR, hWndParent: HWND, lpDialogFunc: DLGPROC): int32 proc DialogBoxIndirectW*(hInstance: HINST, lpTemplate: LPCDLGTEMPLATE, hWndParent: HWND, lpDialogFunc: DLGPROC): int32 -proc CreateDCW*(para1: LPCWSTR, para2: LPCWSTR, para3: LPCWSTR, para4: pDEVMODEW): HDC{. +proc CreateDCW*(para1: LPCWSTR, para2: LPCWSTR, para3: LPCWSTR, para4: PDEVMODEW): HDC{. stdcall, dynlib: "gdi32", importc: "CreateDCW".} proc VerInstallFileW*(uFlags: DWORD, szSrcFileName: LPWSTR, szDestFileName: LPWSTR, szSrcDir: LPWSTR, @@ -17038,7 +17038,7 @@ when defined(winUnicode): lpDialogFunc: DLGPROC): int32 proc DialogBoxIndirect*(hInstance: HINST, lpTemplate: LPCDLGTEMPLATE, hWndParent: HWND, lpDialogFunc: DLGPROC): int32 - proc CreateDC*(para1: LPCWSTR, para2: LPCWSTR, para3: LPCWSTR, para4: pDEVMODE): HDC{. + proc CreateDC*(para1: LPCWSTR, para2: LPCWSTR, para3: LPCWSTR, para4: PDEVMODE): HDC{. stdcall, dynlib: "gdi32", importc: "CreateDCW".} proc VerInstallFile*(uFlags: DWORD, szSrcFileName: LPWSTR, szDestFileName: LPWSTR, szSrcDir: LPWSTR, @@ -17825,19 +17825,19 @@ else: importc: "CharNextA".} proc CharPrev*(lpszStart: LPCSTR, lpszCurrent: LPCSTR): LPSTR{.stdcall, dynlib: "user32", importc: "CharPrevA".} - proc IsCharAlpha*(ch: CHAR): WINBOOL{.stdcall, dynlib: "user32", + proc IsCharAlpha*(ch: char): WINBOOL{.stdcall, dynlib: "user32", importc: "IsCharAlphaA".} - proc IsCharAlphaNumeric*(ch: CHAR): WINBOOL{.stdcall, dynlib: "user32", + proc IsCharAlphaNumeric*(ch: char): WINBOOL{.stdcall, dynlib: "user32", importc: "IsCharAlphaNumericA".} - proc IsCharUpper*(ch: CHAR): WINBOOL{.stdcall, dynlib: "user32", + proc IsCharUpper*(ch: char): WINBOOL{.stdcall, dynlib: "user32", importc: "IsCharUpperA".} - proc IsCharLower*(ch: CHAR): WINBOOL{.stdcall, dynlib: "user32", + proc IsCharLower*(ch: char): WINBOOL{.stdcall, dynlib: "user32", importc: "IsCharLowerA".} proc GetKeyNameText*(lParam: LONG, lpString: LPSTR, nSize: int32): int32{. stdcall, dynlib: "user32", importc: "GetKeyNameTextA".} - proc VkKeyScan*(ch: CHAR): SHORT{.stdcall, dynlib: "user32", + proc VkKeyScan*(ch: char): SHORT{.stdcall, dynlib: "user32", importc: "VkKeyScanA".} - proc VkKeyScanEx*(ch: CHAR, dwhkl: HKL): SHORT{.stdcall, dynlib: "user32", + proc VkKeyScanEx*(ch: char, dwhkl: HKL): SHORT{.stdcall, dynlib: "user32", importc: "VkKeyScanExA".} proc MapVirtualKey*(uCode: WINUINT, uMapType: WINUINT): WINUINT{.stdcall, dynlib: "user32", importc: "MapVirtualKeyA".} @@ -18170,7 +18170,7 @@ else: lpDialogFunc: DLGPROC): int32 proc DialogBoxIndirect*(hInstance: HINST, hDialogTemplate: LPCDLGTEMPLATE, hWndParent: HWND, lpDialogFunc: DLGPROC): int32 - proc CreateDC*(para1: LPCSTR, para2: LPCSTR, para3: LPCSTR, para4: pDEVMODE): HDC{. + proc CreateDC*(para1: LPCSTR, para2: LPCSTR, para3: LPCSTR, para4: PDEVMODE): HDC{. stdcall, dynlib: "gdi32", importc: "CreateDCA".} proc VerInstallFile*(uFlags: DWORD, szSrcFileName: LPSTR, szDestFileName: LPSTR, szSrcDir: LPSTR, szDestDir: LPSTR, @@ -18332,7 +18332,7 @@ else: nLength: DWORD, dwWriteCoord: COORD, lpNumberOfCharsWritten: LPDWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WriteConsoleOutputCharacterA".} - proc FillConsoleOutputCharacter*(hConsoleOutput: HANDLE, cCharacter: CHAR, + proc FillConsoleOutputCharacter*(hConsoleOutput: HANDLE, cCharacter: char, nLength: DWORD, dwWriteCoord: COORD, lpNumberOfCharsWritten: LPDWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "FillConsoleOutputCharacterA".} @@ -18513,9 +18513,9 @@ proc DisableThreadLibraryCalls*(hLibModule: HMODULE): WINBOOL{.stdcall, proc GetProcAddress*(hModule: HINST, lpProcName: LPCSTR): FARPROC{.stdcall, dynlib: "kernel32", importc: "GetProcAddress".} proc GetVersion*(): DWORD{.stdcall, dynlib: "kernel32", importc: "GetVersion".} -proc GlobalAlloc*(uFlags: INT, dwBytes: DWORD): HGLOBAL{.stdcall, +proc GlobalAlloc*(uFlags: int32, dwBytes: DWORD): HGLOBAL{.stdcall, dynlib: "kernel32", importc: "GlobalAlloc".} -proc GlobalReAlloc*(hMem: HGLOBAL, dwBytes: DWORD, uFlags: INT): HGLOBAL{. +proc GlobalReAlloc*(hMem: HGLOBAL, dwBytes: DWORD, uFlags: int32): HGLOBAL{. stdcall, dynlib: "kernel32", importc: "GlobalReAlloc".} proc GlobalSize*(hMem: HGLOBAL): DWORD{.stdcall, dynlib: "kernel32", importc: "GlobalSize".} @@ -19678,7 +19678,7 @@ proc GetSysColor*(nIndex: int32): DWORD{.stdcall, dynlib: "user32", importc: "GetSysColor".} proc GetSysColorBrush*(nIndex: int32): HBRUSH{.stdcall, dynlib: "user32", importc: "GetSysColorBrush".} -proc SetSysColors*(cElements: int32, lpaElements: var wINT, +proc SetSysColors*(cElements: int32, lpaElements: var WINT, lpaRgbValues: var COLORREF): WINBOOL{.stdcall, dynlib: "user32", importc: "SetSysColors".} proc DrawFocusRect*(hDC: HDC, lprc: var RECT): WINBOOL{.stdcall, @@ -19878,7 +19878,7 @@ proc CreatePen*(para1: int32, para2: int32, para3: COLORREF): HPEN{.stdcall, dynlib: "gdi32", importc: "CreatePen".} proc CreatePenIndirect*(para1: var LOGPEN): HPEN{.stdcall, dynlib: "gdi32", importc: "CreatePenIndirect".} -proc CreatePolyPolygonRgn*(para1: var POINT, para2: var wINT, para3: int32, +proc CreatePolyPolygonRgn*(para1: var POINT, para2: var WINT, para3: int32, para4: int32): HRGN{.stdcall, dynlib: "gdi32", importc: "CreatePolyPolygonRgn".} proc CreatePatternBrush*(para1: HBITMAP): HBRUSH{.stdcall, dynlib: "gdi32", @@ -20049,7 +20049,7 @@ proc PlayMetaFile*(para1: HDC, para2: HMETAFILE): WINBOOL{.stdcall, dynlib: "gdi32", importc: "PlayMetaFile".} proc PaintRgn*(para1: HDC, para2: HRGN): WINBOOL{.stdcall, dynlib: "gdi32", importc: "PaintRgn".} -proc PolyPolygon*(para1: HDC, para2: var POINT, para3: var wINT, para4: int32): WINBOOL{. +proc PolyPolygon*(para1: HDC, para2: var POINT, para3: var WINT, para4: int32): WINBOOL{. stdcall, dynlib: "gdi32", importc: "PolyPolygon".} proc PtInRegion*(para1: HRGN, para2: int32, para3: int32): WINBOOL{.stdcall, dynlib: "gdi32", importc: "PtInRegion".} @@ -20165,7 +20165,7 @@ proc GetEnhMetaFilePaletteEntries*(para1: HENHMETAFILE, para2: WINUINT, proc GetEnhMetaFileBits*(para1: HENHMETAFILE, para2: WINUINT, para3: LPBYTE): WINUINT{. stdcall, dynlib: "gdi32", importc: "GetEnhMetaFileBits".} proc GetWinMetaFileBits*(para1: HENHMETAFILE, para2: WINUINT, para3: LPBYTE, - para4: wINT, para5: HDC): WINUINT{.stdcall, + para4: WINT, para5: HDC): WINUINT{.stdcall, dynlib: "gdi32", importc: "GetWinMetaFileBits".} proc PlayEnhMetaFile*(para1: HDC, para2: HENHMETAFILE, para3: RECT): WINBOOL{. stdcall, dynlib: "gdi32", importc: "PlayEnhMetaFile".} @@ -20748,7 +20748,7 @@ proc ListView_GetColumn*(wnd: HWND, iCol: int32, col: var LV_COLUMN): LRESULT proc ListView_GetColumnWidth*(wnd: HWND, iCol: int32): LRESULT proc ListView_GetCountPerPage*(hwndLV: HWND): LRESULT proc ListView_GetEditControl*(hwndLV: HWND): LRESULT -proc ListView_GetImageList*(wnd: HWND, iImageList: wINT): LRESULT +proc ListView_GetImageList*(wnd: HWND, iImageList: WINT): LRESULT proc ListView_GetISearchString*(hwndLV: HWND, lpsz: LPTSTR): LRESULT proc ListView_GetItem*(wnd: HWND, item: var LV_ITEM): LRESULT proc ListView_GetItemCount*(wnd: HWND): LRESULT @@ -20867,13 +20867,13 @@ proc CommDlg_OpenSave_HideControl*(hdlg: HWND, id: int32): LRESULT proc CommDlg_OpenSave_SetDefExt*(hdlg: HWND, pszext: LPSTR): LRESULT proc GetNextWindow*(wnd: HWND, uCmd: WINUINT): HWND{.stdcall, dynlib: "user32", importc: "GetWindow".} -proc GlobalAllocPtr*(flags, cb: DWord): Pointer -proc GlobalFreePtr*(lp: Pointer): Pointer -proc GlobalUnlockPtr*(lp: pointer): Pointer -proc GlobalLockPtr*(lp: pointer): Pointer -proc GlobalReAllocPtr*(lp: Pointer, cbNew, flags: DWord): Pointer -proc GlobalPtrHandle*(lp: pointer): Pointer -proc SetLayeredWindowAttributes*(HWND: hwnd, crKey: COLORREF, bAlpha: int8, +proc GlobalAllocPtr*(flags, cb: DWord): pointer +proc GlobalFreePtr*(lp: pointer): pointer +proc GlobalUnlockPtr*(lp: pointer): pointer +proc GlobalLockPtr*(lp: pointer): pointer +proc GlobalReAllocPtr*(lp: pointer, cbNew, flags: DWord): pointer +proc GlobalPtrHandle*(lp: pointer): pointer +proc SetLayeredWindowAttributes*(hwnd: HWND, crKey: COLORREF, bAlpha: int8, dwFlags: DWORD): WINBOOL{.stdcall, dynlib: "user32", importc: "SetLayeredWindowAttributes".} type @@ -21059,21 +21059,21 @@ proc AllocateAndInitializeSid*(pIdentifierAuthority: TSIDIdentifierAuthority, nSubAuthorityCount: int8, nSubAuthority0, nSubAuthority1: DWORD, nSubAuthority2, nSubAuthority3, nSubAuthority4: DWORD, nSubAuthority5, - nSubAuthority6, nSubAuthority7: DWORD, pSid: var Pointer): WINBOOL{.stdcall, + nSubAuthority6, nSubAuthority7: DWORD, pSid: var pointer): WINBOOL{.stdcall, dynlib: "advapi32", importc: "AllocateAndInitializeSid".} proc AllocateLocallyUniqueId*(Luid: var TLargeInteger): WINBOOL{.stdcall, dynlib: "advapi32", importc: "AllocateLocallyUniqueId".} proc BackupRead*(hFile: THandle, lpBuffer: PByte, nNumberOfBytesToRead: DWORD, lpNumberOfBytesRead: var DWORD, bAbort: WINBOOL, - bProcessSecurity: WINBOOL, lpContext: var Pointer): WINBOOL{. + bProcessSecurity: WINBOOL, lpContext: var pointer): WINBOOL{. stdcall, dynlib: "kernel32", importc: "BackupRead".} proc BackupSeek*(hFile: THandle, dwLowBytesToSeek, dwHighBytesToSeek: DWORD, lpdwLowByteSeeked, lpdwHighByteSeeked: var DWORD, - lpContext: Pointer): WINBOOL{.stdcall, dynlib: "kernel32", + lpContext: pointer): WINBOOL{.stdcall, dynlib: "kernel32", importc: "BackupSeek".} proc BackupWrite*(hFile: THandle, lpBuffer: PByte, nNumberOfBytesToWrite: DWORD, lpNumberOfBytesWritten: var DWORD, - bAbort, bProcessSecurity: WINBOOL, lpContext: var Pointer): WINBOOL{. + bAbort, bProcessSecurity: WINBOOL, lpContext: var pointer): WINBOOL{. stdcall, dynlib: "kernel32", importc: "BackupWrite".} proc BeginPaint*(wnd: HWND, lpPaint: var TPaintStruct): HDC{.stdcall, dynlib: "user32", importc: "BeginPaint".} @@ -21098,18 +21098,18 @@ proc CallMsgFilterA*(lpMsg: var TMsg, nCode: int): WINBOOL{.stdcall, dynlib: "user32", importc: "CallMsgFilterA".} proc CallMsgFilterW*(lpMsg: var TMsg, nCode: int): WINBOOL{.stdcall, dynlib: "user32", importc: "CallMsgFilterW".} -proc CallNamedPipe*(lpNamedPipeName: cstring, lpInBuffer: Pointer, - nInBufferSize: DWORD, lpOutBuffer: Pointer, +proc CallNamedPipe*(lpNamedPipeName: cstring, lpInBuffer: pointer, + nInBufferSize: DWORD, lpOutBuffer: pointer, nOutBufferSize: DWORD, lpBytesRead: var DWORD, nTimeOut: DWORD): WINBOOL{.stdcall, dynlib: "kernel32", importc: "CallNamedPipeA".} -proc CallNamedPipeA*(lpNamedPipeName: LPCSTR, lpInBuffer: Pointer, - nInBufferSize: DWORD, lpOutBuffer: Pointer, +proc CallNamedPipeA*(lpNamedPipeName: LPCSTR, lpInBuffer: pointer, + nInBufferSize: DWORD, lpOutBuffer: pointer, nOutBufferSize: DWORD, lpBytesRead: var DWORD, nTimeOut: DWORD): WINBOOL{.stdcall, dynlib: "kernel32", importc: "CallNamedPipeA".} -proc CallNamedPipeW*(lpNamedPipeName: LPWSTR, lpInBuffer: Pointer, - nInBufferSize: DWORD, lpOutBuffer: Pointer, +proc CallNamedPipeW*(lpNamedPipeName: LPWSTR, lpInBuffer: pointer, + nInBufferSize: DWORD, lpOutBuffer: pointer, nOutBufferSize: DWORD, lpBytesRead: var DWORD, nTimeOut: DWORD): WINBOOL{.stdcall, dynlib: "kernel32", importc: "CallNamedPipeW".} @@ -21122,15 +21122,15 @@ proc ChangeDisplaySettingsA*(lpDevMode: var TDeviceModeA, dwFlags: DWORD): int32 stdcall, dynlib: "user32", importc: "ChangeDisplaySettingsA".} proc ChangeDisplaySettingsEx*(lpszDeviceName: cstring, lpDevMode: var TDeviceMode, wnd: HWND, - dwFlags: DWORD, lParam: Pointer): int32{.stdcall, + dwFlags: DWORD, lParam: pointer): int32{.stdcall, dynlib: "user32", importc: "ChangeDisplaySettingsExA".} proc ChangeDisplaySettingsExA*(lpszDeviceName: LPCSTR, lpDevMode: var TDeviceModeA, wnd: HWND, - dwFlags: DWORD, lParam: Pointer): int32{.stdcall, + dwFlags: DWORD, lParam: pointer): int32{.stdcall, dynlib: "user32", importc: "ChangeDisplaySettingsExA".} proc ChangeDisplaySettingsExW*(lpszDeviceName: LPWSTR, lpDevMode: var TDeviceModeW, wnd: HWND, - dwFlags: DWORD, lParam: Pointer): int32{.stdcall, + dwFlags: DWORD, lParam: pointer): int32{.stdcall, dynlib: "user32", importc: "ChangeDisplaySettingsExW".} proc ChangeDisplaySettingsW*(lpDevMode: var TDeviceModeW, dwFlags: DWORD): int32{. stdcall, dynlib: "user32", importc: "ChangeDisplaySettingsW".} @@ -21184,8 +21184,8 @@ proc CreateDialogIndirectParam*(hInstance: HINST, lpTemplate: TDlgTemplate, #function CreateDialogIndirectParamA(hInstance: HINST; const lpTemplate: TDlgTemplate; hWndParent: HWND; lpDialogFunc: TFNDlgProc; dwInitParam: LPARAM): HWND; stdcall; external 'user32' name 'CreateDialogIndirectParamA'; #function CreateDialogIndirectParamW(hInstance: HINST; const lpTemplate: TDlgTemplate; hWndParent: HWND; lpDialogFunc: TFNDlgProc; dwInitParam: LPARAM): HWND; stdcall; external 'user32' name 'CreateDialogIndirectParamW'; #function CreateDIBitmap(DC: HDC; var InfoHeader: TBitmapInfoHeader; dwUsage: DWORD; InitBits: PChar; var InitInfo: TBitmapInfo; wUsage: WINUINT): HBITMAP; stdcall; external 'gdi32' name 'CreateDIBitmap'; - #function CreateDIBPatternBrushPt(const p1: Pointer; p2: WINUINT): HBRUSH; stdcall; external 'gdi32' name 'CreateDIBPatternBrushPt'; - #function CreateDIBSection(DC: HDC; const p2: TBitmapInfo; p3: WINUINT; var p4: Pointer; p5: THandle; p6: DWORD): HBITMAP; stdcall; external 'gdi32' name 'CreateDIBSection'; + #function CreateDIBPatternBrushPt(const p1: pointer; p2: WINUINT): HBRUSH; stdcall; external 'gdi32' name 'CreateDIBPatternBrushPt'; + #function CreateDIBSection(DC: HDC; const p2: TBitmapInfo; p3: WINUINT; var p4: pointer; p5: THandle; p6: DWORD): HBITMAP; stdcall; external 'gdi32' name 'CreateDIBSection'; #function CreateEllipticRgnIndirect(const p1: TRect): HRGN; stdcall; external 'gdi32' name 'CreateEllipticRgnIndirect'; #function CreateFontIndirect(const p1: TLogFont): HFONT;stdcall; external 'gdi32' name 'CreateFontIndirectA'; #function CreateFontIndirectA(const p1: TLogFontA): HFONT; stdcall; external 'gdi32' name 'CreateFontIndirectA'; @@ -21211,39 +21211,39 @@ proc CreatePolyPolygonRgn*(pPtStructs: pointer, pIntArray: pointer, p3, p4: int) proc CreateProcess*(lpApplicationName: cstring, lpCommandLine: cstring, lpProcessAttributes, lpThreadAttributes: PSecurityAttributes, bInheritHandles: WINBOOL, dwCreationFlags: DWORD, - lpEnvironment: Pointer, lpCurrentDirectory: cstring, + lpEnvironment: pointer, lpCurrentDirectory: cstring, lpStartupInfo: TStartupInfo, lpProcessInformation: var TProcessInformation): WINBOOL{. stdcall, dynlib: "kernel32", importc: "CreateProcessA".} proc CreateProcessA*(lpApplicationName: LPCSTR, lpCommandLine: LPCSTR, lpProcessAttributes, lpThreadAttributes: PSecurityAttributes, bInheritHandles: WINBOOL, dwCreationFlags: DWORD, - lpEnvironment: Pointer, lpCurrentDirectory: LPCSTR, + lpEnvironment: pointer, lpCurrentDirectory: LPCSTR, lpStartupInfo: TStartupInfo, lpProcessInformation: var TProcessInformation): WINBOOL{. stdcall, dynlib: "kernel32", importc: "CreateProcessA".} #function CreateProcessAsUser(hToken: THandle; lpApplicationName: PChar; lpCommandLine: PChar; lpProcessAttributes: PSecurityAttributes; lpThreadAttributes: PSecurityAttributes; bInheritHandles: WINBOOL; dwCreationFlags: DWORD; - # lpEnvironment: Pointer; lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation): WINBOOL;stdcall; external 'advapi32' name 'CreateProcessAsUserA'; + # lpEnvironment: pointer; lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation): WINBOOL;stdcall; external 'advapi32' name 'CreateProcessAsUserA'; #function CreateProcessAsUserA(hToken: THandle; lpApplicationName: LPCSTR; lpCommandLine: LPCSTR; lpProcessAttributes: PSecurityAttributes; lpThreadAttributes: PSecurityAttributes; bInheritHandles: WINBOOL; dwCreationFlags: DWORD; - # lpEnvironment: Pointer; lpCurrentDirectory: LPCSTR; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation): WINBOOL; stdcall; external 'advapi32' name 'CreateProcessAsUserA'; + # lpEnvironment: pointer; lpCurrentDirectory: LPCSTR; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation): WINBOOL; stdcall; external 'advapi32' name 'CreateProcessAsUserA'; #function CreateProcessAsUserW(hToken: THandle; lpApplicationName: LPWSTR; lpCommandLine: LPWSTR; lpProcessAttributes: PSecurityAttributes; lpThreadAttributes: PSecurityAttributes; bInheritHandles: WINBOOL; dwCreationFlags: DWORD; - # lpEnvironment: Pointer; lpCurrentDirectory: LPWSTR; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation): WINBOOL; stdcall; external 'advapi32' name 'CreateProcessAsUserW'; + # lpEnvironment: pointer; lpCurrentDirectory: LPWSTR; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation): WINBOOL; stdcall; external 'advapi32' name 'CreateProcessAsUserW'; proc CreateProcessW*(lpApplicationName: LPWSTR, lpCommandLine: LPWSTR, lpProcessAttributes, lpThreadAttributes: PSecurityAttributes, bInheritHandles: WINBOOL, dwCreationFlags: DWORD, - lpEnvironment: Pointer, lpCurrentDirectory: LPWSTR, + lpEnvironment: pointer, lpCurrentDirectory: LPWSTR, lpStartupInfo: TStartupInfo, lpProcessInformation: var TProcessInformation): WINBOOL{. stdcall, dynlib: "kernel32", importc: "CreateProcessW".} #function CreateRectRgnIndirect(const p1: TRect): HRGN; stdcall; external 'gdi32' name 'CreateRectRgnIndirect'; -proc CreateRemoteThread*(hProcess: THandle, lpThreadAttributes: Pointer, +proc CreateRemoteThread*(hProcess: THandle, lpThreadAttributes: pointer, dwStackSize: DWORD, lpStartAddress: TFNThreadStartRoutine, - lpParameter: Pointer, dwCreationFlags: DWORD, + lpParameter: pointer, dwCreationFlags: DWORD, lpThreadId: var DWORD): THandle{.stdcall, dynlib: "kernel32", importc: "CreateRemoteThread".} -proc CreateThread*(lpThreadAttributes: Pointer, dwStackSize: DWORD, - lpStartAddress: TFNThreadStartRoutine, lpParameter: Pointer, +proc CreateThread*(lpThreadAttributes: pointer, dwStackSize: DWORD, + lpStartAddress: TFNThreadStartRoutine, lpParameter: pointer, dwCreationFlags: DWORD, lpThreadId: var DWORD): THandle{. stdcall, dynlib: "kernel32", importc: "CreateThread".} proc DdeSetQualityOfService*(hWndClient: HWnd, @@ -21256,8 +21256,8 @@ proc DescribePixelFormat*(DC: HDC, p2: int, p3: WINUINT, dynlib: "gdi32", importc: "DescribePixelFormat".} #function DestroyPrivateObjectSecurity(var ObjectDescriptor: PSecurityDescriptor): WINBOOL; stdcall; external 'advapi32' name 'DestroyPrivateObjectSecurity'; proc DeviceIoControl*(hDevice: THandle, dwIoControlCode: DWORD, - lpInBuffer: Pointer, nInBufferSize: DWORD, - lpOutBuffer: Pointer, nOutBufferSize: DWORD, + lpInBuffer: pointer, nInBufferSize: DWORD, + lpOutBuffer: pointer, nOutBufferSize: DWORD, lpBytesReturned: var DWORD, lpOverlapped: POverlapped): WINBOOL{. stdcall, dynlib: "kernel32", importc: "DeviceIoControl".} proc DialogBoxIndirectParam*(hInstance: HINST, lpDialogTemplate: TDlgTemplate, @@ -21311,9 +21311,9 @@ proc DrawTextW*(hDC: HDC, lpString: LPWSTR, nCount: int, lpRect: var TRect, # stdcall; external 'advapi32' name 'DuplicateTokenEx'; proc EndPaint*(wnd: HWND, lpPaint: TPaintStruct): WINBOOL{.stdcall, dynlib: "user32", importc: "EndPaint".} - #function EnumDisplayDevices(Unused: Pointer; iDevNum: DWORD; var lpDisplayDevice: TDisplayDevice; dwFlags: DWORD): WINBOOL;stdcall; external 'user32' name 'EnumDisplayDevicesA'; - #function EnumDisplayDevicesA(Unused: Pointer; iDevNum: DWORD; var lpDisplayDevice: TDisplayDeviceA; dwFlags: DWORD): WINBOOL;stdcall; external 'user32' name 'EnumDisplayDevicesA'; - #function EnumDisplayDevicesW(Unused: Pointer; iDevNum: DWORD; var lpDisplayDevice: TDisplayDeviceW; dwFlags: DWORD): WINBOOL;stdcall; external 'user32' name 'EnumDisplayDevicesW'; + #function EnumDisplayDevices(Unused: pointer; iDevNum: DWORD; var lpDisplayDevice: TDisplayDevice; dwFlags: DWORD): WINBOOL;stdcall; external 'user32' name 'EnumDisplayDevicesA'; + #function EnumDisplayDevicesA(Unused: pointer; iDevNum: DWORD; var lpDisplayDevice: TDisplayDeviceA; dwFlags: DWORD): WINBOOL;stdcall; external 'user32' name 'EnumDisplayDevicesA'; + #function EnumDisplayDevicesW(Unused: pointer; iDevNum: DWORD; var lpDisplayDevice: TDisplayDeviceW; dwFlags: DWORD): WINBOOL;stdcall; external 'user32' name 'EnumDisplayDevicesW'; proc EnumDisplaySettings*(lpszDeviceName: cstring, iModeNum: DWORD, lpDevMode: var TDeviceMode): WINBOOL{.stdcall, dynlib: "user32", importc: "EnumDisplaySettingsA".} @@ -21323,13 +21323,13 @@ proc EnumDisplaySettingsA*(lpszDeviceName: LPCSTR, iModeNum: DWORD, proc EnumDisplaySettingsW*(lpszDeviceName: LPWSTR, iModeNum: DWORD, lpDevMode: var TDeviceModeW): WINBOOL{.stdcall, dynlib: "user32", importc: "EnumDisplaySettingsW".} - #function EnumEnhMetaFile(DC: HDC; p2: HENHMETAFILE; p3: TFNEnhMFEnumProc; p4: Pointer; const p5: TRect): WINBOOL; stdcall; external 'gdi32' name 'EnumEnhMetaFile'; + #function EnumEnhMetaFile(DC: HDC; p2: HENHMETAFILE; p3: TFNEnhMFEnumProc; p4: pointer; const p5: TRect): WINBOOL; stdcall; external 'gdi32' name 'EnumEnhMetaFile'; #function EnumFontFamiliesEx(DC: HDC; var p2: TLogFont; p3: TFNFontEnumProc; p4: LPARAM; p5: DWORD): WINBOOL;stdcall; external 'gdi32' name 'EnumFontFamiliesExA'; #function EnumFontFamiliesExA(DC: HDC; var p2: TLogFontA; p3: TFNFontEnumProcA; p4: LPARAM; p5: DWORD): WINBOOL; stdcall; external 'gdi32' name 'EnumFontFamiliesExA'; #function EnumFontFamiliesExW(DC: HDC; var p2: TLogFontW; p3: TFNFontEnumProcW; p4: LPARAM; p5: DWORD): WINBOOL; stdcall; external 'gdi32' name 'EnumFontFamiliesExW'; #function EqualRect(const lprc1, lprc2: TRect): WINBOOL; stdcall; external 'user32' name 'EqualRect'; proc ExtCreatePen*(PenStyle, Width: DWORD, Brush: TLogBrush, StyleCount: DWORD, - Style: Pointer): HPEN{.stdcall, dynlib: "gdi32", + Style: pointer): HPEN{.stdcall, dynlib: "gdi32", importc: "ExtCreatePen".} proc ExtCreateRegion*(p1: PXForm, p2: DWORD, p3: TRgnData): HRGN{.stdcall, dynlib: "gdi32", importc: "ExtCreateRegion".} @@ -21346,7 +21346,7 @@ proc FillConsoleOutputAttribute*(hConsoleOutput: THandle, wAttribute: int16, nLength: DWORD, dwWriteCoord: TCoord, lpNumberOfAttrsWritten: var DWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "FillConsoleOutputAttribute".} -proc FillConsoleOutputCharacter*(hConsoleOutput: THandle, cCharacter: Char, +proc FillConsoleOutputCharacter*(hConsoleOutput: THandle, cCharacter: char, nLength: DWORD, dwWriteCoord: TCoord, lpNumberOfCharsWritten: var DWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "FillConsoleOutputCharacterA".} @@ -21365,18 +21365,18 @@ proc FindFirstFileA*(lpFileName: LPCSTR, lpFindFileData: var TWIN32FindDataA): T stdcall, dynlib: "kernel32", importc: "FindFirstFileA".} proc FindFirstFileW*(lpFileName: LPWSTR, lpFindFileData: var TWIN32FindDataW): THandle{. stdcall, dynlib: "kernel32", importc: "FindFirstFileW".} - #function FindFirstFreeAce(var pAcl: TACL; var pAce: Pointer): WINBOOL; stdcall; external 'advapi32' name 'FindFirstFreeAce'; + #function FindFirstFreeAce(var pAcl: TACL; var pAce: pointer): WINBOOL; stdcall; external 'advapi32' name 'FindFirstFreeAce'; proc FindNextFile*(hFindFile: THandle, lpFindFileData: var TWIN32FindData): WINBOOL{. stdcall, dynlib: "kernel32", importc: "FindNextFileA".} proc FindNextFileA*(hFindFile: THandle, lpFindFileData: var TWIN32FindDataA): WINBOOL{. stdcall, dynlib: "kernel32", importc: "FindNextFileA".} proc FindNextFileW*(hFindFile: THandle, lpFindFileData: var TWIN32FindDataW): WINBOOL{. stdcall, dynlib: "kernel32", importc: "FindNextFileW".} - #function FlushInstructionCache(hProcess: THandle; const lpBaseAddress: Pointer; dwSize: DWORD): WINBOOL; stdcall; external 'kernel32' name 'FlushInstructionCache'; - #function FlushViewOfFile(const lpBaseAddress: Pointer; dwNumberOfBytesToFlush: DWORD): WINBOOL; stdcall; external 'kernel32' name 'FlushViewOfFile'; + #function FlushInstructionCache(hProcess: THandle; const lpBaseAddress: pointer; dwSize: DWORD): WINBOOL; stdcall; external 'kernel32' name 'FlushInstructionCache'; + #function FlushViewOfFile(const lpBaseAddress: pointer; dwNumberOfBytesToFlush: DWORD): WINBOOL; stdcall; external 'kernel32' name 'FlushViewOfFile'; #function FrameRect(hDC: HDC; const lprc: TRect; hbr: HBRUSH): Integer; stdcall; external 'user32' name 'FrameRect'; - #function GetAce(const pAcl: TACL; dwAceIndex: DWORD; var pAce: Pointer): WINBOOL; stdcall; external 'advapi32' name 'GetAce'; - #function GetAclInformation(const pAcl: TACL; pAclInformation: Pointer; nAclInformationLength: DWORD; dwAclInformationClass: TAclInformationClass): WINBOOL; stdcall; external 'advapi32' name 'GetAclInformation'; + #function GetAce(const pAcl: TACL; dwAceIndex: DWORD; var pAce: pointer): WINBOOL; stdcall; external 'advapi32' name 'GetAce'; + #function GetAclInformation(const pAcl: TACL; pAclInformation: pointer; nAclInformationLength: DWORD; dwAclInformationClass: TAclInformationClass): WINBOOL; stdcall; external 'advapi32' name 'GetAclInformation'; #function GetAltTabInfo(wnd: HWND; iItem: Integer; var pati: TAltTabInfo; pszItemText: PChar; cchItemText: WINUINT): WINBOOL;stdcall; external 'user32' name 'GetAltTabInfoA'; #function GetAltTabInfoA(wnd: HWND; iItem: Integer; var pati: TAltTabInfo; pszItemText: LPCSTR; cchItemText: WINUINT): WINBOOL;stdcall; external 'user32' name 'GetAltTabInfoA'; #function GetAltTabInfoW(wnd: HWND; iItem: Integer; var pati: TAltTabInfo; pszItemText: LPWSTR; cchItemText: WINUINT): WINBOOL;stdcall; external 'user32' name 'GetAltTabInfoW'; @@ -21507,7 +21507,7 @@ proc GetDefaultCommConfigW*(lpszName: LPWSTR, lpCC: var TCommConfig, proc GetDIBColorTable*(DC: HDC, p2, p3: WINUINT, RGBQuadStructs: pointer): WINUINT{. stdcall, dynlib: "gdi32", importc: "GetDIBColorTable".} proc GetDIBits*(DC: HDC, Bitmap: HBitmap, StartScan, NumScans: WINUINT, - Bits: Pointer, BitInfo: var TBitmapInfo, Usage: WINUINT): int{. + Bits: pointer, BitInfo: var TBitmapInfo, Usage: WINUINT): int{. stdcall, dynlib: "gdi32", importc: "GetDIBits".} proc GetDiskFreeSpace*(lpRootPathName: cstring, lpSectorsPerCluster, lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters: var DWORD): WINBOOL{. @@ -21531,13 +21531,13 @@ proc GetDiskFreeSpaceW*(lpRootPathName: LPWSTR, lpSectorsPerCluster, lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters: var DWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "GetDiskFreeSpaceW".} proc GetDiskFreeSpaceEx*(lpDirectoryName: cstring, lpFreeBytesAvailableToCaller, - lpTotalNumberOfBytes: pLargeInteger, lpTotalNumberOfFreeBytes: PLargeInteger): WINBOOL{. + lpTotalNumberOfBytes: PLargeInteger, lpTotalNumberOfFreeBytes: PLargeInteger): WINBOOL{. stdcall, dynlib: "kernel32", importc: "GetDiskFreeSpaceExA".} proc GetDiskFreeSpaceExA*(lpDirectoryName: LPCSTR, lpFreeBytesAvailableToCaller, - lpTotalNumberOfBytes: pLargeInteger, lpTotalNumberOfFreeBytes: PLargeInteger): WINBOOL{. + lpTotalNumberOfBytes: PLargeInteger, lpTotalNumberOfFreeBytes: PLargeInteger): WINBOOL{. stdcall, dynlib: "kernel32", importc: "GetDiskFreeSpaceExA".} proc GetDiskFreeSpaceExW*(lpDirectoryName: LPWSTR, lpFreeBytesAvailableToCaller, - lpTotalNumberOfBytes: pLargeInteger, lpTotalNumberOfFreeBytes: PLargeInteger): WINBOOL{. + lpTotalNumberOfBytes: PLargeInteger, lpTotalNumberOfFreeBytes: PLargeInteger): WINBOOL{. stdcall, dynlib: "kernel32", importc: "GetDiskFreeSpaceExW".} #function GetEnhMetaFilePixelFormat(p1: HENHMETAFILE; p2: Cardinal; var p3: TPixelFormatDescriptor): WINUINT;stdcall; external 'gdi32' name 'GetEnhMetaFilePixelFormat'; proc GetExitCodeProcess*(hProcess: THandle, lpExitCode: var DWORD): WINBOOL{. @@ -21560,13 +21560,13 @@ proc GetFileVersionInfoSizeW*(lptstrFilename: LPWSTR, lpdwHandle: var DWORD): DW # function GetFullPathNameA(lpFileName: LPCSTR; nBufferLength: DWORD; lpBuffer: LPCSTR; var lpFilePart: LPCSTR): DWORD; stdcall; external 'kernel32' name 'GetFullPathNameA'; # function GetFullPathNameW(lpFileName: LPWSTR; nBufferLength: DWORD; lpBuffer: LPWSTR; var lpFilePart: LPWSTR): DWORD; stdcall; external 'kernel32' name 'GetFullPathNameW'; proc GetGlyphOutline*(DC: HDC, p2, p3: WINUINT, p4: TGlyphMetrics, p5: DWORD, - p6: Pointer, p7: TMat2): DWORD{.stdcall, dynlib: "gdi32", + p6: pointer, p7: TMat2): DWORD{.stdcall, dynlib: "gdi32", importc: "GetGlyphOutlineA".} proc GetGlyphOutlineA*(DC: HDC, p2, p3: WINUINT, p4: TGlyphMetrics, p5: DWORD, - p6: Pointer, p7: TMat2): DWORD{.stdcall, dynlib: "gdi32", + p6: pointer, p7: TMat2): DWORD{.stdcall, dynlib: "gdi32", importc: "GetGlyphOutlineA".} proc GetGlyphOutlineW*(DC: HDC, p2, p3: WINUINT, p4: TGlyphMetrics, p5: DWORD, - p6: Pointer, p7: TMat2): DWORD{.stdcall, dynlib: "gdi32", + p6: pointer, p7: TMat2): DWORD{.stdcall, dynlib: "gdi32", importc: "GetGlyphOutlineW".} #function GetGUIThreadInfo(idThread: DWORD; var pgui: TGUIThreadinfo): WINBOOL;stdcall; external 'user32' name 'GetGUIThreadInfo'; proc GetHandleInformation*(hObject: THandle, lpdwFlags: var DWORD): WINBOOL{. @@ -21600,9 +21600,9 @@ proc GetLogColorSpaceA*(p1: HCOLORSPACE, ColorSpace: var TLogColorSpaceA, Size: DWORD): WINBOOL{.stdcall, dynlib: "gdi32", importc: "GetLogColorSpaceA".} #function GetLogColorSpaceW(p1: HCOLORSPACE; var ColorSpace: TLogColorSpaceW; Size: DWORD): WINBOOL; stdcall; external 'gdi32' name 'GetLogColorSpaceW'; -proc GetMailslotInfo*(hMailslot: THandle, lpMaxMessageSize: Pointer, +proc GetMailslotInfo*(hMailslot: THandle, lpMaxMessageSize: pointer, lpNextSize: var DWORD, - lpMessageCount, lpReadTimeout: Pointer): WINBOOL{.stdcall, + lpMessageCount, lpReadTimeout: pointer): WINBOOL{.stdcall, dynlib: "kernel32", importc: "GetMailslotInfo".} #function GetMenuBarInfo(hend: HWND; idObject, idItem: Longint; var pmbi: TMenuBarInfo): WINBOOL;stdcall; external 'user32' name 'GetMenuBarInfo'; #function GetMenuInfo(menu: HMENU; var lpmi: TMenuInfo): WINBOOL;stdcall; external 'user32' name 'GetMenuInfo'; @@ -21625,7 +21625,7 @@ proc GetMiterLimit*(DC: HDC, Limit: var float32): WINBOOL{.stdcall, dynlib: "gdi32", importc: "GetMiterLimit".} #function GetMouseMovePoints(cbSize: WINUINT; var lppt, lpptBuf: TMouseMovePoint; nBufPoints: Integer; resolution: DWORD): Integer;stdcall; external 'user32' name 'GetMouseMovePoints'; proc GetNamedPipeInfo*(hNamedPipe: THandle, lpFlags: var DWORD, - lpOutBufferSize, lpInBufferSize, lpMaxInstances: Pointer): WINBOOL{. + lpOutBufferSize, lpInBufferSize, lpMaxInstances: pointer): WINBOOL{. stdcall, dynlib: "kernel32", importc: "GetNamedPipeInfo".} proc GetNumberOfConsoleInputEvents*(hConsoleInput: THandle, lpNumberOfEvents: var DWORD): WINBOOL{. @@ -21738,11 +21738,11 @@ proc GetTabbedTextExtentW*(hDC: HDC, lpString: LPWSTR, lpnTabStopPositions: pointer): DWORD{.stdcall, dynlib: "user32", importc: "GetTabbedTextExtentW".} proc GetTapeParameters*(hDevice: THandle, dwOperation: DWORD, - lpdwSize: var DWORD, lpTapeInformation: Pointer): DWORD{. + lpdwSize: var DWORD, lpTapeInformation: pointer): DWORD{. stdcall, dynlib: "kernel32", importc: "GetTapeParameters".} proc GetTapePosition*(hDevice: THandle, dwPositionType: DWORD, lpdwPartition, lpdwOffsetLow: var DWORD, - lpdwOffsetHigh: Pointer): DWORD{.stdcall, + lpdwOffsetHigh: pointer): DWORD{.stdcall, dynlib: "kernel32", importc: "GetTapePosition".} proc GetTextExtentExPoint*(DC: HDC, p2: cstring, p3, p4: int, p5, p6: PInteger, p7: var TSize): WINBOOL{.stdcall, dynlib: "gdi32", @@ -21784,7 +21784,7 @@ proc GetThreadTimes*(hThread: THandle, lpCreationTime, lpExitTime, lpKernelTime, proc GetTimeZoneInformation*(lpTimeZoneInformation: var TTimeZoneInformation): DWORD{. stdcall, dynlib: "kernel32", importc: "GetTimeZoneInformation".} #function GetTitleBarInfo(wnd: HWND; var pti: TTitleBarInfo): WINBOOL;stdcall; external 'user32' name 'GetTitleBarInfo'; - #function GetTokenInformation(TokenHandle: THandle; TokenInformationClass: TTokenInformationClass; TokenInformation: Pointer; TokenInformationLength: DWORD; var ReturnLength: DWORD): WINBOOL; stdcall; external 'advapi32' name 'GetTokenInformation'; + #function GetTokenInformation(TokenHandle: THandle; TokenInformationClass: TTokenInformationClass; TokenInformation: pointer; TokenInformationLength: DWORD; var ReturnLength: DWORD): WINBOOL; stdcall; external 'advapi32' name 'GetTokenInformation'; proc GetUpdateRect*(wnd: HWND, lpRect: var TRect, bErase: WINBOOL): WINBOOL{. stdcall, dynlib: "user32", importc: "GetUpdateRect".} proc GetUserName*(lpBuffer: cstring, nSize: var DWORD): WINBOOL{.stdcall, @@ -21793,13 +21793,13 @@ proc GetUserNameA*(lpBuffer: LPCSTR, nSize: var DWORD): WINBOOL{.stdcall, dynlib: "advapi32", importc: "GetUserNameA".} proc GetUserNameW*(lpBuffer: LPWSTR, nSize: var DWORD): WINBOOL{.stdcall, dynlib: "advapi32", importc: "GetUserNameW".} -proc GetUserObjectInformation*(hObj: THandle, nIndex: int, pvInfo: Pointer, +proc GetUserObjectInformation*(hObj: THandle, nIndex: int, pvInfo: pointer, nLength: DWORD, lpnLengthNeeded: var DWORD): WINBOOL{. stdcall, dynlib: "user32", importc: "GetUserObjectInformationA".} -proc GetUserObjectInformationA*(hObj: THandle, nIndex: int, pvInfo: Pointer, +proc GetUserObjectInformationA*(hObj: THandle, nIndex: int, pvInfo: pointer, nLength: DWORD, lpnLengthNeeded: var DWORD): WINBOOL{. stdcall, dynlib: "user32", importc: "GetUserObjectInformationA".} -proc GetUserObjectInformationW*(hObj: THandle, nIndex: int, pvInfo: Pointer, +proc GetUserObjectInformationW*(hObj: THandle, nIndex: int, pvInfo: pointer, nLength: DWORD, lpnLengthNeeded: var DWORD): WINBOOL{. stdcall, dynlib: "user32", importc: "GetUserObjectInformationW".} proc GetUserObjectSecurity*(hObj: THandle, pSIRequested: var DWORD, @@ -21845,7 +21845,7 @@ proc GetWindowRect*(wnd: HWND, lpRect: var TRect): WINBOOL{.stdcall, dynlib: "user32", importc: "GetWindowRect".} proc GetWorldTransform*(DC: HDC, p2: var TXForm): WINBOOL{.stdcall, dynlib: "gdi32", importc: "GetWorldTransform".} - #function GradientFill(DC: HDC; var p2: TTriVertex; p3: ULONG; p4: Pointer; p5, p6: ULONG): WINBOOL;stdcall; external 'gdi32' name 'GradientFill'; + #function GradientFill(DC: HDC; var p2: TTriVertex; p3: ULONG; p4: pointer; p5, p6: ULONG): WINBOOL;stdcall; external 'gdi32' name 'GradientFill'; proc GlobalMemoryStatus*(Buffer: var MEMORYSTATUS){.stdcall, dynlib: "kernel32", importc: "GlobalMemoryStatus".} proc HeapWalk*(hHeap: THandle, lpEntry: var TProcessHeapEntry): WINBOOL{. @@ -21856,7 +21856,7 @@ proc InflateRect*(lprc: var TRect, dx, dy: int): WINBOOL{.stdcall, dynlib: "user32", importc: "InflateRect".} proc InitializeAcl*(pAcl: var TACL, nAclLength, dwAclRevision: DWORD): WINBOOL{. stdcall, dynlib: "advapi32", importc: "InitializeAcl".} -proc InitializeSid*(Sid: Pointer, pIdentifierAuthority: TSIDIdentifierAuthority, +proc InitializeSid*(Sid: pointer, pIdentifierAuthority: TSIDIdentifierAuthority, nSubAuthorityCount: int8): WINBOOL{.stdcall, dynlib: "advapi32", importc: "InitializeSid".} proc InsertMenuItemA*(p1: HMENU, p2: WINUINT, p3: WINBOOL, p4: TMenuItemInfoA): WINBOOL{. @@ -21958,7 +21958,7 @@ proc MakeAbsoluteSD*(pSelfRelativeSecurityDescriptor: PSecurityDescriptor, pDacl: var TACL, lpdwDaclSize: var DWORD, pSacl: var TACL, lpdwSaclSize: var DWORD, pOwner: PSID, - lpdwOwnerSize: var DWORD, pPrimaryGroup: Pointer, + lpdwOwnerSize: var DWORD, pPrimaryGroup: pointer, lpdwPrimaryGroupSize: var DWORD): WINBOOL{.stdcall, dynlib: "advapi32", importc: "MakeAbsoluteSD".} proc MakeSelfRelativeSD*(pAbsoluteSecurityDescriptor: PSecurityDescriptor, @@ -21983,7 +21983,7 @@ proc MsgWaitForMultipleObjectsEx*(nCount: DWORD, pHandles: pointer, dwMilliseconds, dwWakeMask, dwFlags: DWORD): DWORD{. stdcall, dynlib: "user32", importc: "MsgWaitForMultipleObjectsEx".} # function MultiByteToWideChar(CodePage: WINUINT; dwFlags: DWORD; const lpMultiByteStr: LPCSTR; cchMultiByte: Integer; lLPWSTRStr: LPWSTR; cchWideChar: Integer): Integer; stdcall; external 'kernel32' name 'MultiByteToWideChar'; -proc ObjectOpenAuditAlarm*(SubsystemName: cstring, HandleId: Pointer, +proc ObjectOpenAuditAlarm*(SubsystemName: cstring, HandleId: pointer, ObjectTypeName: cstring, ObjectName: cstring, pSecurityDescriptor: PSecurityDescriptor, ClientToken: THandle, @@ -21992,7 +21992,7 @@ proc ObjectOpenAuditAlarm*(SubsystemName: cstring, HandleId: Pointer, ObjectCreation, AccessGranted: WINBOOL, GenerateOnClose: var WINBOOL): WINBOOL{.stdcall, dynlib: "advapi32", importc: "ObjectOpenAuditAlarmA".} -proc ObjectOpenAuditAlarmA*(SubsystemName: LPCSTR, HandleId: Pointer, +proc ObjectOpenAuditAlarmA*(SubsystemName: LPCSTR, HandleId: pointer, ObjectTypeName: LPCSTR, ObjectName: LPCSTR, pSecurityDescriptor: PSecurityDescriptor, ClientToken: THandle, @@ -22001,7 +22001,7 @@ proc ObjectOpenAuditAlarmA*(SubsystemName: LPCSTR, HandleId: Pointer, ObjectCreation, AccessGranted: WINBOOL, GenerateOnClose: var WINBOOL): WINBOOL{.stdcall, dynlib: "advapi32", importc: "ObjectOpenAuditAlarmA".} -proc ObjectOpenAuditAlarmW*(SubsystemName: LPWSTR, HandleId: Pointer, +proc ObjectOpenAuditAlarmW*(SubsystemName: LPWSTR, HandleId: pointer, ObjectTypeName: LPWSTR, ObjectName: LPWSTR, pSecurityDescriptor: PSecurityDescriptor, ClientToken: THandle, @@ -22010,17 +22010,17 @@ proc ObjectOpenAuditAlarmW*(SubsystemName: LPWSTR, HandleId: Pointer, ObjectCreation, AccessGranted: WINBOOL, GenerateOnClose: var WINBOOL): WINBOOL{.stdcall, dynlib: "advapi32", importc: "ObjectOpenAuditAlarmW".} -proc ObjectPrivilegeAuditAlarm*(SubsystemName: cstring, HandleId: Pointer, +proc ObjectPrivilegeAuditAlarm*(SubsystemName: cstring, HandleId: pointer, ClientToken: THandle, DesiredAccess: DWORD, Privileges: var TPrivilegeSet, AccessGranted: WINBOOL): WINBOOL{.stdcall, dynlib: "advapi32", importc: "ObjectPrivilegeAuditAlarmA".} -proc ObjectPrivilegeAuditAlarmA*(SubsystemName: LPCSTR, HandleId: Pointer, +proc ObjectPrivilegeAuditAlarmA*(SubsystemName: LPCSTR, HandleId: pointer, ClientToken: THandle, DesiredAccess: DWORD, Privileges: var TPrivilegeSet, AccessGranted: WINBOOL): WINBOOL{.stdcall, dynlib: "advapi32", importc: "ObjectPrivilegeAuditAlarmA".} -proc ObjectPrivilegeAuditAlarmW*(SubsystemName: LPWSTR, HandleId: Pointer, +proc ObjectPrivilegeAuditAlarmW*(SubsystemName: LPWSTR, HandleId: pointer, ClientToken: THandle, DesiredAccess: DWORD, Privileges: var TPrivilegeSet, AccessGranted: WINBOOL): WINBOOL{.stdcall, @@ -22111,21 +22111,21 @@ proc QueryPerformanceCounter*(lpPerformanceCount: var TLargeInteger): WINBOOL{. stdcall, dynlib: "kernel32", importc: "QueryPerformanceCounter".} proc QueryPerformanceFrequency*(lpFrequency: var TLargeInteger): WINBOOL{. stdcall, dynlib: "kernel32", importc: "QueryPerformanceFrequency".} - #function QueryRecoveryAgents(p1: PChar; var p2: Pointer; var p3: TRecoveryAgentInformation): DWORD;stdcall; external 'kernel32' name 'QueryRecoveryAgentsA'; - #function QueryRecoveryAgentsA(p1: LPCSTR; var p2: Pointer; var p3: TRecoveryAgentInformationA): DWORD;stdcall; external 'kernel32' name 'QueryRecoveryAgentsA'; - #function QueryRecoveryAgentsW(p1: LPWSTR; var p2: Pointer; var p3: TRecoveryAgentInformationW): DWORD;stdcall; external 'kernel32' name 'QueryRecoveryAgentsW'; + #function QueryRecoveryAgents(p1: PChar; var p2: pointer; var p3: TRecoveryAgentInformation): DWORD;stdcall; external 'kernel32' name 'QueryRecoveryAgentsA'; + #function QueryRecoveryAgentsA(p1: LPCSTR; var p2: pointer; var p3: TRecoveryAgentInformationA): DWORD;stdcall; external 'kernel32' name 'QueryRecoveryAgentsA'; + #function QueryRecoveryAgentsW(p1: LPWSTR; var p2: pointer; var p3: TRecoveryAgentInformationW): DWORD;stdcall; external 'kernel32' name 'QueryRecoveryAgentsW'; proc RaiseException*(dwExceptionCode: DWORD, dwExceptionFlags: DWORD, nNumberOfArguments: DWORD, lpArguments: var DWORD){. stdcall, dynlib: "kernel32", importc: "RaiseException".} proc UnhandledExceptionFilter*(ExceptionInfo: var emptyrecord): LONG{.stdcall, dynlib: "kernel32", importc: "UnhandledExceptionFilter".} -proc ReadConsole*(hConsoleInput: THandle, lpBuffer: Pointer, +proc ReadConsole*(hConsoleInput: THandle, lpBuffer: pointer, nNumberOfCharsToRead: DWORD, lpNumberOfCharsRead: var DWORD, - lpReserved: Pointer): WINBOOL{.stdcall, dynlib: "kernel32", + lpReserved: pointer): WINBOOL{.stdcall, dynlib: "kernel32", importc: "ReadConsoleA".} -proc ReadConsoleA*(hConsoleInput: THandle, lpBuffer: Pointer, +proc ReadConsoleA*(hConsoleInput: THandle, lpBuffer: pointer, nNumberOfCharsToRead: DWORD, lpNumberOfCharsRead: var DWORD, - lpReserved: Pointer): WINBOOL{.stdcall, dynlib: "kernel32", + lpReserved: pointer): WINBOOL{.stdcall, dynlib: "kernel32", importc: "ReadConsoleA".} proc ReadConsoleInput*(hConsoleInput: THandle, lpBuffer: var TInputRecord, nLength: DWORD, lpNumberOfEventsRead: var DWORD): WINBOOL{. @@ -22136,15 +22136,15 @@ proc ReadConsoleInputA*(hConsoleInput: THandle, lpBuffer: var TInputRecord, proc ReadConsoleInputW*(hConsoleInput: THandle, lpBuffer: var TInputRecord, nLength: DWORD, lpNumberOfEventsRead: var DWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "ReadConsoleInputW".} -proc ReadConsoleOutput*(hConsoleOutput: THandle, lpBuffer: Pointer, +proc ReadConsoleOutput*(hConsoleOutput: THandle, lpBuffer: pointer, dwBufferSize, dwBufferCoord: TCoord, lpReadRegion: var TSmallRect): WINBOOL{.stdcall, dynlib: "kernel32", importc: "ReadConsoleOutputA".} -proc ReadConsoleOutputA*(hConsoleOutput: THandle, lpBuffer: Pointer, +proc ReadConsoleOutputA*(hConsoleOutput: THandle, lpBuffer: pointer, dwBufferSize, dwBufferCoord: TCoord, lpReadRegion: var TSmallRect): WINBOOL{.stdcall, dynlib: "kernel32", importc: "ReadConsoleOutputA".} -proc ReadConsoleOutputAttribute*(hConsoleOutput: THandle, lpAttribute: Pointer, +proc ReadConsoleOutputAttribute*(hConsoleOutput: THandle, lpAttribute: pointer, nLength: DWORD, dwReadCoord: TCoord, lpNumberOfAttrsRead: var DWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "ReadConsoleOutputAttribute".} @@ -22160,31 +22160,31 @@ proc ReadConsoleOutputCharacterW*(hConsoleOutput: THandle, lpCharacter: LPCSTR, nLength: DWORD, dwReadCoord: TCoord, lpNumberOfCharsRead: var DWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "ReadConsoleOutputCharacterW".} -proc ReadConsoleOutputW*(hConsoleOutput: THandle, lpBuffer: Pointer, +proc ReadConsoleOutputW*(hConsoleOutput: THandle, lpBuffer: pointer, dwBufferSize, dwBufferCoord: TCoord, lpReadRegion: var TSmallRect): WINBOOL{.stdcall, dynlib: "kernel32", importc: "ReadConsoleOutputW".} -proc ReadConsoleW*(hConsoleInput: THandle, lpBuffer: Pointer, +proc ReadConsoleW*(hConsoleInput: THandle, lpBuffer: pointer, nNumberOfCharsToRead: DWORD, lpNumberOfCharsRead: var DWORD, - lpReserved: Pointer): WINBOOL{.stdcall, dynlib: "kernel32", + lpReserved: pointer): WINBOOL{.stdcall, dynlib: "kernel32", importc: "ReadConsoleW".} proc ReadEventLog*(hEventLog: THandle, dwReadFlags, dwRecordOffset: DWORD, - lpBuffer: Pointer, nNumberOfBytesToRead: DWORD, + lpBuffer: pointer, nNumberOfBytesToRead: DWORD, pnBytesRead, pnMinNumberOfBytesNeeded: var DWORD): WINBOOL{. stdcall, dynlib: "advapi32", importc: "ReadEventLogA".} proc ReadEventLogA*(hEventLog: THandle, dwReadFlags, dwRecordOffset: DWORD, - lpBuffer: Pointer, nNumberOfBytesToRead: DWORD, + lpBuffer: pointer, nNumberOfBytesToRead: DWORD, pnBytesRead, pnMinNumberOfBytesNeeded: var DWORD): WINBOOL{. stdcall, dynlib: "advapi32", importc: "ReadEventLogA".} proc ReadEventLogW*(hEventLog: THandle, dwReadFlags, dwRecordOffset: DWORD, - lpBuffer: Pointer, nNumberOfBytesToRead: DWORD, + lpBuffer: pointer, nNumberOfBytesToRead: DWORD, pnBytesRead, pnMinNumberOfBytesNeeded: var DWORD): WINBOOL{. stdcall, dynlib: "advapi32", importc: "ReadEventLogW".} proc ReadFile*(hFile: THandle, Buffer: pointer, nNumberOfBytesToRead: DWORD, lpNumberOfBytesRead: var DWORD, lpOverlapped: POverlapped): WINBOOL{. stdcall, dynlib: "kernel32", importc: "ReadFile".} -proc ReadProcessMemory*(hProcess: THandle, lpBaseAddress: Pointer, - lpBuffer: Pointer, nSize: DWORD, +proc ReadProcessMemory*(hProcess: THandle, lpBaseAddress: pointer, + lpBuffer: pointer, nSize: DWORD, lpNumberOfBytesRead: var DWORD): WINBOOL{.stdcall, dynlib: "kernel32", importc: "ReadProcessMemory".} #function RectInRegion(RGN: HRGN; const p2: TRect): WINBOOL; stdcall; external 'gdi32' name 'RectInRegion'; @@ -22217,27 +22217,27 @@ proc RegCreateKeyExW*(key: HKEY, lpSubKey: LPWSTR, Reserved: DWORD, proc RegCreateKeyW*(key: HKEY, lpSubKey: LPWSTR, phkResult: var HKEY): int32{. stdcall, dynlib: "advapi32", importc: "RegCreateKeyW".} proc RegEnumKeyEx*(key: HKEY, dwIndex: DWORD, lpName: cstring, - lpcbName: var DWORD, lpReserved: Pointer, lpClass: cstring, + lpcbName: var DWORD, lpReserved: pointer, lpClass: cstring, lpcbClass: PDWORD, lpftLastWriteTime: PFileTime): int32{. stdcall, dynlib: "advapi32", importc: "RegEnumKeyExA".} proc RegEnumKeyExA*(key: HKEY, dwIndex: DWORD, lpName: LPCSTR, - lpcbName: var DWORD, lpReserved: Pointer, lpClass: LPCSTR, + lpcbName: var DWORD, lpReserved: pointer, lpClass: LPCSTR, lpcbClass: PDWORD, lpftLastWriteTime: PFileTime): int32{. stdcall, dynlib: "advapi32", importc: "RegEnumKeyExA".} proc RegEnumKeyExW*(key: HKEY, dwIndex: DWORD, lpName: LPWSTR, - lpcbName: var DWORD, lpReserved: Pointer, lpClass: LPWSTR, + lpcbName: var DWORD, lpReserved: pointer, lpClass: LPWSTR, lpcbClass: PDWORD, lpftLastWriteTime: PFileTime): int32{. stdcall, dynlib: "advapi32", importc: "RegEnumKeyExW".} proc RegEnumValue*(key: HKEY, dwIndex: DWORD, lpValueName: cstring, - lpcbValueName: var DWORD, lpReserved: Pointer, + lpcbValueName: var DWORD, lpReserved: pointer, lpType: PDWORD, lpData: PByte, lpcbData: PDWORD): int32{. stdcall, dynlib: "advapi32", importc: "RegEnumValueA".} proc RegEnumValueA*(key: HKEY, dwIndex: DWORD, lpValueName: cstring, - lpcbValueName: var DWORD, lpReserved: Pointer, + lpcbValueName: var DWORD, lpReserved: pointer, lpType: PDWORD, lpData: PByte, lpcbData: PDWORD): int32{. stdcall, dynlib: "advapi32", importc: "RegEnumValueA".} proc RegEnumValueW*(key: HKEY, dwIndex: DWORD, lpValueName: cstring, - lpcbValueName: var DWORD, lpReserved: Pointer, + lpcbValueName: var DWORD, lpReserved: pointer, lpType: PDWORD, lpData: PByte, lpcbData: PDWORD): int32{. stdcall, dynlib: "advapi32", importc: "RegEnumValueW".} proc RegGetKeySecurity*(key: HKEY, SecurityInformation: SECURITY_INFORMATION, @@ -22324,10 +22324,10 @@ proc ScrollConsoleScreenBufferW*(hConsoleOutput: THandle, lpFill: var TCharInfo): WINBOOL{.stdcall, dynlib: "kernel32", importc: "ScrollConsoleScreenBufferW".} proc ScrollWindow*(wnd: HWND, XAmount: int32, YAmount: int32, rect: LPRECT, - lpClipRect: lpRECT): WINBOOL{.stdcall, dynlib: "user32", + lpClipRect: LPRECT): WINBOOL{.stdcall, dynlib: "user32", importc: "ScrollWindow".} -proc ScrollWindowEx*(wnd: HWND, dx: int32, dy: int32, prcScroll: lpRECT, - prcClip: lpRECT, hrgnUpdate: HRGN, prcUpdate: LPRECT, +proc ScrollWindowEx*(wnd: HWND, dx: int32, dy: int32, prcScroll: LPRECT, + prcClip: LPRECT, hrgnUpdate: HRGN, prcUpdate: LPRECT, flags: WINUINT): int32{.stdcall, dynlib: "user32", importc: "ScrollWindowEx".} #function ScrollDC(DC: HDC; DX, DY: Integer; var Scroll, Clip: TRect; Rgn: HRGN; Update: PRect): WINBOOL; stdcall; external 'user32' name 'ScrollDC'; @@ -22344,7 +22344,7 @@ proc SendMessageTimeoutA*(wnd: HWND, Msg: WINUINT, wp: WPARAM, lp: LPARAM, proc SendMessageTimeoutW*(wnd: HWND, Msg: WINUINT, wp: WPARAM, lp: LPARAM, fuFlags, uTimeout: WINUINT, lpdwResult: var DWORD): LRESULT{. stdcall, dynlib: "user32", importc: "SendMessageTimeoutW".} - #function SetAclInformation(var pAcl: TACL; pAclInformation: Pointer; nAclInformationLength: DWORD; dwAclInformationClass: TAclInformationClass): WINBOOL; stdcall; external 'advapi32' name 'SetAclInformation'; + #function SetAclInformation(var pAcl: TACL; pAclInformation: pointer; nAclInformationLength: DWORD; dwAclInformationClass: TAclInformationClass): WINBOOL; stdcall; external 'advapi32' name 'SetAclInformation'; #function SetColorAdjustment(DC: HDC; const p2: TColorAdjustment): WINBOOL; stdcall; external 'gdi32' name 'SetColorAdjustment'; proc SetCommConfig*(hCommDev: THandle, lpCC: TCommConfig, dwSize: DWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "SetCommConfig".} @@ -22359,9 +22359,9 @@ proc SetConsoleCursorInfo*(hConsoleOutput: THandle, proc SetDIBColorTable*(DC: HDC, p2, p3: WINUINT, RGBQuadSTructs: pointer): WINUINT{. stdcall, dynlib: "gdi32", importc: "SetDIBColorTable".} proc SetDIBits*(DC: HDC, Bitmap: HBITMAP, StartScan, NumScans: WINUINT, - Bits: Pointer, BitsInfo: var TBitmapInfo, Usage: WINUINT): int{. + Bits: pointer, BitsInfo: var TBitmapInfo, Usage: WINUINT): int{. stdcall, dynlib: "gdi32", importc: "SetDIBits".} - #function SetDIBitsToDevice(DC: HDC; DestX, DestY: Integer; Width, Height: DWORD; SrcX, SrcY: Integer; nStartScan, NumScans: WINUINT; Bits: Pointer; var BitsInfo: TBitmapInfo; Usage: WINUINT): Integer; stdcall; external 'gdi32' name 'SetDIBitsToDevice'; + #function SetDIBitsToDevice(DC: HDC; DestX, DestY: Integer; Width, Height: DWORD; SrcX, SrcY: Integer; nStartScan, NumScans: WINUINT; Bits: pointer; var BitsInfo: TBitmapInfo; Usage: WINUINT): Integer; stdcall; external 'gdi32' name 'SetDIBitsToDevice'; proc SetEnhMetaFileBits*(para1: WINUINT, para2: pointer): HENHMETAFILE{.stdcall, dynlib: "gdi32", importc: "SetEnhMetaFileBits".} proc SetFileTime*(hFile: HANDLE, lpCreationTime: var FILETIME, @@ -22378,7 +22378,7 @@ proc SetMenuItemInfoA*(p1: HMENU, p2: WINUINT, p3: WINBOOL, p4: TMenuItemInfoA): proc SetMetaFileBitsEx*(p1: WINUINT, p2: cstring): HMETAFILE{.stdcall, dynlib: "gdi32", importc: "SetMetaFileBitsEx".} proc SetNamedPipeHandleState*(hNamedPipe: THandle, lpMode: var DWORD, - lpMaxCollectionCount, lpCollectDataTimeout: Pointer): WINBOOL{.stdcall, + lpMaxCollectionCount, lpCollectDataTimeout: pointer): WINBOOL{.stdcall, dynlib: "kernel32", importc: "SetNamedPipeHandleState".} proc SetPaletteEntries*(Palette: HPALETTE, StartIndex, NumEntries: WINUINT, PaletteEntries: pointer): WINUINT{.stdcall, @@ -22405,7 +22405,7 @@ proc SetUserObjectSecurity*(hObj: THandle, pSIRequested: var DWORD, dynlib: "user32", importc: "SetUserObjectSecurity".} proc SetWaitableTimer*(hTimer: THandle, lpDueTime: var TLargeInteger, lPeriod: int32, pfnCompletionRoutine: TFNTimerAPCRoutine, - lpArgToCompletionRoutine: Pointer, fResume: WINBOOL): WINBOOL{. + lpArgToCompletionRoutine: pointer, fResume: WINBOOL): WINBOOL{. stdcall, dynlib: "kernel32", importc: "SetWaitableTimer".} proc SetWinMetaFileBits*(p1: WINUINT, p2: cstring, p3: HDC, p4: TMetaFilePict): HENHMETAFILE{. stdcall, dynlib: "gdi32", importc: "SetWinMetaFileBits".} @@ -22415,7 +22415,7 @@ proc StartDoc*(DC: HDC, p2: TDocInfo): int{.stdcall, dynlib: "gdi32", proc StartDocA*(DC: HDC, p2: TDocInfoA): int{.stdcall, dynlib: "gdi32", importc: "StartDocA".} #function StartDocW(DC: HDC; const p2: TDocInfoW): Integer; stdcall; external 'gdi32' name 'StartDocW'; - #function StretchDIBits(DC: HDC; DestX, DestY, DestWidth, DestHegiht, SrcX, SrcY, SrcWidth, SrcHeight: Integer; Bits: Pointer; var BitsInfo: TBitmapInfo; Usage: WINUINT; Rop: DWORD): Integer; stdcall; external 'gdi32' name 'StretchDIBits'; + #function StretchDIBits(DC: HDC; DestX, DestY, DestWidth, DestHegiht, SrcX, SrcY, SrcWidth, SrcHeight: Integer; Bits: pointer; var BitsInfo: TBitmapInfo; Usage: WINUINT; Rop: DWORD): Integer; stdcall; external 'gdi32' name 'StretchDIBits'; proc SubtractRect*(lprcDst: var TRect, lprcSrc1, lprcSrc2: TRect): WINBOOL{. stdcall, dynlib: "user32", importc: "SubtractRect".} proc SystemTimeToFileTime*(lpSystemTime: TSystemTime, lpFileTime: var TFileTime): WINBOOL{. @@ -22446,8 +22446,8 @@ proc TrackMouseEvent*(lpEventTrack: PTrackMouseEvent): WINBOOL{.stdcall, proc TrackPopupMenu*(menu: HMENU, uFlags: WINUINT, x: int32, y: int32, nReserved: int32, wnd: HWND, prcRect: PRect): WINBOOL{. stdcall, dynlib: "user32", importc: "TrackPopupMenu".} -proc TransactNamedPipe*(hNamedPipe: THandle, lpInBuffer: Pointer, - nInBufferSize: DWORD, lpOutBuffer: Pointer, +proc TransactNamedPipe*(hNamedPipe: THandle, lpInBuffer: pointer, + nInBufferSize: DWORD, lpOutBuffer: pointer, nOutBufferSize: DWORD, lpBytesRead: var DWORD, lpOverlapped: POverlapped): WINBOOL{.stdcall, dynlib: "kernel32", importc: "TransactNamedPipe".} @@ -22464,8 +22464,8 @@ proc TranslateMDISysAccel*(hWndClient: HWND, lpMsg: TMsg): WINBOOL{.stdcall, dynlib: "user32", importc: "TranslateMDISysAccel".} proc TranslateMessage*(lpMsg: TMsg): WINBOOL{.stdcall, dynlib: "user32", importc: "TranslateMessage".} - #function TransparentDIBits(DC: HDC; p2, p3, p4, p5: Integer; const p6: Pointer; const p7: PBitmapInfo; p8: WINUINT; p9, p10, p11, p12: Integer; p13: WINUINT): WINBOOL;stdcall; external 'gdi32' name 'TransparentDIBits'; -proc UnhandledExceptionFilter*(ExceptionInfo: TExceptionPointers): int32{. + #function TransparentDIBits(DC: HDC; p2, p3, p4, p5: Integer; const p6: pointer; const p7: PBitmapInfo; p8: WINUINT; p9, p10, p11, p12: Integer; p13: WINUINT): WINBOOL;stdcall; external 'gdi32' name 'TransparentDIBits'; +proc UnhandledExceptionFilter*(ExceptionInfo: TExceptionpointers): int32{. stdcall, dynlib: "kernel32", importc: "UnhandledExceptionFilter".} proc UnionRect*(lprcDst: var TRect, lprcSrc1, lprcSrc2: TRect): WINBOOL{. stdcall, dynlib: "user32", importc: "UnionRect".} @@ -22499,19 +22499,19 @@ proc VerInstallFileW*(uFlags: DWORD, szSrcFileName, szDestFileName, szSrcDir, szDestDir, szCurDir, szTmpFile: LPWSTR, lpuTmpFileLen: var WINUINT): DWORD{.stdcall, dynlib: "version", importc: "VerInstallFileW".} -proc VerQueryValue*(pBlock: Pointer, lpSubBlock: cstring, - lplpBuffer: var Pointer, puLen: var WINUINT): WINBOOL{.stdcall, +proc VerQueryValue*(pBlock: pointer, lpSubBlock: cstring, + lplpBuffer: var pointer, puLen: var WINUINT): WINBOOL{.stdcall, dynlib: "version", importc: "VerQueryValueA".} -proc VerQueryValueA*(pBlock: Pointer, lpSubBlock: LPCSTR, - lplpBuffer: var Pointer, puLen: var WINUINT): WINBOOL{. +proc VerQueryValueA*(pBlock: pointer, lpSubBlock: LPCSTR, + lplpBuffer: var pointer, puLen: var WINUINT): WINBOOL{. stdcall, dynlib: "version", importc: "VerQueryValueA".} -proc VerQueryValueW*(pBlock: Pointer, lpSubBlock: LPWSTR, - lplpBuffer: var Pointer, puLen: var WINUINT): WINBOOL{. +proc VerQueryValueW*(pBlock: pointer, lpSubBlock: LPWSTR, + lplpBuffer: var pointer, puLen: var WINUINT): WINBOOL{. stdcall, dynlib: "version", importc: "VerQueryValueW".} -proc VirtualQuery*(lpAddress: Pointer, lpBuffer: var TMemoryBasicInformation, +proc VirtualQuery*(lpAddress: pointer, lpBuffer: var TMemoryBasicInformation, dwLength: DWORD): DWORD{.stdcall, dynlib: "kernel32", importc: "VirtualQuery".} -proc VirtualQueryEx*(hProcess: THandle, lpAddress: Pointer, +proc VirtualQueryEx*(hProcess: THandle, lpAddress: pointer, lpBuffer: var TMemoryBasicInformation, dwLength: DWORD): DWORD{. stdcall, dynlib: "kernel32", importc: "VirtualQueryEx".} proc WaitCommEvent*(hFile: THandle, lpEvtMask: var DWORD, @@ -22528,7 +22528,7 @@ proc wglSetLayerPaletteEntries*(p1: HDC, p2, p3, p4: int, pcr: pointer): int{. stdcall, dynlib: "opengl32", importc: "wglSetLayerPaletteEntries".} #function wglSwapMultipleBuffers(p1: WINUINT; const p2: PWGLSwap): DWORD;stdcall; external 'opengl32' name 'wglSwapMultipleBuffers'; #function WinSubmitCertificate(var lpCertificate: TWinCertificate): WINBOOL;stdcall; external 'imaghlp' name 'WinSubmitCertificate'; - #function WinVerifyTrust(wnd: HWND; const ActionID: TGUID; ActionData: Pointer): Longint;stdcall; external 'imaghlp' name 'WinVerifyTrust'; + #function WinVerifyTrust(wnd: HWND; const ActionID: TGUID; ActionData: pointer): Longint;stdcall; external 'imaghlp' name 'WinVerifyTrust'; proc WNetAddConnection2*(lpNetResource: var TNetResource, lpPassword, lpUserName: cstring, dwFlags: DWORD): DWORD{. stdcall, dynlib: "mpr", importc: "WNetAddConnection2A".} @@ -22553,13 +22553,13 @@ proc WNetDisconnectDialog1*(lpConnDlgStruct: var TDiscDlgStruct): DWORD{. proc WNetDisconnectDialog1A*(lpConnDlgStruct: var TDiscDlgStructA): DWORD{. stdcall, dynlib: "mpr", importc: "WNetDisconnectDialog1A".} #function WNetDisconnectDialog1W(var lpConnDlgStruct: TDiscDlgStructW): DWORD; stdcall; external 'mpr' name 'WNetDisconnectDialog1W'; -proc WNetEnumResource*(hEnum: THandle, lpcCount: var DWORD, lpBuffer: Pointer, +proc WNetEnumResource*(hEnum: THandle, lpcCount: var DWORD, lpBuffer: pointer, lpBufferSize: var DWORD): DWORD{.stdcall, dynlib: "mpr", importc: "WNetEnumResourceA".} -proc WNetEnumResourceA*(hEnum: THandle, lpcCount: var DWORD, lpBuffer: Pointer, +proc WNetEnumResourceA*(hEnum: THandle, lpcCount: var DWORD, lpBuffer: pointer, lpBufferSize: var DWORD): DWORD{.stdcall, dynlib: "mpr", importc: "WNetEnumResourceA".} -proc WNetEnumResourceW*(hEnum: THandle, lpcCount: var DWORD, lpBuffer: Pointer, +proc WNetEnumResourceW*(hEnum: THandle, lpcCount: var DWORD, lpBuffer: pointer, lpBufferSize: var DWORD): DWORD{.stdcall, dynlib: "mpr", importc: "WNetEnumResourceW".} proc WNetGetConnection*(lpLocalName: cstring, lpRemoteName: cstring, @@ -22601,21 +22601,21 @@ proc WNetGetProviderNameA*(dwNetType: DWORD, lpProviderName: LPCSTR, proc WNetGetProviderNameW*(dwNetType: DWORD, lpProviderName: LPWSTR, lpBufferSize: var DWORD): DWORD{.stdcall, dynlib: "mpr", importc: "WNetGetProviderNameW".} -proc WNetGetResourceParent*(lpNetResource: PNetResource, lpBuffer: Pointer, +proc WNetGetResourceParent*(lpNetResource: PNetResource, lpBuffer: pointer, cbBuffer: var DWORD): DWORD{.stdcall, dynlib: "mpr", importc: "WNetGetResourceParentA".} -proc WNetGetResourceParentA*(lpNetResource: PNetResourceA, lpBuffer: Pointer, +proc WNetGetResourceParentA*(lpNetResource: PNetResourceA, lpBuffer: pointer, cbBuffer: var DWORD): DWORD{.stdcall, dynlib: "mpr", importc: "WNetGetResourceParentA".} - #function WNetGetResourceParentW(lpNetResource: PNetResourceW; lpBuffer: Pointer; var cbBuffer: DWORD): DWORD;stdcall; external 'mpr' name 'WNetGetResourceParentW'; + #function WNetGetResourceParentW(lpNetResource: PNetResourceW; lpBuffer: pointer; var cbBuffer: DWORD): DWORD;stdcall; external 'mpr' name 'WNetGetResourceParentW'; proc WNetGetUniversalName*(lpLocalPath: cstring, dwInfoLevel: DWORD, - lpBuffer: Pointer, lpBufferSize: var DWORD): DWORD{. + lpBuffer: pointer, lpBufferSize: var DWORD): DWORD{. stdcall, dynlib: "mpr", importc: "WNetGetUniversalNameA".} proc WNetGetUniversalNameA*(lpLocalPath: LPCSTR, dwInfoLevel: DWORD, - lpBuffer: Pointer, lpBufferSize: var DWORD): DWORD{. + lpBuffer: pointer, lpBufferSize: var DWORD): DWORD{. stdcall, dynlib: "mpr", importc: "WNetGetUniversalNameA".} proc WNetGetUniversalNameW*(lpLocalPath: LPWSTR, dwInfoLevel: DWORD, - lpBuffer: Pointer, lpBufferSize: var DWORD): DWORD{. + lpBuffer: pointer, lpBufferSize: var DWORD): DWORD{. stdcall, dynlib: "mpr", importc: "WNetGetUniversalNameW".} proc WNetGetUser*(lpName: cstring, lpUserName: cstring, lpnLength: var DWORD): DWORD{. stdcall, dynlib: "mpr", importc: "WNetGetUserA".} @@ -22641,13 +22641,13 @@ proc WNetUseConnectionA*(hwndOwner: HWND, lpNetResource: var TNetResourceA, lpResult: var DWORD): DWORD{.stdcall, dynlib: "mpr", importc: "WNetUseConnectionA".} #function WNetUseConnectionW(hwndOwner: HWND; var lpNetResource: TNetResourceW; lpUserID: LPWSTR; lpPassword: LPWSTR; dwFlags: DWORD; lpAccessName: LPWSTR; var lpBufferSize: DWORD; var lpResult: DWORD): DWORD; stdcall; external 'mpr' name 'WNetUseConnectionW'; -proc WriteConsole*(hConsoleOutput: THandle, lpBuffer: Pointer, +proc WriteConsole*(hConsoleOutput: THandle, lpBuffer: pointer, nNumberOfCharsToWrite: DWORD, - lpNumberOfCharsWritten: var DWORD, lpReserved: Pointer): WINBOOL{. + lpNumberOfCharsWritten: var DWORD, lpReserved: pointer): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WriteConsoleA".} -proc WriteConsoleA*(hConsoleOutput: THandle, lpBuffer: Pointer, +proc WriteConsoleA*(hConsoleOutput: THandle, lpBuffer: pointer, nNumberOfCharsToWrite: DWORD, - lpNumberOfCharsWritten: var DWORD, lpReserved: Pointer): WINBOOL{. + lpNumberOfCharsWritten: var DWORD, lpReserved: pointer): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WriteConsoleA".} proc WriteConsoleInput*(hConsoleInput: THandle, lpBuffer: TInputRecord, nLength: DWORD, lpNumberOfEventsWritten: var DWORD): WINBOOL{. @@ -22658,15 +22658,15 @@ proc WriteConsoleInputA*(hConsoleInput: THandle, lpBuffer: TInputRecord, proc WriteConsoleInputW*(hConsoleInput: THandle, lpBuffer: TInputRecord, nLength: DWORD, lpNumberOfEventsWritten: var DWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WriteConsoleInputW".} -proc WriteConsoleOutput*(hConsoleOutput: THandle, lpBuffer: Pointer, +proc WriteConsoleOutput*(hConsoleOutput: THandle, lpBuffer: pointer, dwBufferSize, dwBufferCoord: TCoord, lpWriteRegion: var TSmallRect): WINBOOL{.stdcall, dynlib: "kernel32", importc: "WriteConsoleOutputA".} -proc WriteConsoleOutputA*(hConsoleOutput: THandle, lpBuffer: Pointer, +proc WriteConsoleOutputA*(hConsoleOutput: THandle, lpBuffer: pointer, dwBufferSize, dwBufferCoord: TCoord, lpWriteRegion: var TSmallRect): WINBOOL{.stdcall, dynlib: "kernel32", importc: "WriteConsoleOutputA".} -proc WriteConsoleOutputAttribute*(hConsoleOutput: THandle, lpAttribute: Pointer, +proc WriteConsoleOutputAttribute*(hConsoleOutput: THandle, lpAttribute: pointer, nLength: DWORD, dwWriteCoord: TCoord, lpNumberOfAttrsWritten: var DWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WriteConsoleOutputAttribute".} @@ -22682,18 +22682,18 @@ proc WriteConsoleOutputCharacterW*(hConsoleOutput: THandle, lpCharacter: LPWSTR, nLength: DWORD, dwWriteCoord: TCoord, lpNumberOfCharsWritten: var DWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WriteConsoleOutputCharacterW".} -proc WriteConsoleOutputW*(hConsoleOutput: THandle, lpBuffer: Pointer, +proc WriteConsoleOutputW*(hConsoleOutput: THandle, lpBuffer: pointer, dwBufferSize, dwBufferCoord: TCoord, lpWriteRegion: var TSmallRect): WINBOOL{.stdcall, dynlib: "kernel32", importc: "WriteConsoleOutputW".} -proc WriteConsoleW*(hConsoleOutput: THandle, lpBuffer: Pointer, +proc WriteConsoleW*(hConsoleOutput: THandle, lpBuffer: pointer, nNumberOfCharsToWrite: DWORD, - lpNumberOfCharsWritten: var DWORD, lpReserved: Pointer): WINBOOL{. + lpNumberOfCharsWritten: var DWORD, lpReserved: pointer): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WriteConsoleW".} proc WriteFile*(hFile: THandle, Buffer: pointer, nNumberOfBytesToWrite: DWORD, lpNumberOfBytesWritten: var DWORD, lpOverlapped: POverlapped): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WriteFile".} -proc WriteFileEx*(hFile: THandle, lpBuffer: Pointer, +proc WriteFileEx*(hFile: THandle, lpBuffer: pointer, nNumberOfBytesToWrite: DWORD, lpOverlapped: TOverlapped, lpCompletionRoutine: FARPROC): WINBOOL{.stdcall, dynlib: "kernel32", importc: "WriteFileEx".} @@ -22707,8 +22707,8 @@ proc WritePrivateProfileStructW*(lpszSection, lpszKey: LPCWSTR, proc WritePrivateProfileStruct*(lpszSection, lpszKey: LPCTSTR, lpStruct: LPVOID, uSizeStruct: WINUINT, szFile: LPCTSTR): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WritePrivateProfileStructA".} -proc WriteProcessMemory*(hProcess: THandle, lpBaseAddress: Pointer, - lpBuffer: Pointer, nSize: DWORD, +proc WriteProcessMemory*(hProcess: THandle, lpBaseAddress: pointer, + lpBuffer: pointer, nSize: DWORD, lpNumberOfBytesWritten: var DWORD): WINBOOL{.stdcall, dynlib: "kernel32", importc: "WriteProcessMemory".} proc SHFileOperation*(para1: var SHFILEOPSTRUCT): int32{.stdcall, @@ -22821,7 +22821,7 @@ proc INDEXTOSTATEIMAGEMASK*(i: int32): int32 = result = i shl 12'i32 proc MAKEINTATOM*(i: int32): LPTSTR = - result = cast[LPTSTR](cast[ULONG_PTR](ToU16(i))) + result = cast[LPTSTR](cast[ULONG_PTR](toU16(i))) proc MAKELANGID*(p, s: int32): int32 = # return type might be wrong @@ -22849,10 +22849,10 @@ proc MAKEROP4*(fore, back: int32): DWORD = proc MAKEWPARAM*(L, h: int32): WPARAM = result = WPARAM(MAKELONG(L, h)) -proc GET_X_LPARAM*(lp: Windows.LParam): int32 = +proc GET_X_LPARAM*(lp: windows.LParam): int32 = result = LOWORD(lp.int32) -proc GET_Y_LPARAM*(lp: Windows.LParam): int32 = +proc GET_Y_LPARAM*(lp: windows.LParam): int32 = result = HIWORD(lp.int32) proc UNICODE_NULL*(): WCHAR = @@ -23229,10 +23229,10 @@ proc set_fAckReq(a: var DDEUP, fAckReq: int16) = a.flag0 = a.flag0 or ((fAckReq shl bp_DDEUP_fAckReq) and bm_DDEUP_fAckReq) proc CreateWindowA(lpClassName: LPCSTR, lpWindowName: LPCSTR, dwStyle: DWORD, - X: int32, Y: int32, nWidth: int32, nHeight: int32, + X, Y, nWidth, nHeight: int32, hWndParent: HWND, menu: HMENU, hInstance: HINST, lpParam: LPVOID): HWND = - result = CreateWindowExA(0, lpClassName, lpWindowName, dwStyle, x, y, nWidth, + result = CreateWindowExA(0, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, menu, hInstance, lpParam) proc CreateDialogA(hInstance: HINST, lpTemplateName: LPCSTR, hWndParent: HWND, @@ -23259,7 +23259,7 @@ proc CreateWindowW(lpClassName: LPCWSTR, lpWindowName: LPCWSTR, dwStyle: DWORD, X: int32, Y: int32, nWidth: int32, nHeight: int32, hWndParent: HWND, menu: HMENU, hInstance: HINST, lpParam: LPVOID): HWND = - result = CreateWindowExW(0, lpClassName, lpWindowName, dwStyle, x, y, nWidth, + result = CreateWindowExW(0, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, menu, hInstance, lpParam) proc CreateDialogW(hInstance: HINST, lpName: LPCWSTR, hWndParent: HWND, @@ -23285,7 +23285,7 @@ when defined(winUnicode): X: int32, Y: int32, nWidth: int32, nHeight: int32, hWndParent: HWND, menu: HMENU, hInstance: HINST, lpParam: LPVOID): HWND = - result = CreateWindowEx(0, lpClassName, lpWindowName, dwStyle, x, y, nWidth, + result = CreateWindowEx(0, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam) proc CreateDialog(hInstance: HINST, lpName: LPCWSTR, hWndParent: HWND, @@ -23311,7 +23311,7 @@ else: X: int32, Y: int32, nWidth: int32, nHeight: int32, hWndParent: HWND, menu: HMENU, hInstance: HINST, lpParam: LPVOID): HWND = - result = CreateWindowEx(0, lpClassName, lpWindowName, dwStyle, x, y, nWidth, + result = CreateWindowEx(0, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, menu, hInstance, lpParam) proc CreateDialog(hInstance: HINST, lpTemplateName: LPCSTR, hWndParent: HWND, @@ -23334,24 +23334,24 @@ else: result = DialogBoxIndirectParam(hInstance, hDialogTemplate, hWndParent, lpDialogFunc, 0) -proc GlobalAllocPtr(flags, cb: DWord): Pointer = +proc GlobalAllocPtr(flags, cb: DWord): pointer = result = GlobalLock(GlobalAlloc(flags, cb)) -proc GlobalFreePtr(lp: Pointer): Pointer = - result = cast[Pointer](GlobalFree(cast[HWND](GlobalUnlockPtr(lp)))) +proc GlobalFreePtr(lp: pointer): pointer = + result = cast[pointer](GlobalFree(cast[HWND](GlobalUnlockPtr(lp)))) -proc GlobalUnlockPtr(lp: pointer): Pointer = +proc GlobalUnlockPtr(lp: pointer): pointer = discard GlobalUnlock(GlobalHandle(lp)) result = lp -proc GlobalLockPtr(lp: pointer): Pointer = +proc GlobalLockPtr(lp: pointer): pointer = result = GlobalLock(GlobalHandle(lp)) -proc GlobalReAllocPtr(lp: Pointer, cbNew, flags: DWord): Pointer = +proc GlobalReAllocPtr(lp: pointer, cbNew, flags: DWord): pointer = result = GlobalLock(GlobalReAlloc(cast[HWND](GlobalUnlockPtr(lp)), cbNew, flags)) -proc GlobalPtrHandle(lp: pointer): Pointer = - result = cast[Pointer](GlobalHandle(lp)) +proc GlobalPtrHandle(lp: pointer): pointer = + result = cast[pointer](GlobalHandle(lp)) proc ImageList_AddIcon(himl: HIMAGELIST, hicon: HICON): int32 = result = ImageList_ReplaceIcon(himl, -1, hicon) @@ -23502,7 +23502,7 @@ proc ListView_GetCountPerPage(hwndLV: HWND): LRESULT = proc ListView_GetEditControl(hwndLV: HWND): LRESULT = result = SendMessage(hwndLV, LVM_GETEDITCONTROL, 0, 0) -proc ListView_GetImageList(wnd: HWND, iImageList: wINT): LRESULT = +proc ListView_GetImageList(wnd: HWND, iImageList: WINT): LRESULT = result = SendMessage(wnd, LVM_GETIMAGELIST, WPARAM(iImageList), 0) proc ListView_GetISearchString(hwndLV: HWND, lpsz: LPTSTR): LRESULT = @@ -23702,7 +23702,7 @@ proc TreeView_SetItem(wnd: HWND, item: var TV_ITEM): LRESULT = result = SendMessage(wnd, TVM_SETITEM, 0, cast[LPARAM](addr(item))) proc TreeView_EditLabel(wnd: HWND, hitem: HTREEITEM): LRESULT = - Result = SendMessage(wnd, TVM_EDITLABEL, 0, cast[LPARAM](hitem)) + result = SendMessage(wnd, TVM_EDITLABEL, 0, cast[LPARAM](hitem)) proc TreeView_GetEditControl(wnd: HWND): LRESULT = result = SendMessage(wnd, TVM_GETEDITCONTROL, 0, 0) @@ -23854,10 +23854,10 @@ proc CommDlg_OpenSave_SetDefExt(hdlg: HWND, pszext: LPSTR): LRESULT = proc InternalGetLargestConsoleWindowSize(hConsoleOutput: HANDLE): DWord{. stdcall, dynlib: "kernel32", importc: "GetLargestConsoleWindowSize".} proc GetLargestConsoleWindowSize(hConsoleOutput: HANDLE): COORD = - var res: dword + var res: DWORD res = InternalGetLargestConsoleWindowSize(hConsoleOutput) - result.y = toU16(res and 0x0000ffff) # XXX: correct? - result.x = toU16(res shr 16) + result.Y = toU16(res and 0x0000ffff) # XXX: correct? + result.X = toU16(res shr 16) proc Succeeded(Status: HRESULT): WINBOOL = result = (Status and 0x80000000).WinBool diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 09696b67f..76d17bc4a 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -8,7 +8,7 @@ # ## This module implements a small wrapper for some needed Win API procedures, -## so that the Nimrod compiler does not depend on the huge Windows module. +## so that the Nim compiler does not depend on the huge Windows module. const useWinUnicode* = not defined(useWinAnsi) @@ -104,11 +104,11 @@ proc closeHandle*(hObject: THandle): WINBOOL {.stdcall, dynlib: "kernel32", importc: "CloseHandle".} proc readFile*(hFile: THandle, Buffer: pointer, nNumberOfBytesToRead: int32, - lpNumberOfBytesRead: var int32, lpOverlapped: pointer): WINBOOL{. + lpNumberOfBytesRead: ptr int32, lpOverlapped: pointer): WINBOOL{. stdcall, dynlib: "kernel32", importc: "ReadFile".} proc writeFile*(hFile: THandle, Buffer: pointer, nNumberOfBytesToWrite: int32, - lpNumberOfBytesWritten: var int32, + lpNumberOfBytesWritten: ptr int32, lpOverlapped: pointer): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WriteFile".} @@ -199,14 +199,14 @@ else: importc: "GetCurrentDirectoryA", dynlib: "kernel32", stdcall.} proc setCurrentDirectoryA*(lpPathName: cstring): int32 {. importc: "SetCurrentDirectoryA", dynlib: "kernel32", stdcall.} - proc createDirectoryA*(pathName: cstring, security: Pointer=nil): int32 {. + proc createDirectoryA*(pathName: cstring, security: pointer=nil): int32 {. importc: "CreateDirectoryA", dynlib: "kernel32", stdcall.} proc removeDirectoryA*(lpPathName: cstring): int32 {. importc: "RemoveDirectoryA", dynlib: "kernel32", stdcall.} proc setEnvironmentVariableA*(lpName, lpValue: cstring): int32 {. stdcall, dynlib: "kernel32", importc: "SetEnvironmentVariableA".} - proc getModuleFileNameA*(handle: THandle, buf: CString, size: int32): int32 {. + proc getModuleFileNameA*(handle: THandle, buf: cstring, size: int32): int32 {. importc: "GetModuleFileNameA", dynlib: "kernel32", stdcall.} when useWinUnicode: @@ -304,7 +304,7 @@ else: dwFileAttributes: int32): WINBOOL {. stdcall, dynlib: "kernel32", importc: "SetFileAttributesA".} - proc copyFileA*(lpExistingFileName, lpNewFileName: CString, + proc copyFileA*(lpExistingFileName, lpNewFileName: cstring, bFailIfExists: cint): cint {. importc: "CopyFileA", stdcall, dynlib: "kernel32".} @@ -363,48 +363,50 @@ const proc wsaGetLastError*(): cint {.importc: "WSAGetLastError", dynlib: ws2dll.} type - TSocketHandle* = distinct int + SocketHandle* = distinct int + +{.deprecated: [TSocketHandle: SocketHandle].} type - TWSAData* {.pure, final, importc: "WSADATA", header: "Winsock2.h".} = object + WSAData* {.importc: "WSADATA", header: "Winsock2.h".} = object wVersion, wHighVersion: int16 szDescription: array[0..WSADESCRIPTION_LEN, char] szSystemStatus: array[0..WSASYS_STATUS_LEN, char] iMaxSockets, iMaxUdpDg: int16 lpVendorInfo: cstring - TSockAddr* {.pure, final, importc: "SOCKADDR", header: "Winsock2.h".} = object + SockAddr* {.importc: "SOCKADDR", header: "Winsock2.h".} = object sa_family*: int16 # unsigned sa_data: array[0..13, char] - TInAddr* {.pure, final, importc: "IN_ADDR", header: "Winsock2.h".} = object + InAddr* {.importc: "IN_ADDR", header: "Winsock2.h".} = object s_addr*: int32 # IP address - Tsockaddr_in* {.pure, final, importc: "SOCKADDR_IN", + Sockaddr_in* {.importc: "SOCKADDR_IN", header: "Winsock2.h".} = object sin_family*: int16 sin_port*: int16 # unsigned - sin_addr*: TInAddr + sin_addr*: InAddr sin_zero*: array[0..7, char] - Tin6_addr* {.pure, final, importc: "IN6_ADDR", header: "Winsock2.h".} = object + In6_addr* {.importc: "IN6_ADDR", header: "Winsock2.h".} = object bytes*: array[0..15, char] - Tsockaddr_in6* {.pure, final, importc: "SOCKADDR_IN6", + Sockaddr_in6* {.importc: "SOCKADDR_IN6", header: "Winsock2.h".} = object sin6_family*: int16 sin6_port*: int16 # unsigned sin6_flowinfo*: int32 # unsigned - sin6_addr*: Tin6_addr + sin6_addr*: In6_addr sin6_scope_id*: int32 # unsigned - Tsockaddr_in6_old* {.pure, final.} = object + Sockaddr_in6_old* = object sin6_family*: int16 sin6_port*: int16 # unsigned sin6_flowinfo*: int32 # unsigned - sin6_addr*: Tin6_addr + sin6_addr*: In6_addr - TServent* {.pure, final.} = object + Servent* = object s_name*: cstring s_aliases*: cstringArray when defined(cpu64): @@ -414,35 +416,42 @@ type s_port*: int16 s_proto*: cstring - Thostent* {.pure, final.} = object + Hostent* = object h_name*: cstring h_aliases*: cstringArray h_addrtype*: int16 h_length*: int16 h_addr_list*: cstringArray - TFdSet* {.pure, final.} = object + TFdSet* = object fd_count*: cint # unsigned - fd_array*: array[0..FD_SETSIZE-1, TSocketHandle] + fd_array*: array[0..FD_SETSIZE-1, SocketHandle] - TTimeval* {.pure, final.} = object + Timeval* = object tv_sec*, tv_usec*: int32 - TAddrInfo* {.pure, final.} = object + AddrInfo* = object ai_flags*: cint ## Input flags. ai_family*: cint ## Address family of socket. ai_socktype*: cint ## Socket type. ai_protocol*: cint ## Protocol of socket. ai_addrlen*: int ## Length of socket address. ai_canonname*: cstring ## Canonical name of service location. - ai_addr*: ptr TSockAddr ## Socket address of socket. - ai_next*: ptr TAddrInfo ## Pointer to next in list. + ai_addr*: ptr SockAddr ## Socket address of socket. + ai_next*: ptr AddrInfo ## Pointer to next in list. + + SockLen* = cuint + +{.deprecated: [TSockaddr_in: Sockaddr_in, TAddrinfo: AddrInfo, + TSockAddr: SockAddr, TSockLen: SockLen, TTimeval: Timeval, + TWSADATA: WSADATA, Thostent: Hostent, TServent: Servent, + TInAddr: InAddr, Tin6_addr: In6_addr, Tsockaddr_in6: Sockaddr_in6, + Tsockaddr_in6_old: Sockaddr_in6_old].} - TSockLen* = cuint var SOMAXCONN* {.importc, header: "Winsock2.h".}: cint - INVALID_SOCKET* {.importc, header: "Winsock2.h".}: TSocketHandle + INVALID_SOCKET* {.importc, header: "Winsock2.h".}: SocketHandle SOL_SOCKET* {.importc, header: "Winsock2.h".}: cint SO_DEBUG* {.importc, header: "Winsock2.h".}: cint ## turn on debugging info recording SO_ACCEPTCONN* {.importc, header: "Winsock2.h".}: cint # socket has had listen() @@ -458,94 +467,94 @@ var SO_EXCLUSIVEADDRUSE* {.importc, header: "Winsock2.h".}: cint # disallow local address reuse SO_ERROR* {.importc, header: "Winsock2.h".}: cint -proc `==`*(x, y: TSocketHandle): bool {.borrow.} +proc `==`*(x, y: SocketHandle): bool {.borrow.} -proc getservbyname*(name, proto: cstring): ptr TServent {. +proc getservbyname*(name, proto: cstring): ptr Servent {. stdcall, importc: "getservbyname", dynlib: ws2dll.} -proc getservbyport*(port: cint, proto: cstring): ptr TServent {. +proc getservbyport*(port: cint, proto: cstring): ptr Servent {. stdcall, importc: "getservbyport", dynlib: ws2dll.} -proc gethostbyaddr*(ip: ptr TInAddr, len: cuint, theType: cint): ptr Thostent {. +proc gethostbyaddr*(ip: ptr InAddr, len: cuint, theType: cint): ptr Hostent {. stdcall, importc: "gethostbyaddr", dynlib: ws2dll.} -proc gethostbyname*(name: cstring): ptr Thostent {. +proc gethostbyname*(name: cstring): ptr Hostent {. stdcall, importc: "gethostbyname", dynlib: ws2dll.} -proc socket*(af, typ, protocol: cint): TSocketHandle {. +proc socket*(af, typ, protocol: cint): SocketHandle {. stdcall, importc: "socket", dynlib: ws2dll.} -proc closesocket*(s: TSocketHandle): cint {. +proc closesocket*(s: SocketHandle): cint {. stdcall, importc: "closesocket", dynlib: ws2dll.} -proc accept*(s: TSocketHandle, a: ptr TSockAddr, addrlen: ptr TSockLen): TSocketHandle {. +proc accept*(s: SocketHandle, a: ptr SockAddr, addrlen: ptr SockLen): SocketHandle {. stdcall, importc: "accept", dynlib: ws2dll.} -proc bindSocket*(s: TSocketHandle, name: ptr TSockAddr, namelen: TSockLen): cint {. +proc bindSocket*(s: SocketHandle, name: ptr SockAddr, namelen: SockLen): cint {. stdcall, importc: "bind", dynlib: ws2dll.} -proc connect*(s: TSocketHandle, name: ptr TSockAddr, namelen: TSockLen): cint {. +proc connect*(s: SocketHandle, name: ptr SockAddr, namelen: SockLen): cint {. stdcall, importc: "connect", dynlib: ws2dll.} -proc getsockname*(s: TSocketHandle, name: ptr TSockAddr, - namelen: ptr TSockLen): cint {. +proc getsockname*(s: SocketHandle, name: ptr SockAddr, + namelen: ptr SockLen): cint {. stdcall, importc: "getsockname", dynlib: ws2dll.} -proc getsockopt*(s: TSocketHandle, level, optname: cint, optval: pointer, - optlen: ptr TSockLen): cint {. +proc getsockopt*(s: SocketHandle, level, optname: cint, optval: pointer, + optlen: ptr SockLen): cint {. stdcall, importc: "getsockopt", dynlib: ws2dll.} -proc setsockopt*(s: TSocketHandle, level, optname: cint, optval: pointer, - optlen: TSockLen): cint {. +proc setsockopt*(s: SocketHandle, level, optname: cint, optval: pointer, + optlen: SockLen): cint {. stdcall, importc: "setsockopt", dynlib: ws2dll.} -proc listen*(s: TSocketHandle, backlog: cint): cint {. +proc listen*(s: SocketHandle, backlog: cint): cint {. stdcall, importc: "listen", dynlib: ws2dll.} -proc recv*(s: TSocketHandle, buf: pointer, len, flags: cint): cint {. +proc recv*(s: SocketHandle, buf: pointer, len, flags: cint): cint {. stdcall, importc: "recv", dynlib: ws2dll.} -proc recvfrom*(s: TSocketHandle, buf: cstring, len, flags: cint, - fromm: ptr TSockAddr, fromlen: ptr TSockLen): cint {. +proc recvfrom*(s: SocketHandle, buf: cstring, len, flags: cint, + fromm: ptr SockAddr, fromlen: ptr SockLen): cint {. stdcall, importc: "recvfrom", dynlib: ws2dll.} proc select*(nfds: cint, readfds, writefds, exceptfds: ptr TFdSet, - timeout: ptr TTimeval): cint {. + timeout: ptr Timeval): cint {. stdcall, importc: "select", dynlib: ws2dll.} -proc send*(s: TSocketHandle, buf: pointer, len, flags: cint): cint {. +proc send*(s: SocketHandle, buf: pointer, len, flags: cint): cint {. stdcall, importc: "send", dynlib: ws2dll.} -proc sendto*(s: TSocketHandle, buf: pointer, len, flags: cint, - to: ptr TSockAddr, tolen: TSockLen): cint {. +proc sendto*(s: SocketHandle, buf: pointer, len, flags: cint, + to: ptr SockAddr, tolen: SockLen): cint {. stdcall, importc: "sendto", dynlib: ws2dll.} -proc shutdown*(s: TSocketHandle, how: cint): cint {. +proc shutdown*(s: SocketHandle, how: cint): cint {. stdcall, importc: "shutdown", dynlib: ws2dll.} -proc getnameinfo*(a1: ptr TSockAddr, a2: TSockLen, - a3: cstring, a4: TSockLen, a5: cstring, - a6: TSockLen, a7: cint): cint {. +proc getnameinfo*(a1: ptr SockAddr, a2: SockLen, + a3: cstring, a4: SockLen, a5: cstring, + a6: SockLen, a7: cint): cint {. stdcall, importc: "getnameinfo", dynlib: ws2dll.} proc inet_addr*(cp: cstring): int32 {. stdcall, importc: "inet_addr", dynlib: ws2dll.} -proc WSAFDIsSet(s: TSocketHandle, FDSet: var TFdSet): bool {. +proc WSAFDIsSet(s: SocketHandle, set: var TFdSet): bool {. stdcall, importc: "__WSAFDIsSet", dynlib: ws2dll, noSideEffect.} -proc FD_ISSET*(Socket: TSocketHandle, FDSet: var TFdSet): cint = - result = if WSAFDIsSet(Socket, FDSet): 1'i32 else: 0'i32 +proc FD_ISSET*(socket: SocketHandle, set: var TFdSet): cint = + result = if WSAFDIsSet(socket, set): 1'i32 else: 0'i32 -proc FD_SET*(Socket: TSocketHandle, FDSet: var TFdSet) = - if FDSet.fd_count < FD_SETSIZE: - FDSet.fd_array[int(FDSet.fd_count)] = Socket - inc(FDSet.fd_count) +proc FD_SET*(socket: SocketHandle, s: var TFdSet) = + if s.fd_count < FD_SETSIZE: + s.fd_array[int(s.fd_count)] = socket + inc(s.fd_count) -proc FD_ZERO*(FDSet: var TFdSet) = - FDSet.fd_count = 0 +proc FD_ZERO*(s: var TFdSet) = + s.fd_count = 0 -proc wsaStartup*(wVersionRequired: int16, WSData: ptr TWSAData): cint {. +proc wsaStartup*(wVersionRequired: int16, WSData: ptr WSAData): cint {. stdcall, importc: "WSAStartup", dynlib: ws2dll.} -proc getaddrinfo*(nodename, servname: cstring, hints: ptr TAddrInfo, - res: var ptr TAddrInfo): cint {. +proc getaddrinfo*(nodename, servname: cstring, hints: ptr AddrInfo, + res: var ptr AddrInfo): cint {. stdcall, importc: "getaddrinfo", dynlib: ws2dll.} -proc freeaddrinfo*(ai: ptr TAddrInfo) {. +proc freeaddrinfo*(ai: ptr AddrInfo) {. stdcall, importc: "freeaddrinfo", dynlib: ws2dll.} -proc inet_ntoa*(i: TInAddr): cstring {. +proc inet_ntoa*(i: InAddr): cstring {. stdcall, importc, dynlib: ws2dll.} const @@ -564,12 +573,14 @@ proc waitForMultipleObjects*(nCount: DWORD, lpHandles: PWOHandleArray, const GENERIC_READ* = 0x80000000'i32 + GENERIC_WRITE* = 0x40000000'i32 GENERIC_ALL* = 0x10000000'i32 FILE_SHARE_READ* = 1'i32 FILE_SHARE_DELETE* = 4'i32 FILE_SHARE_WRITE* = 2'i32 CREATE_ALWAYS* = 2'i32 + CREATE_NEW* = 1'i32 OPEN_EXISTING* = 3'i32 FILE_BEGIN* = 0'i32 INVALID_SET_FILE_POINTER* = -1'i32 @@ -586,6 +597,7 @@ const # Error Constants const ERROR_ACCESS_DENIED* = 5 + ERROR_HANDLE_EOF* = 38 when useWinUnicode: proc createFileW*(lpFileName: WideCString, dwDesiredAccess, dwShareMode: DWORD, @@ -640,11 +652,11 @@ proc unmapViewOfFile*(lpBaseAddress: pointer): WINBOOL {.stdcall, type TOVERLAPPED* {.pure, inheritable.} = object - Internal*: PULONG - InternalHigh*: PULONG - Offset*: DWORD - OffsetHigh*: DWORD - hEvent*: THANDLE + internal*: PULONG + internalHigh*: PULONG + offset*: DWORD + offsetHigh*: DWORD + hEvent*: THandle POVERLAPPED* = ptr TOVERLAPPED @@ -659,6 +671,7 @@ type const ERROR_IO_PENDING* = 997 # a.k.a WSA_IO_PENDING + FILE_FLAG_OVERLAPPED* = 1073741824 WSAECONNABORTED* = 10053 WSAECONNRESET* = 10054 WSAEDISCON* = 10101 @@ -666,17 +679,21 @@ const WSAETIMEDOUT* = 10060 ERROR_NETNAME_DELETED* = 64 -proc CreateIoCompletionPort*(FileHandle: THANDLE, ExistingCompletionPort: THANDLE, +proc createIoCompletionPort*(FileHandle: THandle, ExistingCompletionPort: THandle, CompletionKey: DWORD, - NumberOfConcurrentThreads: DWORD): THANDLE{.stdcall, + NumberOfConcurrentThreads: DWORD): THandle{.stdcall, dynlib: "kernel32", importc: "CreateIoCompletionPort".} -proc GetQueuedCompletionStatus*(CompletionPort: THandle, +proc getQueuedCompletionStatus*(CompletionPort: THandle, lpNumberOfBytesTransferred: PDWORD, lpCompletionKey: PULONG, - lpOverlapped: ptr POverlapped, + lpOverlapped: ptr POVERLAPPED, dwMilliseconds: DWORD): WINBOOL{.stdcall, dynlib: "kernel32", importc: "GetQueuedCompletionStatus".} +proc getOverlappedResult*(hFile: THandle, lpOverlapped: TOVERLAPPED, + lpNumberOfBytesTransferred: var DWORD, bWait: WINBOOL): WINBOOL{. + stdcall, dynlib: "kernel32", importc: "GetOverlappedResult".} + const IOC_OUT* = 0x40000000 IOC_IN* = 0x80000000 @@ -697,9 +714,9 @@ var WSAID_GETACCEPTEXSOCKADDRS*: TGUID = TGUID(D1: 0xb5367df2'i32, D2: 0xcbac'i16, D3: 0x11cf, D4: [ 0x95'i8, 0xca'i8, 0x00'i8, 0x80'i8, 0x5f'i8, 0x48'i8, 0xa1'i8, 0x92'i8]) -proc WSAIoctl*(s: TSocketHandle, dwIoControlCode: DWORD, lpvInBuffer: pointer, +proc WSAIoctl*(s: SocketHandle, dwIoControlCode: DWORD, lpvInBuffer: pointer, cbInBuffer: DWORD, lpvOutBuffer: pointer, cbOutBuffer: DWORD, - lpcbBytesReturned: PDword, lpOverlapped: POVERLAPPED, + lpcbBytesReturned: PDWORD, lpOverlapped: POVERLAPPED, lpCompletionRoutine: POVERLAPPED_COMPLETION_ROUTINE): cint {.stdcall, importc: "WSAIoctl", dynlib: "Ws2_32.dll".} @@ -708,17 +725,17 @@ type len*: ULONG buf*: cstring -proc WSARecv*(s: TSocketHandle, buf: ptr TWSABuf, bufCount: DWORD, - bytesReceived, flags: PDWORD, lpOverlapped: POverlapped, +proc WSARecv*(s: SocketHandle, buf: ptr TWSABuf, bufCount: DWORD, + bytesReceived, flags: PDWORD, lpOverlapped: POVERLAPPED, completionProc: POVERLAPPED_COMPLETION_ROUTINE): cint {. stdcall, importc: "WSARecv", dynlib: "Ws2_32.dll".} -proc WSASend*(s: TSocketHandle, buf: ptr TWSABuf, bufCount: DWORD, - bytesSent: PDWord, flags: DWORD, lpOverlapped: POverlapped, +proc WSASend*(s: SocketHandle, buf: ptr TWSABuf, bufCount: DWORD, + bytesSent: PDWORD, flags: DWORD, lpOverlapped: POVERLAPPED, completionProc: POVERLAPPED_COMPLETION_ROUTINE): cint {. stdcall, importc: "WSASend", dynlib: "Ws2_32.dll".} -proc get_osfhandle*(fd:TFileHandle): THandle {. +proc get_osfhandle*(fd:FileHandle): THandle {. importc: "_get_osfhandle", header:"<io.h>".} proc getSystemTimes*(lpIdleTime, lpKernelTime, diff --git a/lib/wrappers/expat.nim b/lib/wrappers/expat.nim index 3400dfdf7..a3d888201 100644 --- a/lib/wrappers/expat.nim +++ b/lib/wrappers/expat.nim @@ -77,8 +77,8 @@ type type TContent*{.pure, final.} = object - typ*: TContent_Type - quant*: TContent_Quant + typ*: TContentType + quant*: TContentQuant name*: cstring numchildren*: cint children*: ptr TContent @@ -93,7 +93,7 @@ type TElementDeclHandler* = proc (userData: pointer, name: cstring, model: ptr TContent){.cdecl.} -proc SetElementDeclHandler*(parser: PParser, eldecl: TElementDeclHandler){. +proc setElementDeclHandler*(parser: PParser, eldecl: TElementDeclHandler){. cdecl, importc: "XML_SetElementDeclHandler", dynlib: expatDll.} # The Attlist declaration handler is called for *each* attribute. So # a single Attlist declaration with multiple attributes declared will @@ -106,10 +106,10 @@ proc SetElementDeclHandler*(parser: PParser, eldecl: TElementDeclHandler){. type TAttlistDeclHandler* = proc (userData: pointer, elname: cstring, - attname: cstring, att_type: cstring, + attname: cstring, attType: cstring, dflt: cstring, isrequired: cint){.cdecl.} -proc SetAttlistDeclHandler*(parser: PParser, attdecl: TAttlistDeclHandler){. +proc setAttlistDeclHandler*(parser: PParser, attdecl: TAttlistDeclHandler){. cdecl, importc: "XML_SetAttlistDeclHandler", dynlib: expatDll.} # The XML declaration handler is called for *both* XML declarations # and text declarations. The way to distinguish is that the version @@ -124,20 +124,20 @@ type TXmlDeclHandler* = proc (userData: pointer, version: cstring, encoding: cstring, standalone: cint){.cdecl.} -proc SetXmlDeclHandler*(parser: PParser, xmldecl: TXmlDeclHandler){.cdecl, +proc setXmlDeclHandler*(parser: PParser, xmldecl: TXmlDeclHandler){.cdecl, importc: "XML_SetXmlDeclHandler", dynlib: expatDll.} type TMemory_Handling_Suite*{.pure, final.} = object - malloc_fcn*: proc (size: int): pointer{.cdecl.} - realloc_fcn*: proc (p: pointer, size: int): pointer{.cdecl.} - free_fcn*: proc (p: pointer){.cdecl.} + mallocFcn*: proc (size: int): pointer{.cdecl.} + reallocFcn*: proc (p: pointer, size: int): pointer{.cdecl.} + freeFcn*: proc (p: pointer){.cdecl.} # Constructs a new parser; encoding is the encoding specified by the # external protocol or NULL if there is none specified. # -proc ParserCreate*(encoding: cstring): PParser{.cdecl, +proc parserCreate*(encoding: cstring): PParser{.cdecl, importc: "XML_ParserCreate", dynlib: expatDll.} # Constructs a new parser and namespace processor. Element type # names and attribute names that belong to a namespace will be @@ -151,7 +151,7 @@ proc ParserCreate*(encoding: cstring): PParser{.cdecl, # triplets (see XML_SetReturnNSTriplet). # -proc ParserCreateNS*(encoding: cstring, namespaceSeparator: char): PParser{. +proc parserCreateNS*(encoding: cstring, namespaceSeparator: char): PParser{. cdecl, importc: "XML_ParserCreateNS", dynlib: expatDll.} # Constructs a new parser using the memory management suite referred to # by memsuite. If memsuite is NULL, then use the standard library memory @@ -163,7 +163,7 @@ proc ParserCreateNS*(encoding: cstring, namespaceSeparator: char): PParser{. # the given suite. # -proc ParserCreate_MM*(encoding: cstring, memsuite: ptr TMemory_Handling_Suite, +proc parserCreateMM*(encoding: cstring, memsuite: ptr TMemoryHandlingSuite, namespaceSeparator: cstring): PParser{.cdecl, importc: "XML_ParserCreate_MM", dynlib: expatDll.} # Prepare a parser object to be re-used. This is particularly @@ -176,7 +176,7 @@ proc ParserCreate_MM*(encoding: cstring, memsuite: ptr TMemory_Handling_Suite, # Added in Expat 1.95.3. # -proc ParserReset*(parser: PParser, encoding: cstring): Bool{.cdecl, +proc parserReset*(parser: PParser, encoding: cstring): bool{.cdecl, importc: "XML_ParserReset", dynlib: expatDll.} # atts is array of name/value pairs, terminated by 0; # names and values are 0 terminated. @@ -230,7 +230,7 @@ type type TStartDoctypeDeclHandler* = proc (userData: pointer, doctypeName: cstring, sysid: cstring, pubid: cstring, - has_internal_subset: cint){.cdecl.} + hasInternalSubset: cint){.cdecl.} # This is called for the start of the DOCTYPE declaration when the # closing > is encountered, but after processing any external @@ -261,12 +261,12 @@ type type TEntityDeclHandler* = proc (userData: pointer, entityName: cstring, - is_parameter_entity: cint, value: cstring, - value_length: cint, base: cstring, + isParameterEntity: cint, value: cstring, + valueLength: cint, base: cstring, systemId: cstring, publicId: cstring, notationName: cstring){.cdecl.} -proc SetEntityDeclHandler*(parser: PParser, handler: TEntityDeclHandler){.cdecl, +proc setEntityDeclHandler*(parser: PParser, handler: TEntityDeclHandler){.cdecl, importc: "XML_SetEntityDeclHandler", dynlib: expatDll.} # OBSOLETE -- OBSOLETE -- OBSOLETE # This handler has been superceded by the EntityDeclHandler above. @@ -372,7 +372,7 @@ type type TSkippedEntityHandler* = proc (userData: pointer, entityName: cstring, - is_parameter_entity: cint){.cdecl.} + isParameterEntity: cint){.cdecl.} # This structure is filled in by the XML_UnknownEncodingHandler to # provide information to the parser about encodings that are unknown @@ -455,27 +455,27 @@ type TUnknownEncodingHandler* = proc (encodingHandlerData: pointer, name: cstring, info: ptr TEncoding): cint{.cdecl.} -proc SetElementHandler*(parser: PParser, start: TStartElementHandler, +proc setElementHandler*(parser: PParser, start: TStartElementHandler, endHandler: TEndElementHandler){.cdecl, importc: "XML_SetElementHandler", dynlib: expatDll.} -proc SetStartElementHandler*(parser: PParser, handler: TStartElementHandler){. +proc setStartElementHandler*(parser: PParser, handler: TStartElementHandler){. cdecl, importc: "XML_SetStartElementHandler", dynlib: expatDll.} -proc SetEndElementHandler*(parser: PParser, handler: TEndElementHandler){.cdecl, +proc setEndElementHandler*(parser: PParser, handler: TEndElementHandler){.cdecl, importc: "XML_SetEndElementHandler", dynlib: expatDll.} -proc SetCharacterDataHandler*(parser: PParser, handler: TCharacterDataHandler){. +proc setCharacterDataHandler*(parser: PParser, handler: TCharacterDataHandler){. cdecl, importc: "XML_SetCharacterDataHandler", dynlib: expatDll.} -proc SetProcessingInstructionHandler*(parser: PParser, +proc setProcessingInstructionHandler*(parser: PParser, handler: TProcessingInstructionHandler){. cdecl, importc: "XML_SetProcessingInstructionHandler", dynlib: expatDll.} -proc SetCommentHandler*(parser: PParser, handler: TCommentHandler){.cdecl, +proc setCommentHandler*(parser: PParser, handler: TCommentHandler){.cdecl, importc: "XML_SetCommentHandler", dynlib: expatDll.} -proc SetCdataSectionHandler*(parser: PParser, start: TStartCdataSectionHandler, +proc setCdataSectionHandler*(parser: PParser, start: TStartCdataSectionHandler, endHandler: TEndCdataSectionHandler){.cdecl, importc: "XML_SetCdataSectionHandler", dynlib: expatDll.} -proc SetStartCdataSectionHandler*(parser: PParser, +proc setStartCdataSectionHandler*(parser: PParser, start: TStartCdataSectionHandler){.cdecl, importc: "XML_SetStartCdataSectionHandler", dynlib: expatDll.} -proc SetEndCdataSectionHandler*(parser: PParser, +proc setEndCdataSectionHandler*(parser: PParser, endHandler: TEndCdataSectionHandler){.cdecl, importc: "XML_SetEndCdataSectionHandler", dynlib: expatDll.} # This sets the default handler and also inhibits expansion of @@ -483,42 +483,42 @@ proc SetEndCdataSectionHandler*(parser: PParser, # default handler, or to the skipped entity handler, if one is set. # -proc SetDefaultHandler*(parser: PParser, handler: TDefaultHandler){.cdecl, +proc setDefaultHandler*(parser: PParser, handler: TDefaultHandler){.cdecl, importc: "XML_SetDefaultHandler", dynlib: expatDll.} # This sets the default handler but does not inhibit expansion of # internal entities. The entity reference will not be passed to the # default handler. # -proc SetDefaultHandlerExpand*(parser: PParser, handler: TDefaultHandler){.cdecl, +proc setDefaultHandlerExpand*(parser: PParser, handler: TDefaultHandler){.cdecl, importc: "XML_SetDefaultHandlerExpand", dynlib: expatDll.} -proc SetDoctypeDeclHandler*(parser: PParser, start: TStartDoctypeDeclHandler, +proc setDoctypeDeclHandler*(parser: PParser, start: TStartDoctypeDeclHandler, endHandler: TEndDoctypeDeclHandler){.cdecl, importc: "XML_SetDoctypeDeclHandler", dynlib: expatDll.} -proc SetStartDoctypeDeclHandler*(parser: PParser, +proc setStartDoctypeDeclHandler*(parser: PParser, start: TStartDoctypeDeclHandler){.cdecl, importc: "XML_SetStartDoctypeDeclHandler", dynlib: expatDll.} -proc SetEndDoctypeDeclHandler*(parser: PParser, +proc setEndDoctypeDeclHandler*(parser: PParser, endHandler: TEndDoctypeDeclHandler){.cdecl, importc: "XML_SetEndDoctypeDeclHandler", dynlib: expatDll.} -proc SetUnparsedEntityDeclHandler*(parser: PParser, +proc setUnparsedEntityDeclHandler*(parser: PParser, handler: TUnparsedEntityDeclHandler){.cdecl, importc: "XML_SetUnparsedEntityDeclHandler", dynlib: expatDll.} -proc SetNotationDeclHandler*(parser: PParser, handler: TNotationDeclHandler){. +proc setNotationDeclHandler*(parser: PParser, handler: TNotationDeclHandler){. cdecl, importc: "XML_SetNotationDeclHandler", dynlib: expatDll.} -proc SetNamespaceDeclHandler*(parser: PParser, +proc setNamespaceDeclHandler*(parser: PParser, start: TStartNamespaceDeclHandler, endHandler: TEndNamespaceDeclHandler){.cdecl, importc: "XML_SetNamespaceDeclHandler", dynlib: expatDll.} -proc SetStartNamespaceDeclHandler*(parser: PParser, +proc setStartNamespaceDeclHandler*(parser: PParser, start: TStartNamespaceDeclHandler){.cdecl, importc: "XML_SetStartNamespaceDeclHandler", dynlib: expatDll.} -proc SetEndNamespaceDeclHandler*(parser: PParser, +proc setEndNamespaceDeclHandler*(parser: PParser, endHandler: TEndNamespaceDeclHandler){.cdecl, importc: "XML_SetEndNamespaceDeclHandler", dynlib: expatDll.} -proc SetNotStandaloneHandler*(parser: PParser, handler: TNotStandaloneHandler){. +proc setNotStandaloneHandler*(parser: PParser, handler: TNotStandaloneHandler){. cdecl, importc: "XML_SetNotStandaloneHandler", dynlib: expatDll.} -proc SetExternalEntityRefHandler*(parser: PParser, +proc setExternalEntityRefHandler*(parser: PParser, handler: TExternalEntityRefHandler){.cdecl, importc: "XML_SetExternalEntityRefHandler", dynlib: expatDll.} # If a non-NULL value for arg is specified here, then it will be @@ -526,11 +526,11 @@ proc SetExternalEntityRefHandler*(parser: PParser, # instead of the parser object. # -proc SetExternalEntityRefHandlerArg*(parser: PParser, arg: pointer){.cdecl, +proc setExternalEntityRefHandlerArg*(parser: PParser, arg: pointer){.cdecl, importc: "XML_SetExternalEntityRefHandlerArg", dynlib: expatDll.} -proc SetSkippedEntityHandler*(parser: PParser, handler: TSkippedEntityHandler){. +proc setSkippedEntityHandler*(parser: PParser, handler: TSkippedEntityHandler){. cdecl, importc: "XML_SetSkippedEntityHandler", dynlib: expatDll.} -proc SetUnknownEncodingHandler*(parser: PParser, +proc setUnknownEncodingHandler*(parser: PParser, handler: TUnknownEncodingHandler, encodingHandlerData: pointer){.cdecl, importc: "XML_SetUnknownEncodingHandler", dynlib: expatDll.} @@ -539,7 +539,7 @@ proc SetUnknownEncodingHandler*(parser: PParser, # corresponding markup to be passed to the default handler. # -proc DefaultCurrent*(parser: PParser){.cdecl, importc: "XML_DefaultCurrent", +proc defaultCurrent*(parser: PParser){.cdecl, importc: "XML_DefaultCurrent", dynlib: expatDll.} # If do_nst is non-zero, and namespace processing is in effect, and # a name has a prefix (i.e. an explicit namespace qualifier) then @@ -555,15 +555,15 @@ proc DefaultCurrent*(parser: PParser){.cdecl, importc: "XML_DefaultCurrent", # XML_ParseBuffer has no effect. # -proc SetReturnNSTriplet*(parser: PParser, do_nst: cint){.cdecl, +proc setReturnNSTriplet*(parser: PParser, doNst: cint){.cdecl, importc: "XML_SetReturnNSTriplet", dynlib: expatDll.} # This value is passed as the userData argument to callbacks. -proc SetUserData*(parser: PParser, userData: pointer){.cdecl, +proc setUserData*(parser: PParser, userData: pointer){.cdecl, importc: "XML_SetUserData", dynlib: expatDll.} # Returns the last value set by XML_SetUserData or NULL. -template GetUserData*(parser: expr): expr = +template getUserData*(parser: expr): expr = (cast[ptr pointer]((parser))[] ) # This is equivalent to supplying an encoding argument to @@ -573,14 +573,14 @@ template GetUserData*(parser: expr): expr = # has no effect and returns XML_STATUS_ERROR. # -proc SetEncoding*(parser: PParser, encoding: cstring): TStatus{.cdecl, +proc setEncoding*(parser: PParser, encoding: cstring): TStatus{.cdecl, importc: "XML_SetEncoding", dynlib: expatDll.} # If this function is called, then the parser will be passed as the # first argument to callbacks instead of userData. The userData will # still be accessible using XML_GetUserData. # -proc UseParserAsHandlerArg*(parser: PParser){.cdecl, +proc useParserAsHandlerArg*(parser: PParser){.cdecl, importc: "XML_UseParserAsHandlerArg", dynlib: expatDll.} # If useDTD == XML_TRUE is passed to this function, then the parser # will assume that there is an external subset, even if none is @@ -601,7 +601,7 @@ proc UseParserAsHandlerArg*(parser: PParser){.cdecl, # XML_ERROR_FEATURE_REQUIRES_XML_DTD. # -proc UseForeignDTD*(parser: PParser, useDTD: Bool): TError{.cdecl, +proc useForeignDTD*(parser: PParser, useDTD: bool): TError{.cdecl, importc: "XML_UseForeignDTD", dynlib: expatDll.} # Sets the base to be used for resolving relative URIs in system # identifiers in declarations. Resolving relative identifiers is @@ -612,9 +612,9 @@ proc UseForeignDTD*(parser: PParser, useDTD: Bool): TError{.cdecl, # XML_STATUS_OK otherwise. # -proc SetBase*(parser: PParser, base: cstring): TStatus{.cdecl, +proc setBase*(parser: PParser, base: cstring): TStatus{.cdecl, importc: "XML_SetBase", dynlib: expatDll.} -proc GetBase*(parser: PParser): cstring{.cdecl, importc: "XML_GetBase", +proc getBase*(parser: PParser): cstring{.cdecl, importc: "XML_GetBase", dynlib: expatDll.} # Returns the number of the attribute/value pairs passed in last call # to the XML_StartElementHandler that were specified in the start-tag @@ -623,7 +623,7 @@ proc GetBase*(parser: PParser): cstring{.cdecl, importc: "XML_GetBase", # XML_StartElementHandler. # -proc GetSpecifiedAttributeCount*(parser: PParser): cint{.cdecl, +proc getSpecifiedAttributeCount*(parser: PParser): cint{.cdecl, importc: "XML_GetSpecifiedAttributeCount", dynlib: expatDll.} # Returns the index of the ID attribute passed in the last call to # XML_StartElementHandler, or -1 if there is no ID attribute. Each @@ -631,7 +631,7 @@ proc GetSpecifiedAttributeCount*(parser: PParser): cint{.cdecl, # index into the atts array passed to the XML_StartElementHandler. # -proc GetIdAttributeIndex*(parser: PParser): cint{.cdecl, +proc getIdAttributeIndex*(parser: PParser): cint{.cdecl, importc: "XML_GetIdAttributeIndex", dynlib: expatDll.} # Parses some input. Returns XML_STATUS_ERROR if a fatal error is # detected. The last call to XML_Parse must have isFinal true; len @@ -643,11 +643,11 @@ proc GetIdAttributeIndex*(parser: PParser): cint{.cdecl, # values. # -proc Parse*(parser: PParser, s: cstring, len: cint, isFinal: cint): TStatus{. +proc parse*(parser: PParser, s: cstring, len: cint, isFinal: cint): TStatus{. cdecl, importc: "XML_Parse", dynlib: expatDll.} -proc GetBuffer*(parser: PParser, len: cint): pointer{.cdecl, +proc getBuffer*(parser: PParser, len: cint): pointer{.cdecl, importc: "XML_GetBuffer", dynlib: expatDll.} -proc ParseBuffer*(parser: PParser, len: cint, isFinal: cint): TStatus{.cdecl, +proc parseBuffer*(parser: PParser, len: cint, isFinal: cint): TStatus{.cdecl, importc: "XML_ParseBuffer", dynlib: expatDll.} # Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return. # Must be called from within a call-back handler, except when aborting @@ -681,7 +681,7 @@ proc ParseBuffer*(parser: PParser, len: cint, isFinal: cint): TStatus{.cdecl, # When suspended, parsing can be resumed by calling XML_ResumeParser(). # -proc StopParser*(parser: PParser, resumable: Bool): TStatus{.cdecl, +proc stopParser*(parser: PParser, resumable: bool): TStatus{.cdecl, importc: "XML_StopParser", dynlib: expatDll.} # Resumes parsing after it has been suspended with XML_StopParser(). # Must not be called from within a handler call-back. Returns same @@ -696,14 +696,14 @@ proc StopParser*(parser: PParser, resumable: Bool): TStatus{.cdecl, # application to call XML_ResumeParser() on it at the appropriate moment. # -proc ResumeParser*(parser: PParser): TStatus{.cdecl, +proc resumeParser*(parser: PParser): TStatus{.cdecl, importc: "XML_ResumeParser", dynlib: expatDll.} type TParsing* = enum INITIALIZED, PARSING, FINISHED, SUSPENDED TParsingStatus*{.pure, final.} = object parsing*: TParsing - finalBuffer*: Bool + finalBuffer*: bool # Returns status of parser with respect to being initialized, parsing, @@ -712,7 +712,7 @@ type # XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED # -proc GetParsingStatus*(parser: PParser, status: ptr TParsingStatus){.cdecl, +proc getParsingStatus*(parser: PParser, status: ptr TParsingStatus){.cdecl, importc: "XML_GetParsingStatus", dynlib: expatDll.} # Creates an XML_Parser object that can parse an external general # entity; context is a '\0'-terminated string specifying the parse @@ -731,7 +731,7 @@ proc GetParsingStatus*(parser: PParser, status: ptr TParsingStatus){.cdecl, # Otherwise returns a new XML_Parser object. # -proc ExternalEntityParserCreate*(parser: PParser, context: cstring, +proc externalEntityParserCreate*(parser: PParser, context: cstring, encoding: cstring): PParser{.cdecl, importc: "XML_ExternalEntityParserCreate", dynlib: expatDll.} type @@ -763,13 +763,13 @@ type # XML_ParseBuffer, then it has no effect and will always return 0. # -proc SetParamEntityParsing*(parser: PParser, parsing: TParamEntityParsing): cint{. +proc setParamEntityParsing*(parser: PParser, parsing: TParamEntityParsing): cint{. cdecl, importc: "XML_SetParamEntityParsing", dynlib: expatDll.} # If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then # XML_GetErrorCode returns information about the error. # -proc GetErrorCode*(parser: PParser): TError{.cdecl, importc: "XML_GetErrorCode", +proc getErrorCode*(parser: PParser): TError{.cdecl, importc: "XML_GetErrorCode", dynlib: expatDll.} # These functions return information about the current parse # location. They may be called from any callback called to report @@ -788,17 +788,17 @@ proc GetErrorCode*(parser: PParser): TError{.cdecl, importc: "XML_GetErrorCode", # parse event, as described above. # -proc GetCurrentLineNumber*(parser: PParser): int{.cdecl, +proc getCurrentLineNumber*(parser: PParser): int{.cdecl, importc: "XML_GetCurrentLineNumber", dynlib: expatDll.} -proc GetCurrentColumnNumber*(parser: PParser): int{.cdecl, +proc getCurrentColumnNumber*(parser: PParser): int{.cdecl, importc: "XML_GetCurrentColumnNumber", dynlib: expatDll.} -proc GetCurrentByteIndex*(parser: PParser): int{.cdecl, +proc getCurrentByteIndex*(parser: PParser): int{.cdecl, importc: "XML_GetCurrentByteIndex", dynlib: expatDll.} # Return the number of bytes in the current event. # Returns 0 if the event is in an internal entity. # -proc GetCurrentByteCount*(parser: PParser): cint{.cdecl, +proc getCurrentByteCount*(parser: PParser): cint{.cdecl, importc: "XML_GetCurrentByteCount", dynlib: expatDll.} # If XML_CONTEXT_BYTES is defined, returns the input buffer, sets # the integer pointed to by offset to the offset within this buffer @@ -811,31 +811,31 @@ proc GetCurrentByteCount*(parser: PParser): cint{.cdecl, # the handler that makes the call. # -proc GetInputContext*(parser: PParser, offset: ptr cint, size: ptr cint): cstring{. +proc getInputContext*(parser: PParser, offset: ptr cint, size: ptr cint): cstring{. cdecl, importc: "XML_GetInputContext", dynlib: expatDll.} # Frees the content model passed to the element declaration handler -proc FreeContentModel*(parser: PParser, model: ptr TContent){.cdecl, +proc freeContentModel*(parser: PParser, model: ptr TContent){.cdecl, importc: "XML_FreeContentModel", dynlib: expatDll.} # Exposing the memory handling functions used in Expat -proc MemMalloc*(parser: PParser, size: int): pointer{.cdecl, +proc memMalloc*(parser: PParser, size: int): pointer{.cdecl, importc: "XML_MemMalloc", dynlib: expatDll.} -proc MemRealloc*(parser: PParser, p: pointer, size: int): pointer{.cdecl, +proc memRealloc*(parser: PParser, p: pointer, size: int): pointer{.cdecl, importc: "XML_MemRealloc", dynlib: expatDll.} -proc MemFree*(parser: PParser, p: pointer){.cdecl, importc: "XML_MemFree", +proc memFree*(parser: PParser, p: pointer){.cdecl, importc: "XML_MemFree", dynlib: expatDll.} # Frees memory used by the parser. -proc ParserFree*(parser: PParser){.cdecl, importc: "XML_ParserFree", +proc parserFree*(parser: PParser){.cdecl, importc: "XML_ParserFree", dynlib: expatDll.} # Returns a string describing the error. -proc ErrorString*(code: TError): cstring{.cdecl, importc: "XML_ErrorString", +proc errorString*(code: TError): cstring{.cdecl, importc: "XML_ErrorString", dynlib: expatDll.} # Return a string containing the version number of this expat -proc ExpatVersion*(): cstring{.cdecl, importc: "XML_ExpatVersion", +proc expatVersion*(): cstring{.cdecl, importc: "XML_ExpatVersion", dynlib: expatDll.} type TExpat_Version*{.pure, final.} = object @@ -848,7 +848,7 @@ type # number information for this version of expat. # -proc ExpatVersionInfo*(): TExpat_Version{.cdecl, +proc expatVersionInfo*(): TExpatVersion{.cdecl, importc: "XML_ExpatVersionInfo", dynlib: expatDll.} # Added in Expat 1.95.5. @@ -863,7 +863,7 @@ type value*: int -proc GetFeatureList*(): ptr TFeature{.cdecl, importc: "XML_GetFeatureList", +proc getFeatureList*(): ptr TFeature{.cdecl, importc: "XML_GetFeatureList", dynlib: expatDll.} # Expat follows the GNU/Linux convention of odd number minor version for # beta/development releases and even number minor version for stable diff --git a/lib/wrappers/iup.nim b/lib/wrappers/iup.nim index 2ee1ca3ee..6695dc5e2 100644 --- a/lib/wrappers/iup.nim +++ b/lib/wrappers/iup.nim @@ -46,321 +46,321 @@ const constIUP_VERSION_DATE* = "2009/07/18" type - Ihandle {.pure.} = object + Ihandle = object PIhandle* = ptr Ihandle Icallback* = proc (arg: PIhandle): cint {.cdecl.} -# pre-definided dialogs -proc FileDlg*: PIhandle {.importc: "IupFileDlg", dynlib: dllname, cdecl.} -proc MessageDlg*: PIhandle {.importc: "IupMessageDlg", dynlib: dllname, cdecl.} -proc ColorDlg*: PIhandle {.importc: "IupColorDlg", dynlib: dllname, cdecl.} -proc FontDlg*: PIhandle {.importc: "IupFontDlg", dynlib: dllname, cdecl.} +# pre-defineded dialogs +proc fileDlg*: PIhandle {.importc: "IupFileDlg", dynlib: dllname, cdecl.} +proc messageDlg*: PIhandle {.importc: "IupMessageDlg", dynlib: dllname, cdecl.} +proc colorDlg*: PIhandle {.importc: "IupColorDlg", dynlib: dllname, cdecl.} +proc fontDlg*: PIhandle {.importc: "IupFontDlg", dynlib: dllname, cdecl.} -proc GetFile*(arq: cstring): cint {. +proc getFile*(arq: cstring): cint {. importc: "IupGetFile", dynlib: dllname, cdecl.} -proc Message*(title, msg: cstring) {. +proc message*(title, msg: cstring) {. importc: "IupMessage", dynlib: dllname, cdecl.} -proc Messagef*(title, format: cstring) {. +proc messagef*(title, format: cstring) {. importc: "IupMessagef", dynlib: dllname, cdecl, varargs.} -proc Alarm*(title, msg, b1, b2, b3: cstring): cint {. +proc alarm*(title, msg, b1, b2, b3: cstring): cint {. importc: "IupAlarm", dynlib: dllname, cdecl.} -proc Scanf*(format: cstring): cint {. +proc scanf*(format: cstring): cint {. importc: "IupScanf", dynlib: dllname, cdecl, varargs.} -proc ListDialog*(theType: cint, title: cstring, size: cint, - list: cstringArray, op, max_col, max_lin: cint, +proc listDialog*(theType: cint, title: cstring, size: cint, + list: cstringArray, op, maxCol, maxLin: cint, marks: ptr cint): cint {. importc: "IupListDialog", dynlib: dllname, cdecl.} -proc GetText*(title, text: cstring): cint {. +proc getText*(title, text: cstring): cint {. importc: "IupGetText", dynlib: dllname, cdecl.} -proc GetColor*(x, y: cint, r, g, b: var byte): cint {. +proc getColor*(x, y: cint, r, g, b: var byte): cint {. importc: "IupGetColor", dynlib: dllname, cdecl.} type - Iparamcb* = proc (dialog: PIhandle, param_index: cint, - user_data: pointer): cint {.cdecl.} + Iparamcb* = proc (dialog: PIhandle, paramIndex: cint, + userData: pointer): cint {.cdecl.} -proc GetParam*(title: cstring, action: Iparamcb, user_data: pointer, +proc getParam*(title: cstring, action: Iparamcb, userData: pointer, format: cstring): cint {. importc: "IupGetParam", cdecl, varargs, dynlib: dllname.} -proc GetParamv*(title: cstring, action: Iparamcb, user_data: pointer, - format: cstring, param_count, param_extra: cint, - param_data: pointer): cint {. +proc getParamv*(title: cstring, action: Iparamcb, userData: pointer, + format: cstring, paramCount, paramExtra: cint, + paramData: pointer): cint {. importc: "IupGetParamv", cdecl, dynlib: dllname.} # Functions -proc Open*(argc: ptr cint, argv: ptr cstringArray): cint {. +proc open*(argc: ptr cint, argv: ptr cstringArray): cint {. importc: "IupOpen", cdecl, dynlib: dllname.} -proc Close*() {.importc: "IupClose", cdecl, dynlib: dllname.} -proc ImageLibOpen*() {.importc: "IupImageLibOpen", cdecl, dynlib: dllname.} +proc close*() {.importc: "IupClose", cdecl, dynlib: dllname.} +proc imageLibOpen*() {.importc: "IupImageLibOpen", cdecl, dynlib: dllname.} -proc MainLoop*(): cint {.importc: "IupMainLoop", cdecl, dynlib: dllname, +proc mainLoop*(): cint {.importc: "IupMainLoop", cdecl, dynlib: dllname, discardable.} -proc LoopStep*(): cint {.importc: "IupLoopStep", cdecl, dynlib: dllname, +proc loopStep*(): cint {.importc: "IupLoopStep", cdecl, dynlib: dllname, discardable.} -proc MainLoopLevel*(): cint {.importc: "IupMainLoopLevel", cdecl, +proc mainLoopLevel*(): cint {.importc: "IupMainLoopLevel", cdecl, dynlib: dllname, discardable.} -proc Flush*() {.importc: "IupFlush", cdecl, dynlib: dllname.} -proc ExitLoop*() {.importc: "IupExitLoop", cdecl, dynlib: dllname.} - -proc Update*(ih: PIhandle) {.importc: "IupUpdate", cdecl, dynlib: dllname.} -proc UpdateChildren*(ih: PIhandle) {.importc: "IupUpdateChildren", cdecl, dynlib: dllname.} -proc Redraw*(ih: PIhandle, children: cint) {.importc: "IupRedraw", cdecl, dynlib: dllname.} -proc Refresh*(ih: PIhandle) {.importc: "IupRefresh", cdecl, dynlib: dllname.} - -proc MapFont*(iupfont: cstring): cstring {.importc: "IupMapFont", cdecl, dynlib: dllname.} -proc UnMapFont*(driverfont: cstring): cstring {.importc: "IupUnMapFont", cdecl, dynlib: dllname.} -proc Help*(url: cstring): cint {.importc: "IupHelp", cdecl, dynlib: dllname.} -proc Load*(filename: cstring): cstring {.importc: "IupLoad", cdecl, dynlib: dllname.} - -proc IupVersion*(): cstring {.importc: "IupVersion", cdecl, dynlib: dllname.} -proc IupVersionDate*(): cstring {.importc: "IupVersionDate", cdecl, dynlib: dllname.} -proc IupVersionNumber*(): cint {.importc: "IupVersionNumber", cdecl, dynlib: dllname.} -proc SetLanguage*(lng: cstring) {.importc: "IupSetLanguage", cdecl, dynlib: dllname.} -proc GetLanguage*(): cstring {.importc: "IupGetLanguage", cdecl, dynlib: dllname.} - -proc Destroy*(ih: PIhandle) {.importc: "IupDestroy", cdecl, dynlib: dllname.} -proc Detach*(child: PIhandle) {.importc: "IupDetach", cdecl, dynlib: dllname.} -proc Append*(ih, child: PIhandle): PIhandle {. +proc flush*() {.importc: "IupFlush", cdecl, dynlib: dllname.} +proc exitLoop*() {.importc: "IupExitLoop", cdecl, dynlib: dllname.} + +proc update*(ih: PIhandle) {.importc: "IupUpdate", cdecl, dynlib: dllname.} +proc updateChildren*(ih: PIhandle) {.importc: "IupUpdateChildren", cdecl, dynlib: dllname.} +proc redraw*(ih: PIhandle, children: cint) {.importc: "IupRedraw", cdecl, dynlib: dllname.} +proc refresh*(ih: PIhandle) {.importc: "IupRefresh", cdecl, dynlib: dllname.} + +proc mapFont*(iupfont: cstring): cstring {.importc: "IupMapFont", cdecl, dynlib: dllname.} +proc unMapFont*(driverfont: cstring): cstring {.importc: "IupUnMapFont", cdecl, dynlib: dllname.} +proc help*(url: cstring): cint {.importc: "IupHelp", cdecl, dynlib: dllname.} +proc load*(filename: cstring): cstring {.importc: "IupLoad", cdecl, dynlib: dllname.} + +proc iupVersion*(): cstring {.importc: "IupVersion", cdecl, dynlib: dllname.} +proc iupVersionDate*(): cstring {.importc: "IupVersionDate", cdecl, dynlib: dllname.} +proc iupVersionNumber*(): cint {.importc: "IupVersionNumber", cdecl, dynlib: dllname.} +proc setLanguage*(lng: cstring) {.importc: "IupSetLanguage", cdecl, dynlib: dllname.} +proc getLanguage*(): cstring {.importc: "IupGetLanguage", cdecl, dynlib: dllname.} + +proc destroy*(ih: PIhandle) {.importc: "IupDestroy", cdecl, dynlib: dllname.} +proc detach*(child: PIhandle) {.importc: "IupDetach", cdecl, dynlib: dllname.} +proc append*(ih, child: PIhandle): PIhandle {. importc: "IupAppend", cdecl, dynlib: dllname, discardable.} -proc Insert*(ih, ref_child, child: PIhandle): PIhandle {. +proc insert*(ih, refChild, child: PIhandle): PIhandle {. importc: "IupInsert", cdecl, dynlib: dllname, discardable.} -proc GetChild*(ih: PIhandle, pos: cint): PIhandle {. +proc getChild*(ih: PIhandle, pos: cint): PIhandle {. importc: "IupGetChild", cdecl, dynlib: dllname.} -proc GetChildPos*(ih, child: PIhandle): cint {. +proc getChildPos*(ih, child: PIhandle): cint {. importc: "IupGetChildPos", cdecl, dynlib: dllname.} -proc GetChildCount*(ih: PIhandle): cint {. +proc getChildCount*(ih: PIhandle): cint {. importc: "IupGetChildCount", cdecl, dynlib: dllname.} -proc GetNextChild*(ih, child: PIhandle): PIhandle {. +proc getNextChild*(ih, child: PIhandle): PIhandle {. importc: "IupGetNextChild", cdecl, dynlib: dllname.} -proc GetBrother*(ih: PIhandle): PIhandle {. +proc getBrother*(ih: PIhandle): PIhandle {. importc: "IupGetBrother", cdecl, dynlib: dllname.} -proc GetParent*(ih: PIhandle): PIhandle {. +proc getParent*(ih: PIhandle): PIhandle {. importc: "IupGetParent", cdecl, dynlib: dllname.} -proc GetDialog*(ih: PIhandle): PIhandle {. +proc getDialog*(ih: PIhandle): PIhandle {. importc: "IupGetDialog", cdecl, dynlib: dllname.} -proc GetDialogChild*(ih: PIhandle, name: cstring): PIhandle {. +proc getDialogChild*(ih: PIhandle, name: cstring): PIhandle {. importc: "IupGetDialogChild", cdecl, dynlib: dllname.} -proc Reparent*(ih, new_parent: PIhandle): cint {. +proc reparent*(ih, newParent: PIhandle): cint {. importc: "IupReparent", cdecl, dynlib: dllname.} -proc Popup*(ih: PIhandle, x, y: cint): cint {. +proc popup*(ih: PIhandle, x, y: cint): cint {. importc: "IupPopup", cdecl, dynlib: dllname, discardable.} -proc Show*(ih: PIhandle): cint {. +proc show*(ih: PIhandle): cint {. importc: "IupShow", cdecl, dynlib: dllname, discardable.} -proc ShowXY*(ih: PIhandle, x, y: cint): cint {. +proc showXY*(ih: PIhandle, x, y: cint): cint {. importc: "IupShowXY", cdecl, dynlib: dllname, discardable.} -proc Hide*(ih: PIhandle): cint {. +proc hide*(ih: PIhandle): cint {. importc: "IupHide", cdecl, dynlib: dllname, discardable.} -proc Map*(ih: PIhandle): cint {. +proc map*(ih: PIhandle): cint {. importc: "IupMap", cdecl, dynlib: dllname, discardable.} -proc Unmap*(ih: PIhandle) {. +proc unmap*(ih: PIhandle) {. importc: "IupUnmap", cdecl, dynlib: dllname, discardable.} -proc SetAttribute*(ih: PIhandle, name, value: cstring) {. +proc setAttribute*(ih: PIhandle, name, value: cstring) {. importc: "IupSetAttribute", cdecl, dynlib: dllname.} -proc StoreAttribute*(ih: PIhandle, name, value: cstring) {. +proc storeAttribute*(ih: PIhandle, name, value: cstring) {. importc: "IupStoreAttribute", cdecl, dynlib: dllname.} -proc SetAttributes*(ih: PIhandle, str: cstring): PIhandle {. +proc setAttributes*(ih: PIhandle, str: cstring): PIhandle {. importc: "IupSetAttributes", cdecl, dynlib: dllname.} -proc GetAttribute*(ih: PIhandle, name: cstring): cstring {. +proc getAttribute*(ih: PIhandle, name: cstring): cstring {. importc: "IupGetAttribute", cdecl, dynlib: dllname.} -proc GetAttributes*(ih: PIhandle): cstring {. +proc getAttributes*(ih: PIhandle): cstring {. importc: "IupGetAttributes", cdecl, dynlib: dllname.} -proc GetInt*(ih: PIhandle, name: cstring): cint {. +proc getInt*(ih: PIhandle, name: cstring): cint {. importc: "IupGetInt", cdecl, dynlib: dllname.} -proc GetInt2*(ih: PIhandle, name: cstring): cint {. +proc getInt2*(ih: PIhandle, name: cstring): cint {. importc: "IupGetInt2", cdecl, dynlib: dllname.} -proc GetIntInt*(ih: PIhandle, name: cstring, i1, i2: var cint): cint {. +proc getIntInt*(ih: PIhandle, name: cstring, i1, i2: var cint): cint {. importc: "IupGetIntInt", cdecl, dynlib: dllname.} -proc GetFloat*(ih: PIhandle, name: cstring): cfloat {. +proc getFloat*(ih: PIhandle, name: cstring): cfloat {. importc: "IupGetFloat", cdecl, dynlib: dllname.} -proc SetfAttribute*(ih: PIhandle, name, format: cstring) {. +proc setfAttribute*(ih: PIhandle, name, format: cstring) {. importc: "IupSetfAttribute", cdecl, dynlib: dllname, varargs.} -proc GetAllAttributes*(ih: PIhandle, names: cstringArray, n: cint): cint {. +proc getAllAttributes*(ih: PIhandle, names: cstringArray, n: cint): cint {. importc: "IupGetAllAttributes", cdecl, dynlib: dllname.} -proc SetAtt*(handle_name: cstring, ih: PIhandle, name: cstring): PIhandle {. +proc setAtt*(handleName: cstring, ih: PIhandle, name: cstring): PIhandle {. importc: "IupSetAtt", cdecl, dynlib: dllname, varargs, discardable.} -proc SetGlobal*(name, value: cstring) {. +proc setGlobal*(name, value: cstring) {. importc: "IupSetGlobal", cdecl, dynlib: dllname.} -proc StoreGlobal*(name, value: cstring) {. +proc storeGlobal*(name, value: cstring) {. importc: "IupStoreGlobal", cdecl, dynlib: dllname.} -proc GetGlobal*(name: cstring): cstring {. +proc getGlobal*(name: cstring): cstring {. importc: "IupGetGlobal", cdecl, dynlib: dllname.} -proc SetFocus*(ih: PIhandle): PIhandle {. +proc setFocus*(ih: PIhandle): PIhandle {. importc: "IupSetFocus", cdecl, dynlib: dllname.} -proc GetFocus*(): PIhandle {. +proc getFocus*(): PIhandle {. importc: "IupGetFocus", cdecl, dynlib: dllname.} -proc PreviousField*(ih: PIhandle): PIhandle {. +proc previousField*(ih: PIhandle): PIhandle {. importc: "IupPreviousField", cdecl, dynlib: dllname.} -proc NextField*(ih: PIhandle): PIhandle {. +proc nextField*(ih: PIhandle): PIhandle {. importc: "IupNextField", cdecl, dynlib: dllname.} -proc GetCallback*(ih: PIhandle, name: cstring): Icallback {. +proc getCallback*(ih: PIhandle, name: cstring): Icallback {. importc: "IupGetCallback", cdecl, dynlib: dllname.} -proc SetCallback*(ih: PIhandle, name: cstring, func: Icallback): Icallback {. +proc setCallback*(ih: PIhandle, name: cstring, func: Icallback): Icallback {. importc: "IupSetCallback", cdecl, dynlib: dllname, discardable.} -proc SetCallbacks*(ih: PIhandle, name: cstring, func: Icallback): PIhandle {. +proc setCallbacks*(ih: PIhandle, name: cstring, func: Icallback): PIhandle {. importc: "IupSetCallbacks", cdecl, dynlib: dllname, varargs, discardable.} -proc GetFunction*(name: cstring): Icallback {. +proc getFunction*(name: cstring): Icallback {. importc: "IupGetFunction", cdecl, dynlib: dllname.} -proc SetFunction*(name: cstring, func: Icallback): Icallback {. +proc setFunction*(name: cstring, func: Icallback): Icallback {. importc: "IupSetFunction", cdecl, dynlib: dllname, discardable.} -proc GetActionName*(): cstring {. +proc getActionName*(): cstring {. importc: "IupGetActionName", cdecl, dynlib: dllname.} -proc GetHandle*(name: cstring): PIhandle {. +proc getHandle*(name: cstring): PIhandle {. importc: "IupGetHandle", cdecl, dynlib: dllname.} -proc SetHandle*(name: cstring, ih: PIhandle): PIhandle {. +proc setHandle*(name: cstring, ih: PIhandle): PIhandle {. importc: "IupSetHandle", cdecl, dynlib: dllname.} -proc GetAllNames*(names: cstringArray, n: cint): cint {. +proc getAllNames*(names: cstringArray, n: cint): cint {. importc: "IupGetAllNames", cdecl, dynlib: dllname.} -proc GetAllDialogs*(names: cstringArray, n: cint): cint {. +proc getAllDialogs*(names: cstringArray, n: cint): cint {. importc: "IupGetAllDialogs", cdecl, dynlib: dllname.} -proc GetName*(ih: PIhandle): cstring {. +proc getName*(ih: PIhandle): cstring {. importc: "IupGetName", cdecl, dynlib: dllname.} -proc SetAttributeHandle*(ih: PIhandle, name: cstring, ih_named: PIhandle) {. +proc setAttributeHandle*(ih: PIhandle, name: cstring, ihNamed: PIhandle) {. importc: "IupSetAttributeHandle", cdecl, dynlib: dllname.} -proc GetAttributeHandle*(ih: PIhandle, name: cstring): PIhandle {. +proc getAttributeHandle*(ih: PIhandle, name: cstring): PIhandle {. importc: "IupGetAttributeHandle", cdecl, dynlib: dllname.} -proc GetClassName*(ih: PIhandle): cstring {. +proc getClassName*(ih: PIhandle): cstring {. importc: "IupGetClassName", cdecl, dynlib: dllname.} -proc GetClassType*(ih: PIhandle): cstring {. +proc getClassType*(ih: PIhandle): cstring {. importc: "IupGetClassType", cdecl, dynlib: dllname.} -proc GetClassAttributes*(classname: cstring, names: cstringArray, +proc getClassAttributes*(classname: cstring, names: cstringArray, n: cint): cint {. importc: "IupGetClassAttributes", cdecl, dynlib: dllname.} -proc SaveClassAttributes*(ih: PIhandle) {. +proc saveClassAttributes*(ih: PIhandle) {. importc: "IupSaveClassAttributes", cdecl, dynlib: dllname.} -proc SetClassDefaultAttribute*(classname, name, value: cstring) {. +proc setClassDefaultAttribute*(classname, name, value: cstring) {. importc: "IupSetClassDefaultAttribute", cdecl, dynlib: dllname.} -proc Create*(classname: cstring): PIhandle {. +proc create*(classname: cstring): PIhandle {. importc: "IupCreate", cdecl, dynlib: dllname.} -proc Createv*(classname: cstring, params: pointer): PIhandle {. +proc createv*(classname: cstring, params: pointer): PIhandle {. importc: "IupCreatev", cdecl, dynlib: dllname.} -proc Createp*(classname: cstring, first: pointer): PIhandle {. +proc createp*(classname: cstring, first: pointer): PIhandle {. importc: "IupCreatep", cdecl, dynlib: dllname, varargs.} -proc Fill*(): PIhandle {.importc: "IupFill", cdecl, dynlib: dllname.} -proc Radio*(child: PIhandle): PIhandle {. +proc fill*(): PIhandle {.importc: "IupFill", cdecl, dynlib: dllname.} +proc radio*(child: PIhandle): PIhandle {. importc: "IupRadio", cdecl, dynlib: dllname.} -proc Vbox*(child: PIhandle): PIhandle {. +proc vbox*(child: PIhandle): PIhandle {. importc: "IupVbox", cdecl, dynlib: dllname, varargs.} -proc Vboxv*(children: ptr PIhandle): PIhandle {. +proc vboxv*(children: ptr PIhandle): PIhandle {. importc: "IupVboxv", cdecl, dynlib: dllname.} -proc Zbox*(child: PIhandle): PIhandle {. +proc zbox*(child: PIhandle): PIhandle {. importc: "IupZbox", cdecl, dynlib: dllname, varargs.} -proc Zboxv*(children: ptr PIhandle): PIhandle {. +proc zboxv*(children: ptr PIhandle): PIhandle {. importc: "IupZboxv", cdecl, dynlib: dllname.} -proc Hbox*(child: PIhandle): PIhandle {. +proc hbox*(child: PIhandle): PIhandle {. importc: "IupHbox", cdecl, dynlib: dllname, varargs.} -proc Hboxv*(children: ptr PIhandle): PIhandle {. +proc hboxv*(children: ptr PIhandle): PIhandle {. importc: "IupHboxv", cdecl, dynlib: dllname.} -proc Normalizer*(ih_first: PIhandle): PIhandle {. +proc normalizer*(ihFirst: PIhandle): PIhandle {. importc: "IupNormalizer", cdecl, dynlib: dllname, varargs.} -proc Normalizerv*(ih_list: ptr PIhandle): PIhandle {. +proc normalizerv*(ihList: ptr PIhandle): PIhandle {. importc: "IupNormalizerv", cdecl, dynlib: dllname.} -proc Cbox*(child: PIhandle): PIhandle {. +proc cbox*(child: PIhandle): PIhandle {. importc: "IupCbox", cdecl, dynlib: dllname, varargs.} -proc Cboxv*(children: ptr PIhandle): PIhandle {. +proc cboxv*(children: ptr PIhandle): PIhandle {. importc: "IupCboxv", cdecl, dynlib: dllname.} -proc Sbox*(child: PIhandle): PIhandle {. +proc sbox*(child: PIhandle): PIhandle {. importc: "IupSbox", cdecl, dynlib: dllname.} -proc Frame*(child: PIhandle): PIhandle {. +proc frame*(child: PIhandle): PIhandle {. importc: "IupFrame", cdecl, dynlib: dllname.} -proc Image*(width, height: cint, pixmap: pointer): PIhandle {. +proc image*(width, height: cint, pixmap: pointer): PIhandle {. importc: "IupImage", cdecl, dynlib: dllname.} -proc ImageRGB*(width, height: cint, pixmap: pointer): PIhandle {. +proc imageRGB*(width, height: cint, pixmap: pointer): PIhandle {. importc: "IupImageRGB", cdecl, dynlib: dllname.} -proc ImageRGBA*(width, height: cint, pixmap: pointer): PIhandle {. +proc imageRGBA*(width, height: cint, pixmap: pointer): PIhandle {. importc: "IupImageRGBA", cdecl, dynlib: dllname.} -proc Item*(title, action: cstring): PIhandle {. +proc item*(title, action: cstring): PIhandle {. importc: "IupItem", cdecl, dynlib: dllname.} -proc Submenu*(title: cstring, child: PIhandle): PIhandle {. +proc submenu*(title: cstring, child: PIhandle): PIhandle {. importc: "IupSubmenu", cdecl, dynlib: dllname.} -proc Separator*(): PIhandle {. +proc separator*(): PIhandle {. importc: "IupSeparator", cdecl, dynlib: dllname.} -proc Menu*(child: PIhandle): PIhandle {. +proc menu*(child: PIhandle): PIhandle {. importc: "IupMenu", cdecl, dynlib: dllname, varargs.} -proc Menuv*(children: ptr PIhandle): PIhandle {. +proc menuv*(children: ptr PIhandle): PIhandle {. importc: "IupMenuv", cdecl, dynlib: dllname.} -proc Button*(title, action: cstring): PIhandle {. +proc button*(title, action: cstring): PIhandle {. importc: "IupButton", cdecl, dynlib: dllname.} -proc Canvas*(action: cstring): PIhandle {. +proc canvas*(action: cstring): PIhandle {. importc: "IupCanvas", cdecl, dynlib: dllname.} -proc Dialog*(child: PIhandle): PIhandle {. +proc dialog*(child: PIhandle): PIhandle {. importc: "IupDialog", cdecl, dynlib: dllname.} -proc User*(): PIhandle {. +proc user*(): PIhandle {. importc: "IupUser", cdecl, dynlib: dllname.} -proc Label*(title: cstring): PIhandle {. +proc label*(title: cstring): PIhandle {. importc: "IupLabel", cdecl, dynlib: dllname.} -proc List*(action: cstring): PIhandle {. +proc list*(action: cstring): PIhandle {. importc: "IupList", cdecl, dynlib: dllname.} -proc Text*(action: cstring): PIhandle {. +proc text*(action: cstring): PIhandle {. importc: "IupText", cdecl, dynlib: dllname.} -proc MultiLine*(action: cstring): PIhandle {. +proc multiLine*(action: cstring): PIhandle {. importc: "IupMultiLine", cdecl, dynlib: dllname.} -proc Toggle*(title, action: cstring): PIhandle {. +proc toggle*(title, action: cstring): PIhandle {. importc: "IupToggle", cdecl, dynlib: dllname.} -proc Timer*(): PIhandle {. +proc timer*(): PIhandle {. importc: "IupTimer", cdecl, dynlib: dllname.} -proc ProgressBar*(): PIhandle {. +proc progressBar*(): PIhandle {. importc: "IupProgressBar", cdecl, dynlib: dllname.} -proc Val*(theType: cstring): PIhandle {. +proc val*(theType: cstring): PIhandle {. importc: "IupVal", cdecl, dynlib: dllname.} -proc Tabs*(child: PIhandle): PIhandle {. +proc tabs*(child: PIhandle): PIhandle {. importc: "IupTabs", cdecl, dynlib: dllname, varargs.} -proc Tabsv*(children: ptr PIhandle): PIhandle {. +proc tabsv*(children: ptr PIhandle): PIhandle {. importc: "IupTabsv", cdecl, dynlib: dllname.} -proc Tree*(): PIhandle {.importc: "IupTree", cdecl, dynlib: dllname.} +proc tree*(): PIhandle {.importc: "IupTree", cdecl, dynlib: dllname.} -proc Spin*(): PIhandle {.importc: "IupSpin", cdecl, dynlib: dllname.} -proc Spinbox*(child: PIhandle): PIhandle {. +proc spin*(): PIhandle {.importc: "IupSpin", cdecl, dynlib: dllname.} +proc spinbox*(child: PIhandle): PIhandle {. importc: "IupSpinbox", cdecl, dynlib: dllname.} # IupText utilities -proc TextConvertLinColToPos*(ih: PIhandle, lin, col: cint, pos: var cint) {. +proc textConvertLinColToPos*(ih: PIhandle, lin, col: cint, pos: var cint) {. importc: "IupTextConvertLinColToPos", cdecl, dynlib: dllname.} -proc TextConvertPosToLinCol*(ih: PIhandle, pos: cint, lin, col: var cint) {. +proc textConvertPosToLinCol*(ih: PIhandle, pos: cint, lin, col: var cint) {. importc: "IupTextConvertPosToLinCol", cdecl, dynlib: dllname.} -proc ConvertXYToPos*(ih: PIhandle, x, y: cint): cint {. +proc convertXYToPos*(ih: PIhandle, x, y: cint): cint {. importc: "IupConvertXYToPos", cdecl, dynlib: dllname.} # IupTree utilities -proc TreeSetUserId*(ih: PIhandle, id: cint, userid: pointer): cint {. +proc treeSetUserId*(ih: PIhandle, id: cint, userid: pointer): cint {. importc: "IupTreeSetUserId", cdecl, dynlib: dllname, discardable.} -proc TreeGetUserId*(ih: PIhandle, id: cint): pointer {. +proc treeGetUserId*(ih: PIhandle, id: cint): pointer {. importc: "IupTreeGetUserId", cdecl, dynlib: dllname.} -proc TreeGetId*(ih: PIhandle, userid: pointer): cint {. +proc treeGetId*(ih: PIhandle, userid: pointer): cint {. importc: "IupTreeGetId", cdecl, dynlib: dllname.} -proc TreeSetAttribute*(ih: PIhandle, name: cstring, id: cint, value: cstring) {. +proc treeSetAttribute*(ih: PIhandle, name: cstring, id: cint, value: cstring) {. importc: "IupTreeSetAttribute", cdecl, dynlib: dllname.} -proc TreeStoreAttribute*(ih: PIhandle, name: cstring, id: cint, value: cstring) {. +proc treeStoreAttribute*(ih: PIhandle, name: cstring, id: cint, value: cstring) {. importc: "IupTreeStoreAttribute", cdecl, dynlib: dllname.} -proc TreeGetAttribute*(ih: PIhandle, name: cstring, id: cint): cstring {. +proc treeGetAttribute*(ih: PIhandle, name: cstring, id: cint): cstring {. importc: "IupTreeGetAttribute", cdecl, dynlib: dllname.} -proc TreeGetInt*(ih: PIhandle, name: cstring, id: cint): cint {. +proc treeGetInt*(ih: PIhandle, name: cstring, id: cint): cint {. importc: "IupTreeGetInt", cdecl, dynlib: dllname.} -proc TreeGetFloat*(ih: PIhandle, name: cstring, id: cint): cfloat {. +proc treeGetFloat*(ih: PIhandle, name: cstring, id: cint): cfloat {. importc: "IupTreeGetFloat", cdecl, dynlib: dllname.} -proc TreeSetfAttribute*(ih: PIhandle, name: cstring, id: cint, format: cstring) {. +proc treeSetfAttribute*(ih: PIhandle, name: cstring, id: cint, format: cstring) {. importc: "IupTreeSetfAttribute", cdecl, dynlib: dllname, varargs.} @@ -434,516 +434,516 @@ const IUP_MASK_INT* = "[+/-]?/d+" IUP_MASK_UINT* = "/d+" -# from 32 to 126, all character sets are equal, -# the key code i the same as the character code. -const - K_SP* = cint(ord(' ')) - K_exclam* = cint(ord('!')) - K_quotedbl* = cint(ord('\"')) - K_numbersign* = cint(ord('#')) - K_dollar* = cint(ord('$')) - K_percent* = cint(ord('%')) - K_ampersand* = cint(ord('&')) - K_apostrophe* = cint(ord('\'')) - K_parentleft* = cint(ord('(')) - K_parentright* = cint(ord(')')) - K_asterisk* = cint(ord('*')) - K_plus* = cint(ord('+')) - K_comma* = cint(ord(',')) - K_minus* = cint(ord('-')) - K_period* = cint(ord('.')) - K_slash* = cint(ord('/')) - K_0* = cint(ord('0')) - K_1* = cint(ord('1')) - K_2* = cint(ord('2')) - K_3* = cint(ord('3')) - K_4* = cint(ord('4')) - K_5* = cint(ord('5')) - K_6* = cint(ord('6')) - K_7* = cint(ord('7')) - K_8* = cint(ord('8')) - K_9* = cint(ord('9')) - K_colon* = cint(ord(':')) - K_semicolon* = cint(ord(';')) - K_less* = cint(ord('<')) - K_equal* = cint(ord('=')) - K_greater* = cint(ord('>')) - K_question* = cint(ord('?')) - K_at* = cint(ord('@')) - K_upperA* = cint(ord('A')) - K_upperB* = cint(ord('B')) - K_upperC* = cint(ord('C')) - K_upperD* = cint(ord('D')) - K_upperE* = cint(ord('E')) - K_upperF* = cint(ord('F')) - K_upperG* = cint(ord('G')) - K_upperH* = cint(ord('H')) - K_upperI* = cint(ord('I')) - K_upperJ* = cint(ord('J')) - K_upperK* = cint(ord('K')) - K_upperL* = cint(ord('L')) - K_upperM* = cint(ord('M')) - K_upperN* = cint(ord('N')) - K_upperO* = cint(ord('O')) - K_upperP* = cint(ord('P')) - K_upperQ* = cint(ord('Q')) - K_upperR* = cint(ord('R')) - K_upperS* = cint(ord('S')) - K_upperT* = cint(ord('T')) - K_upperU* = cint(ord('U')) - K_upperV* = cint(ord('V')) - K_upperW* = cint(ord('W')) - K_upperX* = cint(ord('X')) - K_upperY* = cint(ord('Y')) - K_upperZ* = cint(ord('Z')) - K_bracketleft* = cint(ord('[')) - K_backslash* = cint(ord('\\')) - K_bracketright* = cint(ord(']')) - K_circum* = cint(ord('^')) - K_underscore* = cint(ord('_')) - K_grave* = cint(ord('`')) - K_lowera* = cint(ord('a')) - K_lowerb* = cint(ord('b')) - K_lowerc* = cint(ord('c')) - K_lowerd* = cint(ord('d')) - K_lowere* = cint(ord('e')) - K_lowerf* = cint(ord('f')) - K_lowerg* = cint(ord('g')) - K_lowerh* = cint(ord('h')) - K_loweri* = cint(ord('i')) - K_lowerj* = cint(ord('j')) - K_lowerk* = cint(ord('k')) - K_lowerl* = cint(ord('l')) - K_lowerm* = cint(ord('m')) - K_lowern* = cint(ord('n')) - K_lowero* = cint(ord('o')) - K_lowerp* = cint(ord('p')) - K_lowerq* = cint(ord('q')) - K_lowerr* = cint(ord('r')) - K_lowers* = cint(ord('s')) - K_lowert* = cint(ord('t')) - K_loweru* = cint(ord('u')) - K_lowerv* = cint(ord('v')) - K_lowerw* = cint(ord('w')) - K_lowerx* = cint(ord('x')) - K_lowery* = cint(ord('y')) - K_lowerz* = cint(ord('z')) - K_braceleft* = cint(ord('{')) - K_bar* = cint(ord('|')) - K_braceright* = cint(ord('}')) - K_tilde* = cint(ord('~')) - -proc isPrint*(c: cint): bool = return c > 31 and c < 127 - -# also define the escape sequences that have keys associated -const - K_BS* = cint(ord('\b')) - K_TAB* = cint(ord('\t')) - K_LF* = cint(10) - K_CR* = cint(13) - -# IUP Extended Key Codes, range start at 128 -# Modifiers use 256 interval -# These key code definitions are specific to IUP - -proc isXkey*(c: cint): bool = return c > 128 -proc isShiftXkey*(c: cint): bool = return c > 256 and c < 512 -proc isCtrlXkey*(c: cint): bool = return c > 512 and c < 768 -proc isAltXkey*(c: cint): bool = return c > 768 and c < 1024 -proc isSysXkey*(c: cint): bool = return c > 1024 and c < 1280 - -proc IUPxCODE*(c: cint): cint = return c + cint(128) # Normal (must be above 128) -proc IUPsxCODE*(c: cint): cint = +# from 32 to 126, all character sets are equal, +# the key code i the same as the character code. +const + K_SP* = cint(ord(' ')) + K_exclam* = cint(ord('!')) + K_quotedbl* = cint(ord('\"')) + K_numbersign* = cint(ord('#')) + K_dollar* = cint(ord('$')) + K_percent* = cint(ord('%')) + K_ampersand* = cint(ord('&')) + K_apostrophe* = cint(ord('\'')) + K_parentleft* = cint(ord('(')) + K_parentright* = cint(ord(')')) + K_asterisk* = cint(ord('*')) + K_plus* = cint(ord('+')) + K_comma* = cint(ord(',')) + K_minus* = cint(ord('-')) + K_period* = cint(ord('.')) + K_slash* = cint(ord('/')) + K_0* = cint(ord('0')) + K_1* = cint(ord('1')) + K_2* = cint(ord('2')) + K_3* = cint(ord('3')) + K_4* = cint(ord('4')) + K_5* = cint(ord('5')) + K_6* = cint(ord('6')) + K_7* = cint(ord('7')) + K_8* = cint(ord('8')) + K_9* = cint(ord('9')) + K_colon* = cint(ord(':')) + K_semicolon* = cint(ord(';')) + K_less* = cint(ord('<')) + K_equal* = cint(ord('=')) + K_greater* = cint(ord('>')) + K_question* = cint(ord('?')) + K_at* = cint(ord('@')) + K_upperA* = cint(ord('A')) + K_upperB* = cint(ord('B')) + K_upperC* = cint(ord('C')) + K_upperD* = cint(ord('D')) + K_upperE* = cint(ord('E')) + K_upperF* = cint(ord('F')) + K_upperG* = cint(ord('G')) + K_upperH* = cint(ord('H')) + K_upperI* = cint(ord('I')) + K_upperJ* = cint(ord('J')) + K_upperK* = cint(ord('K')) + K_upperL* = cint(ord('L')) + K_upperM* = cint(ord('M')) + K_upperN* = cint(ord('N')) + K_upperO* = cint(ord('O')) + K_upperP* = cint(ord('P')) + K_upperQ* = cint(ord('Q')) + K_upperR* = cint(ord('R')) + K_upperS* = cint(ord('S')) + K_upperT* = cint(ord('T')) + K_upperU* = cint(ord('U')) + K_upperV* = cint(ord('V')) + K_upperW* = cint(ord('W')) + K_upperX* = cint(ord('X')) + K_upperY* = cint(ord('Y')) + K_upperZ* = cint(ord('Z')) + K_bracketleft* = cint(ord('[')) + K_backslash* = cint(ord('\\')) + K_bracketright* = cint(ord(']')) + K_circum* = cint(ord('^')) + K_underscore* = cint(ord('_')) + K_grave* = cint(ord('`')) + K_lowera* = cint(ord('a')) + K_lowerb* = cint(ord('b')) + K_lowerc* = cint(ord('c')) + K_lowerd* = cint(ord('d')) + K_lowere* = cint(ord('e')) + K_lowerf* = cint(ord('f')) + K_lowerg* = cint(ord('g')) + K_lowerh* = cint(ord('h')) + K_loweri* = cint(ord('i')) + K_lowerj* = cint(ord('j')) + K_lowerk* = cint(ord('k')) + K_lowerl* = cint(ord('l')) + K_lowerm* = cint(ord('m')) + K_lowern* = cint(ord('n')) + K_lowero* = cint(ord('o')) + K_lowerp* = cint(ord('p')) + K_lowerq* = cint(ord('q')) + K_lowerr* = cint(ord('r')) + K_lowers* = cint(ord('s')) + K_lowert* = cint(ord('t')) + K_loweru* = cint(ord('u')) + K_lowerv* = cint(ord('v')) + K_lowerw* = cint(ord('w')) + K_lowerx* = cint(ord('x')) + K_lowery* = cint(ord('y')) + K_lowerz* = cint(ord('z')) + K_braceleft* = cint(ord('{')) + K_bar* = cint(ord('|')) + K_braceright* = cint(ord('}')) + K_tilde* = cint(ord('~')) + +proc isPrint*(c: cint): bool = return c > 31 and c < 127 + +# also define the escape sequences that have keys associated +const + K_BS* = cint(ord('\b')) + K_TAB* = cint(ord('\t')) + K_LF* = cint(10) + K_CR* = cint(13) + +# IUP Extended Key Codes, range start at 128 +# Modifiers use 256 interval +# These key code definitions are specific to IUP + +proc isXkey*(c: cint): bool = return c > 128 +proc isShiftXkey*(c: cint): bool = return c > 256 and c < 512 +proc isCtrlXkey*(c: cint): bool = return c > 512 and c < 768 +proc isAltXkey*(c: cint): bool = return c > 768 and c < 1024 +proc isSysXkey*(c: cint): bool = return c > 1024 and c < 1280 + +proc iUPxCODE*(c: cint): cint = return c + cint(128) # Normal (must be above 128) +proc iUPsxCODE*(c: cint): cint = return c + cint(256) # Shift (must have range to include the standard keys and the normal # extended keys, so must be above 256 -proc IUPcxCODE*(c: cint): cint = return c + cint(512) # Ctrl -proc IUPmxCODE*(c: cint): cint = return c + cint(768) # Alt -proc IUPyxCODE*(c: cint): cint = return c + cint(1024) # Sys (Win or Apple) - -const - IUP_NUMMAXCODES* = 1280 ## 5*256=1280 Normal+Shift+Ctrl+Alt+Sys - - K_HOME* = IUPxCODE(1) - K_UP* = IUPxCODE(2) - K_PGUP* = IUPxCODE(3) - K_LEFT* = IUPxCODE(4) - K_MIDDLE* = IUPxCODE(5) - K_RIGHT* = IUPxCODE(6) - K_END* = IUPxCODE(7) - K_DOWN* = IUPxCODE(8) - K_PGDN* = IUPxCODE(9) - K_INS* = IUPxCODE(10) - K_DEL* = IUPxCODE(11) - K_PAUSE* = IUPxCODE(12) - K_ESC* = IUPxCODE(13) - K_ccedilla* = IUPxCODE(14) - K_F1* = IUPxCODE(15) - K_F2* = IUPxCODE(16) - K_F3* = IUPxCODE(17) - K_F4* = IUPxCODE(18) - K_F5* = IUPxCODE(19) - K_F6* = IUPxCODE(20) - K_F7* = IUPxCODE(21) - K_F8* = IUPxCODE(22) - K_F9* = IUPxCODE(23) - K_F10* = IUPxCODE(24) - K_F11* = IUPxCODE(25) - K_F12* = IUPxCODE(26) - K_Print* = IUPxCODE(27) - K_Menu* = IUPxCODE(28) - - K_acute* = IUPxCODE(29) # no Shift/Ctrl/Alt - - K_sHOME* = IUPsxCODE(K_HOME) - K_sUP* = IUPsxCODE(K_UP) - K_sPGUP* = IUPsxCODE(K_PGUP) - K_sLEFT* = IUPsxCODE(K_LEFT) - K_sMIDDLE* = IUPsxCODE(K_MIDDLE) - K_sRIGHT* = IUPsxCODE(K_RIGHT) - K_sEND* = IUPsxCODE(K_END) - K_sDOWN* = IUPsxCODE(K_DOWN) - K_sPGDN* = IUPsxCODE(K_PGDN) - K_sINS* = IUPsxCODE(K_INS) - K_sDEL* = IUPsxCODE(K_DEL) - K_sSP* = IUPsxCODE(K_SP) - K_sTAB* = IUPsxCODE(K_TAB) - K_sCR* = IUPsxCODE(K_CR) - K_sBS* = IUPsxCODE(K_BS) - K_sPAUSE* = IUPsxCODE(K_PAUSE) - K_sESC* = IUPsxCODE(K_ESC) - K_sCcedilla* = IUPsxCODE(K_ccedilla) - K_sF1* = IUPsxCODE(K_F1) - K_sF2* = IUPsxCODE(K_F2) - K_sF3* = IUPsxCODE(K_F3) - K_sF4* = IUPsxCODE(K_F4) - K_sF5* = IUPsxCODE(K_F5) - K_sF6* = IUPsxCODE(K_F6) - K_sF7* = IUPsxCODE(K_F7) - K_sF8* = IUPsxCODE(K_F8) - K_sF9* = IUPsxCODE(K_F9) - K_sF10* = IUPsxCODE(K_F10) - K_sF11* = IUPsxCODE(K_F11) - K_sF12* = IUPsxCODE(K_F12) - K_sPrint* = IUPsxCODE(K_Print) - K_sMenu* = IUPsxCODE(K_Menu) - - K_cHOME* = IUPcxCODE(K_HOME) - K_cUP* = IUPcxCODE(K_UP) - K_cPGUP* = IUPcxCODE(K_PGUP) - K_cLEFT* = IUPcxCODE(K_LEFT) - K_cMIDDLE* = IUPcxCODE(K_MIDDLE) - K_cRIGHT* = IUPcxCODE(K_RIGHT) - K_cEND* = IUPcxCODE(K_END) - K_cDOWN* = IUPcxCODE(K_DOWN) - K_cPGDN* = IUPcxCODE(K_PGDN) - K_cINS* = IUPcxCODE(K_INS) - K_cDEL* = IUPcxCODE(K_DEL) - K_cSP* = IUPcxCODE(K_SP) - K_cTAB* = IUPcxCODE(K_TAB) - K_cCR* = IUPcxCODE(K_CR) - K_cBS* = IUPcxCODE(K_BS) - K_cPAUSE* = IUPcxCODE(K_PAUSE) - K_cESC* = IUPcxCODE(K_ESC) - K_cCcedilla* = IUPcxCODE(K_ccedilla) - K_cF1* = IUPcxCODE(K_F1) - K_cF2* = IUPcxCODE(K_F2) - K_cF3* = IUPcxCODE(K_F3) - K_cF4* = IUPcxCODE(K_F4) - K_cF5* = IUPcxCODE(K_F5) - K_cF6* = IUPcxCODE(K_F6) - K_cF7* = IUPcxCODE(K_F7) - K_cF8* = IUPcxCODE(K_F8) - K_cF9* = IUPcxCODE(K_F9) - K_cF10* = IUPcxCODE(K_F10) - K_cF11* = IUPcxCODE(K_F11) - K_cF12* = IUPcxCODE(K_F12) - K_cPrint* = IUPcxCODE(K_Print) - K_cMenu* = IUPcxCODE(K_Menu) - - K_mHOME* = IUPmxCODE(K_HOME) - K_mUP* = IUPmxCODE(K_UP) - K_mPGUP* = IUPmxCODE(K_PGUP) - K_mLEFT* = IUPmxCODE(K_LEFT) - K_mMIDDLE* = IUPmxCODE(K_MIDDLE) - K_mRIGHT* = IUPmxCODE(K_RIGHT) - K_mEND* = IUPmxCODE(K_END) - K_mDOWN* = IUPmxCODE(K_DOWN) - K_mPGDN* = IUPmxCODE(K_PGDN) - K_mINS* = IUPmxCODE(K_INS) - K_mDEL* = IUPmxCODE(K_DEL) - K_mSP* = IUPmxCODE(K_SP) - K_mTAB* = IUPmxCODE(K_TAB) - K_mCR* = IUPmxCODE(K_CR) - K_mBS* = IUPmxCODE(K_BS) - K_mPAUSE* = IUPmxCODE(K_PAUSE) - K_mESC* = IUPmxCODE(K_ESC) - K_mCcedilla* = IUPmxCODE(K_ccedilla) - K_mF1* = IUPmxCODE(K_F1) - K_mF2* = IUPmxCODE(K_F2) - K_mF3* = IUPmxCODE(K_F3) - K_mF4* = IUPmxCODE(K_F4) - K_mF5* = IUPmxCODE(K_F5) - K_mF6* = IUPmxCODE(K_F6) - K_mF7* = IUPmxCODE(K_F7) - K_mF8* = IUPmxCODE(K_F8) - K_mF9* = IUPmxCODE(K_F9) - K_mF10* = IUPmxCODE(K_F10) - K_mF11* = IUPmxCODE(K_F11) - K_mF12* = IUPmxCODE(K_F12) - K_mPrint* = IUPmxCODE(K_Print) - K_mMenu* = IUPmxCODE(K_Menu) - - K_yHOME* = IUPyxCODE(K_HOME) - K_yUP* = IUPyxCODE(K_UP) - K_yPGUP* = IUPyxCODE(K_PGUP) - K_yLEFT* = IUPyxCODE(K_LEFT) - K_yMIDDLE* = IUPyxCODE(K_MIDDLE) - K_yRIGHT* = IUPyxCODE(K_RIGHT) - K_yEND* = IUPyxCODE(K_END) - K_yDOWN* = IUPyxCODE(K_DOWN) - K_yPGDN* = IUPyxCODE(K_PGDN) - K_yINS* = IUPyxCODE(K_INS) - K_yDEL* = IUPyxCODE(K_DEL) - K_ySP* = IUPyxCODE(K_SP) - K_yTAB* = IUPyxCODE(K_TAB) - K_yCR* = IUPyxCODE(K_CR) - K_yBS* = IUPyxCODE(K_BS) - K_yPAUSE* = IUPyxCODE(K_PAUSE) - K_yESC* = IUPyxCODE(K_ESC) - K_yCcedilla* = IUPyxCODE(K_ccedilla) - K_yF1* = IUPyxCODE(K_F1) - K_yF2* = IUPyxCODE(K_F2) - K_yF3* = IUPyxCODE(K_F3) - K_yF4* = IUPyxCODE(K_F4) - K_yF5* = IUPyxCODE(K_F5) - K_yF6* = IUPyxCODE(K_F6) - K_yF7* = IUPyxCODE(K_F7) - K_yF8* = IUPyxCODE(K_F8) - K_yF9* = IUPyxCODE(K_F9) - K_yF10* = IUPyxCODE(K_F10) - K_yF11* = IUPyxCODE(K_F11) - K_yF12* = IUPyxCODE(K_F12) - K_yPrint* = IUPyxCODE(K_Print) - K_yMenu* = IUPyxCODE(K_Menu) - - K_sPlus* = IUPsxCODE(K_plus) - K_sComma* = IUPsxCODE(K_comma) - K_sMinus* = IUPsxCODE(K_minus) - K_sPeriod* = IUPsxCODE(K_period) - K_sSlash* = IUPsxCODE(K_slash) - K_sAsterisk* = IUPsxCODE(K_asterisk) - - K_cupperA* = IUPcxCODE(K_upperA) - K_cupperB* = IUPcxCODE(K_upperB) - K_cupperC* = IUPcxCODE(K_upperC) - K_cupperD* = IUPcxCODE(K_upperD) - K_cupperE* = IUPcxCODE(K_upperE) - K_cupperF* = IUPcxCODE(K_upperF) - K_cupperG* = IUPcxCODE(K_upperG) - K_cupperH* = IUPcxCODE(K_upperH) - K_cupperI* = IUPcxCODE(K_upperI) - K_cupperJ* = IUPcxCODE(K_upperJ) - K_cupperK* = IUPcxCODE(K_upperK) - K_cupperL* = IUPcxCODE(K_upperL) - K_cupperM* = IUPcxCODE(K_upperM) - K_cupperN* = IUPcxCODE(K_upperN) - K_cupperO* = IUPcxCODE(K_upperO) - K_cupperP* = IUPcxCODE(K_upperP) - K_cupperQ* = IUPcxCODE(K_upperQ) - K_cupperR* = IUPcxCODE(K_upperR) - K_cupperS* = IUPcxCODE(K_upperS) - K_cupperT* = IUPcxCODE(K_upperT) - K_cupperU* = IUPcxCODE(K_upperU) - K_cupperV* = IUPcxCODE(K_upperV) - K_cupperW* = IUPcxCODE(K_upperW) - K_cupperX* = IUPcxCODE(K_upperX) - K_cupperY* = IUPcxCODE(K_upperY) - K_cupperZ* = IUPcxCODE(K_upperZ) - K_c1* = IUPcxCODE(K_1) - K_c2* = IUPcxCODE(K_2) - K_c3* = IUPcxCODE(K_3) - K_c4* = IUPcxCODE(K_4) - K_c5* = IUPcxCODE(K_5) - K_c6* = IUPcxCODE(K_6) - K_c7* = IUPcxCODE(K_7) - K_c8* = IUPcxCODE(K_8) - K_c9* = IUPcxCODE(K_9) - K_c0* = IUPcxCODE(K_0) - K_cPlus* = IUPcxCODE(K_plus) - K_cComma* = IUPcxCODE(K_comma) - K_cMinus* = IUPcxCODE(K_minus) - K_cPeriod* = IUPcxCODE(K_period) - K_cSlash* = IUPcxCODE(K_slash) - K_cSemicolon* = IUPcxCODE(K_semicolon) - K_cEqual* = IUPcxCODE(K_equal) - K_cBracketleft* = IUPcxCODE(K_bracketleft) - K_cBracketright* = IUPcxCODE(K_bracketright) - K_cBackslash* = IUPcxCODE(K_backslash) - K_cAsterisk* = IUPcxCODE(K_asterisk) - - K_mupperA* = IUPmxCODE(K_upperA) - K_mupperB* = IUPmxCODE(K_upperB) - K_mupperC* = IUPmxCODE(K_upperC) - K_mupperD* = IUPmxCODE(K_upperD) - K_mupperE* = IUPmxCODE(K_upperE) - K_mupperF* = IUPmxCODE(K_upperF) - K_mupperG* = IUPmxCODE(K_upperG) - K_mupperH* = IUPmxCODE(K_upperH) - K_mupperI* = IUPmxCODE(K_upperI) - K_mupperJ* = IUPmxCODE(K_upperJ) - K_mupperK* = IUPmxCODE(K_upperK) - K_mupperL* = IUPmxCODE(K_upperL) - K_mupperM* = IUPmxCODE(K_upperM) - K_mupperN* = IUPmxCODE(K_upperN) - K_mupperO* = IUPmxCODE(K_upperO) - K_mupperP* = IUPmxCODE(K_upperP) - K_mupperQ* = IUPmxCODE(K_upperQ) - K_mupperR* = IUPmxCODE(K_upperR) - K_mupperS* = IUPmxCODE(K_upperS) - K_mupperT* = IUPmxCODE(K_upperT) - K_mupperU* = IUPmxCODE(K_upperU) - K_mupperV* = IUPmxCODE(K_upperV) - K_mupperW* = IUPmxCODE(K_upperW) - K_mupperX* = IUPmxCODE(K_upperX) - K_mupperY* = IUPmxCODE(K_upperY) - K_mupperZ* = IUPmxCODE(K_upperZ) - K_m1* = IUPmxCODE(K_1) - K_m2* = IUPmxCODE(K_2) - K_m3* = IUPmxCODE(K_3) - K_m4* = IUPmxCODE(K_4) - K_m5* = IUPmxCODE(K_5) - K_m6* = IUPmxCODE(K_6) - K_m7* = IUPmxCODE(K_7) - K_m8* = IUPmxCODE(K_8) - K_m9* = IUPmxCODE(K_9) - K_m0* = IUPmxCODE(K_0) - K_mPlus* = IUPmxCODE(K_plus) - K_mComma* = IUPmxCODE(K_comma) - K_mMinus* = IUPmxCODE(K_minus) - K_mPeriod* = IUPmxCODE(K_period) - K_mSlash* = IUPmxCODE(K_slash) - K_mSemicolon* = IUPmxCODE(K_semicolon) - K_mEqual* = IUPmxCODE(K_equal) - K_mBracketleft* = IUPmxCODE(K_bracketleft) - K_mBracketright* = IUPmxCODE(K_bracketright) - K_mBackslash* = IUPmxCODE(K_backslash) - K_mAsterisk* = IUPmxCODE(K_asterisk) - - K_yA* = IUPyxCODE(K_upperA) - K_yB* = IUPyxCODE(K_upperB) - K_yC* = IUPyxCODE(K_upperC) - K_yD* = IUPyxCODE(K_upperD) - K_yE* = IUPyxCODE(K_upperE) - K_yF* = IUPyxCODE(K_upperF) - K_yG* = IUPyxCODE(K_upperG) - K_yH* = IUPyxCODE(K_upperH) - K_yI* = IUPyxCODE(K_upperI) - K_yJ* = IUPyxCODE(K_upperJ) - K_yK* = IUPyxCODE(K_upperK) - K_yL* = IUPyxCODE(K_upperL) - K_yM* = IUPyxCODE(K_upperM) - K_yN* = IUPyxCODE(K_upperN) - K_yO* = IUPyxCODE(K_upperO) - K_yP* = IUPyxCODE(K_upperP) - K_yQ* = IUPyxCODE(K_upperQ) - K_yR* = IUPyxCODE(K_upperR) - K_yS* = IUPyxCODE(K_upperS) - K_yT* = IUPyxCODE(K_upperT) - K_yU* = IUPyxCODE(K_upperU) - K_yV* = IUPyxCODE(K_upperV) - K_yW* = IUPyxCODE(K_upperW) - K_yX* = IUPyxCODE(K_upperX) - K_yY* = IUPyxCODE(K_upperY) - K_yZ* = IUPyxCODE(K_upperZ) - K_y1* = IUPyxCODE(K_1) - K_y2* = IUPyxCODE(K_2) - K_y3* = IUPyxCODE(K_3) - K_y4* = IUPyxCODE(K_4) - K_y5* = IUPyxCODE(K_5) - K_y6* = IUPyxCODE(K_6) - K_y7* = IUPyxCODE(K_7) - K_y8* = IUPyxCODE(K_8) - K_y9* = IUPyxCODE(K_9) - K_y0* = IUPyxCODE(K_0) - K_yPlus* = IUPyxCODE(K_plus) - K_yComma* = IUPyxCODE(K_comma) - K_yMinus* = IUPyxCODE(K_minus) - K_yPeriod* = IUPyxCODE(K_period) - K_ySlash* = IUPyxCODE(K_slash) - K_ySemicolon* = IUPyxCODE(K_semicolon) - K_yEqual* = IUPyxCODE(K_equal) - K_yBracketleft* = IUPyxCODE(K_bracketleft) - K_yBracketright* = IUPyxCODE(K_bracketright) - K_yBackslash* = IUPyxCODE(K_backslash) - K_yAsterisk* = IUPyxCODE(K_asterisk) - -proc ControlsOpen*(): cint {.cdecl, importc: "IupControlsOpen", dynlib: dllname.} -proc ControlsClose*() {.cdecl, importc: "IupControlsClose", dynlib: dllname.} - -proc OldValOpen*() {.cdecl, importc: "IupOldValOpen", dynlib: dllname.} -proc OldTabsOpen*() {.cdecl, importc: "IupOldTabsOpen", dynlib: dllname.} - -proc Colorbar*(): PIhandle {.cdecl, importc: "IupColorbar", dynlib: dllname.} -proc Cells*(): PIhandle {.cdecl, importc: "IupCells", dynlib: dllname.} -proc ColorBrowser*(): PIhandle {.cdecl, importc: "IupColorBrowser", dynlib: dllname.} -proc Gauge*(): PIhandle {.cdecl, importc: "IupGauge", dynlib: dllname.} -proc Dial*(theType: cstring): PIhandle {.cdecl, importc: "IupDial", dynlib: dllname.} -proc Matrix*(action: cstring): PIhandle {.cdecl, importc: "IupMatrix", dynlib: dllname.} - -# IupMatrix utilities -proc MatSetAttribute*(ih: PIhandle, name: cstring, lin, col: cint, +proc iUPcxCODE*(c: cint): cint = return c + cint(512) # Ctrl +proc iUPmxCODE*(c: cint): cint = return c + cint(768) # Alt +proc iUPyxCODE*(c: cint): cint = return c + cint(1024) # Sys (Win or Apple) + +const + IUP_NUMMAXCODES* = 1280 ## 5*256=1280 Normal+Shift+Ctrl+Alt+Sys + + K_HOME* = iUPxCODE(1) + K_UP* = iUPxCODE(2) + K_PGUP* = iUPxCODE(3) + K_LEFT* = iUPxCODE(4) + K_MIDDLE* = iUPxCODE(5) + K_RIGHT* = iUPxCODE(6) + K_END* = iUPxCODE(7) + K_DOWN* = iUPxCODE(8) + K_PGDN* = iUPxCODE(9) + K_INS* = iUPxCODE(10) + K_DEL* = iUPxCODE(11) + K_PAUSE* = iUPxCODE(12) + K_ESC* = iUPxCODE(13) + K_ccedilla* = iUPxCODE(14) + K_F1* = iUPxCODE(15) + K_F2* = iUPxCODE(16) + K_F3* = iUPxCODE(17) + K_F4* = iUPxCODE(18) + K_F5* = iUPxCODE(19) + K_F6* = iUPxCODE(20) + K_F7* = iUPxCODE(21) + K_F8* = iUPxCODE(22) + K_F9* = iUPxCODE(23) + K_F10* = iUPxCODE(24) + K_F11* = iUPxCODE(25) + K_F12* = iUPxCODE(26) + K_Print* = iUPxCODE(27) + K_Menu* = iUPxCODE(28) + + K_acute* = iUPxCODE(29) # no Shift/Ctrl/Alt + + K_sHOME* = iUPsxCODE(K_HOME) + K_sUP* = iUPsxCODE(K_UP) + K_sPGUP* = iUPsxCODE(K_PGUP) + K_sLEFT* = iUPsxCODE(K_LEFT) + K_sMIDDLE* = iUPsxCODE(K_MIDDLE) + K_sRIGHT* = iUPsxCODE(K_RIGHT) + K_sEND* = iUPsxCODE(K_END) + K_sDOWN* = iUPsxCODE(K_DOWN) + K_sPGDN* = iUPsxCODE(K_PGDN) + K_sINS* = iUPsxCODE(K_INS) + K_sDEL* = iUPsxCODE(K_DEL) + K_sSP* = iUPsxCODE(K_SP) + K_sTAB* = iUPsxCODE(K_TAB) + K_sCR* = iUPsxCODE(K_CR) + K_sBS* = iUPsxCODE(K_BS) + K_sPAUSE* = iUPsxCODE(K_PAUSE) + K_sESC* = iUPsxCODE(K_ESC) + K_sCcedilla* = iUPsxCODE(K_ccedilla) + K_sF1* = iUPsxCODE(K_F1) + K_sF2* = iUPsxCODE(K_F2) + K_sF3* = iUPsxCODE(K_F3) + K_sF4* = iUPsxCODE(K_F4) + K_sF5* = iUPsxCODE(K_F5) + K_sF6* = iUPsxCODE(K_F6) + K_sF7* = iUPsxCODE(K_F7) + K_sF8* = iUPsxCODE(K_F8) + K_sF9* = iUPsxCODE(K_F9) + K_sF10* = iUPsxCODE(K_F10) + K_sF11* = iUPsxCODE(K_F11) + K_sF12* = iUPsxCODE(K_F12) + K_sPrint* = iUPsxCODE(K_Print) + K_sMenu* = iUPsxCODE(K_Menu) + + K_cHOME* = iUPcxCODE(K_HOME) + K_cUP* = iUPcxCODE(K_UP) + K_cPGUP* = iUPcxCODE(K_PGUP) + K_cLEFT* = iUPcxCODE(K_LEFT) + K_cMIDDLE* = iUPcxCODE(K_MIDDLE) + K_cRIGHT* = iUPcxCODE(K_RIGHT) + K_cEND* = iUPcxCODE(K_END) + K_cDOWN* = iUPcxCODE(K_DOWN) + K_cPGDN* = iUPcxCODE(K_PGDN) + K_cINS* = iUPcxCODE(K_INS) + K_cDEL* = iUPcxCODE(K_DEL) + K_cSP* = iUPcxCODE(K_SP) + K_cTAB* = iUPcxCODE(K_TAB) + K_cCR* = iUPcxCODE(K_CR) + K_cBS* = iUPcxCODE(K_BS) + K_cPAUSE* = iUPcxCODE(K_PAUSE) + K_cESC* = iUPcxCODE(K_ESC) + K_cCcedilla* = iUPcxCODE(K_ccedilla) + K_cF1* = iUPcxCODE(K_F1) + K_cF2* = iUPcxCODE(K_F2) + K_cF3* = iUPcxCODE(K_F3) + K_cF4* = iUPcxCODE(K_F4) + K_cF5* = iUPcxCODE(K_F5) + K_cF6* = iUPcxCODE(K_F6) + K_cF7* = iUPcxCODE(K_F7) + K_cF8* = iUPcxCODE(K_F8) + K_cF9* = iUPcxCODE(K_F9) + K_cF10* = iUPcxCODE(K_F10) + K_cF11* = iUPcxCODE(K_F11) + K_cF12* = iUPcxCODE(K_F12) + K_cPrint* = iUPcxCODE(K_Print) + K_cMenu* = iUPcxCODE(K_Menu) + + K_mHOME* = iUPmxCODE(K_HOME) + K_mUP* = iUPmxCODE(K_UP) + K_mPGUP* = iUPmxCODE(K_PGUP) + K_mLEFT* = iUPmxCODE(K_LEFT) + K_mMIDDLE* = iUPmxCODE(K_MIDDLE) + K_mRIGHT* = iUPmxCODE(K_RIGHT) + K_mEND* = iUPmxCODE(K_END) + K_mDOWN* = iUPmxCODE(K_DOWN) + K_mPGDN* = iUPmxCODE(K_PGDN) + K_mINS* = iUPmxCODE(K_INS) + K_mDEL* = iUPmxCODE(K_DEL) + K_mSP* = iUPmxCODE(K_SP) + K_mTAB* = iUPmxCODE(K_TAB) + K_mCR* = iUPmxCODE(K_CR) + K_mBS* = iUPmxCODE(K_BS) + K_mPAUSE* = iUPmxCODE(K_PAUSE) + K_mESC* = iUPmxCODE(K_ESC) + K_mCcedilla* = iUPmxCODE(K_ccedilla) + K_mF1* = iUPmxCODE(K_F1) + K_mF2* = iUPmxCODE(K_F2) + K_mF3* = iUPmxCODE(K_F3) + K_mF4* = iUPmxCODE(K_F4) + K_mF5* = iUPmxCODE(K_F5) + K_mF6* = iUPmxCODE(K_F6) + K_mF7* = iUPmxCODE(K_F7) + K_mF8* = iUPmxCODE(K_F8) + K_mF9* = iUPmxCODE(K_F9) + K_mF10* = iUPmxCODE(K_F10) + K_mF11* = iUPmxCODE(K_F11) + K_mF12* = iUPmxCODE(K_F12) + K_mPrint* = iUPmxCODE(K_Print) + K_mMenu* = iUPmxCODE(K_Menu) + + K_yHOME* = iUPyxCODE(K_HOME) + K_yUP* = iUPyxCODE(K_UP) + K_yPGUP* = iUPyxCODE(K_PGUP) + K_yLEFT* = iUPyxCODE(K_LEFT) + K_yMIDDLE* = iUPyxCODE(K_MIDDLE) + K_yRIGHT* = iUPyxCODE(K_RIGHT) + K_yEND* = iUPyxCODE(K_END) + K_yDOWN* = iUPyxCODE(K_DOWN) + K_yPGDN* = iUPyxCODE(K_PGDN) + K_yINS* = iUPyxCODE(K_INS) + K_yDEL* = iUPyxCODE(K_DEL) + K_ySP* = iUPyxCODE(K_SP) + K_yTAB* = iUPyxCODE(K_TAB) + K_yCR* = iUPyxCODE(K_CR) + K_yBS* = iUPyxCODE(K_BS) + K_yPAUSE* = iUPyxCODE(K_PAUSE) + K_yESC* = iUPyxCODE(K_ESC) + K_yCcedilla* = iUPyxCODE(K_ccedilla) + K_yF1* = iUPyxCODE(K_F1) + K_yF2* = iUPyxCODE(K_F2) + K_yF3* = iUPyxCODE(K_F3) + K_yF4* = iUPyxCODE(K_F4) + K_yF5* = iUPyxCODE(K_F5) + K_yF6* = iUPyxCODE(K_F6) + K_yF7* = iUPyxCODE(K_F7) + K_yF8* = iUPyxCODE(K_F8) + K_yF9* = iUPyxCODE(K_F9) + K_yF10* = iUPyxCODE(K_F10) + K_yF11* = iUPyxCODE(K_F11) + K_yF12* = iUPyxCODE(K_F12) + K_yPrint* = iUPyxCODE(K_Print) + K_yMenu* = iUPyxCODE(K_Menu) + + K_sPlus* = iUPsxCODE(K_plus) + K_sComma* = iUPsxCODE(K_comma) + K_sMinus* = iUPsxCODE(K_minus) + K_sPeriod* = iUPsxCODE(K_period) + K_sSlash* = iUPsxCODE(K_slash) + K_sAsterisk* = iUPsxCODE(K_asterisk) + + K_cupperA* = iUPcxCODE(K_upperA) + K_cupperB* = iUPcxCODE(K_upperB) + K_cupperC* = iUPcxCODE(K_upperC) + K_cupperD* = iUPcxCODE(K_upperD) + K_cupperE* = iUPcxCODE(K_upperE) + K_cupperF* = iUPcxCODE(K_upperF) + K_cupperG* = iUPcxCODE(K_upperG) + K_cupperH* = iUPcxCODE(K_upperH) + K_cupperI* = iUPcxCODE(K_upperI) + K_cupperJ* = iUPcxCODE(K_upperJ) + K_cupperK* = iUPcxCODE(K_upperK) + K_cupperL* = iUPcxCODE(K_upperL) + K_cupperM* = iUPcxCODE(K_upperM) + K_cupperN* = iUPcxCODE(K_upperN) + K_cupperO* = iUPcxCODE(K_upperO) + K_cupperP* = iUPcxCODE(K_upperP) + K_cupperQ* = iUPcxCODE(K_upperQ) + K_cupperR* = iUPcxCODE(K_upperR) + K_cupperS* = iUPcxCODE(K_upperS) + K_cupperT* = iUPcxCODE(K_upperT) + K_cupperU* = iUPcxCODE(K_upperU) + K_cupperV* = iUPcxCODE(K_upperV) + K_cupperW* = iUPcxCODE(K_upperW) + K_cupperX* = iUPcxCODE(K_upperX) + K_cupperY* = iUPcxCODE(K_upperY) + K_cupperZ* = iUPcxCODE(K_upperZ) + K_c1* = iUPcxCODE(K_1) + K_c2* = iUPcxCODE(K_2) + K_c3* = iUPcxCODE(K_3) + K_c4* = iUPcxCODE(K_4) + K_c5* = iUPcxCODE(K_5) + K_c6* = iUPcxCODE(K_6) + K_c7* = iUPcxCODE(K_7) + K_c8* = iUPcxCODE(K_8) + K_c9* = iUPcxCODE(K_9) + K_c0* = iUPcxCODE(K_0) + K_cPlus* = iUPcxCODE(K_plus) + K_cComma* = iUPcxCODE(K_comma) + K_cMinus* = iUPcxCODE(K_minus) + K_cPeriod* = iUPcxCODE(K_period) + K_cSlash* = iUPcxCODE(K_slash) + K_cSemicolon* = iUPcxCODE(K_semicolon) + K_cEqual* = iUPcxCODE(K_equal) + K_cBracketleft* = iUPcxCODE(K_bracketleft) + K_cBracketright* = iUPcxCODE(K_bracketright) + K_cBackslash* = iUPcxCODE(K_backslash) + K_cAsterisk* = iUPcxCODE(K_asterisk) + + K_mupperA* = iUPmxCODE(K_upperA) + K_mupperB* = iUPmxCODE(K_upperB) + K_mupperC* = iUPmxCODE(K_upperC) + K_mupperD* = iUPmxCODE(K_upperD) + K_mupperE* = iUPmxCODE(K_upperE) + K_mupperF* = iUPmxCODE(K_upperF) + K_mupperG* = iUPmxCODE(K_upperG) + K_mupperH* = iUPmxCODE(K_upperH) + K_mupperI* = iUPmxCODE(K_upperI) + K_mupperJ* = iUPmxCODE(K_upperJ) + K_mupperK* = iUPmxCODE(K_upperK) + K_mupperL* = iUPmxCODE(K_upperL) + K_mupperM* = iUPmxCODE(K_upperM) + K_mupperN* = iUPmxCODE(K_upperN) + K_mupperO* = iUPmxCODE(K_upperO) + K_mupperP* = iUPmxCODE(K_upperP) + K_mupperQ* = iUPmxCODE(K_upperQ) + K_mupperR* = iUPmxCODE(K_upperR) + K_mupperS* = iUPmxCODE(K_upperS) + K_mupperT* = iUPmxCODE(K_upperT) + K_mupperU* = iUPmxCODE(K_upperU) + K_mupperV* = iUPmxCODE(K_upperV) + K_mupperW* = iUPmxCODE(K_upperW) + K_mupperX* = iUPmxCODE(K_upperX) + K_mupperY* = iUPmxCODE(K_upperY) + K_mupperZ* = iUPmxCODE(K_upperZ) + K_m1* = iUPmxCODE(K_1) + K_m2* = iUPmxCODE(K_2) + K_m3* = iUPmxCODE(K_3) + K_m4* = iUPmxCODE(K_4) + K_m5* = iUPmxCODE(K_5) + K_m6* = iUPmxCODE(K_6) + K_m7* = iUPmxCODE(K_7) + K_m8* = iUPmxCODE(K_8) + K_m9* = iUPmxCODE(K_9) + K_m0* = iUPmxCODE(K_0) + K_mPlus* = iUPmxCODE(K_plus) + K_mComma* = iUPmxCODE(K_comma) + K_mMinus* = iUPmxCODE(K_minus) + K_mPeriod* = iUPmxCODE(K_period) + K_mSlash* = iUPmxCODE(K_slash) + K_mSemicolon* = iUPmxCODE(K_semicolon) + K_mEqual* = iUPmxCODE(K_equal) + K_mBracketleft* = iUPmxCODE(K_bracketleft) + K_mBracketright* = iUPmxCODE(K_bracketright) + K_mBackslash* = iUPmxCODE(K_backslash) + K_mAsterisk* = iUPmxCODE(K_asterisk) + + K_yA* = iUPyxCODE(K_upperA) + K_yB* = iUPyxCODE(K_upperB) + K_yC* = iUPyxCODE(K_upperC) + K_yD* = iUPyxCODE(K_upperD) + K_yE* = iUPyxCODE(K_upperE) + K_yF* = iUPyxCODE(K_upperF) + K_yG* = iUPyxCODE(K_upperG) + K_yH* = iUPyxCODE(K_upperH) + K_yI* = iUPyxCODE(K_upperI) + K_yJ* = iUPyxCODE(K_upperJ) + K_yK* = iUPyxCODE(K_upperK) + K_yL* = iUPyxCODE(K_upperL) + K_yM* = iUPyxCODE(K_upperM) + K_yN* = iUPyxCODE(K_upperN) + K_yO* = iUPyxCODE(K_upperO) + K_yP* = iUPyxCODE(K_upperP) + K_yQ* = iUPyxCODE(K_upperQ) + K_yR* = iUPyxCODE(K_upperR) + K_yS* = iUPyxCODE(K_upperS) + K_yT* = iUPyxCODE(K_upperT) + K_yU* = iUPyxCODE(K_upperU) + K_yV* = iUPyxCODE(K_upperV) + K_yW* = iUPyxCODE(K_upperW) + K_yX* = iUPyxCODE(K_upperX) + K_yY* = iUPyxCODE(K_upperY) + K_yZ* = iUPyxCODE(K_upperZ) + K_y1* = iUPyxCODE(K_1) + K_y2* = iUPyxCODE(K_2) + K_y3* = iUPyxCODE(K_3) + K_y4* = iUPyxCODE(K_4) + K_y5* = iUPyxCODE(K_5) + K_y6* = iUPyxCODE(K_6) + K_y7* = iUPyxCODE(K_7) + K_y8* = iUPyxCODE(K_8) + K_y9* = iUPyxCODE(K_9) + K_y0* = iUPyxCODE(K_0) + K_yPlus* = iUPyxCODE(K_plus) + K_yComma* = iUPyxCODE(K_comma) + K_yMinus* = iUPyxCODE(K_minus) + K_yPeriod* = iUPyxCODE(K_period) + K_ySlash* = iUPyxCODE(K_slash) + K_ySemicolon* = iUPyxCODE(K_semicolon) + K_yEqual* = iUPyxCODE(K_equal) + K_yBracketleft* = iUPyxCODE(K_bracketleft) + K_yBracketright* = iUPyxCODE(K_bracketright) + K_yBackslash* = iUPyxCODE(K_backslash) + K_yAsterisk* = iUPyxCODE(K_asterisk) + +proc controlsOpen*(): cint {.cdecl, importc: "IupControlsOpen", dynlib: dllname.} +proc controlsClose*() {.cdecl, importc: "IupControlsClose", dynlib: dllname.} + +proc oldValOpen*() {.cdecl, importc: "IupOldValOpen", dynlib: dllname.} +proc oldTabsOpen*() {.cdecl, importc: "IupOldTabsOpen", dynlib: dllname.} + +proc colorbar*(): PIhandle {.cdecl, importc: "IupColorbar", dynlib: dllname.} +proc cells*(): PIhandle {.cdecl, importc: "IupCells", dynlib: dllname.} +proc colorBrowser*(): PIhandle {.cdecl, importc: "IupColorBrowser", dynlib: dllname.} +proc gauge*(): PIhandle {.cdecl, importc: "IupGauge", dynlib: dllname.} +proc dial*(theType: cstring): PIhandle {.cdecl, importc: "IupDial", dynlib: dllname.} +proc matrix*(action: cstring): PIhandle {.cdecl, importc: "IupMatrix", dynlib: dllname.} + +# IupMatrix utilities +proc matSetAttribute*(ih: PIhandle, name: cstring, lin, col: cint, value: cstring) {. - cdecl, importc: "IupMatSetAttribute", dynlib: dllname.} -proc MatStoreAttribute*(ih: PIhandle, name: cstring, lin, col: cint, + cdecl, importc: "IupMatSetAttribute", dynlib: dllname.} +proc matStoreAttribute*(ih: PIhandle, name: cstring, lin, col: cint, value: cstring) {.cdecl, - importc: "IupMatStoreAttribute", dynlib: dllname.} -proc MatGetAttribute*(ih: PIhandle, name: cstring, lin, col: cint): cstring {. - cdecl, importc: "IupMatGetAttribute", dynlib: dllname.} -proc MatGetInt*(ih: PIhandle, name: cstring, lin, col: cint): cint {. - cdecl, importc: "IupMatGetInt", dynlib: dllname.} -proc MatGetFloat*(ih: PIhandle, name: cstring, lin, col: cint): cfloat {. - cdecl, importc: "IupMatGetFloat", dynlib: dllname.} -proc MatSetfAttribute*(ih: PIhandle, name: cstring, lin, col: cint, + importc: "IupMatStoreAttribute", dynlib: dllname.} +proc matGetAttribute*(ih: PIhandle, name: cstring, lin, col: cint): cstring {. + cdecl, importc: "IupMatGetAttribute", dynlib: dllname.} +proc matGetInt*(ih: PIhandle, name: cstring, lin, col: cint): cint {. + cdecl, importc: "IupMatGetInt", dynlib: dllname.} +proc matGetFloat*(ih: PIhandle, name: cstring, lin, col: cint): cfloat {. + cdecl, importc: "IupMatGetFloat", dynlib: dllname.} +proc matSetfAttribute*(ih: PIhandle, name: cstring, lin, col: cint, format: cstring) {.cdecl, importc: "IupMatSetfAttribute", - dynlib: dllname, varargs.} - -# Used by IupColorbar + dynlib: dllname, varargs.} + +# Used by IupColorbar const - IUP_PRIMARY* = -1 - IUP_SECONDARY* = -2 - -# Initialize PPlot widget class -proc PPlotOpen*() {.cdecl, importc: "IupPPlotOpen", dynlib: dllname.} - -# Create an PPlot widget instance -proc PPlot*: PIhandle {.cdecl, importc: "IupPPlot", dynlib: dllname.} - -# Add dataset to plot -proc PPlotBegin*(ih: PIhandle, strXdata: cint) {. - cdecl, importc: "IupPPlotBegin", dynlib: dllname.} -proc PPlotAdd*(ih: PIhandle, x, y: cfloat) {. - cdecl, importc: "IupPPlotAdd", dynlib: dllname.} -proc PPlotAddStr*(ih: PIhandle, x: cstring, y: cfloat) {. - cdecl, importc: "IupPPlotAddStr", dynlib: dllname.} -proc PPlotEnd*(ih: PIhandle): cint {. - cdecl, importc: "IupPPlotEnd", dynlib: dllname.} - -proc PPlotInsertStr*(ih: PIhandle, index, sample_index: cint, x: cstring, + IUP_PRIMARY* = -1 + IUP_SECONDARY* = -2 + +# Initialize PPlot widget class +proc pPlotOpen*() {.cdecl, importc: "IupPPlotOpen", dynlib: dllname.} + +# Create an PPlot widget instance +proc pPlot*: PIhandle {.cdecl, importc: "IupPPlot", dynlib: dllname.} + +# Add dataset to plot +proc pPlotBegin*(ih: PIhandle, strXdata: cint) {. + cdecl, importc: "IupPPlotBegin", dynlib: dllname.} +proc pPlotAdd*(ih: PIhandle, x, y: cfloat) {. + cdecl, importc: "IupPPlotAdd", dynlib: dllname.} +proc pPlotAddStr*(ih: PIhandle, x: cstring, y: cfloat) {. + cdecl, importc: "IupPPlotAddStr", dynlib: dllname.} +proc pPlotEnd*(ih: PIhandle): cint {. + cdecl, importc: "IupPPlotEnd", dynlib: dllname.} + +proc pPlotInsertStr*(ih: PIhandle, index, sampleIndex: cint, x: cstring, y: cfloat) {.cdecl, importc: "IupPPlotInsertStr", - dynlib: dllname.} -proc PPlotInsert*(ih: PIhandle, index, sample_index: cint, + dynlib: dllname.} +proc pPlotInsert*(ih: PIhandle, index, sampleIndex: cint, x, y: cfloat) {. - cdecl, importc: "IupPPlotInsert", dynlib: dllname.} - -# convert from plot coordinates to pixels -proc PPlotTransform*(ih: PIhandle, x, y: cfloat, ix, iy: var cint) {. - cdecl, importc: "IupPPlotTransform", dynlib: dllname.} - -# Plot on the given device. Uses a "cdCanvas*". -proc PPlotPaintTo*(ih: PIhandle, cnv: pointer) {. - cdecl, importc: "IupPPlotPaintTo", dynlib: dllname.} - + cdecl, importc: "IupPPlotInsert", dynlib: dllname.} + +# convert from plot coordinates to pixels +proc pPlotTransform*(ih: PIhandle, x, y: cfloat, ix, iy: var cint) {. + cdecl, importc: "IupPPlotTransform", dynlib: dllname.} + +# Plot on the given device. Uses a "cdCanvas*". +proc pPlotPaintTo*(ih: PIhandle, cnv: pointer) {. + cdecl, importc: "IupPPlotPaintTo", dynlib: dllname.} + diff --git a/lib/wrappers/libcurl.nim b/lib/wrappers/libcurl.nim index bd8616759..8c962f6cb 100644 --- a/lib/wrappers/libcurl.nim +++ b/lib/wrappers/libcurl.nim @@ -43,10 +43,10 @@ type Pinfotype* = ptr Tinfotype Plock_access* = ptr Tlock_access Plock_data* = ptr Tlock_data - Pmalloc_callback* = ptr tmalloc_callback + Pmalloc_callback* = ptr Tmalloc_callback PNETRC_OPTION* = ptr TNETRC_OPTION Pproxytype* = ptr Tproxytype - Prealloc_callback* = ptr trealloc_callback + Prealloc_callback* = ptr Trealloc_callback Pslist* = ptr Tslist Psocket* = ptr Tsocket PSSL_VERSION* = ptr TSSL_VERSION @@ -309,7 +309,7 @@ type TMsg*{.pure, final.} = object msg*: TMSGEnum easy_handle*: PCurl - whatever*: Pointer #data : record + whatever*: pointer #data : record # case longint of # 0 : ( whatever : pointer ); # 1 : ( result : CURLcode ); @@ -442,7 +442,7 @@ proc slist_append*(slist: Pslist, p: cstring): Pslist{.cdecl, dynlib: libname, importc: "curl_slist_append".} proc slist_free_all*(para1: Pslist){.cdecl, dynlib: libname, importc: "curl_slist_free_all".} -proc getdate*(p: cstring, unused: ptr TTime): TTime{.cdecl, dynlib: libname, +proc getdate*(p: cstring, unused: ptr Time): Time{.cdecl, dynlib: libname, importc: "curl_getdate".} proc share_init*(): PSH{.cdecl, dynlib: libname, importc: "curl_share_init".} proc share_setopt*(para1: PSH, option: TSHoption): TSHcode{.cdecl, varargs, diff --git a/lib/wrappers/libsvm.nim b/lib/wrappers/libsvm.nim index 8dec05bcf..00d5ac73c 100644 --- a/lib/wrappers/libsvm.nim +++ b/lib/wrappers/libsvm.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/wrappers/libuv.nim b/lib/wrappers/libuv.nim index 1b6416982..3189ec408 100644 --- a/lib/wrappers/libuv.nim +++ b/lib/wrappers/libuv.nim @@ -35,7 +35,7 @@ type GetAddrInfoProc* = proc (handle: PGetAddrInfo, status: cint, res: ptr TAddrInfo) ExitProc* = proc (a2: PProcess, exit_status: cint, term_signal: cint) - FsProc* = proc (req: pFS) + FsProc* = proc (req: PFS) WorkProc* = proc (req: PWork) AfterWorkProc* = proc (req: PWork) @@ -338,7 +338,7 @@ type FS_CHMOD, FS_FCHMOD, FS_FSYNC, FS_FDATASYNC, FS_UNLINK, FS_RMDIR, FS_MKDIR, FS_RENAME, FS_READDIR, FS_LINK, FS_SYMLINK, FS_READLINK, FS_CHOWN, FS_FCHOWN - tFS* {.pure, final, importc: "uv_fs_t", header: "uv.h".} = object + TFS* {.pure, final, importc: "uv_fs_t", header: "uv.h".} = object typ* {.importc: "type".}: TReqType data* {.importc: "data".}: pointer loop* {.importc: "loop".}: PLoop @@ -349,7 +349,7 @@ type path* {.importc: "path".}: cstring errorno* {.importc: "errorno".}: cint - pFS* = ptr tFS + PFS* = ptr TFS TReq* {.pure, final, importc: "uv_req_t", header: "uv.h".} = object typ* {.importc: "type".}: TReqType @@ -591,85 +591,85 @@ proc process_kill*(a2: PProcess, signum: cint): cint{. proc queue_work*(loop: PLoop, req: PWork, work_cb: WorkProc, after_work_cb: AfterWorkProc): cint{. importc: "uv_queue_work", header: "uv.h".} -proc req_cleanup*(req: pFS){. +proc req_cleanup*(req: PFS){. importc: "uv_fs_req_cleanup", header: "uv.h".} -proc close*(loop: PLoop, req: pFS, file: TFile, cb: FsProc): cint{. +proc close*(loop: PLoop, req: PFS, file: TFile, cb: FsProc): cint{. importc: "uv_fs_close", header: "uv.h".} -proc open*(loop: PLoop, req: pFS, path: cstring, flags: cint, mode: cint, cb: FsProc): cint{. +proc open*(loop: PLoop, req: PFS, path: cstring, flags: cint, mode: cint, cb: FsProc): cint{. importc: "uv_fs_open", header: "uv.h".} -proc read*(loop: PLoop, req: pFS, file: TFile, buf: pointer, length: csize, offset: coff, cb: FsProc): cint{. +proc read*(loop: PLoop, req: PFS, file: TFile, buf: pointer, length: csize, offset: coff, cb: FsProc): cint{. importc: "uv_fs_read", header: "uv.h".} -proc unlink*(loop: PLoop, req: pFS, path: cstring, cb: FsProc): cint{. +proc unlink*(loop: PLoop, req: PFS, path: cstring, cb: FsProc): cint{. importc: "uv_fs_unlink", header: "uv.h".} -proc write*(loop: PLoop, req: pFS, file: TFile, buf: pointer, length: csize, offset: coff, cb: FsProc): cint{. +proc write*(loop: PLoop, req: PFS, file: TFile, buf: pointer, length: csize, offset: coff, cb: FsProc): cint{. importc: "uv_fs_write", header: "uv.h".} -proc mkdir*(loop: PLoop, req: pFS, path: cstring, mode: cint, cb: FsProc): cint{. +proc mkdir*(loop: PLoop, req: PFS, path: cstring, mode: cint, cb: FsProc): cint{. importc: "uv_fs_mkdir", header: "uv.h".} -proc rmdir*(loop: PLoop, req: pFS, path: cstring, cb: FsProc): cint{. +proc rmdir*(loop: PLoop, req: PFS, path: cstring, cb: FsProc): cint{. importc: "uv_fs_rmdir", header: "uv.h".} -proc readdir*(loop: PLoop, req: pFS, path: cstring, flags: cint, cb: FsProc): cint{. +proc readdir*(loop: PLoop, req: PFS, path: cstring, flags: cint, cb: FsProc): cint{. importc: "uv_fs_readdir", header: "uv.h".} -proc stat*(loop: PLoop, req: pFS, path: cstring, cb: FsProc): cint{. +proc stat*(loop: PLoop, req: PFS, path: cstring, cb: FsProc): cint{. importc: "uv_fs_stat", header: "uv.h".} -proc fstat*(loop: PLoop, req: pFS, file: TFile, cb: FsProc): cint{. +proc fstat*(loop: PLoop, req: PFS, file: TFile, cb: FsProc): cint{. importc: "uv_fs_fstat", header: "uv.h".} -proc rename*(loop: PLoop, req: pFS, path: cstring, new_path: cstring, cb: FsProc): cint{. +proc rename*(loop: PLoop, req: PFS, path: cstring, new_path: cstring, cb: FsProc): cint{. importc: "uv_fs_rename", header: "uv.h".} -proc fsync*(loop: PLoop, req: pFS, file: TFile, cb: FsProc): cint{. +proc fsync*(loop: PLoop, req: PFS, file: TFile, cb: FsProc): cint{. importc: "uv_fs_fsync", header: "uv.h".} -proc fdatasync*(loop: PLoop, req: pFS, file: TFile, cb: FsProc): cint{. +proc fdatasync*(loop: PLoop, req: PFS, file: TFile, cb: FsProc): cint{. importc: "uv_fs_fdatasync", header: "uv.h".} -proc ftruncate*(loop: PLoop, req: pFS, file: TFile, offset: coff, cb: FsProc): cint{. +proc ftruncate*(loop: PLoop, req: PFS, file: TFile, offset: coff, cb: FsProc): cint{. importc: "uv_fs_ftruncate", header: "uv.h".} -proc sendfile*(loop: PLoop, req: pFS, out_fd: TFile, in_fd: TFile, in_offset: coff, length: csize, cb: FsProc): cint{. +proc sendfile*(loop: PLoop, req: PFS, out_fd: TFile, in_fd: TFile, in_offset: coff, length: csize, cb: FsProc): cint{. importc: "uv_fs_sendfile", header: "uv.h".} -proc chmod*(loop: PLoop, req: pFS, path: cstring, mode: cint, cb: FsProc): cint{. +proc chmod*(loop: PLoop, req: PFS, path: cstring, mode: cint, cb: FsProc): cint{. importc: "uv_fs_chmod", header: "uv.h".} -proc utime*(loop: PLoop, req: pFS, path: cstring, atime: cdouble, mtime: cdouble, cb: FsProc): cint{. +proc utime*(loop: PLoop, req: PFS, path: cstring, atime: cdouble, mtime: cdouble, cb: FsProc): cint{. importc: "uv_fs_utime", header: "uv.h".} -proc futime*(loop: PLoop, req: pFS, file: TFile, atime: cdouble, mtime: cdouble, cb: FsProc): cint{. +proc futime*(loop: PLoop, req: PFS, file: TFile, atime: cdouble, mtime: cdouble, cb: FsProc): cint{. importc: "uv_fs_futime", header: "uv.h".} -proc lstat*(loop: PLoop, req: pFS, path: cstring, cb: FsProc): cint{. +proc lstat*(loop: PLoop, req: PFS, path: cstring, cb: FsProc): cint{. importc: "uv_fs_lstat", header: "uv.h".} -proc link*(loop: PLoop, req: pFS, path: cstring, new_path: cstring, cb: FsProc): cint{. +proc link*(loop: PLoop, req: PFS, path: cstring, new_path: cstring, cb: FsProc): cint{. importc: "uv_fs_link", header: "uv.h".} -proc symlink*(loop: PLoop, req: pFS, path: cstring, new_path: cstring, flags: cint, cb: FsProc): cint{. +proc symlink*(loop: PLoop, req: PFS, path: cstring, new_path: cstring, flags: cint, cb: FsProc): cint{. importc: "uv_fs_symlink", header: "uv.h".} -proc readlink*(loop: PLoop, req: pFS, path: cstring, cb: FsProc): cint{. +proc readlink*(loop: PLoop, req: PFS, path: cstring, cb: FsProc): cint{. importc: "uv_fs_readlink", header: "uv.h".} -proc fchmod*(loop: PLoop, req: pFS, file: TFile, mode: cint, cb: FsProc): cint{. +proc fchmod*(loop: PLoop, req: PFS, file: TFile, mode: cint, cb: FsProc): cint{. importc: "uv_fs_fchmod", header: "uv.h".} -proc chown*(loop: PLoop, req: pFS, path: cstring, uid: cint, gid: cint, cb: FsProc): cint{. +proc chown*(loop: PLoop, req: PFS, path: cstring, uid: cint, gid: cint, cb: FsProc): cint{. importc: "uv_fs_chown", header: "uv.h".} -proc fchown*(loop: PLoop, req: pFS, file: TFile, uid: cint, gid: cint, cb: FsProc): cint{. +proc fchown*(loop: PLoop, req: PFS, file: TFile, uid: cint, gid: cint, cb: FsProc): cint{. importc: "uv_fs_fchown", header: "uv.h".} -proc event_init*(loop: PLoop, handle: PFsEvent, filename: cstring, cb: FsEventProc): cint{. +proc event_init*(loop: PLoop, handle: PFSEvent, filename: cstring, cb: FsEventProc): cint{. importc: "uv_fs_event_init", header: "uv.h".} proc ip4_addr*(ip: cstring, port: cint): TSockAddrIn{. diff --git a/lib/wrappers/mysql.nim b/lib/wrappers/mysql.nim index 84d70287f..945e09ecf 100644 --- a/lib/wrappers/mysql.nim +++ b/lib/wrappers/mysql.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this @@ -729,7 +729,7 @@ type len*: int # output length pointer is_null*: Pmy_bool # Pointer to null indicator buffer*: pointer # buffer to get/put data - error*: pmy_bool # set this if you want to track data truncations happened during fetch + error*: PMy_bool # set this if you want to track data truncations happened during fetch buffer_type*: Tenum_field_types # buffer type buffer_length*: int # buffer length, must be set for str/binary # Following are for internal use. Set by mysql_stmt_bind_param @@ -904,7 +904,7 @@ proc shutdown*(MySQL: PMySQL, shutdown_level: Tenum_shutdown_level): cint{.stdca dynlib: lib, importc: "mysql_shutdown".} proc dump_debug_info*(MySQL: PMySQL): cint{.stdcall, dynlib: lib, importc: "mysql_dump_debug_info".} -proc refresh*(MySQL: PMySQL, refresh_options: cuint): cint{.stdcall, dynlib: lib, +proc refresh*(sql: PMySQL, refresh_options: cuint): cint{.stdcall, dynlib: lib, importc: "mysql_refresh".} proc kill*(MySQL: PMySQL, pid: int): cint{.stdcall, dynlib: lib, importc: "mysql_kill".} proc set_server_option*(MySQL: PMySQL, option: Tenum_mysql_set_option): cint{.stdcall, @@ -1040,7 +1040,7 @@ const NO_DATA* = 100 DATA_TRUNCATED* = 101 -proc reload*(MySQL: PMySQL): cint +proc reload*(x: PMySQL): cint when defined(USE_OLD_FUNCTIONS): proc connect*(MySQL: PMySQL, host: cstring, user: cstring, passwd: cstring): PMySQL{.stdcall, dynlib: lib, importc: "mysql_connect".} @@ -1059,7 +1059,7 @@ proc IS_NOT_NULL(n: int32): bool = proc IS_BLOB(n: int32): bool = result = (n and BLOB_FLAG) != 0 -proc IS_NUM_FIELD(f: pst_mysql_field): bool = +proc IS_NUM_FIELD(f: Pst_mysql_field): bool = result = (f.flags and NUM_FLAG) != 0 proc IS_NUM(t: Tenum_field_types): bool = @@ -1071,7 +1071,7 @@ proc INTERNAL_NUM_FIELD(f: Pst_mysql_field): bool = ((f.ftype != FIELD_TYPE_TIMESTAMP) or (f.len == 14) or (f.len == 8)) or (f.ftype == FIELD_TYPE_YEAR) -proc reload(mysql: PMySQL): cint = - result = refresh(mysql, REFRESH_GRANT) +proc reload(x: PMySQL): cint = + result = refresh(x, REFRESH_GRANT) {.pop.} diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim index 4dc71bffd..6e85fb9dd 100644 --- a/lib/wrappers/openssl.nim +++ b/lib/wrappers/openssl.nim @@ -41,11 +41,13 @@ {.deadCodeElim: on.} -when defined(WINDOWS): +const useWinVersion = defined(Windows) or defined(nimdoc) + +when useWinVersion: const DLLSSLName = "(ssleay32|libssl32).dll" DLLUtilName = "libeay32.dll" - from winlean import TSocketHandle + from winlean import SocketHandle else: const versions = "(|.1.0.0|.0.9.9|.0.9.8|.0.9.7|.0.9.6|.0.9.5|.0.9.4)" @@ -57,20 +59,19 @@ else: const DLLSSLName = "libssl.so" & versions DLLUtilName = "libcrypto.so" & versions - from posix import TSocketHandle + from posix import SocketHandle type SslStruct {.final, pure.} = object SslPtr* = ptr SslStruct PSslPtr* = ptr SslPtr - PSSL_CTX* = SslPtr - PSSL* = SslPtr + SslCtx* = SslPtr PSSL_METHOD* = SslPtr PX509* = SslPtr PX509_NAME* = SslPtr PEVP_MD* = SslPtr PBIO_METHOD* = SslPtr - PBIO* = SslPtr + BIO* = SslPtr EVP_PKEY* = SslPtr PRSA* = SslPtr PASN1_UTCTIME* = SslPtr @@ -85,6 +86,8 @@ type des_key_schedule* = array[1..16, des_ks_struct] +{.deprecated: [PSSL: SslPtr, PSSL_CTX: SslCtx, PBIO: BIO].} + const EVP_MAX_MD_SIZE* = 16 + 20 SSL_ERROR_NONE* = 0 @@ -206,58 +209,59 @@ proc SSLv2_method*(): PSSL_METHOD{.cdecl, dynlib: DLLSSLName, importc.} proc SSLv3_method*(): PSSL_METHOD{.cdecl, dynlib: DLLSSLName, importc.} proc TLSv1_method*(): PSSL_METHOD{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_new*(context: PSSL_CTX): PSSL{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_free*(ssl: PSSL){.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_CTX_new*(meth: PSSL_METHOD): PSSL_CTX{.cdecl, +proc SSL_new*(context: SslCtx): SslPtr{.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_free*(ssl: SslPtr){.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_CTX_new*(meth: PSSL_METHOD): SslCtx{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_CTX_load_verify_locations*(ctx: PSSL_CTX, CAfile: cstring, +proc SSL_CTX_load_verify_locations*(ctx: SslCtx, CAfile: cstring, CApath: cstring): cInt{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_CTX_free*(arg0: PSSL_CTX){.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_CTX_set_verify*(s: PSSL_CTX, mode: int, cb: proc (a: int, b: pointer): int {.cdecl.}){.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_get_verify_result*(ssl: PSSL): int{.cdecl, +proc SSL_CTX_free*(arg0: SslCtx){.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_CTX_set_verify*(s: SslCtx, mode: int, cb: proc (a: int, b: pointer): int {.cdecl.}){.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_get_verify_result*(ssl: SslPtr): int{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_CTX_set_cipher_list*(s: PSSLCTX, ciphers: cstring): cint{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_CTX_use_certificate_file*(ctx: PSSL_CTX, filename: cstring, typ: cInt): cInt{. +proc SSL_CTX_set_cipher_list*(s: SslCtx, ciphers: cstring): cint{.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_CTX_use_certificate_file*(ctx: SslCtx, filename: cstring, typ: cInt): cInt{. stdcall, dynlib: DLLSSLName, importc.} -proc SSL_CTX_use_certificate_chain_file*(ctx: PSSL_CTX, filename: cstring): cInt{. +proc SSL_CTX_use_certificate_chain_file*(ctx: SslCtx, filename: cstring): cInt{. stdcall, dynlib: DLLSSLName, importc.} -proc SSL_CTX_use_PrivateKey_file*(ctx: PSSL_CTX, +proc SSL_CTX_use_PrivateKey_file*(ctx: SslCtx, filename: cstring, typ: cInt): cInt{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_CTX_check_private_key*(ctx: PSSL_CTX): cInt{.cdecl, dynlib: DLLSSLName, +proc SSL_CTX_check_private_key*(ctx: SslCtx): cInt{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_set_fd*(ssl: PSSL, fd: TSocketHandle): cint{.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_set_fd*(ssl: SslPtr, fd: SocketHandle): cint{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_shutdown*(ssl: PSSL): cInt{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_connect*(ssl: PSSL): cint{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_read*(ssl: PSSL, buf: pointer, num: int): cint{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_write*(ssl: PSSL, buf: cstring, num: int): cint{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_get_error*(s: PSSL, ret_code: cInt): cInt{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_accept*(ssl: PSSL): cInt{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_pending*(ssl: PSSL): cInt{.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_shutdown*(ssl: SslPtr): cInt{.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_connect*(ssl: SslPtr): cint{.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_read*(ssl: SslPtr, buf: pointer, num: int): cint{.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_write*(ssl: SslPtr, buf: cstring, num: int): cint{.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_get_error*(s: SslPtr, ret_code: cInt): cInt{.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_accept*(ssl: SslPtr): cInt{.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_pending*(ssl: SslPtr): cInt{.cdecl, dynlib: DLLSSLName, importc.} -proc BIO_new_ssl_connect*(ctx: PSSL_CTX): PBIO{.cdecl, +proc BIO_new_ssl_connect*(ctx: SslCtx): BIO{.cdecl, dynlib: DLLSSLName, importc.} -proc BIO_ctrl*(bio: PBIO, cmd: cint, larg: int, arg: cstring): int{.cdecl, +proc BIO_ctrl*(bio: BIO, cmd: cint, larg: int, arg: cstring): int{.cdecl, dynlib: DLLSSLName, importc.} -proc BIO_get_ssl*(bio: PBIO, ssl: ptr PSSL): int = +proc BIO_get_ssl*(bio: BIO, ssl: ptr SslPtr): int = return BIO_ctrl(bio, BIO_C_GET_SSL, 0, cast[cstring](ssl)) -proc BIO_set_conn_hostname*(bio: PBIO, name: cstring): int = +proc BIO_set_conn_hostname*(bio: BIO, name: cstring): int = return BIO_ctrl(bio, BIO_C_SET_CONNECT, 0, name) -proc BIO_do_handshake*(bio: PBIO): int = - return BIO_ctrl(bio, BIO_C_DO_STATE_MACHINE, 0, NIL) -proc BIO_do_connect*(bio: PBIO): int = +proc BIO_do_handshake*(bio: BIO): int = + return BIO_ctrl(bio, BIO_C_DO_STATE_MACHINE, 0, nil) +proc BIO_do_connect*(bio: BIO): int = return BIO_do_handshake(bio) -proc BIO_read*(b: PBIO, data: cstring, length: cInt): cInt{.cdecl, - dynlib: DLLUtilName, importc.} -proc BIO_write*(b: PBIO, data: cstring, length: cInt): cInt{.cdecl, - dynlib: DLLUtilName, importc.} +when not defined(nimfix): + proc BIO_read*(b: BIO, data: cstring, length: cInt): cInt{.cdecl, + dynlib: DLLUtilName, importc.} + proc BIO_write*(b: BIO, data: cstring, length: cInt): cInt{.cdecl, + dynlib: DLLUtilName, importc.} -proc BIO_free*(b: PBIO): cInt{.cdecl, dynlib: DLLUtilName, importc.} +proc BIO_free*(b: BIO): cInt{.cdecl, dynlib: DLLUtilName, importc.} -proc ERR_print_errors_fp*(fp: TFile){.cdecl, dynlib: DLLSSLName, importc.} +proc ERR_print_errors_fp*(fp: File){.cdecl, dynlib: DLLSSLName, importc.} proc ERR_error_string*(e: cInt, buf: cstring): cstring{.cdecl, dynlib: DLLUtilName, importc.} @@ -268,20 +272,48 @@ proc OpenSSL_add_all_algorithms*(){.cdecl, dynlib: DLLUtilName, importc: "OPENSS proc OPENSSL_config*(configName: cstring){.cdecl, dynlib: DLLSSLName, importc.} -when not defined(windows): +when not useWinVersion: proc CRYPTO_set_mem_functions(a,b,c: pointer){.cdecl, dynlib: DLLUtilName, importc.} proc CRYPTO_malloc_init*() = - when not defined(windows): + when not useWinVersion: CRYPTO_set_mem_functions(alloc, realloc, dealloc) -proc SSL_CTX_ctrl*(ctx: PSSL_CTX, cmd: cInt, larg: int, parg: pointer): int{. +proc SSL_CTX_ctrl*(ctx: SslCtx, cmd: cInt, larg: int, parg: pointer): int{. cdecl, dynlib: DLLSSLName, importc.} -proc SSLCTXSetMode*(ctx: PSSL_CTX, mode: int): int = +proc SSLCTXSetMode*(ctx: SslCtx, mode: int): int = result = SSL_CTX_ctrl(ctx, SSL_CTRL_MODE, mode, nil) +proc bioNew*(b: PBIO_METHOD): BIO{.cdecl, dynlib: DLLUtilName, importc: "BIO_new".} +proc bioFreeAll*(b: BIO){.cdecl, dynlib: DLLUtilName, importc: "BIO_free_all".} +proc bioSMem*(): PBIO_METHOD{.cdecl, dynlib: DLLUtilName, importc: "BIO_s_mem".} +proc bioCtrlPending*(b: BIO): cInt{.cdecl, dynlib: DLLUtilName, importc: "BIO_ctrl_pending".} +proc bioRead*(b: BIO, Buf: cstring, length: cInt): cInt{.cdecl, + dynlib: DLLUtilName, importc: "BIO_read".} +proc bioWrite*(b: BIO, Buf: cstring, length: cInt): cInt{.cdecl, + dynlib: DLLUtilName, importc: "BIO_write".} + +proc sslSetConnectState*(s: SslPtr) {.cdecl, + dynlib: DLLSSLName, importc: "SSL_set_connect_state".} +proc sslSetAcceptState*(s: SslPtr) {.cdecl, + dynlib: DLLSSLName, importc: "SSL_set_accept_state".} + +proc sslRead*(ssl: SslPtr, buf: cstring, num: cInt): cInt{.cdecl, + dynlib: DLLSSLName, importc: "SSL_read".} +proc sslPeek*(ssl: SslPtr, buf: cstring, num: cInt): cInt{.cdecl, + dynlib: DLLSSLName, importc: "SSL_peek".} +proc sslWrite*(ssl: SslPtr, buf: cstring, num: cInt): cInt{.cdecl, + dynlib: DLLSSLName, importc: "SSL_write".} + +proc sslSetBio*(ssl: SslPtr, rbio, wbio: BIO) {.cdecl, + dynlib: DLLSSLName, importc: "SSL_set_bio".} + +proc sslDoHandshake*(ssl: SslPtr): cint {.cdecl, + dynlib: DLLSSLName, importc: "SSL_do_handshake".} + + when true: discard else: @@ -328,12 +360,7 @@ else: proc SslConnect*(ssl: PSSL): cInt{.cdecl, dynlib: DLLSSLName, importc.} - proc SslRead*(ssl: PSSL, buf: SslPtr, num: cInt): cInt{.cdecl, - dynlib: DLLSSLName, importc.} - proc SslPeek*(ssl: PSSL, buf: SslPtr, num: cInt): cInt{.cdecl, - dynlib: DLLSSLName, importc.} - proc SslWrite*(ssl: PSSL, buf: SslPtr, num: cInt): cInt{.cdecl, - dynlib: DLLSSLName, importc.} + proc SslGetVersion*(ssl: PSSL): cstring{.cdecl, dynlib: DLLSSLName, importc.} proc SslGetPeerCertificate*(ssl: PSSL): PX509{.cdecl, dynlib: DLLSSLName, importc.} @@ -393,14 +420,7 @@ else: proc OPENSSLaddallalgorithms*(){.cdecl, dynlib: DLLUtilName, importc.} proc CRYPTOcleanupAllExData*(){.cdecl, dynlib: DLLUtilName, importc.} proc RandScreen*(){.cdecl, dynlib: DLLUtilName, importc.} - proc BioNew*(b: PBIO_METHOD): PBIO{.cdecl, dynlib: DLLUtilName, importc.} - proc BioFreeAll*(b: PBIO){.cdecl, dynlib: DLLUtilName, importc.} - proc BioSMem*(): PBIO_METHOD{.cdecl, dynlib: DLLUtilName, importc.} - proc BioCtrlPending*(b: PBIO): cInt{.cdecl, dynlib: DLLUtilName, importc.} - proc BioRead*(b: PBIO, Buf: cstring, length: cInt): cInt{.cdecl, - dynlib: DLLUtilName, importc.} - proc BioWrite*(b: PBIO, Buf: cstring, length: cInt): cInt{.cdecl, - dynlib: DLLUtilName, importc.} + proc d2iPKCS12bio*(b: PBIO, Pkcs12: SslPtr): SslPtr{.cdecl, dynlib: DLLUtilName, importc.} proc PKCS12parse*(p12: SslPtr, pass: cstring, pkey, cert, ca: var SslPtr): cint{. @@ -448,11 +468,11 @@ type {.pragma: ic, importc: "$1".} {.push callconv:cdecl, dynlib:DLLUtilName.} -proc MD5_Init*(c: var MD5_CTX): cint{.ic.} -proc MD5_Update*(c: var MD5_CTX; data: pointer; len: csize): cint{.ic.} -proc MD5_Final*(md: cstring; c: var MD5_CTX): cint{.ic.} -proc MD5*(d: ptr cuchar; n: csize; md: ptr cuchar): ptr cuchar{.ic.} -proc MD5_Transform*(c: var MD5_CTX; b: ptr cuchar){.ic.} +proc md5_Init*(c: var MD5_CTX): cint{.ic.} +proc md5_Update*(c: var MD5_CTX; data: pointer; len: csize): cint{.ic.} +proc md5_Final*(md: cstring; c: var MD5_CTX): cint{.ic.} +proc md5*(d: ptr cuchar; n: csize; md: ptr cuchar): ptr cuchar{.ic.} +proc md5_Transform*(c: var MD5_CTX; b: ptr cuchar){.ic.} {.pop.} from strutils import toHex,toLower @@ -463,7 +483,7 @@ proc hexStr (buf:cstring): string = for i in 0 .. <16: result.add toHex(buf[i].ord, 2).toLower -proc MD5_File* (file: string): string {.raises:[EIO,Ebase].} = +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` @@ -483,7 +503,7 @@ proc MD5_File* (file: string): string {.raises:[EIO,Ebase].} = result = hexStr(buf) -proc MD5_Str* (str:string): string {.raises:[EIO].} = +proc md5_Str* (str:string): string {.raises:[IOError].} = ##Generate MD5 hash for a string. Result is a 32 character #hex string with lowercase characters var diff --git a/lib/wrappers/pdcurses.nim b/lib/wrappers/pdcurses.nim index a53289bce..bed69648a 100644 --- a/lib/wrappers/pdcurses.nim +++ b/lib/wrappers/pdcurses.nim @@ -741,7 +741,7 @@ proc getbkgd*(a2: ptr TWINDOW): cunsignedlong{.extdecl, importc: "getbkgd", 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: TFile): ptr TWINDOW{.extdecl, importc: "getwin", +proc getwin*(a2: File): ptr TWINDOW{.extdecl, importc: "getwin", dynlib: pdcursesdll.} proc halfdelay*(a2: cint): cint{.extdecl, importc: "halfdelay", dynlib: pdcursesdll.} @@ -895,7 +895,7 @@ proc mvwvline*(a2: ptr TWINDOW; a3: cint; a4: cint; a5: cunsignedlong; a6: cint) proc napms*(a2: cint): cint{.extdecl, importc: "napms", dynlib: pdcursesdll.} proc newpad*(a2: cint; a3: cint): ptr TWINDOW{.extdecl, importc: "newpad", dynlib: pdcursesdll.} -proc newterm*(a2: cstring; a3: TFile; a4: TFile): ptr TSCREEN{.extdecl, +proc newterm*(a2: cstring; a3: File; a4: File): ptr TSCREEN{.extdecl, importc: "newterm", dynlib: pdcursesdll.} proc newwin*(a2: cint; a3: cint; a4: cint; a5: cint): ptr TWINDOW{.extdecl, importc: "newwin", dynlib: pdcursesdll.} @@ -924,7 +924,7 @@ proc prefresh*(a2: ptr TWINDOW; 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 TWINDOW; a3: TFile): cint{.extdecl, importc: "putwin", +proc putwin*(a2: ptr TWINDOW; a3: File): cint{.extdecl, importc: "putwin", dynlib: pdcursesdll.} proc qiflush*(){.extdecl, importc: "qiflush", dynlib: pdcursesdll.} proc raw*(): cint{.extdecl, importc: "raw", dynlib: pdcursesdll.} diff --git a/lib/wrappers/postgres.nim b/lib/wrappers/postgres.nim index ce78d3435..cb39c41bb 100644 --- a/lib/wrappers/postgres.nim +++ b/lib/wrappers/postgres.nim @@ -68,9 +68,9 @@ type dbName*: cstring status*: TConnStatusType errorMessage*: array[0..(ERROR_MSG_LENGTH) - 1, char] - Pfin*: TFile - Pfout*: TFile - Pfdebug*: TFile + Pfin*: File + Pfout*: File + Pfdebug*: File sock*: int32 laddr*: TSockAddr raddr*: TSockAddr @@ -145,184 +145,184 @@ type p*: pointer -proc PQconnectStart*(conninfo: cstring): PPGconn{.cdecl, dynlib: dllName, +proc pqconnectStart*(conninfo: cstring): PPGconn{.cdecl, dynlib: dllName, importc: "PQconnectStart".} -proc PQconnectPoll*(conn: PPGconn): PostgresPollingStatusType{.cdecl, +proc pqconnectPoll*(conn: PPGconn): PostgresPollingStatusType{.cdecl, dynlib: dllName, importc: "PQconnectPoll".} -proc PQconnectdb*(conninfo: cstring): PPGconn{.cdecl, dynlib: dllName, +proc pqconnectdb*(conninfo: cstring): PPGconn{.cdecl, dynlib: dllName, importc: "PQconnectdb".} -proc PQsetdbLogin*(pghost: cstring, pgport: cstring, pgoptions: cstring, +proc pqsetdbLogin*(pghost: cstring, pgport: cstring, pgoptions: cstring, pgtty: cstring, dbName: cstring, login: cstring, pwd: cstring): PPGconn{. cdecl, dynlib: dllName, importc: "PQsetdbLogin".} -proc PQsetdb*(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME: cstring): ppgconn -proc PQfinish*(conn: PPGconn){.cdecl, dynlib: dllName, importc: "PQfinish".} -proc PQconndefaults*(): PPQconninfoOption{.cdecl, dynlib: dllName, +proc pqsetdb*(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME: cstring): Ppgconn +proc pqfinish*(conn: PPGconn){.cdecl, dynlib: dllName, importc: "PQfinish".} +proc pqconndefaults*(): PPQconninfoOption{.cdecl, dynlib: dllName, importc: "PQconndefaults".} -proc PQconninfoFree*(connOptions: PPQconninfoOption){.cdecl, dynlib: dllName, +proc pqconninfoFree*(connOptions: PPQconninfoOption){.cdecl, dynlib: dllName, importc: "PQconninfoFree".} -proc PQresetStart*(conn: PPGconn): int32{.cdecl, dynlib: dllName, +proc pqresetStart*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQresetStart".} -proc PQresetPoll*(conn: PPGconn): PostgresPollingStatusType{.cdecl, +proc pqresetPoll*(conn: PPGconn): PostgresPollingStatusType{.cdecl, dynlib: dllName, importc: "PQresetPoll".} -proc PQreset*(conn: PPGconn){.cdecl, dynlib: dllName, importc: "PQreset".} -proc PQrequestCancel*(conn: PPGconn): int32{.cdecl, dynlib: dllName, +proc pqreset*(conn: PPGconn){.cdecl, dynlib: dllName, importc: "PQreset".} +proc pqrequestCancel*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQrequestCancel".} -proc PQdb*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQdb".} -proc PQuser*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQuser".} -proc PQpass*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQpass".} -proc PQhost*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQhost".} -proc PQport*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQport".} -proc PQtty*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQtty".} -proc PQoptions*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, +proc pqdb*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQdb".} +proc pquser*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQuser".} +proc pqpass*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQpass".} +proc pqhost*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQhost".} +proc pqport*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQport".} +proc pqtty*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQtty".} +proc pqoptions*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQoptions".} -proc PQstatus*(conn: PPGconn): TConnStatusType{.cdecl, dynlib: dllName, +proc pqstatus*(conn: PPGconn): TConnStatusType{.cdecl, dynlib: dllName, importc: "PQstatus".} -proc PQtransactionStatus*(conn: PPGconn): PGTransactionStatusType{.cdecl, +proc pqtransactionStatus*(conn: PPGconn): PGTransactionStatusType{.cdecl, dynlib: dllName, importc: "PQtransactionStatus".} -proc PQparameterStatus*(conn: PPGconn, paramName: cstring): cstring{.cdecl, +proc pqparameterStatus*(conn: PPGconn, paramName: cstring): cstring{.cdecl, dynlib: dllName, importc: "PQparameterStatus".} -proc PQprotocolVersion*(conn: PPGconn): int32{.cdecl, dynlib: dllName, +proc pqprotocolVersion*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQprotocolVersion".} -proc PQerrorMessage*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, +proc pqerrorMessage*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQerrorMessage".} -proc PQsocket*(conn: PPGconn): int32{.cdecl, dynlib: dllName, +proc pqsocket*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQsocket".} -proc PQbackendPID*(conn: PPGconn): int32{.cdecl, dynlib: dllName, +proc pqbackendPID*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQbackendPID".} -proc PQclientEncoding*(conn: PPGconn): int32{.cdecl, dynlib: dllName, +proc pqclientEncoding*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQclientEncoding".} -proc PQsetClientEncoding*(conn: PPGconn, encoding: cstring): int32{.cdecl, +proc pqsetClientEncoding*(conn: PPGconn, encoding: cstring): int32{.cdecl, dynlib: dllName, importc: "PQsetClientEncoding".} when defined(USE_SSL): # Get the SSL structure associated with a connection - proc PQgetssl*(conn: PPGconn): PSSL{.cdecl, dynlib: dllName, + proc pqgetssl*(conn: PPGconn): PSSL{.cdecl, dynlib: dllName, importc: "PQgetssl".} -proc PQsetErrorVerbosity*(conn: PPGconn, verbosity: PGVerbosity): PGVerbosity{. +proc pqsetErrorVerbosity*(conn: PPGconn, verbosity: PGVerbosity): PGVerbosity{. cdecl, dynlib: dllName, importc: "PQsetErrorVerbosity".} -proc PQtrace*(conn: PPGconn, debug_port: TFile){.cdecl, dynlib: dllName, +proc pqtrace*(conn: PPGconn, debug_port: File){.cdecl, dynlib: dllName, importc: "PQtrace".} -proc PQuntrace*(conn: PPGconn){.cdecl, dynlib: dllName, importc: "PQuntrace".} -proc PQsetNoticeReceiver*(conn: PPGconn, theProc: PQnoticeReceiver, arg: pointer): PQnoticeReceiver{. +proc pquntrace*(conn: PPGconn){.cdecl, dynlib: dllName, importc: "PQuntrace".} +proc pqsetNoticeReceiver*(conn: PPGconn, theProc: PQnoticeReceiver, arg: pointer): PQnoticeReceiver{. cdecl, dynlib: dllName, importc: "PQsetNoticeReceiver".} -proc PQsetNoticeProcessor*(conn: PPGconn, theProc: PQnoticeProcessor, +proc pqsetNoticeProcessor*(conn: PPGconn, theProc: PQnoticeProcessor, arg: pointer): PQnoticeProcessor{.cdecl, dynlib: dllName, importc: "PQsetNoticeProcessor".} -proc PQexec*(conn: PPGconn, query: cstring): PPGresult{.cdecl, dynlib: dllName, +proc pqexec*(conn: PPGconn, query: cstring): PPGresult{.cdecl, dynlib: dllName, importc: "PQexec".} -proc PQexecParams*(conn: PPGconn, command: cstring, nParams: int32, +proc pqexecParams*(conn: PPGconn, command: cstring, nParams: int32, paramTypes: POid, paramValues: cstringArray, paramLengths, paramFormats: ptr int32, resultFormat: int32): PPGresult{. cdecl, dynlib: dllName, importc: "PQexecParams".} -proc PQprepare*(conn: PPGconn, stmtName, query: cstring, nParams: int32, +proc pqprepare*(conn: PPGconn, stmtName, query: cstring, nParams: int32, paramTypes: POid): PPGresult{.cdecl, dynlib: dllName, importc: "PQprepare".} -proc PQexecPrepared*(conn: PPGconn, stmtName: cstring, nParams: int32, - paramValues: cstringArray, +proc pqexecPrepared*(conn: PPGconn, stmtName: cstring, nParams: int32, + paramValues: cstringArray, paramLengths, paramFormats: ptr int32, resultFormat: int32): PPGresult{. cdecl, dynlib: dllName, importc: "PQexecPrepared".} -proc PQsendQuery*(conn: PPGconn, query: cstring): int32{.cdecl, dynlib: dllName, +proc pqsendQuery*(conn: PPGconn, query: cstring): int32{.cdecl, dynlib: dllName, importc: "PQsendQuery".} -proc PQsendQueryParams*(conn: PPGconn, command: cstring, nParams: int32, +proc pqsendQueryParams*(conn: PPGconn, command: cstring, nParams: int32, paramTypes: POid, paramValues: cstringArray, paramLengths, paramFormats: ptr int32, resultFormat: int32): int32{.cdecl, dynlib: dllName, importc: "PQsendQueryParams".} -proc PQsendQueryPrepared*(conn: PPGconn, stmtName: cstring, nParams: int32, +proc pqsendQueryPrepared*(conn: PPGconn, stmtName: cstring, nParams: int32, paramValues: cstringArray, paramLengths, paramFormats: ptr int32, resultFormat: int32): int32{.cdecl, dynlib: dllName, importc: "PQsendQueryPrepared".} -proc PQgetResult*(conn: PPGconn): PPGresult{.cdecl, dynlib: dllName, +proc pqgetResult*(conn: PPGconn): PPGresult{.cdecl, dynlib: dllName, importc: "PQgetResult".} -proc PQisBusy*(conn: PPGconn): int32{.cdecl, dynlib: dllName, +proc pqisBusy*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQisBusy".} -proc PQconsumeInput*(conn: PPGconn): int32{.cdecl, dynlib: dllName, +proc pqconsumeInput*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQconsumeInput".} -proc PQnotifies*(conn: PPGconn): PPGnotify{.cdecl, dynlib: dllName, +proc pqnotifies*(conn: PPGconn): PPGnotify{.cdecl, dynlib: dllName, importc: "PQnotifies".} -proc PQputCopyData*(conn: PPGconn, buffer: cstring, nbytes: int32): int32{. +proc pqputCopyData*(conn: PPGconn, buffer: cstring, nbytes: int32): int32{. cdecl, dynlib: dllName, importc: "PQputCopyData".} -proc PQputCopyEnd*(conn: PPGconn, errormsg: cstring): int32{.cdecl, +proc pqputCopyEnd*(conn: PPGconn, errormsg: cstring): int32{.cdecl, dynlib: dllName, importc: "PQputCopyEnd".} -proc PQgetCopyData*(conn: PPGconn, buffer: cstringArray, async: int32): int32{. +proc pqgetCopyData*(conn: PPGconn, buffer: cstringArray, async: int32): int32{. cdecl, dynlib: dllName, importc: "PQgetCopyData".} -proc PQgetline*(conn: PPGconn, str: cstring, len: int32): int32{.cdecl, +proc pqgetline*(conn: PPGconn, str: cstring, len: int32): int32{.cdecl, dynlib: dllName, importc: "PQgetline".} -proc PQputline*(conn: PPGconn, str: cstring): int32{.cdecl, dynlib: dllName, +proc pqputline*(conn: PPGconn, str: cstring): int32{.cdecl, dynlib: dllName, importc: "PQputline".} -proc PQgetlineAsync*(conn: PPGconn, buffer: cstring, bufsize: int32): int32{. +proc pqgetlineAsync*(conn: PPGconn, buffer: cstring, bufsize: int32): int32{. cdecl, dynlib: dllName, importc: "PQgetlineAsync".} -proc PQputnbytes*(conn: PPGconn, buffer: cstring, nbytes: int32): int32{.cdecl, +proc pqputnbytes*(conn: PPGconn, buffer: cstring, nbytes: int32): int32{.cdecl, dynlib: dllName, importc: "PQputnbytes".} -proc PQendcopy*(conn: PPGconn): int32{.cdecl, dynlib: dllName, +proc pqendcopy*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQendcopy".} -proc PQsetnonblocking*(conn: PPGconn, arg: int32): int32{.cdecl, +proc pqsetnonblocking*(conn: PPGconn, arg: int32): int32{.cdecl, dynlib: dllName, importc: "PQsetnonblocking".} -proc PQisnonblocking*(conn: PPGconn): int32{.cdecl, dynlib: dllName, +proc pqisnonblocking*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQisnonblocking".} -proc PQflush*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQflush".} -proc PQfn*(conn: PPGconn, fnid: int32, result_buf, result_len: ptr int32, +proc pqflush*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQflush".} +proc pqfn*(conn: PPGconn, fnid: int32, result_buf, result_len: ptr int32, result_is_int: int32, args: PPQArgBlock, nargs: int32): PPGresult{. cdecl, dynlib: dllName, importc: "PQfn".} -proc PQresultStatus*(res: PPGresult): TExecStatusType{.cdecl, dynlib: dllName, +proc pqresultStatus*(res: PPGresult): TExecStatusType{.cdecl, dynlib: dllName, importc: "PQresultStatus".} -proc PQresStatus*(status: TExecStatusType): cstring{.cdecl, dynlib: dllName, +proc pqresStatus*(status: TExecStatusType): cstring{.cdecl, dynlib: dllName, importc: "PQresStatus".} -proc PQresultErrorMessage*(res: PPGresult): cstring{.cdecl, dynlib: dllName, +proc pqresultErrorMessage*(res: PPGresult): cstring{.cdecl, dynlib: dllName, importc: "PQresultErrorMessage".} -proc PQresultErrorField*(res: PPGresult, fieldcode: int32): cstring{.cdecl, +proc pqresultErrorField*(res: PPGresult, fieldcode: int32): cstring{.cdecl, dynlib: dllName, importc: "PQresultErrorField".} -proc PQntuples*(res: PPGresult): int32{.cdecl, dynlib: dllName, +proc pqntuples*(res: PPGresult): int32{.cdecl, dynlib: dllName, importc: "PQntuples".} -proc PQnfields*(res: PPGresult): int32{.cdecl, dynlib: dllName, +proc pqnfields*(res: PPGresult): int32{.cdecl, dynlib: dllName, importc: "PQnfields".} -proc PQbinaryTuples*(res: PPGresult): int32{.cdecl, dynlib: dllName, +proc pqbinaryTuples*(res: PPGresult): int32{.cdecl, dynlib: dllName, importc: "PQbinaryTuples".} -proc PQfname*(res: PPGresult, field_num: int32): cstring{.cdecl, +proc pqfname*(res: PPGresult, field_num: int32): cstring{.cdecl, dynlib: dllName, importc: "PQfname".} -proc PQfnumber*(res: PPGresult, field_name: cstring): int32{.cdecl, +proc pqfnumber*(res: PPGresult, field_name: cstring): int32{.cdecl, dynlib: dllName, importc: "PQfnumber".} -proc PQftable*(res: PPGresult, field_num: int32): Oid{.cdecl, dynlib: dllName, +proc pqftable*(res: PPGresult, field_num: int32): Oid{.cdecl, dynlib: dllName, importc: "PQftable".} -proc PQftablecol*(res: PPGresult, field_num: int32): int32{.cdecl, +proc pqftablecol*(res: PPGresult, field_num: int32): int32{.cdecl, dynlib: dllName, importc: "PQftablecol".} -proc PQfformat*(res: PPGresult, field_num: int32): int32{.cdecl, +proc pqfformat*(res: PPGresult, field_num: int32): int32{.cdecl, dynlib: dllName, importc: "PQfformat".} -proc PQftype*(res: PPGresult, field_num: int32): Oid{.cdecl, dynlib: dllName, +proc pqftype*(res: PPGresult, field_num: int32): Oid{.cdecl, dynlib: dllName, importc: "PQftype".} -proc PQfsize*(res: PPGresult, field_num: int32): int32{.cdecl, dynlib: dllName, +proc pqfsize*(res: PPGresult, field_num: int32): int32{.cdecl, dynlib: dllName, importc: "PQfsize".} -proc PQfmod*(res: PPGresult, field_num: int32): int32{.cdecl, dynlib: dllName, +proc pqfmod*(res: PPGresult, field_num: int32): int32{.cdecl, dynlib: dllName, importc: "PQfmod".} -proc PQcmdStatus*(res: PPGresult): cstring{.cdecl, dynlib: dllName, +proc pqcmdStatus*(res: PPGresult): cstring{.cdecl, dynlib: dllName, importc: "PQcmdStatus".} -proc PQoidStatus*(res: PPGresult): cstring{.cdecl, dynlib: dllName, +proc pqoidStatus*(res: PPGresult): cstring{.cdecl, dynlib: dllName, importc: "PQoidStatus".} -proc PQoidValue*(res: PPGresult): Oid{.cdecl, dynlib: dllName, +proc pqoidValue*(res: PPGresult): Oid{.cdecl, dynlib: dllName, importc: "PQoidValue".} -proc PQcmdTuples*(res: PPGresult): cstring{.cdecl, dynlib: dllName, +proc pqcmdTuples*(res: PPGresult): cstring{.cdecl, dynlib: dllName, importc: "PQcmdTuples".} -proc PQgetvalue*(res: PPGresult, tup_num: int32, field_num: int32): cstring{. +proc pqgetvalue*(res: PPGresult, tup_num: int32, field_num: int32): cstring{. cdecl, dynlib: dllName, importc: "PQgetvalue".} -proc PQgetlength*(res: PPGresult, tup_num: int32, field_num: int32): int32{. +proc pqgetlength*(res: PPGresult, tup_num: int32, field_num: int32): int32{. cdecl, dynlib: dllName, importc: "PQgetlength".} -proc PQgetisnull*(res: PPGresult, tup_num: int32, field_num: int32): int32{. +proc pqgetisnull*(res: PPGresult, tup_num: int32, field_num: int32): int32{. cdecl, dynlib: dllName, importc: "PQgetisnull".} -proc PQclear*(res: PPGresult){.cdecl, dynlib: dllName, importc: "PQclear".} -proc PQfreemem*(p: pointer){.cdecl, dynlib: dllName, importc: "PQfreemem".} -proc PQmakeEmptyPGresult*(conn: PPGconn, status: TExecStatusType): PPGresult{. +proc pqclear*(res: PPGresult){.cdecl, dynlib: dllName, importc: "PQclear".} +proc pqfreemem*(p: pointer){.cdecl, dynlib: dllName, importc: "PQfreemem".} +proc pqmakeEmptyPGresult*(conn: PPGconn, status: TExecStatusType): PPGresult{. cdecl, dynlib: dllName, importc: "PQmakeEmptyPGresult".} -proc PQescapeString*(till, `from`: cstring, len: int): int{.cdecl, +proc pqescapeString*(till, `from`: cstring, len: int): int{.cdecl, dynlib: dllName, importc: "PQescapeString".} -proc PQescapeBytea*(bintext: cstring, binlen: int, bytealen: var int): cstring{. +proc pqescapeBytea*(bintext: cstring, binlen: int, bytealen: var int): cstring{. cdecl, dynlib: dllName, importc: "PQescapeBytea".} -proc PQunescapeBytea*(strtext: cstring, retbuflen: var int): cstring{.cdecl, +proc pqunescapeBytea*(strtext: cstring, retbuflen: var int): cstring{.cdecl, dynlib: dllName, importc: "PQunescapeBytea".} -proc PQprint*(fout: TFile, res: PPGresult, ps: PPQprintOpt){.cdecl, +proc pqprint*(fout: File, res: PPGresult, ps: PPQprintOpt){.cdecl, dynlib: dllName, importc: "PQprint".} -proc PQdisplayTuples*(res: PPGresult, fp: TFile, fillAlign: int32, +proc pqdisplayTuples*(res: PPGresult, fp: File, fillAlign: int32, fieldSep: cstring, printHeader: int32, quiet: int32){. cdecl, dynlib: dllName, importc: "PQdisplayTuples".} -proc PQprintTuples*(res: PPGresult, fout: TFile, printAttName: int32, +proc pqprintTuples*(res: PPGresult, fout: File, printAttName: int32, terseOutput: int32, width: int32){.cdecl, dynlib: dllName, importc: "PQprintTuples".} proc lo_open*(conn: PPGconn, lobjId: Oid, mode: int32): int32{.cdecl, @@ -345,8 +345,8 @@ proc lo_import*(conn: PPGconn, filename: cstring): Oid{.cdecl, dynlib: dllName, importc: "lo_import".} proc lo_export*(conn: PPGconn, lobjId: Oid, filename: cstring): int32{.cdecl, dynlib: dllName, importc: "lo_export".} -proc PQmblen*(s: cstring, encoding: int32): int32{.cdecl, dynlib: dllName, +proc pqmblen*(s: cstring, encoding: int32): int32{.cdecl, dynlib: dllName, importc: "PQmblen".} -proc PQenv2encoding*(): int32{.cdecl, dynlib: dllName, importc: "PQenv2encoding".} -proc PQsetdb(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME: cstring): ppgconn = - result = PQsetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, "", "") +proc pqenv2encoding*(): int32{.cdecl, dynlib: dllName, importc: "PQenv2encoding".} +proc pqsetdb(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME: cstring): PPgConn = + result = pqSetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, "", "") diff --git a/lib/wrappers/readline/history.nim b/lib/wrappers/readline/history.nim index 12dfa2707..caa857ceb 100644 --- a/lib/wrappers/readline/history.nim +++ b/lib/wrappers/readline/history.nim @@ -142,7 +142,7 @@ proc history_get*(a2: cint): ptr THIST_ENTRY{.cdecl, importc: "history_get", # Return the timestamp associated with the HIST_ENTRY * passed as an # argument -proc history_get_time*(a2: ptr THIST_ENTRY): TTime{.cdecl, +proc history_get_time*(a2: ptr THIST_ENTRY): Time{.cdecl, importc: "history_get_time", dynlib: historyDll.} # Return the number of bytes that the primary history entries are using. # This just adds up the lengths of the_history->lines. diff --git a/lib/wrappers/readline/readline.nim b/lib/wrappers/readline/readline.nim index bbe416534..5a319243e 100644 --- a/lib/wrappers/readline/readline.nim +++ b/lib/wrappers/readline/readline.nim @@ -776,7 +776,7 @@ proc execute_next*(a2: cint): cint{.cdecl, importc: "rl_execute_next", proc clear_pending_input*(): cint{.cdecl, importc: "rl_clear_pending_input", dynlib: readlineDll.} proc read_key*(): cint{.cdecl, importc: "rl_read_key", dynlib: readlineDll.} -proc getc*(a2: TFile): cint{.cdecl, importc: "rl_getc", dynlib: readlineDll.} +proc getc*(a2: File): cint{.cdecl, importc: "rl_getc", dynlib: readlineDll.} proc set_keyboard_input_timeout*(a2: cint): cint{.cdecl, importc: "rl_set_keyboard_input_timeout", dynlib: readlineDll.} # `Public' utility functions . @@ -881,8 +881,8 @@ when false: # The name of the terminal to use. var terminal_name*{.importc: "rl_terminal_name", dynlib: readlineDll.}: cstring # The input and output streams. - var instream*{.importc: "rl_instream", dynlib: readlineDll.}: TFile - var outstream*{.importc: "rl_outstream", dynlib: readlineDll.}: TFile + var instream*{.importc: "rl_instream", dynlib: readlineDll.}: File + var outstream*{.importc: "rl_outstream", dynlib: readlineDll.}: File # If non-zero, Readline gives values of LINES and COLUMNS from the environment # greater precedence than values fetched from the kernel when computing the # screen dimensions. @@ -1184,8 +1184,8 @@ type insmode*: cint edmode*: cint kseqlen*: cint - inf*: TFile - outf*: TFile + inf*: File + outf*: File pendingin*: cint theMacro*: cstring # signal state catchsigs*: cint diff --git a/lib/wrappers/readline/rltypedefs.nim b/lib/wrappers/readline/rltypedefs.nim index 202cf925d..847834e80 100644 --- a/lib/wrappers/readline/rltypedefs.nim +++ b/lib/wrappers/readline/rltypedefs.nim @@ -48,7 +48,7 @@ type # Input function type type - Tgetc_func* = proc (a2: TFile): cint{.cdecl.} + Tgetc_func* = proc (a2: File): cint{.cdecl.} # Generic function that takes a character buffer (which could be the readline # line buffer) and an index into it (which could be rl_point) and returns diff --git a/lib/wrappers/sdl/sdl.nim b/lib/wrappers/sdl/sdl.nim index 1c88bc14e..449b651f9 100644 --- a/lib/wrappers/sdl/sdl.nim +++ b/lib/wrappers/sdl/sdl.nim @@ -250,14 +250,14 @@ # SDL_GL_MULTISAMPLESAMPLES # # Add DLL/Shared object functions -# function SDL_LoadObject( const sofile : PChar ) : Pointer; +# function SDL_LoadObject( const sofile : PChar ) : pointer; # -# function SDL_LoadFunction( handle : Pointer; const name : PChar ) : Pointer; +# function SDL_LoadFunction( handle : pointer; const name : PChar ) : pointer; # -# procedure SDL_UnloadObject( handle : Pointer ); +# procedure SDL_UnloadObject( handle : pointer ); # # Added function to create RWops from const memory: SDL_RWFromConstMem() -# function SDL_RWFromConstMem(const mem: Pointer; size: Integer) : PSDL_RWops; +# function SDL_RWFromConstMem(const mem: pointer; size: Integer) : PSDL_RWops; # # Ported SDL_cpuinfo.h so Now you can test for Specific CPU types. # @@ -752,12 +752,12 @@ const # Enumeration of valid key mods (possibly OR'd tog type THandle* = int #SDL_types.h types # Basic data types - TBool* = enum + TBool* = enum sdlFALSE, sdlTRUE PUInt8Array* = ptr TUInt8Array TUInt8Array* = array[0..high(int) shr 1, byte] - PUInt16* = ptr UInt16 - PUInt32* = ptr UInt32 + PUInt16* = ptr uint16 + PUInt32* = ptr uint32 PUInt64* = ptr UInt64 UInt64*{.final.} = object hi*: int32 @@ -771,12 +771,12 @@ type TGrabMode* = int32 # SDL_error.h types Terrorcode* = enum ENOMEM, EFREAD, EFWRITE, EFSEEK, LASTERROR - errorcode* = Terrorcode + Errorcode* = Terrorcode TArg*{.final.} = object buf*: array[0..ERR_MAX_STRLEN - 1, int8] Perror* = ptr Terror - Terror*{.final.} = object # This is a numeric value corresponding to the current error + TError*{.final.} = object # This is a numeric value corresponding to the current error # SDL_rwops.h types # This is the read/write operation structure -- very basic # some helper types to handle the unions @@ -790,8 +790,8 @@ type args*: array[0..ERR_MAX_ARGS - 1, TArg] TStdio*{.final.} = object - autoclose*: int # FILE * is only defined in Kylix so we use a simple Pointer - fp*: Pointer + autoclose*: int # FILE * is only defined in Kylix so we use a simple pointer + fp*: pointer TMem*{.final.} = object base*: ptr byte @@ -800,9 +800,9 @@ type PRWops* = ptr TRWops # now the pointer to function types TSeek* = proc (context: PRWops, offset: int, whence: int): int{.cdecl.} - TRead* = proc (context: PRWops, thePtr: Pointer, size: int, maxnum: int): int{. + TRead* = proc (context: PRWops, thePtr: pointer, size: int, maxnum: int): int{. cdecl.} - TWrite* = proc (context: PRWops, thePtr: Pointer, size: int, num: int): int{. + TWrite* = proc (context: PRWops, thePtr: pointer, size: int, num: int): int{. cdecl.} TClose* = proc (context: PRWops): int{.cdecl.} # the variant record itself TRWops*{.final.} = object @@ -817,27 +817,27 @@ type RWops* = TRWops # SDL_timer.h types # Function prototype for the timer callback function TTimerCallback* = proc (interval: int32): int32{.cdecl.} - TNewTimerCallback* = proc (interval: int32, param: Pointer): int32{.cdecl.} + TNewTimerCallback* = proc (interval: int32, param: pointer): int32{.cdecl.} PTimerID* = ptr TTimerID TTimerID*{.final.} = object interval*: int32 callback*: TNewTimerCallback - param*: Pointer - last_alarm*: int32 + param*: pointer + lastAlarm*: int32 next*: PTimerID - TAudioSpecCallback* = proc (userdata: Pointer, stream: ptr byte, length: int){. + TAudioSpecCallback* = proc (userdata: pointer, stream: ptr byte, length: int){. cdecl.} # SDL_audio.h types # The calculated values in this structure are calculated by SDL_OpenAudio() PAudioSpec* = ptr TAudioSpec TAudioSpec*{.final.} = object # A structure to hold a set of audio conversion filters and buffers freq*: int # DSP frequency -- samples per second - format*: UInt16 # Audio data format + format*: uint16 # Audio data format channels*: byte # Number of channels: 1 mono, 2 stereo silence*: byte # Audio buffer silence value (calculated) - samples*: UInt16 # Audio buffer size in samples - padding*: UInt16 # Necessary for some compile environments + samples*: uint16 # Audio buffer size in samples + padding*: uint16 # Necessary for some compile environments size*: int32 # Audio buffer size in bytes (calculated) # This function is called when the audio device needs more data. # 'stream' is a pointer to the audio data buffer @@ -845,28 +845,28 @@ type # Once the callback returns, the buffer will no longer be valid. # Stereo samples are stored in a LRLRLR ordering. callback*: TAudioSpecCallback - userdata*: Pointer + userdata*: pointer PAudioCVT* = ptr TAudioCVT PAudioCVTFilter* = ptr TAudioCVTFilter TAudioCVTFilter*{.final.} = object cvt*: PAudioCVT - format*: UInt16 + format*: uint16 PAudioCVTFilterArray* = ptr TAudioCVTFilterArray TAudioCVTFilterArray* = array[0..9, PAudioCVTFilter] TAudioCVT*{.final.} = object needed*: int # Set to 1 if conversion possible - src_format*: UInt16 # Source audio format - dst_format*: UInt16 # Target audio format - rate_incr*: float64 # Rate conversion increment + srcFormat*: uint16 # Source audio format + dstFormat*: uint16 # Target audio format + rateIncr*: float64 # Rate conversion increment buf*: ptr byte # Buffer to hold entire audio data length*: int # Length of original audio buffer - len_cvt*: int # Length of converted audio buffer - len_mult*: int # buffer must be len*len_mult big - len_ratio*: float64 # Given len, final size is len*len_ratio + lenCvt*: int # Length of converted audio buffer + lenMult*: int # buffer must be len*len_mult big + lenRatio*: float64 # Given len, final size is len*len_ratio filters*: TAudioCVTFilterArray - filter_index*: int # Current audio conversion function + filterIndex*: int # Current audio conversion function TAudiostatus* = enum # SDL_cdrom.h types AUDIO_STOPPED, AUDIO_PLAYING, AUDIO_PAUSED @@ -876,7 +876,7 @@ type TCDTrack*{.final.} = object # This structure is only current as of the last call to SDL_CDStatus() id*: byte # Track number theType*: byte # Data or audio track - unused*: UInt16 + unused*: uint16 len*: int32 # Length, in frames, of this track offset*: int32 # Offset, in frames, from start of disk @@ -886,8 +886,8 @@ type status*: TCDStatus # Current drive status # The rest of this structure is only valid if there's a CD in drive numtracks*: int # Number of tracks on disk - cur_track*: int # Current track position - cur_frame*: int # Current frame offset within current track + curTrack*: int # Current track position + curFrame*: int # Current frame offset within current track track*: array[0..MAX_TRACKS, TCDTrack] PTransAxis* = ptr TTransAxis @@ -895,7 +895,7 @@ type offset*: int scale*: float32 - PJoystick_hwdata* = ptr TJoystick_hwdata + PJoystickHwdata* = ptr TJoystickHwdata TJoystick_hwdata*{.final.} = object # joystick ID id*: int # values used to translate device-specific coordinates into SDL-standard ranges transaxis*: array[0..5, TTransAxis] @@ -918,8 +918,8 @@ type balls*: PBallDelta # Current ball motion deltas nbuttons*: int # Number of buttons on the joystick buttons*: ptr byte # Current button states - hwdata*: PJoystick_hwdata # Driver dependent information - ref_count*: int # Reference count for multiple opens + hwdata*: PJoystickHwdata # Driver dependent information + refCount*: int # Reference count for multiple opens Pversion* = ptr Tversion Tversion*{.final.} = object # SDL_keyboard.h types @@ -945,7 +945,7 @@ type scancode*: byte # hardware specific scancode sym*: TKey # SDL virtual keysym modifier*: TMod # current key modifiers - unicode*: UInt16 # translated character + unicode*: uint16 # translated character TEventAction* = enum # Application visibility event structure ADDEVENT, PEEKEVENT, GETEVENT @@ -971,7 +971,7 @@ type kind*: TEventKind which*: byte # The mouse device index state*: byte # The current button state - x*, y*: UInt16 # The X/Y coordinates of the mouse + x*, y*: uint16 # The X/Y coordinates of the mouse xrel*: int16 # The relative motion in the X direction yrel*: int16 # The relative motion in the Y direction @@ -982,8 +982,8 @@ type which*: byte # The mouse device index button*: byte # The mouse button index state*: byte # SDL_PRESSED or SDL_RELEASED - x*: UInt16 # The X coordinates of the mouse at press time - y*: UInt16 # The Y coordinates of the mouse at press time + x*: uint16 # The X coordinates of the mouse at press time + y*: uint16 # The Y coordinates of the mouse at press time PJoyAxisEvent* = ptr TJoyAxisEvent TJoyAxisEvent*{.final.} = object # SDL_JOYAXISMOTION @@ -1036,8 +1036,8 @@ type TUserEvent*{.final.} = object # SDL_USEREVENT through SDL_NUMEVENTS-1 kind*: TEventKind code*: cint # User defined event code - data1*: Pointer # User defined data pointer - data2*: Pointer # User defined data pointer + data1*: pointer # User defined data pointer + data2*: pointer # User defined data pointer when defined(Unix): @@ -1051,7 +1051,7 @@ when defined(WINDOWS): version*: Tversion hwnd*: THandle # The window for the message msg*: int # The type of message - w_Param*: int32 # WORD message parameter + wParam*: int32 # WORD message parameter lParam*: int32 # LONG message parameter elif defined(Unix): @@ -1090,8 +1090,8 @@ elif defined(Unix): # any X11 functions using the display variable. # They lock the event thread, so should not be # called around event functions or from event filters. - lock_func*: Pointer - unlock_func*: Pointer # Introduced in SDL 1.0.2 + lock_func*: pointer + unlock_func*: pointer # Introduced in SDL 1.0.2 fswindow*: TWindow # The X11 fullscreen window wmwindow*: TWindow # The X11 managed input window @@ -1135,7 +1135,7 @@ type PRect* = ptr TRect TRect*{.final.} = object x*, y*: int16 - w*, h*: UInt16 + w*, h*: uint16 Rect* = TRect PColor* = ptr TColor @@ -1155,34 +1155,34 @@ type PPixelFormat* = ptr TPixelFormat TPixelFormat*{.final.} = object # The structure passed to the low level blit functions palette*: PPalette - BitsPerPixel*: byte - BytesPerPixel*: byte - Rloss*: byte - Gloss*: byte - Bloss*: byte - Aloss*: byte - Rshift*: byte - Gshift*: byte - Bshift*: byte - Ashift*: byte - RMask*: int32 - GMask*: int32 - BMask*: int32 - AMask*: int32 + bitsPerPixel*: byte + bytesPerPixel*: byte + rloss*: byte + gloss*: byte + bloss*: byte + aloss*: byte + rshift*: byte + gshift*: byte + bshift*: byte + ashift*: byte + rMask*: int32 + gMask*: int32 + bMask*: int32 + aMask*: int32 colorkey*: int32 # RGB color key information alpha*: byte # Alpha value information (per-surface alpha) PBlitInfo* = ptr TBlitInfo TBlitInfo*{.final.} = object # typedef for private surface blitting functions - s_pixels*: ptr byte - s_width*: int - s_height*: int - s_skip*: int - d_pixels*: ptr byte - d_width*: int - d_height*: int - d_skip*: int - aux_data*: Pointer + sPixels*: ptr byte + sWidth*: int + sHeight*: int + sSkip*: int + dPixels*: ptr byte + dWidth*: int + dHeight*: int + dSkip*: int + auxData*: pointer src*: PPixelFormat table*: ptr byte dst*: PPixelFormat @@ -1194,30 +1194,30 @@ type flags*: int32 # Read-only format*: PPixelFormat # Read-only w*, h*: cint # Read-only - pitch*: UInt16 # Read-only - pixels*: Pointer # Read-write + pitch*: uint16 # Read-only + pixels*: pointer # Read-write offset*: cint # Private - hwdata*: Pointer #TPrivate_hwdata; Hardware-specific surface info + hwdata*: pointer #TPrivate_hwdata; Hardware-specific surface info # clipping information: - clip_rect*: TRect # Read-only + clipRect*: TRect # Read-only unused1*: int32 # for binary compatibility # Allow recursive locks locked*: int32 # Private # info for fast blit mapping to other surfaces - Blitmap*: Pointer # PSDL_BlitMap; // Private + blitmap*: pointer # PSDL_BlitMap; // Private # format version, bumped at every change to invalidate blit maps - format_version*: cint # Private + formatVersion*: cint # Private refcount*: cint PVideoInfo* = ptr TVideoInfo TVideoInfo*{.final.} = object # The YUV hardware video overlay - hw_available*: byte - blit_hw*: byte - UnusedBits3*: byte # Unused at this point - video_mem*: int32 # The total amount of video memory (in K) + hwAvailable*: byte + blitHw*: byte + unusedBits3*: byte # Unused at this point + videoMem*: int32 # The total amount of video memory (in K) vfmt*: PPixelFormat # Value: The format of the video surface - current_w*: int32 # Value: The current video mode width - current_h*: int32 # Value: The current video mode height + currentW*: int32 # Value: The current video mode width + currentH*: int32 # Value: The current video mode height POverlay* = ptr TOverlay TOverlay*{.final.} = object # Public enumeration for setting the OpenGL window attributes. @@ -1226,7 +1226,7 @@ type planes*: int # Number of planes in the overlay. Usually either 1 or 3 pitches*: PUInt16 # An array of pitches, one for each plane. Pitch is the length of a row in bytes. pixels*: ptr ptr byte # An array of pointers to the data of each plane. The overlay should be locked before these pointers are used. - hw_overlay*: int32 # This will be set to 1 if the overlay is hardware accelerated. + hwOverlay*: int32 # This will be set to 1 if the overlay is hardware accelerated. TGLAttr* = enum GL_RED_SIZE, GL_GREEN_SIZE, GL_BLUE_SIZE, GL_ALPHA_SIZE, GL_BUFFER_SIZE, @@ -1237,11 +1237,11 @@ type PCursor* = ptr TCursor TCursor*{.final.} = object # SDL_mutex.h types area*: TRect # The area of the mouse cursor - hot_x*, hot_y*: int16 # The "tip" of the cursor + hotX*, hot_y*: int16 # The "tip" of the cursor data*: ptr byte # B/W cursor data mask*: ptr byte # B/W cursor mask save*: array[1..2, ptr byte] # Place to save cursor area - wm_cursor*: Pointer # Window-manager cursor + wmCursor*: pointer # Window-manager cursor type @@ -1250,7 +1250,7 @@ type Psemaphore* = ptr Tsemaphore Tsemaphore*{.final.} = object PSem* = ptr TSem - TSem* = TSemaphore + TSem* = Tsemaphore PCond* = ptr TCond TCond*{.final.} = object # SDL_thread.h types @@ -1267,8 +1267,8 @@ type # This is the system-independent thread info struc threadid*: int32 handle*: TSYS_ThreadHandle status*: int - errbuf*: TError - data*: Pointer + errbuf*: Terror + data*: pointer PKeyStateArr* = ptr TKeyStateArr TKeyStateArr* = array[0..65000, byte] # Types required so we don't need to use Windows.pas @@ -1282,24 +1282,24 @@ type # This is the system-independent thread info struc TWordArray* = array[0..16383, int16] # Generic procedure pointer type TEventSeq = set[TEventKind] -template evconv(procName: expr, ptrName: typeDesc, assertions: TEventSeq): stmt {.immediate.} = +template evconv(procName: expr, ptrName: typedesc, assertions: TEventSeq): stmt {.immediate.} = proc `procName`*(event: PEvent): ptrName = assert(contains(assertions, event.kind)) result = cast[ptrName](event) -evconv(EvActive, PActiveEvent, {ACTIVEEVENT}) -evconv(EvKeyboard, PKeyboardEvent, {KEYDOWN, KEYUP}) -evconv(EvMouseMotion, PMouseMotionEvent, {MOUSEMOTION}) -evconv(EvMouseButton, PMouseButtonEvent, {MOUSEBUTTONDOWN, MOUSEBUTTONUP}) -evconv(EvJoyAxis, PJoyAxisEvent,{JOYAXISMOTION}) -evconv(EvJoyBall, PJoyBallEvent, {JOYBALLMOTION}) -evconv(EvJoyHat, PJoyHatEvent, {JOYHATMOTION}) -evconv(EvJoyButton, PJoyButtonEvent, {JOYBUTTONDOWN, JOYBUTTONUP}) -evconv(EvResize, PResizeEvent, {VIDEORESIZE}) -evconv(EvExpose, PExposeEvent, {VIDEOEXPOSE}) -evconv(EvQuit, PQuitEvent, {QUITEV}) -evconv(EvUser, PUserEvent, {USEREVENT}) -evconv(EvSysWM, PSysWMEvent, {SYSWMEVENT}) +evconv(evActive, PActiveEvent, {ACTIVEEVENT}) +evconv(evKeyboard, PKeyboardEvent, {KEYDOWN, KEYUP}) +evconv(evMouseMotion, PMouseMotionEvent, {MOUSEMOTION}) +evconv(evMouseButton, PMouseButtonEvent, {MOUSEBUTTONDOWN, MOUSEBUTTONUP}) +evconv(evJoyAxis, PJoyAxisEvent,{JOYAXISMOTION}) +evconv(evJoyBall, PJoyBallEvent, {JOYBALLMOTION}) +evconv(evJoyHat, PJoyHatEvent, {JOYHATMOTION}) +evconv(evJoyButton, PJoyButtonEvent, {JOYBUTTONDOWN, JOYBUTTONUP}) +evconv(evResize, PResizeEvent, {VIDEORESIZE}) +evconv(evExpose, PExposeEvent, {VIDEOEXPOSE}) +evconv(evQuit, PQuitEvent, {QUITEV}) +evconv(evUser, PUserEvent, {USEREVENT}) +evconv(evSysWM, PSysWMEvent, {SYSWMEVENT}) #------------------------------------------------------------------------------ # initialization @@ -1309,73 +1309,72 @@ evconv(EvSysWM, PSysWMEvent, {SYSWMEVENT}) # Unless the SDL_INIT_NOPARACHUTE flag is set, it will install cleanup # signal handlers for some commonly ignored fatal signals (like SIGSEGV) -proc Init*(flags: int32): int{.cdecl, importc: "SDL_Init", dynlib: LibName.} +proc init*(flags: int32): int{.cdecl, importc: "SDL_Init", dynlib: LibName.} # This function initializes specific SDL subsystems -proc InitSubSystem*(flags: int32): int{.cdecl, importc: "SDL_InitSubSystem", +proc initSubSystem*(flags: int32): int{.cdecl, importc: "SDL_InitSubSystem", dynlib: LibName.} # This function cleans up specific SDL subsystems -proc QuitSubSystem*(flags: int32){.cdecl, importc: "SDL_QuitSubSystem", +proc quitSubSystem*(flags: int32){.cdecl, importc: "SDL_QuitSubSystem", dynlib: LibName.} # This function returns mask of the specified subsystems which have # been initialized. # If 'flags' is 0, it returns a mask of all initialized subsystems. -proc WasInit*(flags: int32): int32{.cdecl, importc: "SDL_WasInit", +proc wasInit*(flags: int32): int32{.cdecl, importc: "SDL_WasInit", dynlib: LibName.} # This function cleans up all initialized subsystems and unloads the # dynamically linked library. You should call it upon all exit conditions. -proc Quit*(){.cdecl, importc: "SDL_Quit", dynlib: LibName.} +proc quit*(){.cdecl, importc: "SDL_Quit", dynlib: LibName.} when defined(WINDOWS): # This should be called from your WinMain() function, if any - proc RegisterApp*(name: cstring, style: int32, h_Inst: Pointer): int{.cdecl, + proc registerApp*(name: cstring, style: int32, hInst: pointer): int{.cdecl, importc: "SDL_RegisterApp", dynlib: LibName.} -proc TableSize*(table: cstring): int +proc tableSize*(table: cstring): int #------------------------------------------------------------------------------ # error-handling #------------------------------------------------------------------------------ # Public functions -proc GetError*(): cstring{.cdecl, importc: "SDL_GetError", dynlib: LibName.} -proc SetError*(fmt: cstring){.cdecl, importc: "SDL_SetError", dynlib: LibName.} -proc ClearError*(){.cdecl, importc: "SDL_ClearError", dynlib: LibName.} -when not (defined(WINDOWS)): - proc Error*(Code: Terrorcode){.cdecl, importc: "SDL_Error", dynlib: LibName.} -proc OutOfMemory*() +proc getError*(): cstring{.cdecl, importc: "SDL_GetError", dynlib: LibName.} +proc setError*(fmt: cstring){.cdecl, importc: "SDL_SetError", dynlib: LibName.} +proc clearError*(){.cdecl, importc: "SDL_ClearError", dynlib: LibName.} +when not (defined(WINDOWS)): + proc error*(Code: Terrorcode){.cdecl, importc: "SDL_Error", dynlib: LibName.} #------------------------------------------------------------------------------ # io handling #------------------------------------------------------------------------------ # Functions to create SDL_RWops structures from various data sources -proc RWFromFile*(filename, mode: cstring): PRWops{.cdecl, +proc rwFromFile*(filename, mode: cstring): PRWops{.cdecl, importc: "SDL_RWFromFile", dynlib: LibName.} -proc FreeRW*(area: PRWops){.cdecl, importc: "SDL_FreeRW", dynlib: LibName.} +proc freeRW*(area: PRWops){.cdecl, importc: "SDL_FreeRW", dynlib: LibName.} #fp is FILE *fp ??? -proc RWFromFP*(fp: Pointer, autoclose: int): PRWops{.cdecl, +proc rwFromFP*(fp: pointer, autoclose: int): PRWops{.cdecl, importc: "SDL_RWFromFP", dynlib: LibName.} -proc RWFromMem*(mem: Pointer, size: int): PRWops{.cdecl, +proc rwFromMem*(mem: pointer, size: int): PRWops{.cdecl, importc: "SDL_RWFromMem", dynlib: LibName.} -proc RWFromConstMem*(mem: Pointer, size: int): PRWops{.cdecl, +proc rwFromConstMem*(mem: pointer, size: int): PRWops{.cdecl, importc: "SDL_RWFromConstMem", dynlib: LibName.} -proc AllocRW*(): PRWops{.cdecl, importc: "SDL_AllocRW", dynlib: LibName.} -proc RWSeek*(context: PRWops, offset: int, whence: int): int -proc RWTell*(context: PRWops): int -proc RWRead*(context: PRWops, theptr: Pointer, size: int, n: int): int -proc RWWrite*(context: PRWops, theptr: Pointer, size: int, n: int): int -proc RWClose*(context: PRWops): int +proc allocRW*(): PRWops{.cdecl, importc: "SDL_AllocRW", dynlib: LibName.} +proc rwSeek*(context: PRWops, offset: int, whence: int): int +proc rwTell*(context: PRWops): int +proc rwRead*(context: PRWops, theptr: pointer, size: int, n: int): int +proc rwWrite*(context: PRWops, theptr: pointer, size: int, n: int): int +proc rwClose*(context: PRWops): int #------------------------------------------------------------------------------ # time-handling #------------------------------------------------------------------------------ # Get the number of milliseconds since the SDL library initialization. # Note that this value wraps if the program runs for more than ~49 days. -proc GetTicks*(): int32{.cdecl, importc: "SDL_GetTicks", dynlib: LibName.} +proc getTicks*(): int32{.cdecl, importc: "SDL_GetTicks", dynlib: LibName.} # Wait a specified number of milliseconds before returning -proc Delay*(msec: int32){.cdecl, importc: "SDL_Delay", dynlib: LibName.} +proc delay*(msec: int32){.cdecl, importc: "SDL_Delay", dynlib: LibName.} # Add a new timer to the pool of timers already running. # Returns a timer ID, or NULL when an error occurs. -proc AddTimer*(interval: int32, callback: TNewTimerCallback, param: Pointer): PTimerID{. +proc addTimer*(interval: int32, callback: TNewTimerCallback, param: pointer): PTimerID{. cdecl, importc: "SDL_AddTimer", dynlib: LibName.} # Remove one of the multiple timers knowing its ID. # Returns a boolean value indicating success. -proc RemoveTimer*(t: PTimerID): TBool{.cdecl, importc: "SDL_RemoveTimer", +proc removeTimer*(t: PTimerID): TBool{.cdecl, importc: "SDL_RemoveTimer", dynlib: LibName.} -proc SetTimer*(interval: int32, callback: TTimerCallback): int{.cdecl, +proc setTimer*(interval: int32, callback: TTimerCallback): int{.cdecl, importc: "SDL_SetTimer", dynlib: LibName.} #------------------------------------------------------------------------------ # audio-routines @@ -1383,13 +1382,13 @@ proc SetTimer*(interval: int32, callback: TTimerCallback): int{.cdecl, # These functions are used internally, and should not be used unless you # have a specific need to specify the audio driver you want to use. # You should normally use SDL_Init() or SDL_InitSubSystem(). -proc AudioInit*(driver_name: cstring): int{.cdecl, importc: "SDL_AudioInit", +proc audioInit*(driverName: cstring): int{.cdecl, importc: "SDL_AudioInit", dynlib: LibName.} -proc AudioQuit*(){.cdecl, importc: "SDL_AudioQuit", dynlib: LibName.} +proc audioQuit*(){.cdecl, importc: "SDL_AudioQuit", dynlib: LibName.} # This function fills the given character buffer with the name of the - # current audio driver, and returns a Pointer to it if the audio driver has + # current audio driver, and returns a pointer to it if the audio driver has # been initialized. It returns NULL if no driver has been initialized. -proc AudioDriverName*(namebuf: cstring, maxlen: int): cstring{.cdecl, +proc audioDriverName*(namebuf: cstring, maxlen: int): cstring{.cdecl, importc: "SDL_AudioDriverName", dynlib: LibName.} # This function opens the audio device with the desired parameters, and # returns 0 if successful, placing the actual hardware parameters in the @@ -1430,17 +1429,17 @@ proc AudioDriverName*(namebuf: cstring, maxlen: int): cstring{.cdecl, # for your audio callback function to be called. Since the audio driver # may modify the requested size of the audio buffer, you should allocate # any local mixing buffers after you open the audio device. -proc OpenAudio*(desired, obtained: PAudioSpec): int{.cdecl, +proc openAudio*(desired, obtained: PAudioSpec): int{.cdecl, importc: "SDL_OpenAudio", dynlib: LibName.} # Get the current audio state: -proc GetAudioStatus*(): TAudiostatus{.cdecl, importc: "SDL_GetAudioStatus", +proc getAudioStatus*(): TAudiostatus{.cdecl, importc: "SDL_GetAudioStatus", dynlib: LibName.} # This function pauses and unpauses the audio callback processing. # It should be called with a parameter of 0 after opening the audio # device to start playing sound. This is so you can safely initialize # data for your callback function after opening the audio device. # Silence will be written to the audio device during the pause. -proc PauseAudio*(pause_on: int){.cdecl, importc: "SDL_PauseAudio", +proc pauseAudio*(pauseOn: int){.cdecl, importc: "SDL_PauseAudio", dynlib: LibName.} # This function loads a WAVE from the data source, automatically freeing # that source if 'freesrc' is non-zero. For example, to load a WAVE file, @@ -1457,22 +1456,22 @@ proc PauseAudio*(pause_on: int){.cdecl, importc: "SDL_PauseAudio", # This function returns NULL and sets the SDL error message if the # wave file cannot be opened, uses an unknown data format, or is # corrupt. Currently raw and MS-ADPCM WAVE files are supported. -proc LoadWAV_RW*(src: PRWops, freesrc: int, spec: PAudioSpec, audio_buf: ptr byte, +proc loadWAV_RW*(src: PRWops, freesrc: int, spec: PAudioSpec, audioBuf: ptr byte, audiolen: PUInt32): PAudioSpec{.cdecl, importc: "SDL_LoadWAV_RW", dynlib: LibName.} # Compatibility convenience function -- loads a WAV from a file -proc LoadWAV*(filename: cstring, spec: PAudioSpec, audio_buf: ptr byte, +proc loadWAV*(filename: cstring, spec: PAudioSpec, audioBuf: ptr byte, audiolen: PUInt32): PAudioSpec # This function frees data previously allocated with SDL_LoadWAV_RW() -proc FreeWAV*(audio_buf: ptr byte){.cdecl, importc: "SDL_FreeWAV", dynlib: LibName.} +proc freeWAV*(audioBuf: ptr byte){.cdecl, importc: "SDL_FreeWAV", dynlib: LibName.} # This function takes a source format and rate and a destination format # and rate, and initializes the 'cvt' structure with information needed # by SDL_ConvertAudio() to convert a buffer of audio data from one format # to the other. # This function returns 0, or -1 if there was an error. -proc BuildAudioCVT*(cvt: PAudioCVT, src_format: UInt16, src_channels: byte, - src_rate: int, dst_format: UInt16, dst_channels: byte, - dst_rate: int): int{.cdecl, importc: "SDL_BuildAudioCVT", +proc buildAudioCVT*(cvt: PAudioCVT, srcFormat: uint16, srcChannels: byte, + srcRate: int, dstFormat: uint16, dstChannels: byte, + dstRate: int): int{.cdecl, importc: "SDL_BuildAudioCVT", dynlib: LibName.} # Once you have initialized the 'cvt' structure using SDL_BuildAudioCVT(), # created an audio buffer cvt->buf, and filled it with cvt->len bytes of @@ -1481,45 +1480,45 @@ proc BuildAudioCVT*(cvt: PAudioCVT, src_format: UInt16, src_channels: byte, # The data conversion may expand the size of the audio data, so the buffer # cvt->buf should be allocated after the cvt structure is initialized by # SDL_BuildAudioCVT(), and should be cvt->len*cvt->len_mult bytes long. -proc ConvertAudio*(cvt: PAudioCVT): int{.cdecl, importc: "SDL_ConvertAudio", +proc convertAudio*(cvt: PAudioCVT): int{.cdecl, importc: "SDL_ConvertAudio", dynlib: LibName.} # This takes two audio buffers of the playing audio format and mixes # them, performing addition, volume adjustment, and overflow clipping. # The volume ranges from 0 - 128, and should be set to SDL_MIX_MAXVOLUME # for full audio volume. Note this does not change hardware volume. # This is provided for convenience -- you can mix your own audio data. -proc MixAudio*(dst, src: ptr byte, length: int32, volume: int){.cdecl, +proc mixAudio*(dst, src: ptr byte, length: int32, volume: int){.cdecl, importc: "SDL_MixAudio", dynlib: LibName.} # The lock manipulated by these functions protects the callback function. # During a LockAudio/UnlockAudio pair, you can be guaranteed that the # callback function is not running. Do not call these from the callback # function or you will cause deadlock. -proc LockAudio*(){.cdecl, importc: "SDL_LockAudio", dynlib: LibName.} -proc UnlockAudio*(){.cdecl, importc: "SDL_UnlockAudio", dynlib: LibName.} +proc lockAudio*(){.cdecl, importc: "SDL_LockAudio", dynlib: LibName.} +proc unlockAudio*(){.cdecl, importc: "SDL_UnlockAudio", dynlib: LibName.} # This function shuts down audio processing and closes the audio device. -proc CloseAudio*(){.cdecl, importc: "SDL_CloseAudio", dynlib: LibName.} +proc closeAudio*(){.cdecl, importc: "SDL_CloseAudio", dynlib: LibName.} #------------------------------------------------------------------------------ # CD-routines #------------------------------------------------------------------------------ # Returns the number of CD-ROM drives on the system, or -1 if # SDL_Init() has not been called with the SDL_INIT_CDROM flag. -proc CDNumDrives*(): int{.cdecl, importc: "SDL_CDNumDrives", dynlib: LibName.} +proc cdNumDrives*(): int{.cdecl, importc: "SDL_CDNumDrives", dynlib: LibName.} # Returns a human-readable, system-dependent identifier for the CD-ROM. # Example: # "/dev/cdrom" # "E:" # "/dev/disk/ide/1/master" -proc CDName*(drive: int): cstring{.cdecl, importc: "SDL_CDName", dynlib: LibName.} +proc cdName*(drive: int): cstring{.cdecl, importc: "SDL_CDName", dynlib: LibName.} # Opens a CD-ROM drive for access. It returns a drive handle on success, # or NULL if the drive was invalid or busy. This newly opened CD-ROM # becomes the default CD used when other CD functions are passed a NULL # CD-ROM handle. # Drives are numbered starting with 0. Drive 0 is the system default CD-ROM. -proc CDOpen*(drive: int): PCD{.cdecl, importc: "SDL_CDOpen", dynlib: LibName.} +proc cdOpen*(drive: int): PCD{.cdecl, importc: "SDL_CDOpen", dynlib: LibName.} # This function returns the current status of the given drive. # If the drive has a CD in it, the table of contents of the CD and current # play position of the CD will be stored in the SDL_CD structure. -proc CDStatus*(cdrom: PCD): TCDStatus{.cdecl, importc: "SDL_CDStatus", +proc cdStatus*(cdrom: PCD): TCDStatus{.cdecl, importc: "SDL_CDStatus", dynlib: LibName.} # Play the given CD starting at 'start_track' and 'start_frame' for 'ntracks' # tracks and 'nframes' frames. If both 'ntrack' and 'nframe' are 0, play @@ -1542,95 +1541,89 @@ proc CDStatus*(cdrom: PCD): TCDStatus{.cdecl, importc: "SDL_CDStatus", # SDL_CDPlayTracks(cdrom, 0, 0, 2, 10); # # This function returns 0, or -1 if there was an error. -proc CDPlayTracks*(cdrom: PCD, start_track: int, start_frame: int, ntracks: int, +proc cdPlayTracks*(cdrom: PCD, startTrack: int, startFrame: int, ntracks: int, nframes: int): int{.cdecl, importc: "SDL_CDPlayTracks", dynlib: LibName.} # Play the given CD starting at 'start' frame for 'length' frames. # It returns 0, or -1 if there was an error. -proc CDPlay*(cdrom: PCD, start: int, len: int): int{.cdecl, +proc cdPlay*(cdrom: PCD, start: int, len: int): int{.cdecl, importc: "SDL_CDPlay", dynlib: LibName.} # Pause play -- returns 0, or -1 on error -proc CDPause*(cdrom: PCD): int{.cdecl, importc: "SDL_CDPause", dynlib: LibName.} +proc cdPause*(cdrom: PCD): int{.cdecl, importc: "SDL_CDPause", dynlib: LibName.} # Resume play -- returns 0, or -1 on error -proc CDResume*(cdrom: PCD): int{.cdecl, importc: "SDL_CDResume", dynlib: LibName.} +proc cdResume*(cdrom: PCD): int{.cdecl, importc: "SDL_CDResume", dynlib: LibName.} # Stop play -- returns 0, or -1 on error -proc CDStop*(cdrom: PCD): int{.cdecl, importc: "SDL_CDStop", dynlib: LibName.} +proc cdStop*(cdrom: PCD): int{.cdecl, importc: "SDL_CDStop", dynlib: LibName.} # Eject CD-ROM -- returns 0, or -1 on error -proc CDEject*(cdrom: PCD): int{.cdecl, importc: "SDL_CDEject", dynlib: LibName.} +proc cdEject*(cdrom: PCD): int{.cdecl, importc: "SDL_CDEject", dynlib: LibName.} # Closes the handle for the CD-ROM drive -proc CDClose*(cdrom: PCD){.cdecl, importc: "SDL_CDClose", dynlib: LibName.} +proc cdClose*(cdrom: PCD){.cdecl, importc: "SDL_CDClose", dynlib: LibName.} # Given a status, returns true if there's a disk in the drive -proc CDInDrive*(status: TCDStatus): bool - # Conversion functions from frames to Minute/Second/Frames and vice versa -proc FRAMES_TO_MSF*(frames: int, M: var int, S: var int, F: var int) -proc MSF_TO_FRAMES*(M: int, S: int, F: int): int - #------------------------------------------------------------------------------ - # JoyStick-routines - #------------------------------------------------------------------------------ - # Count the number of joysticks attached to the system -proc NumJoysticks*(): int{.cdecl, importc: "SDL_NumJoysticks", dynlib: LibName.} +proc cdInDrive*(status: TCDStatus): bool + +proc numJoysticks*(): int{.cdecl, importc: "SDL_NumJoysticks", dynlib: LibName.} # Get the implementation dependent name of a joystick. # This can be called before any joysticks are opened. # If no name can be found, this function returns NULL. -proc JoystickName*(index: int): cstring{.cdecl, importc: "SDL_JoystickName", +proc joystickName*(index: int): cstring{.cdecl, importc: "SDL_JoystickName", dynlib: LibName.} # Open a joystick for use - the index passed as an argument refers to # the N'th joystick on the system. This index is the value which will # identify this joystick in future joystick events. # # This function returns a joystick identifier, or NULL if an error occurred. -proc JoystickOpen*(index: int): PJoystick{.cdecl, importc: "SDL_JoystickOpen", +proc joystickOpen*(index: int): PJoystick{.cdecl, importc: "SDL_JoystickOpen", dynlib: LibName.} # Returns 1 if the joystick has been opened, or 0 if it has not. -proc JoystickOpened*(index: int): int{.cdecl, importc: "SDL_JoystickOpened", +proc joystickOpened*(index: int): int{.cdecl, importc: "SDL_JoystickOpened", dynlib: LibName.} # Get the device index of an opened joystick. -proc JoystickIndex*(joystick: PJoystick): int{.cdecl, +proc joystickIndex*(joystick: PJoystick): int{.cdecl, importc: "SDL_JoystickIndex", dynlib: LibName.} # Get the number of general axis controls on a joystick -proc JoystickNumAxes*(joystick: PJoystick): int{.cdecl, +proc joystickNumAxes*(joystick: PJoystick): int{.cdecl, importc: "SDL_JoystickNumAxes", dynlib: LibName.} # Get the number of trackballs on a joystick # Joystick trackballs have only relative motion events associated # with them and their state cannot be polled. -proc JoystickNumBalls*(joystick: PJoystick): int{.cdecl, +proc joystickNumBalls*(joystick: PJoystick): int{.cdecl, importc: "SDL_JoystickNumBalls", dynlib: LibName.} # Get the number of POV hats on a joystick -proc JoystickNumHats*(joystick: PJoystick): int{.cdecl, +proc joystickNumHats*(joystick: PJoystick): int{.cdecl, importc: "SDL_JoystickNumHats", dynlib: LibName.} # Get the number of buttons on a joystick -proc JoystickNumButtons*(joystick: PJoystick): int{.cdecl, +proc joystickNumButtons*(joystick: PJoystick): int{.cdecl, importc: "SDL_JoystickNumButtons", dynlib: LibName.} # Update the current state of the open joysticks. # This is called automatically by the event loop if any joystick # events are enabled. -proc JoystickUpdate*(){.cdecl, importc: "SDL_JoystickUpdate", dynlib: LibName.} +proc joystickUpdate*(){.cdecl, importc: "SDL_JoystickUpdate", dynlib: LibName.} # Enable/disable joystick event polling. # If joystick events are disabled, you must call SDL_JoystickUpdate() # yourself and check the state of the joystick when you want joystick # information. # The state can be one of SDL_QUERY, SDL_ENABLE or SDL_IGNORE. -proc JoystickEventState*(state: int): int{.cdecl, +proc joystickEventState*(state: int): int{.cdecl, importc: "SDL_JoystickEventState", dynlib: LibName.} # Get the current state of an axis control on a joystick # The state is a value ranging from -32768 to 32767. # The axis indices start at index 0. -proc JoystickGetAxis*(joystick: PJoystick, axis: int): int16{.cdecl, +proc joystickGetAxis*(joystick: PJoystick, axis: int): int16{.cdecl, importc: "SDL_JoystickGetAxis", dynlib: LibName.} # The hat indices start at index 0. -proc JoystickGetHat*(joystick: PJoystick, hat: int): byte{.cdecl, +proc joystickGetHat*(joystick: PJoystick, hat: int): byte{.cdecl, importc: "SDL_JoystickGetHat", dynlib: LibName.} # Get the ball axis change since the last poll # This returns 0, or -1 if you passed it invalid parameters. # The ball indices start at index 0. -proc JoystickGetBall*(joystick: PJoystick, ball: int, dx: var int, dy: var int): int{. +proc joystickGetBall*(joystick: PJoystick, ball: int, dx: var int, dy: var int): int{. cdecl, importc: "SDL_JoystickGetBall", dynlib: LibName.} # Get the current state of a button on a joystick # The button indices start at index 0. -proc JoystickGetButton*(joystick: PJoystick, Button: int): byte{.cdecl, +proc joystickGetButton*(joystick: PJoystick, button: int): byte{.cdecl, importc: "SDL_JoystickGetButton", dynlib: LibName.} # Close a joystick previously opened with SDL_JoystickOpen() -proc JoystickClose*(joystick: PJoystick){.cdecl, importc: "SDL_JoystickClose", +proc joystickClose*(joystick: PJoystick){.cdecl, importc: "SDL_JoystickClose", dynlib: LibName.} #------------------------------------------------------------------------------ # event-handling @@ -1638,7 +1631,7 @@ proc JoystickClose*(joystick: PJoystick){.cdecl, importc: "SDL_JoystickClose", # Pumps the event loop, gathering events from the input devices. # This function updates the event queue and internal input device state. # This should only be run in the thread that sets the video mode. -proc PumpEvents*(){.cdecl, importc: "SDL_PumpEvents", dynlib: LibName.} +proc pumpEvents*(){.cdecl, importc: "SDL_PumpEvents", dynlib: LibName.} # Checks the event queue for messages and optionally returns them. # If 'action' is SDL_ADDEVENT, up to 'numevents' events will be added to # the back of the event queue. @@ -1650,20 +1643,20 @@ proc PumpEvents*(){.cdecl, importc: "SDL_PumpEvents", dynlib: LibName.} # removed from the queue. # This function returns the number of events actually stored, or -1 # if there was an error. This function is thread-safe. -proc PeepEvents*(events: PEvent, numevents: int, action: Teventaction, +proc peepEvents*(events: PEvent, numevents: int, action: TEventAction, mask: int32): int{.cdecl, importc: "SDL_PeepEvents", dynlib: LibName.} # Polls for currently pending events, and returns 1 if there are any pending # events, or 0 if there are none available. If 'event' is not NULL, the next # event is removed from the queue and stored in that area. -proc PollEvent*(event: PEvent): int{.cdecl, importc: "SDL_PollEvent", +proc pollEvent*(event: PEvent): int{.cdecl, importc: "SDL_PollEvent", dynlib: LibName.} # Waits indefinitely for the next available event, returning 1, or 0 if there # was an error while waiting for events. If 'event' is not NULL, the next # event is removed from the queue and stored in that area. -proc WaitEvent*(event: PEvent): int{.cdecl, importc: "SDL_WaitEvent", +proc waitEvent*(event: PEvent): int{.cdecl, importc: "SDL_WaitEvent", dynlib: LibName.} -proc PushEvent*(event: PEvent): int{.cdecl, importc: "SDL_PushEvent", +proc pushEvent*(event: PEvent): int{.cdecl, importc: "SDL_PushEvent", dynlib: LibName.} # If the filter returns 1, then the event will be added to the internal queue. # If it returns 0, then the event will be dropped from the queue, but the @@ -1679,11 +1672,11 @@ proc PushEvent*(event: PEvent): int{.cdecl, importc: "SDL_PushEvent", # be closed, otherwise the window will remain open if possible. # If the quit event is generated by an interrupt signal, it will bypass the # internal queue and be delivered to the application at the next event poll. -proc SetEventFilter*(filter: TEventFilter){.cdecl, +proc setEventFilter*(filter: TEventFilter){.cdecl, importc: "SDL_SetEventFilter", dynlib: LibName.} # Return the current event filter - can be used to "chain" filters. # If there is no event filter set, this function returns NULL. -proc GetEventFilter*(): TEventFilter{.cdecl, importc: "SDL_GetEventFilter", +proc getEventFilter*(): TEventFilter{.cdecl, importc: "SDL_GetEventFilter", dynlib: LibName.} # This function allows you to set the state of processing certain events. # If 'state' is set to SDL_IGNORE, that event will be automatically dropped @@ -1691,26 +1684,26 @@ proc GetEventFilter*(): TEventFilter{.cdecl, importc: "SDL_GetEventFilter", # If 'state' is set to SDL_ENABLE, that event will be processed normally. # If 'state' is set to SDL_QUERY, SDL_EventState() will return the # current processing state of the specified event. -proc EventState*(theType: byte, state: int): byte{.cdecl, +proc eventState*(theType: byte, state: int): byte{.cdecl, importc: "SDL_EventState", dynlib: LibName.} #------------------------------------------------------------------------------ # Version Routines #------------------------------------------------------------------------------ # This macro can be used to fill a version structure with the compile-time # version of the SDL library. -proc VERSION*(X: var TVersion) +proc version*(x: var Tversion) # This macro turns the version numbers into a numeric value: # (1,2,3) -> (1203) # This assumes that there will never be more than 100 patchlevels -proc VERSIONNUM*(X, Y, Z: int): int +proc versionnum*(x, y, z: int): int # This is the version number macro for the current SDL version -proc COMPILEDVERSION*(): int +proc compiledversion*(): int # This macro will evaluate to true if compiled with SDL at least X.Y.Z -proc VERSION_ATLEAST*(X: int, Y: int, Z: int): bool +proc versionAtleast*(x, y, z: int): bool # This function gets the version of the dynamically linked SDL library. # it should NOT be used to fill a version structure, instead you should # use the SDL_Version() macro. -proc Linked_Version*(): Pversion{.cdecl, importc: "SDL_Linked_Version", +proc linkedVersion*(): PVersion{.cdecl, importc: "SDL_Linked_Version", dynlib: LibName.} #------------------------------------------------------------------------------ # video @@ -1727,25 +1720,25 @@ proc Linked_Version*(): Pversion{.cdecl, importc: "SDL_Linked_Version", # If you use both sound and video in your application, you need to call # SDL_Init() before opening the sound device, otherwise under Win32 DirectX, # you won't be able to set full-screen display modes. -proc VideoInit*(driver_name: cstring, flags: int32): int{.cdecl, +proc videoInit*(driverName: cstring, flags: int32): int{.cdecl, importc: "SDL_VideoInit", dynlib: LibName.} -proc VideoQuit*(){.cdecl, importc: "SDL_VideoQuit", dynlib: LibName.} +proc videoQuit*(){.cdecl, importc: "SDL_VideoQuit", dynlib: LibName.} # This function fills the given character buffer with the name of the # video driver, and returns a pointer to it if the video driver has # been initialized. It returns NULL if no driver has been initialized. -proc VideoDriverName*(namebuf: cstring, maxlen: int): cstring{.cdecl, +proc videoDriverName*(namebuf: cstring, maxlen: int): cstring{.cdecl, importc: "SDL_VideoDriverName", dynlib: LibName.} # This function returns a pointer to the current display surface. # If SDL is doing format conversion on the display surface, this # function returns the publicly visible surface, not the real video # surface. -proc GetVideoSurface*(): PSurface{.cdecl, importc: "SDL_GetVideoSurface", +proc getVideoSurface*(): PSurface{.cdecl, importc: "SDL_GetVideoSurface", dynlib: LibName.} # This function returns a read-only pointer to information about the # video hardware. If this is called before SDL_SetVideoMode(), the 'vfmt' # member of the returned structure will contain the pixel format of the # "best" video mode. -proc GetVideoInfo*(): PVideoInfo{.cdecl, importc: "SDL_GetVideoInfo", +proc getVideoInfo*(): PVideoInfo{.cdecl, importc: "SDL_GetVideoInfo", dynlib: LibName.} # Check to see if a particular video mode is supported. # It returns 0 if the requested mode is not supported under any bit depth, @@ -1756,7 +1749,7 @@ proc GetVideoInfo*(): PVideoInfo{.cdecl, importc: "SDL_GetVideoInfo", # # The arguments to SDL_VideoModeOK() are the same ones you would pass to # SDL_SetVideoMode() -proc VideoModeOK*(width, height, bpp: int, flags: int32): int{.cdecl, +proc videoModeOK*(width, height, bpp: int, flags: int32): int{.cdecl, importc: "SDL_VideoModeOK", importc: "SDL_VideoModeOK", dynlib: LibName.} # Return a pointer to an array of available screen dimensions for the # given format and video flags, sorted largest to smallest. Returns @@ -1765,7 +1758,7 @@ proc VideoModeOK*(width, height, bpp: int, flags: int32): int{.cdecl, # # if 'format' is NULL, the mode list will be for the format given # by SDL_GetVideoInfo( ) - > vfmt -proc ListModes*(format: PPixelFormat, flags: int32): PPSDL_Rect{.cdecl, +proc listModes*(format: PPixelFormat, flags: int32): PPSDL_Rect{.cdecl, importc: "SDL_ListModes", dynlib: LibName.} # Set up a video mode with the specified width, height and bits-per-pixel. # @@ -1808,15 +1801,15 @@ proc ListModes*(format: PPixelFormat, flags: int32): PPSDL_Rect{.cdecl, # applications that redraw the entire screen on every update. # # This function returns the video framebuffer surface, or NULL if it fails. -proc SetVideoMode*(width, height, bpp: int, flags: uint32): PSurface{.cdecl, +proc setVideoMode*(width, height, bpp: int, flags: uint32): PSurface{.cdecl, importc: "SDL_SetVideoMode", dynlib: LibName.} # Makes sure the given list of rectangles is updated on the given screen. # If 'x', 'y', 'w' and 'h' are all 0, SDL_UpdateRect will update the entire # screen. # These functions should not be called while 'screen' is locked. -proc UpdateRects*(screen: PSurface, numrects: int, rects: PRect){.cdecl, +proc updateRects*(screen: PSurface, numrects: int, rects: PRect){.cdecl, importc: "SDL_UpdateRects", dynlib: LibName.} -proc UpdateRect*(screen: PSurface, x, y: int32, w, h: int32){.cdecl, +proc updateRect*(screen: PSurface, x, y: int32, w, h: int32){.cdecl, importc: "SDL_UpdateRect", dynlib: LibName.} # On hardware that supports double-buffering, this function sets up a flip # and returns. The hardware will wait for vertical retrace, and then swap @@ -1826,14 +1819,14 @@ proc UpdateRect*(screen: PSurface, x, y: int32, w, h: int32){.cdecl, # The SDL_DOUBLEBUF flag must have been passed to SDL_SetVideoMode() when # setting the video mode for this function to perform hardware flipping. # This function returns 0 if successful, or -1 if there was an error. -proc Flip*(screen: PSurface): int{.cdecl, importc: "SDL_Flip", dynlib: LibName.} +proc flip*(screen: PSurface): int{.cdecl, importc: "SDL_Flip", dynlib: LibName.} # Set the gamma correction for each of the color channels. # The gamma values range (approximately) between 0.1 and 10.0 # # If this function isn't supported directly by the hardware, it will # be emulated using gamma ramps, if available. If successful, this # function returns 0, otherwise it returns -1. -proc SetGamma*(redgamma: float32, greengamma: float32, bluegamma: float32): int{. +proc setGamma*(redgamma: float32, greengamma: float32, bluegamma: float32): int{. cdecl, importc: "SDL_SetGamma", dynlib: LibName.} # Set the gamma translation table for the red, green, and blue channels # of the video hardware. Each table is an array of 256 16-bit quantities, @@ -1845,7 +1838,7 @@ proc SetGamma*(redgamma: float32, greengamma: float32, bluegamma: float32): int{ # If the call succeeds, it will return 0. If the display driver or # hardware does not support gamma translation, or otherwise fails, # this function will return -1. -proc SetGammaRamp*(redtable: PUInt16, greentable: PUInt16, bluetable: PUInt16): int{. +proc setGammaRamp*(redtable: PUInt16, greentable: PUInt16, bluetable: PUInt16): int{. cdecl, importc: "SDL_SetGammaRamp", dynlib: LibName.} # Retrieve the current values of the gamma translation tables. # @@ -1854,7 +1847,7 @@ proc SetGammaRamp*(redtable: PUInt16, greentable: PUInt16, bluetable: PUInt16): # If the call succeeds, it will return 0. If the display driver or # hardware does not support gamma translation, or otherwise fails, # this function will return -1. -proc GetGammaRamp*(redtable: PUInt16, greentable: PUInt16, bluetable: PUInt16): int{. +proc getGammaRamp*(redtable: PUInt16, greentable: PUInt16, bluetable: PUInt16): int{. cdecl, importc: "SDL_GetGammaRamp", dynlib: LibName.} # Sets a portion of the colormap for the given 8-bit surface. If 'surface' # is not a palettized surface, this function does nothing, returning 0. @@ -1869,7 +1862,7 @@ proc GetGammaRamp*(redtable: PUInt16, greentable: PUInt16, bluetable: PUInt16): # will always return 1, and the palette is guaranteed to be set the way # you desire, even if the window colormap has to be warped or run under # emulation. -proc SetColors*(surface: PSurface, colors: PColor, firstcolor: int, ncolors: int): int{. +proc setColors*(surface: PSurface, colors: PColor, firstcolor: int, ncolors: int): int{. cdecl, importc: "SDL_SetColors", dynlib: LibName.} # Sets a portion of the colormap for a given 8-bit surface. # 'flags' is one or both of: @@ -1885,20 +1878,20 @@ proc SetColors*(surface: PSurface, colors: PColor, firstcolor: int, ncolors: int # # SDL_SetColors() is equivalent to calling this function with # flags = (SDL_LOGPAL or SDL_PHYSPAL). -proc SetPalette*(surface: PSurface, flags: int, colors: PColor, firstcolor: int, +proc setPalette*(surface: PSurface, flags: int, colors: PColor, firstcolor: int, ncolors: int): int{.cdecl, importc: "SDL_SetPalette", dynlib: LibName.} # Maps an RGB triple to an opaque pixel value for a given pixel format -proc MapRGB*(format: PPixelFormat, r: byte, g: byte, b: byte): int32{.cdecl, +proc mapRGB*(format: PPixelFormat, r: byte, g: byte, b: byte): int32{.cdecl, importc: "SDL_MapRGB", dynlib: LibName.} # Maps an RGBA quadruple to a pixel value for a given pixel format -proc MapRGBA*(format: PPixelFormat, r: byte, g: byte, b: byte, a: byte): int32{. +proc mapRGBA*(format: PPixelFormat, r: byte, g: byte, b: byte, a: byte): int32{. cdecl, importc: "SDL_MapRGBA", dynlib: LibName.} # Maps a pixel value into the RGB components for a given pixel format -proc GetRGB*(pixel: int32, fmt: PPixelFormat, r: ptr byte, g: ptr byte, b: ptr byte){. +proc getRGB*(pixel: int32, fmt: PPixelFormat, r: ptr byte, g: ptr byte, b: ptr byte){. cdecl, importc: "SDL_GetRGB", dynlib: LibName.} # Maps a pixel value into the RGBA components for a given pixel format -proc GetRGBA*(pixel: int32, fmt: PPixelFormat, r: ptr byte, g: ptr byte, b: ptr byte, +proc getRGBA*(pixel: int32, fmt: PPixelFormat, r: ptr byte, g: ptr byte, b: ptr byte, a: ptr byte){.cdecl, importc: "SDL_GetRGBA", dynlib: LibName.} # Allocate and free an RGB surface (must be called after SDL_SetVideoMode) # If the depth is 4 or 8 bits, an empty palette is allocated for the surface. @@ -1932,17 +1925,17 @@ proc GetRGBA*(pixel: int32, fmt: PPixelFormat, r: ptr byte, g: ptr byte, b: ptr # will be set in the flags member of the returned surface. If for some # reason the surface could not be placed in video memory, it will not have # the SDL_HWSURFACE flag set, and will be created in system memory instead. -proc AllocSurface*(flags: int32, width, height, depth: int, - RMask, GMask, BMask, AMask: int32): PSurface -proc CreateRGBSurface*(flags: int32, width, height, depth: int, - RMask, GMask, BMask, AMask: int32): PSurface{.cdecl, +proc allocSurface*(flags: int32, width, height, depth: int, + rMask, gMask, bMask, aMask: int32): PSurface +proc createRGBSurface*(flags: int32, width, height, depth: int, + rMask, gMask, bMask, aMask: int32): PSurface{.cdecl, importc: "SDL_CreateRGBSurface", dynlib: LibName.} -proc CreateRGBSurfaceFrom*(pixels: Pointer, width, height, depth, pitch: int, - RMask, GMask, BMask, AMask: int32): PSurface{.cdecl, +proc createRGBSurfaceFrom*(pixels: pointer, width, height, depth, pitch: int, + rMask, gMask, bMask, aMask: int32): PSurface{.cdecl, importc: "SDL_CreateRGBSurfaceFrom", dynlib: LibName.} -proc FreeSurface*(surface: PSurface){.cdecl, importc: "SDL_FreeSurface", +proc freeSurface*(surface: PSurface){.cdecl, importc: "SDL_FreeSurface", dynlib: LibName.} -proc MustLock*(Surface: PSurface): bool +proc mustLock*(surface: PSurface): bool # SDL_LockSurface() sets up a surface for directly accessing the pixels. # Between calls to SDL_LockSurface()/SDL_UnlockSurface(), you can write # to and read from 'surface->pixels', using the pixel format stored in @@ -1959,25 +1952,25 @@ proc MustLock*(Surface: PSurface): bool # pairs, as critical system locks may be held during this time. # # SDL_LockSurface() returns 0, or -1 if the surface couldn't be locked. -proc LockSurface*(surface: PSurface): int{.cdecl, importc: "SDL_LockSurface", +proc lockSurface*(surface: PSurface): int{.cdecl, importc: "SDL_LockSurface", dynlib: LibName.} -proc UnlockSurface*(surface: PSurface){.cdecl, importc: "SDL_UnlockSurface", +proc unlockSurface*(surface: PSurface){.cdecl, importc: "SDL_UnlockSurface", dynlib: LibName.} # Load a surface from a seekable SDL data source (memory or file.) # If 'freesrc' is non-zero, the source will be closed after being read. # Returns the new surface, or NULL if there was an error. # The new surface should be freed with SDL_FreeSurface(). -proc LoadBMP_RW*(src: PRWops, freesrc: int): PSurface{.cdecl, +proc loadBMP_RW*(src: PRWops, freesrc: int): PSurface{.cdecl, importc: "SDL_LoadBMP_RW", dynlib: LibName.} # Convenience macro -- load a surface from a file -proc LoadBMP*(filename: cstring): PSurface +proc loadBMP*(filename: cstring): PSurface # Save a surface to a seekable SDL data source (memory or file.) # If 'freedst' is non-zero, the source will be closed after being written. # Returns 0 if successful or -1 if there was an error. -proc SaveBMP_RW*(surface: PSurface, dst: PRWops, freedst: int): int{.cdecl, +proc saveBMP_RW*(surface: PSurface, dst: PRWops, freedst: int): int{.cdecl, importc: "SDL_SaveBMP_RW", dynlib: LibName.} # Convenience macro -- save a surface to a file -proc SaveBMP*(surface: PSurface, filename: cstring): int +proc saveBMP*(surface: PSurface, filename: cstring): int # Sets the color key (transparent pixel) in a blittable surface. # If 'flag' is SDL_SRCCOLORKEY (optionally OR'd with SDL_RLEACCEL), # 'key' will be the transparent pixel in the source image of a blit. @@ -1985,7 +1978,7 @@ proc SaveBMP*(surface: PSurface, filename: cstring): int # and removes RLE acceleration if absent. # If 'flag' is 0, this function clears any current color key. # This function returns 0, or -1 if there was an error. -proc SetColorKey*(surface: PSurface, flag, key: int32): int{.cdecl, +proc setColorKey*(surface: PSurface, flag, key: int32): int{.cdecl, importc: "SDL_SetColorKey", dynlib: LibName.} # This function sets the alpha value for the entire surface, as opposed to # using the alpha component of each pixel. This value measures the range @@ -1998,7 +1991,7 @@ proc SetColorKey*(surface: PSurface, flag, key: int32): int{.cdecl, # If 'flag' is SDL_SRCALPHA, alpha blending is enabled for the surface. # OR:ing the flag with SDL_RLEACCEL requests RLE acceleration for the # surface; if SDL_RLEACCEL is not specified, the RLE accel will be removed. -proc SetAlpha*(surface: PSurface, flag: int32, alpha: byte): int{.cdecl, +proc setAlpha*(surface: PSurface, flag: int32, alpha: byte): int{.cdecl, importc: "SDL_SetAlpha", dynlib: LibName.} # Sets the clipping rectangle for the destination surface in a blit. # @@ -2010,12 +2003,12 @@ proc SetAlpha*(surface: PSurface, flag: int32, alpha: byte): int{.cdecl, # # Note that blits are automatically clipped to the edges of the source # and destination surfaces. -proc SetClipRect*(surface: PSurface, rect: PRect){.cdecl, +proc setClipRect*(surface: PSurface, rect: PRect){.cdecl, importc: "SDL_SetClipRect", dynlib: LibName.} # Gets the clipping rectangle for the destination surface in a blit. # 'rect' must be a pointer to a valid rectangle which will be filled # with the correct values. -proc GetClipRect*(surface: PSurface, rect: PRect){.cdecl, +proc getClipRect*(surface: PSurface, rect: PRect){.cdecl, importc: "SDL_GetClipRect", dynlib: LibName.} # Creates a new surface of the specified format, and then copies and maps # the given surface to it so the blit of the converted surface will be as @@ -2027,7 +2020,7 @@ proc GetClipRect*(surface: PSurface, rect: PRect){.cdecl, # surface. # # This function is used internally by SDL_DisplayFormat(). -proc ConvertSurface*(src: PSurface, fmt: PPixelFormat, flags: int32): PSurface{. +proc convertSurface*(src: PSurface, fmt: PPixelFormat, flags: int32): PSurface{. cdecl, importc: "SDL_ConvertSurface", dynlib: LibName.} # # This performs a fast blit from the source surface to the destination @@ -2098,14 +2091,14 @@ proc ConvertSurface*(src: PSurface, fmt: PPixelFormat, flags: int32): PSurface{. # to the video memory again. # You should call SDL_BlitSurface() unless you know exactly how SDL # blitting works internally and how to use the other blit functions. -proc BlitSurface*(src: PSurface, srcrect: PRect, dst: PSurface, dstrect: PRect): int +proc blitSurface*(src: PSurface, srcrect: PRect, dst: PSurface, dstrect: PRect): int # This is the public blit function, SDL_BlitSurface(), and it performs # rectangle validation and clipping before passing it to SDL_LowerBlit() -proc UpperBlit*(src: PSurface, srcrect: PRect, dst: PSurface, dstrect: PRect): int{. +proc upperBlit*(src: PSurface, srcrect: PRect, dst: PSurface, dstrect: PRect): int{. cdecl, importc: "SDL_UpperBlit", dynlib: LibName.} # This is a semi-private blit function and it performs low-level surface # blitting only. -proc LowerBlit*(src: PSurface, srcrect: PRect, dst: PSurface, dstrect: PRect): int{. +proc lowerBlit*(src: PSurface, srcrect: PRect, dst: PSurface, dstrect: PRect): int{. cdecl, importc: "SDL_LowerBlit", dynlib: LibName.} # This function performs a fast fill of the given rectangle with 'color' # The given rectangle is clipped to the destination surface clip area @@ -2114,7 +2107,7 @@ proc LowerBlit*(src: PSurface, srcrect: PRect, dst: PSurface, dstrect: PRect): i # The color should be a pixel of the format used by the surface, and # can be generated by the SDL_MapRGB() function. # This function returns 0 on success, or -1 on error. -proc FillRect*(dst: PSurface, dstrect: PRect, color: int32): int{.cdecl, +proc fillRect*(dst: PSurface, dstrect: PRect, color: int32): int{.cdecl, importc: "SDL_FillRect", dynlib: LibName.} # This function takes a surface and copies it to a new surface of the # pixel format and colors of the video framebuffer, suitable for fast @@ -2125,7 +2118,7 @@ proc FillRect*(dst: PSurface, dstrect: PRect, color: int32): int{.cdecl, # calling this function. # # If the conversion fails or runs out of memory, it returns NULL -proc DisplayFormat*(surface: PSurface): PSurface{.cdecl, +proc displayFormat*(surface: PSurface): PSurface{.cdecl, importc: "SDL_DisplayFormat", dynlib: LibName.} # This function takes a surface and copies it to a new surface of the # pixel format and colors of the video framebuffer (if possible), @@ -2137,7 +2130,7 @@ proc DisplayFormat*(surface: PSurface): PSurface{.cdecl, # calling this function. # # If the conversion fails or runs out of memory, it returns NULL -proc DisplayFormatAlpha*(surface: PSurface): PSurface{.cdecl, +proc displayFormatAlpha*(surface: PSurface): PSurface{.cdecl, importc: "SDL_DisplayFormatAlpha", dynlib: LibName.} #* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #* YUV video surface overlay functions */ @@ -2146,23 +2139,23 @@ proc DisplayFormatAlpha*(surface: PSurface): PSurface{.cdecl, # Calling the returned surface an overlay is something of a misnomer because # the contents of the display surface underneath the area where the overlay # is shown is undefined - it may be overwritten with the converted YUV data. -proc CreateYUVOverlay*(width: int, height: int, format: int32, +proc createYUVOverlay*(width: int, height: int, format: int32, display: PSurface): POverlay{.cdecl, importc: "SDL_CreateYUVOverlay", dynlib: LibName.} # Lock an overlay for direct access, and unlock it when you are done -proc LockYUVOverlay*(Overlay: POverlay): int{.cdecl, +proc lockYUVOverlay*(overlay: POverlay): int{.cdecl, importc: "SDL_LockYUVOverlay", dynlib: LibName.} -proc UnlockYUVOverlay*(Overlay: POverlay){.cdecl, +proc unlockYUVOverlay*(overlay: POverlay){.cdecl, importc: "SDL_UnlockYUVOverlay", dynlib: LibName.} # Blit a video overlay to the display surface. # The contents of the video surface underneath the blit destination are # not defined. # The width and height of the destination rectangle may be different from # that of the overlay, but currently only 2x scaling is supported. -proc DisplayYUVOverlay*(Overlay: POverlay, dstrect: PRect): int{.cdecl, +proc displayYUVOverlay*(overlay: POverlay, dstrect: PRect): int{.cdecl, importc: "SDL_DisplayYUVOverlay", dynlib: LibName.} # Free a video overlay -proc FreeYUVOverlay*(Overlay: POverlay){.cdecl, importc: "SDL_FreeYUVOverlay", +proc freeYUVOverlay*(overlay: POverlay){.cdecl, importc: "SDL_FreeYUVOverlay", dynlib: LibName.} #------------------------------------------------------------------------------ # OpenGL Routines @@ -2175,13 +2168,13 @@ proc FreeYUVOverlay*(Overlay: POverlay){.cdecl, importc: "SDL_FreeYUVOverlay", # your program from the dynamic library using SDL_GL_GetProcAddress(). # # This is disabled in default builds of SDL. -proc GL_LoadLibrary*(filename: cstring): int{.cdecl, +proc glLoadLibrary*(filename: cstring): int{.cdecl, importc: "SDL_GL_LoadLibrary", dynlib: LibName.} # Get the address of a GL function (for extension functions) -proc GL_GetProcAddress*(procname: cstring): Pointer{.cdecl, +proc glGetProcAddress*(procname: cstring): pointer{.cdecl, importc: "SDL_GL_GetProcAddress", dynlib: LibName.} # Set an attribute of the OpenGL subsystem before intialization. -proc GL_SetAttribute*(attr: TGLAttr, value: int): int{.cdecl, +proc glSetAttribute*(attr: TGLAttr, value: int): int{.cdecl, importc: "SDL_GL_SetAttribute", dynlib: LibName.} # Get an attribute of the OpenGL subsystem from the windowing # interface, such as glX. This is of course different from getting @@ -2190,34 +2183,34 @@ proc GL_SetAttribute*(attr: TGLAttr, value: int): int{.cdecl, # # Developers should track the values they pass into SDL_GL_SetAttribute # themselves if they want to retrieve these values. -proc GL_GetAttribute*(attr: TGLAttr, value: var int): int{.cdecl, +proc glGetAttribute*(attr: TGLAttr, value: var int): int{.cdecl, importc: "SDL_GL_GetAttribute", dynlib: LibName.} # Swap the OpenGL buffers, if double-buffering is supported. -proc GL_SwapBuffers*(){.cdecl, importc: "SDL_GL_SwapBuffers", dynlib: LibName.} +proc glSwapBuffers*(){.cdecl, importc: "SDL_GL_SwapBuffers", dynlib: LibName.} # Internal functions that should not be called unless you have read # and understood the source code for these functions. -proc GL_UpdateRects*(numrects: int, rects: PRect){.cdecl, +proc glUpdateRects*(numrects: int, rects: PRect){.cdecl, importc: "SDL_GL_UpdateRects", dynlib: LibName.} -proc GL_Lock*(){.cdecl, importc: "SDL_GL_Lock", dynlib: LibName.} -proc GL_Unlock*(){.cdecl, importc: "SDL_GL_Unlock", dynlib: LibName.} +proc glLock*(){.cdecl, importc: "SDL_GL_Lock", dynlib: LibName.} +proc glUnlock*(){.cdecl, importc: "SDL_GL_Unlock", dynlib: LibName.} #* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * #* These functions allow interaction with the window manager, if any. * #* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # Sets/Gets the title and icon text of the display window -proc WM_GetCaption*(title: var cstring, icon: var cstring){.cdecl, +proc wmGetCaption*(title: var cstring, icon: var cstring){.cdecl, importc: "SDL_WM_GetCaption", dynlib: LibName.} -proc WM_SetCaption*(title: cstring, icon: cstring){.cdecl, +proc wmSetCaption*(title: cstring, icon: cstring){.cdecl, importc: "SDL_WM_SetCaption", dynlib: LibName.} # Sets the icon for the display window. # This function must be called before the first call to SDL_SetVideoMode(). # It takes an icon surface, and a mask in MSB format. # If 'mask' is NULL, the entire icon surface will be used as the icon. -proc WM_SetIcon*(icon: PSurface, mask: byte){.cdecl, importc: "SDL_WM_SetIcon", +proc wmSetIcon*(icon: PSurface, mask: byte){.cdecl, importc: "SDL_WM_SetIcon", dynlib: LibName.} # This function iconifies the window, and returns 1 if it succeeded. # If the function succeeds, it generates an SDL_APPACTIVE loss event. # This function is a noop and returns 0 in non-windowed environments. -proc WM_IconifyWindow*(): int{.cdecl, importc: "SDL_WM_IconifyWindow", +proc wmIconifyWindow*(): int{.cdecl, importc: "SDL_WM_IconifyWindow", dynlib: LibName.} # Toggle fullscreen mode without changing the contents of the screen. # If the display surface does not require locking before accessing @@ -2232,12 +2225,12 @@ proc WM_IconifyWindow*(): int{.cdecl, importc: "SDL_WM_IconifyWindow", # set, then the display will be windowed by default where supported. # # This is currently only implemented in the X11 video driver. -proc WM_ToggleFullScreen*(surface: PSurface): int{.cdecl, +proc wmToggleFullScreen*(surface: PSurface): int{.cdecl, importc: "SDL_WM_ToggleFullScreen", dynlib: LibName.} # Grabbing means that the mouse is confined to the application window, # and nearly all keyboard input is passed directly to the application, # and not interpreted by a window manager, if any. -proc WM_GrabInput*(mode: TGrabMode): TGrabMode{.cdecl, +proc wmGrabInput*(mode: TGrabMode): TGrabMode{.cdecl, importc: "SDL_WM_GrabInput", dynlib: LibName.} #------------------------------------------------------------------------------ # mouse-routines @@ -2246,16 +2239,16 @@ proc WM_GrabInput*(mode: TGrabMode): TGrabMode{.cdecl, # The current button state is returned as a button bitmask, which can # be tested using the SDL_BUTTON(X) macros, and x and y are set to the # current mouse cursor position. You can pass NULL for either x or y. -proc GetMouseState*(x: var int, y: var int): byte{.cdecl, +proc getMouseState*(x: var int, y: var int): byte{.cdecl, importc: "SDL_GetMouseState", dynlib: LibName.} # Retrieve the current state of the mouse. # The current button state is returned as a button bitmask, which can # be tested using the SDL_BUTTON(X) macros, and x and y are set to the # mouse deltas since the last call to SDL_GetRelativeMouseState(). -proc GetRelativeMouseState*(x: var int, y: var int): byte{.cdecl, +proc getRelativeMouseState*(x: var int, y: var int): byte{.cdecl, importc: "SDL_GetRelativeMouseState", dynlib: LibName.} # Set the position of the mouse cursor (generates a mouse motion event) -proc WarpMouse*(x, y: UInt16){.cdecl, importc: "SDL_WarpMouse", dynlib: LibName.} +proc warpMouse*(x, y: uint16){.cdecl, importc: "SDL_WarpMouse", dynlib: LibName.} # Create a cursor using the specified data and mask (in MSB format). # The cursor width must be a multiple of 8 bits. # @@ -2267,26 +2260,26 @@ proc WarpMouse*(x, y: UInt16){.cdecl, importc: "SDL_WarpMouse", dynlib: LibName. # 1 0 Inverted color if possible, black if not. # # Cursors created with this function must be freed with SDL_FreeCursor(). -proc CreateCursor*(data, mask: ptr byte, w, h, hot_x, hot_y: int): PCursor{.cdecl, +proc createCursor*(data, mask: ptr byte, w, h, hotX, hotY: int): PCursor{.cdecl, importc: "SDL_CreateCursor", dynlib: LibName.} # Set the currently active cursor to the specified one. # If the cursor is currently visible, the change will be immediately # represented on the display. -proc SetCursor*(cursor: PCursor){.cdecl, importc: "SDL_SetCursor", +proc setCursor*(cursor: PCursor){.cdecl, importc: "SDL_SetCursor", dynlib: LibName.} # Returns the currently active cursor. -proc GetCursor*(): PCursor{.cdecl, importc: "SDL_GetCursor", dynlib: LibName.} +proc getCursor*(): PCursor{.cdecl, importc: "SDL_GetCursor", dynlib: LibName.} # Deallocates a cursor created with SDL_CreateCursor(). -proc FreeCursor*(cursor: PCursor){.cdecl, importc: "SDL_FreeCursor", +proc freeCursor*(cursor: PCursor){.cdecl, importc: "SDL_FreeCursor", dynlib: LibName.} # Toggle whether or not the cursor is shown on the screen. # The cursor start off displayed, but can be turned off. # SDL_ShowCursor() returns 1 if the cursor was being displayed # before the call, or 0 if it was not. You can query the current # state by passing a 'toggle' value of -1. -proc ShowCursor*(toggle: int): int{.cdecl, importc: "SDL_ShowCursor", +proc showCursor*(toggle: int): int{.cdecl, importc: "SDL_ShowCursor", dynlib: LibName.} -proc BUTTON*(Button: int): int +proc button*(b: int): int #------------------------------------------------------------------------------ # Keyboard-routines #------------------------------------------------------------------------------ @@ -2296,12 +2289,12 @@ proc BUTTON*(Button: int): int # If 'enable' is 0, translation is disabled. # If 'enable' is -1, the translation state is not changed. # It returns the previous state of keyboard translation. -proc EnableUNICODE*(enable: int): int{.cdecl, importc: "SDL_EnableUNICODE", +proc enableUNICODE*(enable: int): int{.cdecl, importc: "SDL_EnableUNICODE", dynlib: LibName.} # If 'delay' is set to 0, keyboard repeat is disabled. -proc EnableKeyRepeat*(delay: int, interval: int): int{.cdecl, +proc enableKeyRepeat*(delay: int, interval: int): int{.cdecl, importc: "SDL_EnableKeyRepeat", dynlib: LibName.} -proc GetKeyRepeat*(delay: PInteger, interval: PInteger){.cdecl, +proc getKeyRepeat*(delay: PInteger, interval: PInteger){.cdecl, importc: "SDL_GetKeyRepeat", dynlib: LibName.} # Get a snapshot of the current state of the keyboard. # Returns an array of keystates, indexed by the SDLK_* syms. @@ -2309,16 +2302,16 @@ proc GetKeyRepeat*(delay: PInteger, interval: PInteger){.cdecl, # # byte *keystate = SDL_GetKeyState(NULL); # if ( keystate[SDLK_RETURN] ) ... <RETURN> is pressed -proc GetKeyState*(numkeys: pointer): ptr byte{.cdecl, importc: "SDL_GetKeyState", +proc getKeyState*(numkeys: pointer): ptr byte{.cdecl, importc: "SDL_GetKeyState", dynlib: LibName.} # Get the current key modifier state -proc GetModState*(): TMod{.cdecl, importc: "SDL_GetModState", dynlib: LibName.} +proc getModState*(): TMod{.cdecl, importc: "SDL_GetModState", dynlib: LibName.} # Set the current key modifier state # This does not change the keyboard state, only the key modifier flags. -proc SetModState*(modstate: TMod){.cdecl, importc: "SDL_SetModState", +proc setModState*(modstate: TMod){.cdecl, importc: "SDL_SetModState", dynlib: LibName.} # Get the name of an SDL virtual keysym -proc GetKeyName*(key: TKey): cstring{.cdecl, importc: "SDL_GetKeyName", +proc getKeyName*(key: TKey): cstring{.cdecl, importc: "SDL_GetKeyName", dynlib: LibName.} #------------------------------------------------------------------------------ # Active Routines @@ -2327,96 +2320,96 @@ proc GetKeyName*(key: TKey): cstring{.cdecl, importc: "SDL_GetKeyName", # bitwise combination of SDL_APPMOUSEFOCUS, SDL_APPINPUTFOCUS, and # SDL_APPACTIVE. If SDL_APPACTIVE is set, then the user is able to # see your application, otherwise it has been iconified or disabled. -proc GetAppState*(): byte{.cdecl, importc: "SDL_GetAppState", dynlib: LibName.} +proc getAppState*(): byte{.cdecl, importc: "SDL_GetAppState", dynlib: LibName.} # Mutex functions # Create a mutex, initialized unlocked -proc CreateMutex*(): PMutex{.cdecl, importc: "SDL_CreateMutex", dynlib: LibName.} +proc createMutex*(): PMutex{.cdecl, importc: "SDL_CreateMutex", dynlib: LibName.} # Lock the mutex (Returns 0, or -1 on error) -proc mutexP*(mutex: Pmutex): int{.cdecl, importc: "SDL_mutexP", dynlib: LibName.} -proc LockMutex*(mutex: Pmutex): int +proc mutexP*(mutex: PMutex): int{.cdecl, importc: "SDL_mutexP", dynlib: LibName.} +proc lockMutex*(mutex: PMutex): int # Unlock the mutex (Returns 0, or -1 on error) -proc mutexV*(mutex: Pmutex): int{.cdecl, importc: "SDL_mutexV", dynlib: LibName.} -proc UnlockMutex*(mutex: Pmutex): int +proc mutexV*(mutex: PMutex): int{.cdecl, importc: "SDL_mutexV", dynlib: LibName.} +proc unlockMutex*(mutex: PMutex): int # Destroy a mutex -proc DestroyMutex*(mutex: Pmutex){.cdecl, importc: "SDL_DestroyMutex", +proc destroyMutex*(mutex: PMutex){.cdecl, importc: "SDL_DestroyMutex", dynlib: LibName.} # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # Semaphore functions # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # Create a semaphore, initialized with value, returns NULL on failure. -proc CreateSemaphore*(initial_value: int32): PSem{.cdecl, +proc createSemaphore*(initialValue: int32): PSem{.cdecl, importc: "SDL_CreateSemaphore", dynlib: LibName.} # Destroy a semaphore -proc DestroySemaphore*(sem: Psem){.cdecl, importc: "SDL_DestroySemaphore", +proc destroySemaphore*(sem: PSem){.cdecl, importc: "SDL_DestroySemaphore", dynlib: LibName.} # This function suspends the calling thread until the semaphore pointed # to by sem has a positive count. It then atomically decreases the semaphore # count. -proc SemWait*(sem: Psem): int{.cdecl, importc: "SDL_SemWait", dynlib: LibName.} +proc semWait*(sem: PSem): int{.cdecl, importc: "SDL_SemWait", dynlib: LibName.} # Non-blocking variant of SDL_SemWait(), returns 0 if the wait succeeds, # SDL_MUTEX_TIMEDOUT if the wait would block, and -1 on error. -proc SemTryWait*(sem: Psem): int{.cdecl, importc: "SDL_SemTryWait", +proc semTryWait*(sem: PSem): int{.cdecl, importc: "SDL_SemTryWait", dynlib: LibName.} # Variant of SDL_SemWait() with a timeout in milliseconds, returns 0 if # the wait succeeds, SDL_MUTEX_TIMEDOUT if the wait does not succeed in # the allotted time, and -1 on error. # On some platforms this function is implemented by looping with a delay # of 1 ms, and so should be avoided if possible. -proc SemWaitTimeout*(sem: Psem, ms: int32): int{.cdecl, +proc semWaitTimeout*(sem: PSem, ms: int32): int{.cdecl, importc: "SDL_SemWaitTimeout", dynlib: LibName.} # Atomically increases the semaphore's count (not blocking), returns 0, # or -1 on error. -proc SemPost*(sem: Psem): int{.cdecl, importc: "SDL_SemPost", dynlib: LibName.} +proc semPost*(sem: PSem): int{.cdecl, importc: "SDL_SemPost", dynlib: LibName.} # Returns the current count of the semaphore -proc SemValue*(sem: Psem): int32{.cdecl, importc: "SDL_SemValue", +proc semValue*(sem: PSem): int32{.cdecl, importc: "SDL_SemValue", dynlib: LibName.} # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # Condition variable functions # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # Create a condition variable -proc CreateCond*(): PCond{.cdecl, importc: "SDL_CreateCond", dynlib: LibName.} +proc createCond*(): PCond{.cdecl, importc: "SDL_CreateCond", dynlib: LibName.} # Destroy a condition variable -proc DestroyCond*(cond: PCond){.cdecl, importc: "SDL_DestroyCond", +proc destroyCond*(cond: PCond){.cdecl, importc: "SDL_DestroyCond", dynlib: LibName.} # Restart one of the threads that are waiting on the condition variable, # returns 0 or -1 on error. -proc CondSignal*(cond: Pcond): int{.cdecl, importc: "SDL_CondSignal", +proc condSignal*(cond: PCond): int{.cdecl, importc: "SDL_CondSignal", dynlib: LibName.} # Restart all threads that are waiting on the condition variable, # returns 0 or -1 on error. -proc CondBroadcast*(cond: Pcond): int{.cdecl, importc: "SDL_CondBroadcast", +proc condBroadcast*(cond: PCond): int{.cdecl, importc: "SDL_CondBroadcast", dynlib: LibName.} # Wait on the condition variable, unlocking the provided mutex. # The mutex must be locked before entering this function! # Returns 0 when it is signaled, or -1 on error. -proc CondWait*(cond: Pcond, mut: Pmutex): int{.cdecl, importc: "SDL_CondWait", +proc condWait*(cond: PCond, mut: PMutex): int{.cdecl, importc: "SDL_CondWait", dynlib: LibName.} # Waits for at most 'ms' milliseconds, and returns 0 if the condition # variable is signaled, SDL_MUTEX_TIMEDOUT if the condition is not # signaled in the allotted time, and -1 on error. # On some platforms this function is implemented by looping with a delay # of 1 ms, and so should be avoided if possible. -proc CondWaitTimeout*(cond: Pcond, mut: Pmutex, ms: int32): int{.cdecl, +proc condWaitTimeout*(cond: PCond, mut: PMutex, ms: int32): int{.cdecl, importc: "SDL_CondWaitTimeout", dynlib: LibName.} # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # Condition variable functions # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # Create a thread -proc CreateThread*(fn, data: Pointer): PThread{.cdecl, +proc createThread*(fn, data: pointer): PThread{.cdecl, importc: "SDL_CreateThread", dynlib: LibName.} # Get the 32-bit thread identifier for the current thread -proc ThreadID*(): int32{.cdecl, importc: "SDL_ThreadID", dynlib: LibName.} +proc threadID*(): int32{.cdecl, importc: "SDL_ThreadID", dynlib: LibName.} # Get the 32-bit thread identifier for the specified thread, # equivalent to SDL_ThreadID() if the specified thread is NULL. -proc GetThreadID*(thread: PThread): int32{.cdecl, importc: "SDL_GetThreadID", +proc getThreadID*(thread: PThread): int32{.cdecl, importc: "SDL_GetThreadID", dynlib: LibName.} # Wait for a thread to finish. # The return code for the thread function is placed in the area # pointed to by 'status', if 'status' is not NULL. -proc WaitThread*(thread: PThread, status: var int){.cdecl, +proc waitThread*(thread: PThread, status: var int){.cdecl, importc: "SDL_WaitThread", dynlib: LibName.} # Forcefully kill a thread without worrying about its state -proc KillThread*(thread: PThread){.cdecl, importc: "SDL_KillThread", +proc killThread*(thread: PThread){.cdecl, importc: "SDL_KillThread", dynlib: LibName.} #------------------------------------------------------------------------------ # Get Environment Routines @@ -2427,7 +2420,7 @@ proc KillThread*(thread: PThread){.cdecl, importc: "SDL_KillThread", # * returns 1 if the function is implemented. If it's not implemented, or # * the version member of the 'info' structure is invalid, it returns 0. # * -proc GetWMInfo*(info: PSysWMinfo): int{.cdecl, importc: "SDL_GetWMInfo", +proc getWMInfo*(info: PSysWMinfo): int{.cdecl, importc: "SDL_GetWMInfo", dynlib: LibName.} #------------------------------------------------------------------------------ #SDL_loadso.h @@ -2435,115 +2428,111 @@ proc GetWMInfo*(info: PSysWMinfo): int{.cdecl, importc: "SDL_GetWMInfo", # * to the object handle (or NULL if there was an error). # * The 'sofile' parameter is a system dependent name of the object file. # * -proc LoadObject*(sofile: cstring): Pointer{.cdecl, importc: "SDL_LoadObject", +proc loadObject*(sofile: cstring): pointer{.cdecl, importc: "SDL_LoadObject", dynlib: LibName.} #* Given an object handle, this function looks up the address of the # * named function in the shared object and returns it. This address # * is no longer valid after calling SDL_UnloadObject(). # * -proc LoadFunction*(handle: Pointer, name: cstring): Pointer{.cdecl, +proc loadFunction*(handle: pointer, name: cstring): pointer{.cdecl, importc: "SDL_LoadFunction", dynlib: LibName.} #* Unload a shared object from memory * -proc UnloadObject*(handle: Pointer){.cdecl, importc: "SDL_UnloadObject", +proc unloadObject*(handle: pointer){.cdecl, importc: "SDL_UnloadObject", dynlib: LibName.} #------------------------------------------------------------------------------ -proc Swap32*(D: int32): int32 +proc swap32*(d: int32): int32 # Bitwise Checking functions -proc IsBitOn*(value: int, bit: int8): bool -proc TurnBitOn*(value: int, bit: int8): int -proc TurnBitOff*(value: int, bit: int8): int +proc isBitOn*(value: int, bit: int8): bool +proc turnBitOn*(value: int, bit: int8): int +proc turnBitOff*(value: int, bit: int8): int # implementation -proc TABLESIZE(table: cstring): int = - Result = SizeOf(table) div SizeOf(table[0]) +proc tablesize(table: cstring): int = + result = sizeOf(table) div sizeOf(table[0]) -proc OutOfMemory() = - when not (defined(WINDOWS)): Error(ENOMEM) - -proc RWSeek(context: PRWops, offset: int, whence: int): int = - Result = context.seek(context, offset, whence) +proc rwSeek(context: PRWops, offset: int, whence: int): int = + result = context.seek(context, offset, whence) -proc RWTell(context: PRWops): int = - Result = context.seek(context, 0, 1) +proc rwTell(context: PRWops): int = + result = context.seek(context, 0, 1) -proc RWRead(context: PRWops, theptr: Pointer, size: int, n: int): int = - Result = context.read(context, theptr, size, n) +proc rwRead(context: PRWops, theptr: pointer, size: int, n: int): int = + result = context.read(context, theptr, size, n) -proc RWWrite(context: PRWops, theptr: Pointer, size: int, n: int): int = - Result = context.write(context, theptr, size, n) +proc rwWrite(context: PRWops, theptr: pointer, size: int, n: int): int = + result = context.write(context, theptr, size, n) -proc RWClose(context: PRWops): int = - Result = context.closeFile(context) +proc rwClose(context: PRWops): int = + result = context.closeFile(context) -proc LoadWAV(filename: cstring, spec: PAudioSpec, audio_buf: ptr byte, +proc loadWAV(filename: cstring, spec: PAudioSpec, audioBuf: ptr byte, audiolen: PUInt32): PAudioSpec = - Result = LoadWAV_RW(RWFromFile(filename, "rb"), 1, spec, audio_buf, audiolen) + result = loadWAV_RW(rWFromFile(filename, "rb"), 1, spec, audioBuf, audiolen) -proc CDInDrive(status: TCDStatus): bool = - Result = ord(status) > ord(CD_ERROR) +proc cdInDrive(status: TCDStatus): bool = + result = ord(status) > ord(CD_ERROR) -proc FRAMES_TO_MSF(frames: int, M: var int, S: var int, F: var int) = - var value: int - value = frames - F = value mod CD_FPS +proc framesToMsf*(frames: int; m, s, f: var int) = + var value = frames + f = value mod CD_FPS value = value div CD_FPS - S = value mod 60 + s = value mod 60 value = value div 60 - M = value + m = value -proc MSF_TO_FRAMES(M: int, S: int, F: int): int = - Result = M * 60 * CD_FPS + S * CD_FPS + F +proc msfToFrames*(m, s, f: int): int = + result = m * 60 * CD_FPS + s * CD_FPS + f -proc VERSION(X: var TVersion) = - X.major = MAJOR_VERSION - X.minor = MINOR_VERSION - X.patch = PATCHLEVEL +proc version(x: var Tversion) = + x.major = MAJOR_VERSION + x.minor = MINOR_VERSION + x.patch = PATCHLEVEL -proc VERSIONNUM(X, Y, Z: int): int = - Result = X * 1000 + Y * 100 + Z +proc versionnum(x, y, z: int): int = + result = x * 1000 + y * 100 + z -proc COMPILEDVERSION(): int = - Result = VERSIONNUM(MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL) +proc compiledversion(): int = + result = versionnum(MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL) -proc VERSION_ATLEAST(X, Y, Z: int): bool = - Result = (COMPILEDVERSION() >= VERSIONNUM(X, Y, Z)) +proc versionAtleast(x, y, z: int): bool = + result = (compiledversion() >= versionnum(x, y, z)) -proc LoadBMP(filename: cstring): PSurface = - Result = LoadBMP_RW(RWFromFile(filename, "rb"), 1) +proc loadBMP(filename: cstring): PSurface = + result = loadBMP_RW(rWFromFile(filename, "rb"), 1) -proc SaveBMP(surface: PSurface, filename: cstring): int = - Result = SaveBMP_RW(surface, RWFromFile(filename, "wb"), 1) +proc saveBMP(surface: PSurface, filename: cstring): int = + result = saveBMP_RW(surface, rWFromFile(filename, "wb"), 1) -proc BlitSurface(src: PSurface, srcrect: PRect, dst: PSurface, dstrect: PRect): int = - Result = UpperBlit(src, srcrect, dst, dstrect) +proc blitSurface(src: PSurface, srcrect: PRect, dst: PSurface, dstrect: PRect): int = + result = upperBlit(src, srcrect, dst, dstrect) -proc AllocSurface(flags: int32, width, height, depth: int, - RMask, GMask, BMask, AMask: int32): PSurface = - Result = CreateRGBSurface(flags, width, height, depth, RMask, GMask, BMask, - AMask) +proc allocSurface(flags: int32, width, height, depth: int, + rMask, gMask, bMask, aMask: int32): PSurface = + result = createRGBSurface(flags, width, height, depth, rMask, gMask, bMask, + aMask) -proc MustLock(Surface: PSurface): bool = - Result = ((surface[].offset != 0) or - ((surface[].flags and (HWSURFACE or ASYNCBLIT or RLEACCEL)) != 0)) +proc mustLock(surface: PSurface): bool = + result = ((surface.offset != 0) or + ((surface.flags and (HWSURFACE or ASYNCBLIT or RLEACCEL)) != 0)) -proc LockMutex(mutex: Pmutex): int = - Result = mutexP(mutex) +proc lockMutex(mutex: PMutex): int = + result = mutexP(mutex) -proc UnlockMutex(mutex: Pmutex): int = - Result = mutexV(mutex) +proc unlockMutex(mutex: PMutex): int = + result = mutexV(mutex) -proc BUTTON(Button: int): int = - Result = PRESSED shl (Button - 1) +proc button(b: int): int = + result = PRESSED shl (b - 1) -proc Swap32(D: int32): int32 = - Result = ((D shl 24) or ((D shl 8) and 0x00FF0000) or - ((D shr 8) and 0x0000FF00) or (D shr 24)) +proc swap32(d: int32): int32 = + result = ((d shl 24) or ((d shl 8) and 0x00FF0000) or + ((d shr 8) and 0x0000FF00) or (d shr 24)) -proc IsBitOn(value: int, bit: int8): bool = +proc isBitOn(value: int, bit: int8): bool = result = ((value and (1 shl ze(bit))) != 0) -proc TurnBitOn(value: int, bit: int8): int = +proc turnBitOn(value: int, bit: int8): int = result = (value or (1 shl ze(bit))) -proc TurnBitOff(value: int, bit: int8): int = +proc turnBitOff(value: int, bit: int8): int = result = (value and not (1 shl ze(bit))) diff --git a/lib/wrappers/sdl/sdl_gfx.nim b/lib/wrappers/sdl/sdl_gfx.nim index cf36c4989..5523ad0a2 100644 --- a/lib/wrappers/sdl/sdl_gfx.nim +++ b/lib/wrappers/sdl/sdl_gfx.nim @@ -39,10 +39,10 @@ const # Some rates in Hz type PFPSmanager* = ptr TFPSmanager TFPSmanager*{.final.} = object # ---- Structures - framecount*: Uint32 + framecount*: uint32 rateticks*: float32 - lastticks*: Uint32 - rate*: Uint32 + lastticks*: uint32 + rate*: uint32 PColorRGBA* = ptr TColorRGBA TColorRGBA*{.final.} = object @@ -79,102 +79,102 @@ proc framerateDelay*(manager: PFPSmanager){.cdecl, # # Note: all ___Color routines expect the color to be in format 0xRRGGBBAA # Pixel -proc pixelColor*(dst: PSurface, x: int16, y: int16, color: Uint32): cint{. +proc pixelColor*(dst: PSurface, x: int16, y: int16, color: uint32): cint{. cdecl, importc: "pixelColor", dynlib: gfxLibName.} proc pixelRGBA*(dst: PSurface, x: int16, y: int16, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "pixelRGBA", dynlib: gfxLibName.} # Horizontal line -proc hlineColor*(dst: PSurface, x1: int16, x2: int16, y: int16, color: Uint32): cint{. +proc hlineColor*(dst: PSurface, x1: int16, x2: int16, y: int16, color: uint32): cint{. cdecl, importc: "hlineColor", dynlib: gfxLibName.} proc hlineRGBA*(dst: PSurface, x1: int16, x2: int16, y: int16, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "hlineRGBA", dynlib: gfxLibName.} # Vertical line -proc vlineColor*(dst: PSurface, x: int16, y1: int16, y2: int16, color: Uint32): cint{. +proc vlineColor*(dst: PSurface, x: int16, y1: int16, y2: int16, color: uint32): cint{. cdecl, importc: "vlineColor", dynlib: gfxLibName.} proc vlineRGBA*(dst: PSurface, x: int16, y1: int16, y2: int16, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "vlineRGBA", dynlib: gfxLibName.} # Rectangle proc rectangleColor*(dst: PSurface, x1: int16, y1: int16, x2: int16, - y2: int16, color: Uint32): cint{.cdecl, + y2: int16, color: uint32): cint{.cdecl, importc: "rectangleColor", dynlib: gfxLibName.} proc rectangleRGBA*(dst: PSurface, x1: int16, y1: int16, x2: int16, y2: int16, r: byte, g: byte, b: byte, a: byte): cint{. cdecl, importc: "rectangleRGBA", dynlib: gfxLibName.} # Filled rectangle (Box) proc boxColor*(dst: PSurface, x1: int16, y1: int16, x2: int16, y2: int16, - color: Uint32): cint{.cdecl, importc: "boxColor", + color: uint32): cint{.cdecl, importc: "boxColor", dynlib: gfxLibName.} proc boxRGBA*(dst: PSurface, x1: int16, y1: int16, x2: int16, y2: int16, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "boxRGBA", dynlib: gfxLibName.} # Line proc lineColor*(dst: PSurface, x1: int16, y1: int16, x2: int16, y2: int16, - color: Uint32): cint{.cdecl, importc: "lineColor", + color: uint32): cint{.cdecl, importc: "lineColor", dynlib: gfxLibName.} proc lineRGBA*(dst: PSurface, x1: int16, y1: int16, x2: int16, y2: int16, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "lineRGBA", dynlib: gfxLibName.} # AA Line proc aalineColor*(dst: PSurface, x1: int16, y1: int16, x2: int16, y2: int16, - color: Uint32): cint{.cdecl, importc: "aalineColor", + color: uint32): cint{.cdecl, importc: "aalineColor", dynlib: gfxLibName.} proc aalineRGBA*(dst: PSurface, x1: int16, y1: int16, x2: int16, y2: int16, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "aalineRGBA", dynlib: gfxLibName.} # Circle -proc circleColor*(dst: PSurface, x: int16, y: int16, r: int16, color: Uint32): cint{. +proc circleColor*(dst: PSurface, x: int16, y: int16, r: int16, color: uint32): cint{. cdecl, importc: "circleColor", dynlib: gfxLibName.} proc circleRGBA*(dst: PSurface, x: int16, y: int16, rad: int16, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "circleRGBA", dynlib: gfxLibName.} # AA Circle proc aacircleColor*(dst: PSurface, x: int16, y: int16, r: int16, - color: Uint32): cint{.cdecl, importc: "aacircleColor", + color: uint32): cint{.cdecl, importc: "aacircleColor", dynlib: gfxLibName.} proc aacircleRGBA*(dst: PSurface, x: int16, y: int16, rad: int16, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "aacircleRGBA", dynlib: gfxLibName.} # Filled Circle proc filledCircleColor*(dst: PSurface, x: int16, y: int16, r: int16, - color: Uint32): cint{.cdecl, + color: uint32): cint{.cdecl, importc: "filledCircleColor", dynlib: gfxLibName.} proc filledCircleRGBA*(dst: PSurface, x: int16, y: int16, rad: int16, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "filledCircleRGBA", dynlib: gfxLibName.} # Ellipse proc ellipseColor*(dst: PSurface, x: int16, y: int16, rx: int16, ry: int16, - color: Uint32): cint{.cdecl, importc: "ellipseColor", + color: uint32): cint{.cdecl, importc: "ellipseColor", dynlib: gfxLibName.} proc ellipseRGBA*(dst: PSurface, x: int16, y: int16, rx: int16, ry: int16, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "ellipseRGBA", dynlib: gfxLibName.} # AA Ellipse proc aaellipseColor*(dst: PSurface, xc: int16, yc: int16, rx: int16, - ry: int16, color: Uint32): cint{.cdecl, + ry: int16, color: uint32): cint{.cdecl, importc: "aaellipseColor", dynlib: gfxLibName.} proc aaellipseRGBA*(dst: PSurface, x: int16, y: int16, rx: int16, ry: int16, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "aaellipseRGBA", dynlib: gfxLibName.} # Filled Ellipse proc filledEllipseColor*(dst: PSurface, x: int16, y: int16, rx: int16, - ry: int16, color: Uint32): cint{.cdecl, + ry: int16, color: uint32): cint{.cdecl, importc: "filledEllipseColor", dynlib: gfxLibName.} proc filledEllipseRGBA*(dst: PSurface, x: int16, y: int16, rx: int16, ry: int16, r: byte, g: byte, b: byte, a: byte): cint{. cdecl, importc: "filledEllipseRGBA", dynlib: gfxLibName.} # Pie proc pieColor*(dst: PSurface, x: int16, y: int16, rad: int16, start: int16, - finish: int16, color: Uint32): cint{.cdecl, importc: "pieColor", + finish: int16, color: uint32): cint{.cdecl, importc: "pieColor", dynlib: gfxLibName.} proc pieRGBA*(dst: PSurface, x: int16, y: int16, rad: int16, start: int16, finish: int16, r: byte, g: byte, b: byte, a: byte): cint{. cdecl, importc: "pieRGBA", dynlib: gfxLibName.} # Filled Pie proc filledPieColor*(dst: PSurface, x: int16, y: int16, rad: int16, - start: int16, finish: int16, color: Uint32): cint{.cdecl, + start: int16, finish: int16, color: uint32): cint{.cdecl, importc: "filledPieColor", dynlib: gfxLibName.} proc filledPieRGBA*(dst: PSurface, x: int16, y: int16, rad: int16, start: int16, finish: int16, r: byte, g: byte, b: byte, @@ -182,14 +182,14 @@ proc filledPieRGBA*(dst: PSurface, x: int16, y: int16, rad: int16, dynlib: gfxLibName.} # Trigon proc trigonColor*(dst: PSurface, x1: int16, y1: int16, x2: int16, y2: int16, - x3: int16, y3: int16, color: Uint32): cint{.cdecl, + x3: int16, y3: int16, color: uint32): cint{.cdecl, importc: "trigonColor", dynlib: gfxLibName.} proc trigonRGBA*(dst: PSurface, x1: int16, y1: int16, x2: int16, y2: int16, x3: int16, y3: int16, r: byte, g: byte, b: byte, a: byte): cint{. cdecl, importc: "trigonRGBA", dynlib: gfxLibName.} # AA-Trigon proc aatrigonColor*(dst: PSurface, x1: int16, y1: int16, x2: int16, - y2: int16, x3: int16, y3: int16, color: Uint32): cint{. + y2: int16, x3: int16, y3: int16, color: uint32): cint{. cdecl, importc: "aatrigonColor", dynlib: gfxLibName.} proc aatrigonRGBA*(dst: PSurface, x1: int16, y1: int16, x2: int16, y2: int16, x3: int16, y3: int16, r: byte, g: byte, @@ -197,7 +197,7 @@ proc aatrigonRGBA*(dst: PSurface, x1: int16, y1: int16, x2: int16, dynlib: gfxLibName.} # Filled Trigon proc filledTrigonColor*(dst: PSurface, x1: int16, y1: int16, x2: int16, - y2: int16, x3: int16, y3: int16, color: Uint32): cint{. + y2: int16, x3: int16, y3: int16, color: uint32): cint{. cdecl, importc: "filledTrigonColor", dynlib: gfxLibName.} proc filledTrigonRGBA*(dst: PSurface, x1: int16, y1: int16, x2: int16, y2: int16, x3: int16, y3: int16, r: byte, g: byte, @@ -205,21 +205,21 @@ proc filledTrigonRGBA*(dst: PSurface, x1: int16, y1: int16, x2: int16, importc: "filledTrigonRGBA", dynlib: gfxLibName.} # Polygon proc polygonColor*(dst: PSurface, vx: ptr int16, vy: ptr int16, n: cint, - color: Uint32): cint{.cdecl, importc: "polygonColor", + color: uint32): cint{.cdecl, importc: "polygonColor", dynlib: gfxLibName.} proc polygonRGBA*(dst: PSurface, vx: ptr int16, vy: ptr int16, n: cint, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "polygonRGBA", dynlib: gfxLibName.} # AA-Polygon proc aapolygonColor*(dst: PSurface, vx: ptr int16, vy: ptr int16, n: cint, - color: Uint32): cint{.cdecl, importc: "aapolygonColor", + color: uint32): cint{.cdecl, importc: "aapolygonColor", dynlib: gfxLibName.} proc aapolygonRGBA*(dst: PSurface, vx: ptr int16, vy: ptr int16, n: cint, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "aapolygonRGBA", dynlib: gfxLibName.} # Filled Polygon proc filledPolygonColor*(dst: PSurface, vx: ptr int16, vy: ptr int16, n: cint, - color: Uint32): cint{.cdecl, + color: uint32): cint{.cdecl, importc: "filledPolygonColor", dynlib: gfxLibName.} proc filledPolygonRGBA*(dst: PSurface, vx: ptr int16, vy: ptr int16, n: cint, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, @@ -227,23 +227,23 @@ proc filledPolygonRGBA*(dst: PSurface, vx: ptr int16, vy: ptr int16, n: cint, # Bezier # s = number of steps proc bezierColor*(dst: PSurface, vx: ptr int16, vy: ptr int16, n: cint, s: cint, - color: Uint32): cint{.cdecl, importc: "bezierColor", + color: uint32): cint{.cdecl, importc: "bezierColor", dynlib: gfxLibName.} proc bezierRGBA*(dst: PSurface, vx: ptr int16, vy: ptr int16, n: cint, s: cint, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "bezierRGBA", dynlib: gfxLibName.} # Characters/Strings -proc characterColor*(dst: PSurface, x: int16, y: int16, c: char, color: Uint32): cint{. +proc characterColor*(dst: PSurface, x: int16, y: int16, c: char, color: uint32): cint{. cdecl, importc: "characterColor", dynlib: gfxLibName.} proc characterRGBA*(dst: PSurface, x: int16, y: int16, c: char, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "characterRGBA", dynlib: gfxLibName.} -proc stringColor*(dst: PSurface, x: int16, y: int16, c: cstring, color: Uint32): cint{. +proc stringColor*(dst: PSurface, x: int16, y: int16, c: cstring, color: uint32): cint{. cdecl, importc: "stringColor", dynlib: gfxLibName.} proc stringRGBA*(dst: PSurface, x: int16, y: int16, c: cstring, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "stringRGBA", dynlib: gfxLibName.} -proc gfxPrimitivesSetFont*(fontdata: Pointer, cw: cint, ch: cint){.cdecl, +proc gfxPrimitivesSetFont*(fontdata: pointer, cw: cint, ch: cint){.cdecl, importc: "gfxPrimitivesSetFont", dynlib: gfxLibName.} # # @@ -271,132 +271,132 @@ proc imageFilterMMXon*(){.cdecl, importc: "SDL_imageFilterMMXon", # -1 Error (internal error, parameter error) # # SDL_imageFilterAdd: D = saturation255(S1 + S2) -proc imageFilterAdd*(Src1: cstring, Src2: cstring, Dest: cstring, len: cint): cint{. +proc imageFilterAdd*(src1: cstring, src2: cstring, dest: cstring, len: cint): cint{. cdecl, importc: "SDL_imageFilterAdd", dynlib: gfxLibName.} # SDL_imageFilterMean: D = S1/2 + S2/2 -proc imageFilterMean*(Src1: cstring, Src2: cstring, Dest: cstring, len: cint): cint{. +proc imageFilterMean*(src1: cstring, src2: cstring, dest: cstring, len: cint): cint{. cdecl, importc: "SDL_imageFilterMean", dynlib: gfxLibName.} # SDL_imageFilterSub: D = saturation0(S1 - S2) -proc imageFilterSub*(Src1: cstring, Src2: cstring, Dest: cstring, len: cint): cint{. +proc imageFilterSub*(src1: cstring, src2: cstring, dest: cstring, len: cint): cint{. cdecl, importc: "SDL_imageFilterSub", dynlib: gfxLibName.} # SDL_imageFilterAbsDiff: D = | S1 - S2 | -proc imageFilterAbsDiff*(Src1: cstring, Src2: cstring, Dest: cstring, len: cint): cint{. +proc imageFilterAbsDiff*(src1: cstring, src2: cstring, dest: cstring, len: cint): cint{. cdecl, importc: "SDL_imageFilterAbsDiff", dynlib: gfxLibName.} # SDL_imageFilterMult: D = saturation(S1 * S2) -proc imageFilterMult*(Src1: cstring, Src2: cstring, Dest: cstring, len: cint): cint{. +proc imageFilterMult*(src1: cstring, src2: cstring, dest: cstring, len: cint): cint{. cdecl, importc: "SDL_imageFilterMult", dynlib: gfxLibName.} # SDL_imageFilterMultNor: D = S1 * S2 (non-MMX) -proc imageFilterMultNor*(Src1: cstring, Src2: cstring, Dest: cstring, len: cint): cint{. +proc imageFilterMultNor*(src1: cstring, src2: cstring, dest: cstring, len: cint): cint{. cdecl, importc: "SDL_imageFilterMultNor", dynlib: gfxLibName.} # SDL_imageFilterMultDivby2: D = saturation255(S1/2 * S2) -proc imageFilterMultDivby2*(Src1: cstring, Src2: cstring, Dest: cstring, +proc imageFilterMultDivby2*(src1: cstring, src2: cstring, dest: cstring, len: cint): cint{.cdecl, importc: "SDL_imageFilterMultDivby2", dynlib: gfxLibName.} # SDL_imageFilterMultDivby4: D = saturation255(S1/2 * S2/2) -proc imageFilterMultDivby4*(Src1: cstring, Src2: cstring, Dest: cstring, +proc imageFilterMultDivby4*(src1: cstring, src2: cstring, dest: cstring, len: cint): cint{.cdecl, importc: "SDL_imageFilterMultDivby4", dynlib: gfxLibName.} # SDL_imageFilterBitAnd: D = S1 & S2 -proc imageFilterBitAnd*(Src1: cstring, Src2: cstring, Dest: cstring, len: cint): cint{. +proc imageFilterBitAnd*(src1: cstring, src2: cstring, dest: cstring, len: cint): cint{. cdecl, importc: "SDL_imageFilterBitAnd", dynlib: gfxLibName.} # SDL_imageFilterBitOr: D = S1 | S2 -proc imageFilterBitOr*(Src1: cstring, Src2: cstring, Dest: cstring, len: cint): cint{. +proc imageFilterBitOr*(src1: cstring, src2: cstring, dest: cstring, len: cint): cint{. cdecl, importc: "SDL_imageFilterBitOr", dynlib: gfxLibName.} # SDL_imageFilterDiv: D = S1 / S2 (non-MMX) -proc imageFilterDiv*(Src1: cstring, Src2: cstring, Dest: cstring, len: cint): cint{. +proc imageFilterDiv*(src1: cstring, src2: cstring, dest: cstring, len: cint): cint{. cdecl, importc: "SDL_imageFilterDiv", dynlib: gfxLibName.} # SDL_imageFilterBitNegation: D = !S -proc imageFilterBitNegation*(Src1: cstring, Dest: cstring, len: cint): cint{. +proc imageFilterBitNegation*(src1: cstring, dest: cstring, len: cint): cint{. cdecl, importc: "SDL_imageFilterBitNegation", dynlib: gfxLibName.} # SDL_imageFilterAddByte: D = saturation255(S + C) -proc imageFilterAddByte*(Src1: cstring, Dest: cstring, len: cint, C: char): cint{. +proc imageFilterAddByte*(src1: cstring, dest: cstring, len: cint, c: char): cint{. cdecl, importc: "SDL_imageFilterAddByte", dynlib: gfxLibName.} # SDL_imageFilterAddUint: D = saturation255(S + (uint)C) -proc imageFilterAddUint*(Src1: cstring, Dest: cstring, len: cint, C: cint): cint{. +proc imageFilterAddUint*(src1: cstring, dest: cstring, len: cint, c: cint): cint{. cdecl, importc: "SDL_imageFilterAddUint", dynlib: gfxLibName.} # SDL_imageFilterAddByteToHalf: D = saturation255(S/2 + C) -proc imageFilterAddByteToHalf*(Src1: cstring, Dest: cstring, len: cint, C: char): cint{. +proc imageFilterAddByteToHalf*(src1: cstring, dest: cstring, len: cint, c: char): cint{. cdecl, importc: "SDL_imageFilterAddByteToHalf", dynlib: gfxLibName.} # SDL_imageFilterSubByte: D = saturation0(S - C) -proc imageFilterSubByte*(Src1: cstring, Dest: cstring, len: cint, C: char): cint{. +proc imageFilterSubByte*(src1: cstring, dest: cstring, len: cint, c: char): cint{. cdecl, importc: "SDL_imageFilterSubByte", dynlib: gfxLibName.} # SDL_imageFilterSubUint: D = saturation0(S - (uint)C) -proc imageFilterSubUint*(Src1: cstring, Dest: cstring, len: cint, C: cint): cint{. +proc imageFilterSubUint*(src1: cstring, dest: cstring, len: cint, c: cint): cint{. cdecl, importc: "SDL_imageFilterSubUint", dynlib: gfxLibName.} # SDL_imageFilterShiftRight: D = saturation0(S >> N) -proc imageFilterShiftRight*(Src1: cstring, Dest: cstring, len: cint, N: char): cint{. +proc imageFilterShiftRight*(src1: cstring, dest: cstring, len: cint, n: char): cint{. cdecl, importc: "SDL_imageFilterShiftRight", dynlib: gfxLibName.} # SDL_imageFilterShiftRightUint: D = saturation0((uint)S >> N) -proc imageFilterShiftRightUint*(Src1: cstring, Dest: cstring, len: cint, N: char): cint{. +proc imageFilterShiftRightUint*(src1: cstring, dest: cstring, len: cint, n: char): cint{. cdecl, importc: "SDL_imageFilterShiftRightUint", dynlib: gfxLibName.} # SDL_imageFilterMultByByte: D = saturation255(S * C) -proc imageFilterMultByByte*(Src1: cstring, Dest: cstring, len: cint, C: char): cint{. +proc imageFilterMultByByte*(src1: cstring, dest: cstring, len: cint, c: char): cint{. cdecl, importc: "SDL_imageFilterMultByByte", dynlib: gfxLibName.} # SDL_imageFilterShiftRightAndMultByByte: D = saturation255((S >> N) * C) -proc imageFilterShiftRightAndMultByByte*(Src1: cstring, Dest: cstring, len: cint, - N: char, C: char): cint{.cdecl, +proc imageFilterShiftRightAndMultByByte*(src1: cstring, dest: cstring, len: cint, + n: char, c: char): cint{.cdecl, importc: "SDL_imageFilterShiftRightAndMultByByte", dynlib: gfxLibName.} # SDL_imageFilterShiftLeftByte: D = (S << N) -proc imageFilterShiftLeftByte*(Src1: cstring, Dest: cstring, len: cint, N: char): cint{. +proc imageFilterShiftLeftByte*(src1: cstring, dest: cstring, len: cint, n: char): cint{. cdecl, importc: "SDL_imageFilterShiftLeftByte", dynlib: gfxLibName.} # SDL_imageFilterShiftLeftUint: D = ((uint)S << N) -proc imageFilterShiftLeftUint*(Src1: cstring, Dest: cstring, len: cint, N: char): cint{. +proc imageFilterShiftLeftUint*(src1: cstring, dest: cstring, len: cint, n: char): cint{. cdecl, importc: "SDL_imageFilterShiftLeftUint", dynlib: gfxLibName.} # SDL_imageFilterShiftLeft: D = saturation255(S << N) -proc imageFilterShiftLeft*(Src1: cstring, Dest: cstring, len: cint, N: char): cint{. +proc imageFilterShiftLeft*(src1: cstring, dest: cstring, len: cint, n: char): cint{. cdecl, importc: "SDL_imageFilterShiftLeft", dynlib: gfxLibName.} # SDL_imageFilterBinarizeUsingThreshold: D = S >= T ? 255:0 -proc imageFilterBinarizeUsingThreshold*(Src1: cstring, Dest: cstring, len: cint, - T: char): cint{.cdecl, +proc imageFilterBinarizeUsingThreshold*(src1: cstring, dest: cstring, len: cint, + t: char): cint{.cdecl, importc: "SDL_imageFilterBinarizeUsingThreshold", dynlib: gfxLibName.} # SDL_imageFilterClipToRange: D = (S >= Tmin) & (S <= Tmax) 255:0 -proc imageFilterClipToRange*(Src1: cstring, Dest: cstring, len: cint, Tmin: int8, - Tmax: int8): cint{.cdecl, +proc imageFilterClipToRange*(src1: cstring, dest: cstring, len: cint, tmin: int8, + tmax: int8): cint{.cdecl, importc: "SDL_imageFilterClipToRange", dynlib: gfxLibName.} # SDL_imageFilterNormalizeLinear: D = saturation255((Nmax - Nmin)/(Cmax - Cmin)*(S - Cmin) + Nmin) -proc imageFilterNormalizeLinear*(Src1: cstring, Dest: cstring, len: cint, - Cmin: cint, Cmax: cint, Nmin: cint, Nmax: cint): cint{. +proc imageFilterNormalizeLinear*(src1: cstring, dest: cstring, len: cint, + cmin: cint, cmax: cint, nmin: cint, nmax: cint): cint{. cdecl, importc: "SDL_imageFilterNormalizeLinear", dynlib: gfxLibName.} # !!! NO C-ROUTINE FOR THESE FUNCTIONS YET !!! # SDL_imageFilterConvolveKernel3x3Divide: Dij = saturation0and255( ... ) -proc imageFilterConvolveKernel3x3Divide*(Src: cstring, Dest: cstring, rows: cint, - columns: cint, Kernel: pointer, Divisor: int8): cint{.cdecl, +proc imageFilterConvolveKernel3x3Divide*(src: cstring, dest: cstring, rows: cint, + columns: cint, kernel: pointer, divisor: int8): cint{.cdecl, importc: "SDL_imageFilterConvolveKernel3x3Divide", dynlib: gfxLibName.} # SDL_imageFilterConvolveKernel5x5Divide: Dij = saturation0and255( ... ) -proc imageFilterConvolveKernel5x5Divide*(Src: cstring, Dest: cstring, rows: cint, - columns: cint, Kernel: pointer, Divisor: int8): cint{.cdecl, +proc imageFilterConvolveKernel5x5Divide*(src: cstring, dest: cstring, rows: cint, + columns: cint, kernel: pointer, divisor: int8): cint{.cdecl, importc: "SDL_imageFilterConvolveKernel5x5Divide", dynlib: gfxLibName.} # SDL_imageFilterConvolveKernel7x7Divide: Dij = saturation0and255( ... ) -proc imageFilterConvolveKernel7x7Divide*(Src: cstring, Dest: cstring, rows: cint, - columns: cint, Kernel: pointer, Divisor: int8): cint{.cdecl, +proc imageFilterConvolveKernel7x7Divide*(src: cstring, dest: cstring, rows: cint, + columns: cint, kernel: pointer, divisor: int8): cint{.cdecl, importc: "SDL_imageFilterConvolveKernel7x7Divide", dynlib: gfxLibName.} # SDL_imageFilterConvolveKernel9x9Divide: Dij = saturation0and255( ... ) -proc imageFilterConvolveKernel9x9Divide*(Src: cstring, Dest: cstring, rows: cint, - columns: cint, Kernel: pointer, Divisor: int8): cint{.cdecl, +proc imageFilterConvolveKernel9x9Divide*(src: cstring, dest: cstring, rows: cint, + columns: cint, kernel: pointer, divisor: int8): cint{.cdecl, importc: "SDL_imageFilterConvolveKernel9x9Divide", dynlib: gfxLibName.} # SDL_imageFilterConvolveKernel3x3ShiftRight: Dij = saturation0and255( ... ) -proc imageFilterConvolveKernel3x3ShiftRight*(Src: cstring, Dest: cstring, - rows: cint, columns: cint, Kernel: pointer, NRightShift: char): cint{.cdecl, +proc imageFilterConvolveKernel3x3ShiftRight*(src: cstring, dest: cstring, + rows: cint, columns: cint, kernel: pointer, nRightShift: char): cint{.cdecl, importc: "SDL_imageFilterConvolveKernel3x3ShiftRight", dynlib: gfxLibName.} # SDL_imageFilterConvolveKernel5x5ShiftRight: Dij = saturation0and255( ... ) -proc imageFilterConvolveKernel5x5ShiftRight*(Src: cstring, Dest: cstring, - rows: cint, columns: cint, Kernel: pointer, NRightShift: char): cint{.cdecl, +proc imageFilterConvolveKernel5x5ShiftRight*(src: cstring, dest: cstring, + rows: cint, columns: cint, kernel: pointer, nRightShift: char): cint{.cdecl, importc: "SDL_imageFilterConvolveKernel5x5ShiftRight", dynlib: gfxLibName.} # SDL_imageFilterConvolveKernel7x7ShiftRight: Dij = saturation0and255( ... ) -proc imageFilterConvolveKernel7x7ShiftRight*(Src: cstring, Dest: cstring, - rows: cint, columns: cint, Kernel: pointer, NRightShift: char): cint{.cdecl, +proc imageFilterConvolveKernel7x7ShiftRight*(src: cstring, dest: cstring, + rows: cint, columns: cint, kernel: pointer, nRightShift: char): cint{.cdecl, importc: "SDL_imageFilterConvolveKernel7x7ShiftRight", dynlib: gfxLibName.} # SDL_imageFilterConvolveKernel9x9ShiftRight: Dij = saturation0and255( ... ) -proc imageFilterConvolveKernel9x9ShiftRight*(Src: cstring, Dest: cstring, - rows: cint, columns: cint, Kernel: pointer, NRightShift: char): cint{.cdecl, +proc imageFilterConvolveKernel9x9ShiftRight*(src: cstring, dest: cstring, + rows: cint, columns: cint, kernel: pointer, nRightShift: char): cint{.cdecl, importc: "SDL_imageFilterConvolveKernel9x9ShiftRight", dynlib: gfxLibName.} # SDL_imageFilterSobelX: Dij = saturation255( ... ) -proc imageFilterSobelX*(Src: cstring, Dest: cstring, rows: cint, columns: cint): cint{. +proc imageFilterSobelX*(src: cstring, dest: cstring, rows: cint, columns: cint): cint{. cdecl, importc: "SDL_imageFilterSobelX", dynlib: gfxLibName.} # SDL_imageFilterSobelXShiftRight: Dij = saturation255( ... ) -proc imageFilterSobelXShiftRight*(Src: cstring, Dest: cstring, rows: cint, - columns: cint, NRightShift: char): cint{.cdecl, +proc imageFilterSobelXShiftRight*(src: cstring, dest: cstring, rows: cint, + columns: cint, nRightShift: char): cint{.cdecl, importc: "SDL_imageFilterSobelXShiftRight", dynlib: gfxLibName.} # Align/restore stack to 32 byte boundary -- Functionality untested! -- proc imageFilterAlignStack*(){.cdecl, importc: "SDL_imageFilterAlignStack", diff --git a/lib/wrappers/sdl/sdl_image.nim b/lib/wrappers/sdl/sdl_image.nim index 2bd731506..9c56e6a46 100644 --- a/lib/wrappers/sdl/sdl_image.nim +++ b/lib/wrappers/sdl/sdl_image.nim @@ -148,13 +148,13 @@ const # This macro can be used to fill a version structure with the compile-time # version of the SDL_image library. -proc IMAGE_VERSION*(X: var TVersion) +proc imageVersion*(x: var Tversion) # This function gets the version of the dynamically linked SDL_image library. # it should NOT be used to fill a version structure, instead you should # use the SDL_IMAGE_VERSION() macro. # -proc IMG_Linked_Version*(): Pversion{.importc: "IMG_Linked_Version", - dynlib: ImageLibName.} +proc imgLinkedVersion*(): Pversion{.importc: "IMG_Linked_Version", + dynlib: ImageLibName.} # Load an image from an SDL data source. # The 'type' may be one of: "BMP", "GIF", "PNG", etc. # @@ -170,74 +170,74 @@ const IMG_INIT_TIF* = 0x00000004 IMG_INIT_WEBP* = 0x00000008 -proc IMG_Init*(flags: cint): int {.cdecl, importc: "IMG_Init", +proc imgInit*(flags: cint): int {.cdecl, importc: "IMG_Init", dynlib: ImageLibName.} -proc IMG_Quit*() {.cdecl, importc: "IMG_Quit", +proc imgQuit*() {.cdecl, importc: "IMG_Quit", dynlib: ImageLibName.} -proc IMG_LoadTyped_RW*(src: PRWops, freesrc: cint, theType: cstring): PSurface{. +proc imgLoadTypedRW*(src: PRWops, freesrc: cint, theType: cstring): PSurface{. cdecl, importc: "IMG_LoadTyped_RW", dynlib: ImageLibName.} # Convenience functions -proc IMG_Load*(theFile: cstring): PSurface{.cdecl, importc: "IMG_Load", +proc imgLoad*(theFile: cstring): PSurface{.cdecl, importc: "IMG_Load", dynlib: ImageLibName.} -proc IMG_Load_RW*(src: PRWops, freesrc: cint): PSurface{.cdecl, +proc imgLoadRW*(src: PRWops, freesrc: cint): PSurface{.cdecl, importc: "IMG_Load_RW", dynlib: ImageLibName.} # Invert the alpha of a surface for use with OpenGL # This function is now a no-op, and only provided for backwards compatibility. -proc IMG_InvertAlpha*(theOn: cint): cint{.cdecl, importc: "IMG_InvertAlpha", +proc imgInvertAlpha*(theOn: cint): cint{.cdecl, importc: "IMG_InvertAlpha", dynlib: ImageLibName.} # Functions to detect a file type, given a seekable source -proc IMG_isBMP*(src: PRWops): cint{.cdecl, importc: "IMG_isBMP", +proc imgIsBMP*(src: PRWops): cint{.cdecl, importc: "IMG_isBMP", dynlib: ImageLibName.} -proc IMG_isGIF*(src: PRWops): cint{.cdecl, importc: "IMG_isGIF", +proc imgIsGIF*(src: PRWops): cint{.cdecl, importc: "IMG_isGIF", dynlib: ImageLibName.} -proc IMG_isJPG*(src: PRWops): cint{.cdecl, importc: "IMG_isJPG", +proc imgIsJPG*(src: PRWops): cint{.cdecl, importc: "IMG_isJPG", dynlib: ImageLibName.} -proc IMG_isLBM*(src: PRWops): cint{.cdecl, importc: "IMG_isLBM", +proc imgIsLBM*(src: PRWops): cint{.cdecl, importc: "IMG_isLBM", dynlib: ImageLibName.} -proc IMG_isPCX*(src: PRWops): cint{.cdecl, importc: "IMG_isPCX", +proc imgIsPCX*(src: PRWops): cint{.cdecl, importc: "IMG_isPCX", dynlib: ImageLibName.} -proc IMG_isPNG*(src: PRWops): cint{.cdecl, importc: "IMG_isPNG", +proc imgIsPNG*(src: PRWops): cint{.cdecl, importc: "IMG_isPNG", dynlib: ImageLibName.} -proc IMG_isPNM*(src: PRWops): cint{.cdecl, importc: "IMG_isPNM", +proc imgIsPNM*(src: PRWops): cint{.cdecl, importc: "IMG_isPNM", dynlib: ImageLibName.} -proc IMG_isTIF*(src: PRWops): cint{.cdecl, importc: "IMG_isTIF", +proc imgIsTIF*(src: PRWops): cint{.cdecl, importc: "IMG_isTIF", dynlib: ImageLibName.} -proc IMG_isXCF*(src: PRWops): cint{.cdecl, importc: "IMG_isXCF", +proc imgIsXCF*(src: PRWops): cint{.cdecl, importc: "IMG_isXCF", dynlib: ImageLibName.} -proc IMG_isXPM*(src: PRWops): cint{.cdecl, importc: "IMG_isXPM", +proc imgIsXPM*(src: PRWops): cint{.cdecl, importc: "IMG_isXPM", dynlib: ImageLibName.} -proc IMG_isXV*(src: PRWops): cint{.cdecl, importc: "IMG_isXV", +proc imgIsXV*(src: PRWops): cint{.cdecl, importc: "IMG_isXV", dynlib: ImageLibName.} # Individual loading functions -proc IMG_LoadBMP_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadBMP_RW", +proc imgLoadBMP_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadBMP_RW", dynlib: ImageLibName.} -proc IMG_LoadGIF_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadGIF_RW", +proc imgLoadGIF_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadGIF_RW", dynlib: ImageLibName.} -proc IMG_LoadJPG_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadJPG_RW", +proc imgLoadJPG_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadJPG_RW", dynlib: ImageLibName.} -proc IMG_LoadLBM_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadLBM_RW", +proc imgLoadLBM_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadLBM_RW", dynlib: ImageLibName.} -proc IMG_LoadPCX_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadPCX_RW", +proc imgLoadPCX_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadPCX_RW", dynlib: ImageLibName.} -proc IMG_LoadPNM_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadPNM_RW", +proc imgLoadPNM_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadPNM_RW", dynlib: ImageLibName.} -proc IMG_LoadPNG_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadPNG_RW", +proc imgLoadPNG_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadPNG_RW", dynlib: ImageLibName.} -proc IMG_LoadTGA_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadTGA_RW", +proc imgLoadTGA_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadTGA_RW", dynlib: ImageLibName.} -proc IMG_LoadTIF_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadTIF_RW", +proc imgLoadTIF_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadTIF_RW", dynlib: ImageLibName.} -proc IMG_LoadXCF_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadXCF_RW", +proc imgLoadXCF_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadXCF_RW", dynlib: ImageLibName.} -proc IMG_LoadXPM_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadXPM_RW", +proc imgLoadXPM_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadXPM_RW", dynlib: ImageLibName.} -proc IMG_LoadXV_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadXV_RW", +proc imgLoadXV_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadXV_RW", dynlib: ImageLibName.} -proc IMG_ReadXPMFromArray*(xpm: cstringArray): PSurface{.cdecl, +proc imgReadXPMFromArray*(xpm: cstringArray): PSurface{.cdecl, importc: "IMG_ReadXPMFromArray", dynlib: ImageLibName.} -proc IMAGE_VERSION(X: var TVersion) = - X.major = IMAGE_MAJOR_VERSION - X.minor = IMAGE_MINOR_VERSION - X.patch = IMAGE_PATCHLEVEL +proc imageVersion(x: var Tversion) = + x.major = IMAGE_MAJOR_VERSION + x.minor = IMAGE_MINOR_VERSION + x.patch = IMAGE_PATCHLEVEL diff --git a/lib/wrappers/sdl/sdl_mixer.nim b/lib/wrappers/sdl/sdl_mixer.nim index 9199a9271..33a71508a 100644 --- a/lib/wrappers/sdl/sdl_mixer.nim +++ b/lib/wrappers/sdl/sdl_mixer.nim @@ -196,7 +196,7 @@ type #music_cmd.h types PWAVStream* = ptr TWAVStream TWAVStream*{.final.} = object #playmidi.h types - wavefp*: Pointer + wavefp*: pointer start*: int32 stop*: int32 cvt*: TAudioCVT @@ -223,8 +223,8 @@ type #music_cmd.h types volume*: int32 #vf: OggVorbis_File; section*: int32 cvt*: TAudioCVT - len_available*: int32 - snd_available*: pointer + lenAvailable*: int32 + sndAvailable*: pointer TErrorEnum* = enum MMERR_OPENING_FILE, MMERR_OUT_OF_MEMORY, MMERR_DYNAMIC_LINKING, @@ -255,7 +255,7 @@ type #music_cmd.h types TChunk*{.final.} = object allocated*: cint abuf*: pointer - alen*: Uint32 + alen*: uint32 volume*: byte # Per-sample volume, 0-128 TFading* = enum @@ -272,18 +272,18 @@ type #music_cmd.h types # fade_steps : integer; # error : integer; - TMixFunction* = proc (udata, stream: pointer, length: cint): Pointer{. + TMixFunction* = proc (udata, stream: pointer, length: cint): pointer{. cdecl.} # This macro can be used to fill a version structure with the compile-time # version of the SDL_mixer library. -proc VERSION*(X: var sdl.TVersion) +proc version*(x: var sdl.Tversion) # This function gets the version of the dynamically linked SDL_mixer library. # It should NOT be used to fill a version structure, instead you should use the # SDL_MIXER_VERSION() macro. -proc Linked_Version*(): sdl.Pversion{.cdecl, importc: "Mix_Linked_Version", +proc linkedVersion*(): sdl.Pversion{.cdecl, importc: "Mix_Linked_Version", dynlib: MixerLibName.} # Open the mixer with a certain audio format -proc OpenAudio*(frequency: cint, format: Uint16, channels: cint, +proc openAudio*(frequency: cint, format: uint16, channels: cint, chunksize: cint): cint{.cdecl, importc: "Mix_OpenAudio", dynlib: MixerLibName.} # Dynamically change the number of channels managed by the mixer. @@ -291,194 +291,194 @@ proc OpenAudio*(frequency: cint, format: Uint16, channels: cint, # stopped. # This function returns the new number of allocated channels. # -proc AllocateChannels*(numchannels: cint): cint{.cdecl, +proc allocateChannels*(numchannels: cint): cint{.cdecl, importc: "Mix_AllocateChannels", dynlib: MixerLibName.} # Find out what the actual audio device parameters are. # This function returns 1 if the audio has been opened, 0 otherwise. # -proc QuerySpec*(frequency: var cint, format: var Uint16, channels: var cint): cint{. +proc querySpec*(frequency: var cint, format: var uint16, channels: var cint): cint{. cdecl, importc: "Mix_QuerySpec", dynlib: MixerLibName.} # Load a wave file or a music (.mod .s3m .it .xm) file -proc LoadWAV_RW*(src: PRWops, freesrc: cint): PChunk{.cdecl, +proc loadWAV_RW*(src: PRWops, freesrc: cint): PChunk{.cdecl, importc: "Mix_LoadWAV_RW", dynlib: MixerLibName.} -proc LoadWAV*(filename: cstring): PChunk -proc LoadMUS*(filename: cstring): PMusic{.cdecl, importc: "Mix_LoadMUS", +proc loadWAV*(filename: cstring): PChunk +proc loadMUS*(filename: cstring): PMusic{.cdecl, importc: "Mix_LoadMUS", dynlib: MixerLibName.} # Load a wave file of the mixer format from a memory buffer -proc QuickLoad_WAV*(mem: pointer): PChunk{.cdecl, +proc quickLoadWAV*(mem: pointer): PChunk{.cdecl, importc: "Mix_QuickLoad_WAV", dynlib: MixerLibName.} # Free an audio chunk previously loaded -proc FreeChunk*(chunk: PChunk){.cdecl, importc: "Mix_FreeChunk", +proc freeChunk*(chunk: PChunk){.cdecl, importc: "Mix_FreeChunk", dynlib: MixerLibName.} -proc FreeMusic*(music: PMusic){.cdecl, importc: "Mix_FreeMusic", +proc freeMusic*(music: PMusic){.cdecl, importc: "Mix_FreeMusic", dynlib: MixerLibName.} # Find out the music format of a mixer music, or the currently playing # music, if 'music' is NULL. -proc GetMusicType*(music: PMusic): TMusicType{.cdecl, +proc getMusicType*(music: PMusic): TMusicType{.cdecl, importc: "Mix_GetMusicType", dynlib: MixerLibName.} # Set a function that is called after all mixing is performed. # This can be used to provide real-time visual display of the audio stream # or add a custom mixer filter for the stream data. # -proc SetPostMix*(mix_func: TMixFunction, arg: Pointer){.cdecl, +proc setPostMix*(mixFunc: TMixFunction, arg: pointer){.cdecl, importc: "Mix_SetPostMix", dynlib: MixerLibName.} # Add your own music player or additional mixer function. # If 'mix_func' is NULL, the default music player is re-enabled. # -proc HookMusic*(mix_func: TMixFunction, arg: Pointer){.cdecl, +proc hookMusic*(mixFunc: TMixFunction, arg: pointer){.cdecl, importc: "Mix_HookMusic", dynlib: MixerLibName.} # Add your own callback when the music has finished playing. # -proc HookMusicFinished*(music_finished: Pointer){.cdecl, +proc hookMusicFinished*(musicFinished: pointer){.cdecl, importc: "Mix_HookMusicFinished", dynlib: MixerLibName.} # Get a pointer to the user data for the current music hook -proc GetMusicHookData*(): Pointer{.cdecl, importc: "Mix_GetMusicHookData", +proc getMusicHookData*(): pointer{.cdecl, importc: "Mix_GetMusicHookData", dynlib: MixerLibName.} #* Add your own callback when a channel has finished playing. NULL # * to disable callback.* type - TChannel_finished* = proc (channel: cint){.cdecl.} + TChannelFinished* = proc (channel: cint){.cdecl.} -proc ChannelFinished*(channel_finished: TChannel_finished){.cdecl, +proc channelFinished*(channelFinished: TChannelFinished){.cdecl, importc: "Mix_ChannelFinished", dynlib: MixerLibName.} const CHANNEL_POST* = - 2 type - TEffectFunc* = proc (chan: cint, stream: Pointer, length: cint, - udata: Pointer): Pointer{.cdecl.} - TEffectDone* = proc (chan: cint, udata: Pointer): Pointer{.cdecl.} -proc RegisterEffect*(chan: cint, f: TEffectFunc, d: TEffectDone, - arg: Pointer): cint{.cdecl, + TEffectFunc* = proc (chan: cint, stream: pointer, length: cint, + udata: pointer): pointer{.cdecl.} + TEffectDone* = proc (chan: cint, udata: pointer): pointer{.cdecl.} +proc registerEffect*(chan: cint, f: TEffectFunc, d: TEffectDone, + arg: pointer): cint{.cdecl, importc: "Mix_RegisterEffect", dynlib: MixerLibName.} -proc UnregisterEffect*(channel: cint, f: TEffectFunc): cint{.cdecl, +proc unregisterEffect*(channel: cint, f: TEffectFunc): cint{.cdecl, importc: "Mix_UnregisterEffect", dynlib: MixerLibName.} -proc UnregisterAllEffects*(channel: cint): cint{.cdecl, +proc unregisterAllEffects*(channel: cint): cint{.cdecl, importc: "Mix_UnregisterAllEffects", dynlib: MixerLibName.} const EFFECTSMAXSPEED* = "MIX_EFFECTSMAXSPEED" -proc SetPanning*(channel: cint, left: byte, right: byte): cint{.cdecl, +proc setPanning*(channel: cint, left: byte, right: byte): cint{.cdecl, importc: "Mix_SetPanning", dynlib: MixerLibName.} -proc SetPosition*(channel: cint, angle: int16, distance: byte): cint{.cdecl, +proc setPosition*(channel: cint, angle: int16, distance: byte): cint{.cdecl, importc: "Mix_SetPosition", dynlib: MixerLibName.} -proc SetDistance*(channel: cint, distance: byte): cint{.cdecl, +proc setDistance*(channel: cint, distance: byte): cint{.cdecl, importc: "Mix_SetDistance", dynlib: MixerLibName.} -proc SetReverseStereo*(channel: cint, flip: cint): cint{.cdecl, +proc setReverseStereo*(channel: cint, flip: cint): cint{.cdecl, importc: "Mix_SetReverseStereo", dynlib: MixerLibName.} -proc ReserveChannels*(num: cint): cint{.cdecl, importc: "Mix_ReserveChannels", +proc reserveChannels*(num: cint): cint{.cdecl, importc: "Mix_ReserveChannels", dynlib: MixerLibName.} -proc GroupChannel*(which: cint, tag: cint): cint{.cdecl, +proc groupChannel*(which: cint, tag: cint): cint{.cdecl, importc: "Mix_GroupChannel", dynlib: MixerLibName.} -proc GroupChannels*(`from`: cint, `to`: cint, tag: cint): cint{.cdecl, +proc groupChannels*(`from`: cint, `to`: cint, tag: cint): cint{.cdecl, importc: "Mix_GroupChannels", dynlib: MixerLibName.} -proc GroupAvailable*(tag: cint): cint{.cdecl, importc: "Mix_GroupAvailable", +proc groupAvailable*(tag: cint): cint{.cdecl, importc: "Mix_GroupAvailable", dynlib: MixerLibName.} -proc GroupCount*(tag: cint): cint{.cdecl, importc: "Mix_GroupCount", +proc groupCount*(tag: cint): cint{.cdecl, importc: "Mix_GroupCount", dynlib: MixerLibName.} -proc GroupOldest*(tag: cint): cint{.cdecl, importc: "Mix_GroupOldest", +proc groupOldest*(tag: cint): cint{.cdecl, importc: "Mix_GroupOldest", dynlib: MixerLibName.} -proc GroupNewer*(tag: cint): cint{.cdecl, importc: "Mix_GroupNewer", +proc groupNewer*(tag: cint): cint{.cdecl, importc: "Mix_GroupNewer", dynlib: MixerLibName.} -proc PlayChannelTimed*(channel: cint, chunk: PChunk, loops: cint, +proc playChannelTimed*(channel: cint, chunk: PChunk, loops: cint, ticks: cint): cint{.cdecl, importc: "Mix_PlayChannelTimed", dynlib: MixerLibName.} -proc PlayChannel*(channel: cint, chunk: PChunk, loops: cint): cint -proc PlayMusic*(music: PMusic, loops: cint): cint{.cdecl, +proc playChannel*(channel: cint, chunk: PChunk, loops: cint): cint +proc playMusic*(music: PMusic, loops: cint): cint{.cdecl, importc: "Mix_PlayMusic", dynlib: MixerLibName.} -proc FadeInMusic*(music: PMusic, loops: cint, ms: cint): cint{.cdecl, +proc fadeInMusic*(music: PMusic, loops: cint, ms: cint): cint{.cdecl, importc: "Mix_FadeInMusic", dynlib: MixerLibName.} -proc FadeInChannelTimed*(channel: cint, chunk: PChunk, loops: cint, +proc fadeInChannelTimed*(channel: cint, chunk: PChunk, loops: cint, ms: cint, ticks: cint): cint{.cdecl, importc: "Mix_FadeInChannelTimed", dynlib: MixerLibName.} -proc FadeInChannel*(channel: cint, chunk: PChunk, loops: cint, ms: cint): cint +proc fadeInChannel*(channel: cint, chunk: PChunk, loops: cint, ms: cint): cint -proc Volume*(channel: cint, volume: cint): cint{.cdecl, importc: "Mix_Volume", +proc volume*(channel: cint, volume: cint): cint{.cdecl, importc: "Mix_Volume", dynlib: MixerLibName.} -proc VolumeChunk*(chunk: PChunk, volume: cint): cint{.cdecl, +proc volumeChunk*(chunk: PChunk, volume: cint): cint{.cdecl, importc: "Mix_VolumeChunk", dynlib: MixerLibName.} -proc VolumeMusic*(volume: cint): cint{.cdecl, importc: "Mix_VolumeMusic", +proc volumeMusic*(volume: cint): cint{.cdecl, importc: "Mix_VolumeMusic", dynlib: MixerLibName.} -proc HaltChannel*(channel: cint): cint{.cdecl, importc: "Mix_HaltChannel", +proc haltChannel*(channel: cint): cint{.cdecl, importc: "Mix_HaltChannel", dynlib: MixerLibName.} -proc HaltGroup*(tag: cint): cint{.cdecl, importc: "Mix_HaltGroup", +proc haltGroup*(tag: cint): cint{.cdecl, importc: "Mix_HaltGroup", dynlib: MixerLibName.} -proc HaltMusic*(): cint{.cdecl, importc: "Mix_HaltMusic", +proc haltMusic*(): cint{.cdecl, importc: "Mix_HaltMusic", dynlib: MixerLibName.} # Change the expiration delay for a particular channel. # The sample will stop playing after the 'ticks' milliseconds have elapsed, # or remove the expiration if 'ticks' is -1 # -proc ExpireChannel*(channel: cint, ticks: cint): cint{.cdecl, +proc expireChannel*(channel: cint, ticks: cint): cint{.cdecl, importc: "Mix_ExpireChannel", dynlib: MixerLibName.} # Halt a channel, fading it out progressively till it's silent # The ms parameter indicates the number of milliseconds the fading # will take. # -proc FadeOutChannel*(which: cint, ms: cint): cint{.cdecl, +proc fadeOutChannel*(which: cint, ms: cint): cint{.cdecl, importc: "Mix_FadeOutChannel", dynlib: MixerLibName.} -proc FadeOutGroup*(tag: cint, ms: cint): cint{.cdecl, +proc fadeOutGroup*(tag: cint, ms: cint): cint{.cdecl, importc: "Mix_FadeOutGroup", dynlib: MixerLibName.} -proc FadeOutMusic*(ms: cint): cint{.cdecl, importc: "Mix_FadeOutMusic", +proc fadeOutMusic*(ms: cint): cint{.cdecl, importc: "Mix_FadeOutMusic", dynlib: MixerLibName.} # Query the fading status of a channel -proc FadingMusic*(): TFading{.cdecl, importc: "Mix_FadingMusic", +proc fadingMusic*(): TFading{.cdecl, importc: "Mix_FadingMusic", dynlib: MixerLibName.} -proc FadingChannel*(which: cint): TFading{.cdecl, +proc fadingChannel*(which: cint): TFading{.cdecl, importc: "Mix_FadingChannel", dynlib: MixerLibName.} -proc Pause*(channel: cint){.cdecl, importc: "Mix_Pause", dynlib: MixerLibName.} -proc Resume*(channel: cint){.cdecl, importc: "Mix_Resume", +proc pause*(channel: cint){.cdecl, importc: "Mix_Pause", dynlib: MixerLibName.} +proc resume*(channel: cint){.cdecl, importc: "Mix_Resume", dynlib: MixerLibName.} -proc Paused*(channel: cint): cint{.cdecl, importc: "Mix_Paused", +proc paused*(channel: cint): cint{.cdecl, importc: "Mix_Paused", dynlib: MixerLibName.} -proc PauseMusic*(){.cdecl, importc: "Mix_PauseMusic", dynlib: MixerLibName.} -proc ResumeMusic*(){.cdecl, importc: "Mix_ResumeMusic", dynlib: MixerLibName.} -proc RewindMusic*(){.cdecl, importc: "Mix_RewindMusic", dynlib: MixerLibName.} -proc PausedMusic*(): cint{.cdecl, importc: "Mix_PausedMusic", +proc pauseMusic*(){.cdecl, importc: "Mix_PauseMusic", dynlib: MixerLibName.} +proc resumeMusic*(){.cdecl, importc: "Mix_ResumeMusic", dynlib: MixerLibName.} +proc rewindMusic*(){.cdecl, importc: "Mix_RewindMusic", dynlib: MixerLibName.} +proc pausedMusic*(): cint{.cdecl, importc: "Mix_PausedMusic", dynlib: MixerLibName.} -proc SetMusicPosition*(position: float64): cint{.cdecl, +proc setMusicPosition*(position: float64): cint{.cdecl, importc: "Mix_SetMusicPosition", dynlib: MixerLibName.} -proc Playing*(channel: cint): cint{.cdecl, importc: "Mix_Playing", +proc playing*(channel: cint): cint{.cdecl, importc: "Mix_Playing", dynlib: MixerLibName.} -proc PlayingMusic*(): cint{.cdecl, importc: "Mix_PlayingMusic", +proc playingMusic*(): cint{.cdecl, importc: "Mix_PlayingMusic", dynlib: MixerLibName.} -proc SetMusicCMD*(command: cstring): cint{.cdecl, importc: "Mix_SetMusicCMD", +proc setMusicCMD*(command: cstring): cint{.cdecl, importc: "Mix_SetMusicCMD", dynlib: MixerLibName.} -proc SetSynchroValue*(value: cint): cint{.cdecl, +proc setSynchroValue*(value: cint): cint{.cdecl, importc: "Mix_SetSynchroValue", dynlib: MixerLibName.} -proc GetSynchroValue*(): cint{.cdecl, importc: "Mix_GetSynchroValue", +proc getSynchroValue*(): cint{.cdecl, importc: "Mix_GetSynchroValue", dynlib: MixerLibName.} -proc GetChunk*(channel: cint): PChunk{.cdecl, importc: "Mix_GetChunk", +proc getChunk*(channel: cint): PChunk{.cdecl, importc: "Mix_GetChunk", dynlib: MixerLibName.} -proc CloseAudio*(){.cdecl, importc: "Mix_CloseAudio", dynlib: MixerLibName.} +proc closeAudio*(){.cdecl, importc: "Mix_CloseAudio", dynlib: MixerLibName.} -proc VERSION(X: var sdl.Tversion) = - X.major = MAJOR_VERSION - X.minor = MINOR_VERSION - X.patch = PATCHLEVEL +proc version(x: var sdl.Tversion) = + x.major = MAJOR_VERSION + x.minor = MINOR_VERSION + x.patch = PATCHLEVEL -proc LoadWAV(filename: cstring): PChunk = - result = LoadWAV_RW(RWFromFile(filename, "rb"), 1) +proc loadWAV(filename: cstring): PChunk = + result = loadWAV_RW(rWFromFile(filename, "rb"), 1) -proc PlayChannel(channel: cint, chunk: PChunk, loops: cint): cint = - result = PlayChannelTimed(channel, chunk, loops, - 1) +proc playChannel(channel: cint, chunk: PChunk, loops: cint): cint = + result = playChannelTimed(channel, chunk, loops, - 1) -proc FadeInChannel(channel: cint, chunk: PChunk, loops: cint, ms: cint): cint = - result = FadeInChannelTimed(channel, chunk, loops, ms, - 1) +proc fadeInChannel(channel: cint, chunk: PChunk, loops: cint, ms: cint): cint = + result = fadeInChannelTimed(channel, chunk, loops, ms, - 1) diff --git a/lib/wrappers/sdl/sdl_mixer_nosmpeg.nim b/lib/wrappers/sdl/sdl_mixer_nosmpeg.nim index 11f00e0a7..7a8c41af1 100644 --- a/lib/wrappers/sdl/sdl_mixer_nosmpeg.nim +++ b/lib/wrappers/sdl/sdl_mixer_nosmpeg.nim @@ -48,7 +48,7 @@ type #music_cmd.h types PWAVStream* = ptr TWAVStream TWAVStream*{.final.} = object #playmidi.h types - wavefp*: Pointer + wavefp*: pointer start*: int32 stop*: int32 cvt*: TAudioCVT @@ -75,8 +75,8 @@ type #music_cmd.h types volume*: cint #vf: OggVorbis_File; section*: cint cvt*: TAudioCVT - len_available*: cint - snd_available*: pointer + lenAvailable*: cint + sndAvailable*: pointer TErrorEnum* = enum MMERR_OPENING_FILE, MMERR_OUT_OF_MEMORY, MMERR_DYNAMIC_LINKING, @@ -107,7 +107,7 @@ type #music_cmd.h types TChunk*{.final.} = object allocated*: cint abuf*: pointer - alen*: Uint32 + alen*: uint32 volume*: byte # Per-sample volume, 0-128 TFading* = enum @@ -118,18 +118,18 @@ type #music_cmd.h types TMusic*{.final.} = object typ*: TMusicType - TMixFunction* = proc (udata, stream: pointer, length: cint): Pointer{. + TMixFunction* = proc (udata, stream: pointer, length: cint): pointer{. cdecl.} # This macro can be used to fill a version structure with the compile-time # version of the SDL_mixer library. -proc VERSION*(X: var sdl.TVersion) +proc version*(x: var sdl.Tversion) # This function gets the version of the dynamically linked SDL_mixer library. # It should NOT be used to fill a version structure, instead you should use the # SDL_MIXER_VERSION() macro. -proc Linked_Version*(): sdl.Pversion{.cdecl, importc: "Mix_Linked_Version", +proc linkedVersion*(): sdl.Pversion{.cdecl, importc: "Mix_Linked_Version", dynlib: MixerLibName.} # Open the mixer with a certain audio format -proc OpenAudio*(frequency: cint, format: Uint16, channels: cint, +proc openAudio*(frequency: cint, format: uint16, channels: cint, chunksize: cint): cint{.cdecl, importc: "Mix_OpenAudio", dynlib: MixerLibName.} # Dynamically change the number of channels managed by the mixer. @@ -137,170 +137,170 @@ proc OpenAudio*(frequency: cint, format: Uint16, channels: cint, # stopped. # This function returns the new number of allocated channels. # -proc AllocateChannels*(numchannels: cint): cint{.cdecl, +proc allocateChannels*(numchannels: cint): cint{.cdecl, importc: "Mix_AllocateChannels", dynlib: MixerLibName.} # Find out what the actual audio device parameters are. # This function returns 1 if the audio has been opened, 0 otherwise. # -proc QuerySpec*(frequency: var cint, format: var Uint16, channels: var cint): cint{. +proc querySpec*(frequency: var cint, format: var uint16, channels: var cint): cint{. cdecl, importc: "Mix_QuerySpec", dynlib: MixerLibName.} # Load a wave file or a music (.mod .s3m .it .xm) file proc LoadWAV_RW*(src: PRWops, freesrc: cint): PChunk{.cdecl, importc: "Mix_LoadWAV_RW", dynlib: MixerLibName.} -proc LoadWAV*(filename: cstring): PChunk -proc LoadMUS*(filename: cstring): PMusic{.cdecl, importc: "Mix_LoadMUS", +proc loadWAV*(filename: cstring): PChunk +proc loadMUS*(filename: cstring): PMusic{.cdecl, importc: "Mix_LoadMUS", dynlib: MixerLibName.} # Load a wave file of the mixer format from a memory buffer -proc QuickLoad_WAV*(mem: pointer): PChunk{.cdecl, +proc quickLoadWAV*(mem: pointer): PChunk{.cdecl, importc: "Mix_QuickLoad_WAV", dynlib: MixerLibName.} # Free an audio chunk previously loaded -proc FreeChunk*(chunk: PChunk){.cdecl, importc: "Mix_FreeChunk", +proc freeChunk*(chunk: PChunk){.cdecl, importc: "Mix_FreeChunk", dynlib: MixerLibName.} -proc FreeMusic*(music: PMusic){.cdecl, importc: "Mix_FreeMusic", +proc freeMusic*(music: PMusic){.cdecl, importc: "Mix_FreeMusic", dynlib: MixerLibName.} # Find out the music format of a mixer music, or the currently playing # music, if 'music' is NULL. -proc GetMusicType*(music: PMusic): TMusicType{.cdecl, +proc getMusicType*(music: PMusic): TMusicType{.cdecl, importc: "Mix_GetMusicType", dynlib: MixerLibName.} # Set a function that is called after all mixing is performed. # This can be used to provide real-time visual display of the audio stream # or add a custom mixer filter for the stream data. # -proc SetPostMix*(mixfunc: TMixFunction, arg: Pointer){.cdecl, +proc setPostMix*(mixfunc: TMixFunction, arg: pointer){.cdecl, importc: "Mix_SetPostMix", dynlib: MixerLibName.} # Add your own music player or additional mixer function. # If 'mix_func' is NULL, the default music player is re-enabled. # -proc HookMusic*(mix_func: TMixFunction, arg: Pointer){.cdecl, +proc hookMusic*(mixFunc: TMixFunction, arg: pointer){.cdecl, importc: "Mix_HookMusic", dynlib: MixerLibName.} # Add your own callback when the music has finished playing. # -proc HookMusicFinished*(music_finished: Pointer){.cdecl, +proc hookMusicFinished*(musicFinished: pointer){.cdecl, importc: "Mix_HookMusicFinished", dynlib: MixerLibName.} # Get a pointer to the user data for the current music hook -proc GetMusicHookData*(): Pointer{.cdecl, importc: "Mix_GetMusicHookData", +proc getMusicHookData*(): pointer{.cdecl, importc: "Mix_GetMusicHookData", dynlib: MixerLibName.} #* Add your own callback when a channel has finished playing. NULL # * to disable callback.* type - TChannel_finished* = proc (channel: cint){.cdecl.} + TChannelFinished* = proc (channel: cint){.cdecl.} -proc ChannelFinished*(channel_finished: TChannel_finished){.cdecl, +proc channelFinished*(channelFinished: TChannelFinished){.cdecl, importc: "Mix_ChannelFinished", dynlib: MixerLibName.} const CHANNEL_POST* = - 2 type - TEffectFunc* = proc (chan: cint, stream: Pointer, length: cint, - udata: Pointer): Pointer{.cdecl.} - TEffectDone* = proc (chan: cint, udata: Pointer): Pointer{.cdecl.} + TEffectFunc* = proc (chan: cint, stream: pointer, length: cint, + udata: pointer): pointer{.cdecl.} + TEffectDone* = proc (chan: cint, udata: pointer): pointer{.cdecl.} -proc RegisterEffect*(chan: cint, f: TEffectFunc, d: TEffectDone, - arg: Pointer): cint{.cdecl, +proc registerEffect*(chan: cint, f: TEffectFunc, d: TEffectDone, + arg: pointer): cint{.cdecl, importc: "Mix_RegisterEffect", dynlib: MixerLibName.} -proc UnregisterEffect*(channel: cint, f: TEffectFunc): cint{.cdecl, +proc unregisterEffect*(channel: cint, f: TEffectFunc): cint{.cdecl, importc: "Mix_UnregisterEffect", dynlib: MixerLibName.} -proc UnregisterAllEffects*(channel: cint): cint{.cdecl, +proc unregisterAllEffects*(channel: cint): cint{.cdecl, importc: "Mix_UnregisterAllEffects", dynlib: MixerLibName.} const EFFECTSMAXSPEED* = "MIX_EFFECTSMAXSPEED" -proc SetPanning*(channel: cint, left: byte, right: byte): cint{.cdecl, +proc setPanning*(channel: cint, left: byte, right: byte): cint{.cdecl, importc: "Mix_SetPanning", dynlib: MixerLibName.} -proc SetPosition*(channel: cint, angle: int16, distance: byte): cint{.cdecl, +proc setPosition*(channel: cint, angle: int16, distance: byte): cint{.cdecl, importc: "Mix_SetPosition", dynlib: MixerLibName.} -proc SetDistance*(channel: cint, distance: byte): cint{.cdecl, +proc setDistance*(channel: cint, distance: byte): cint{.cdecl, importc: "Mix_SetDistance", dynlib: MixerLibName.} -proc SetReverseStereo*(channel: cint, flip: cint): cint{.cdecl, +proc setReverseStereo*(channel: cint, flip: cint): cint{.cdecl, importc: "Mix_SetReverseStereo", dynlib: MixerLibName.} -proc ReserveChannels*(num: cint): cint{.cdecl, importc: "Mix_ReserveChannels", +proc reserveChannels*(num: cint): cint{.cdecl, importc: "Mix_ReserveChannels", dynlib: MixerLibName.} -proc GroupChannel*(which: cint, tag: cint): cint{.cdecl, +proc groupChannel*(which: cint, tag: cint): cint{.cdecl, importc: "Mix_GroupChannel", dynlib: MixerLibName.} # Assign several consecutive channels to a group -proc GroupChannels*(`from`: cint, `to`: cint, tag: cint): cint{.cdecl, +proc groupChannels*(`from`: cint, `to`: cint, tag: cint): cint{.cdecl, importc: "Mix_GroupChannels", dynlib: MixerLibName.} # Finds the first available channel in a group of channels -proc GroupAvailable*(tag: cint): cint{.cdecl, importc: "Mix_GroupAvailable", +proc groupAvailable*(tag: cint): cint{.cdecl, importc: "Mix_GroupAvailable", dynlib: MixerLibName.} # Returns the number of channels in a group. This is also a subtle # way to get the total number of channels when 'tag' is -1 # -proc GroupCount*(tag: cint): cint{.cdecl, importc: "Mix_GroupCount", +proc groupCount*(tag: cint): cint{.cdecl, importc: "Mix_GroupCount", dynlib: MixerLibName.} # Finds the "oldest" sample playing in a group of channels -proc GroupOldest*(tag: cint): cint{.cdecl, importc: "Mix_GroupOldest", +proc groupOldest*(tag: cint): cint{.cdecl, importc: "Mix_GroupOldest", dynlib: MixerLibName.} # Finds the "most recent" (i.e. last) sample playing in a group of channels -proc GroupNewer*(tag: cint): cint{.cdecl, importc: "Mix_GroupNewer", +proc groupNewer*(tag: cint): cint{.cdecl, importc: "Mix_GroupNewer", dynlib: MixerLibName.} # The same as above, but the sound is played at most 'ticks' milliseconds -proc PlayChannelTimed*(channel: cint, chunk: PChunk, loops: cint, +proc playChannelTimed*(channel: cint, chunk: PChunk, loops: cint, ticks: cint): cint{.cdecl, importc: "Mix_PlayChannelTimed", dynlib: MixerLibName.} -proc PlayChannel*(channel: cint, chunk: PChunk, loops: cint): cint -proc PlayMusic*(music: PMusic, loops: cint): cint{.cdecl, +proc playChannel*(channel: cint, chunk: PChunk, loops: cint): cint +proc playMusic*(music: PMusic, loops: cint): cint{.cdecl, importc: "Mix_PlayMusic", dynlib: MixerLibName.} # Fade in music or a channel over "ms" milliseconds, same semantics as the "Play" functions -proc FadeInMusic*(music: PMusic, loops: cint, ms: cint): cint{.cdecl, +proc fadeInMusic*(music: PMusic, loops: cint, ms: cint): cint{.cdecl, importc: "Mix_FadeInMusic", dynlib: MixerLibName.} -proc FadeInChannelTimed*(channel: cint, chunk: PChunk, loops: cint, +proc fadeInChannelTimed*(channel: cint, chunk: PChunk, loops: cint, ms: cint, ticks: cint): cint{.cdecl, importc: "Mix_FadeInChannelTimed", dynlib: MixerLibName.} -proc FadeInChannel*(channel: cint, chunk: PChunk, loops: cint, ms: cint): cint +proc fadeInChannel*(channel: cint, chunk: PChunk, loops: cint, ms: cint): cint # Set the volume in the range of 0-128 of a specific channel or chunk. # If the specified channel is -1, set volume for all channels. # Returns the original volume. # If the specified volume is -1, just return the current volume. # -proc Volume*(channel: cint, volume: cint): cint{.cdecl, importc: "Mix_Volume", +proc volume*(channel: cint, volume: cint): cint{.cdecl, importc: "Mix_Volume", dynlib: MixerLibName.} -proc VolumeChunk*(chunk: PChunk, volume: cint): cint{.cdecl, +proc volumeChunk*(chunk: PChunk, volume: cint): cint{.cdecl, importc: "Mix_VolumeChunk", dynlib: MixerLibName.} -proc VolumeMusic*(volume: cint): cint{.cdecl, importc: "Mix_VolumeMusic", +proc volumeMusic*(volume: cint): cint{.cdecl, importc: "Mix_VolumeMusic", dynlib: MixerLibName.} # Halt playing of a particular channel -proc HaltChannel*(channel: cint): cint{.cdecl, importc: "Mix_HaltChannel", +proc haltChannel*(channel: cint): cint{.cdecl, importc: "Mix_HaltChannel", dynlib: MixerLibName.} -proc HaltGroup*(tag: cint): cint{.cdecl, importc: "Mix_HaltGroup", +proc haltGroup*(tag: cint): cint{.cdecl, importc: "Mix_HaltGroup", dynlib: MixerLibName.} -proc HaltMusic*(): cint{.cdecl, importc: "Mix_HaltMusic", +proc haltMusic*(): cint{.cdecl, importc: "Mix_HaltMusic", dynlib: MixerLibName.} -proc ExpireChannel*(channel: cint, ticks: cint): cint{.cdecl, +proc expireChannel*(channel: cint, ticks: cint): cint{.cdecl, importc: "Mix_ExpireChannel", dynlib: MixerLibName.} -proc FadeOutChannel*(which: cint, ms: cint): cint{.cdecl, +proc fadeOutChannel*(which: cint, ms: cint): cint{.cdecl, importc: "Mix_FadeOutChannel", dynlib: MixerLibName.} -proc FadeOutGroup*(tag: cint, ms: cint): cint{.cdecl, +proc fadeOutGroup*(tag: cint, ms: cint): cint{.cdecl, importc: "Mix_FadeOutGroup", dynlib: MixerLibName.} -proc FadeOutMusic*(ms: cint): cint{.cdecl, importc: "Mix_FadeOutMusic", +proc fadeOutMusic*(ms: cint): cint{.cdecl, importc: "Mix_FadeOutMusic", dynlib: MixerLibName.} # Query the fading status of a channel -proc FadingMusic*(): TFading{.cdecl, importc: "Mix_FadingMusic", +proc fadingMusic*(): TFading{.cdecl, importc: "Mix_FadingMusic", dynlib: MixerLibName.} -proc FadingChannel*(which: cint): TFading{.cdecl, +proc fadingChannel*(which: cint): TFading{.cdecl, importc: "Mix_FadingChannel", dynlib: MixerLibName.} # Pause/Resume a particular channel -proc Pause*(channel: cint){.cdecl, importc: "Mix_Pause", dynlib: MixerLibName.} -proc Resume*(channel: cint){.cdecl, importc: "Mix_Resume", +proc pause*(channel: cint){.cdecl, importc: "Mix_Pause", dynlib: MixerLibName.} +proc resume*(channel: cint){.cdecl, importc: "Mix_Resume", dynlib: MixerLibName.} -proc Paused*(channel: cint): cint{.cdecl, importc: "Mix_Paused", +proc paused*(channel: cint): cint{.cdecl, importc: "Mix_Paused", dynlib: MixerLibName.} # Pause/Resume the music stream -proc PauseMusic*(){.cdecl, importc: "Mix_PauseMusic", dynlib: MixerLibName.} -proc ResumeMusic*(){.cdecl, importc: "Mix_ResumeMusic", dynlib: MixerLibName.} -proc RewindMusic*(){.cdecl, importc: "Mix_RewindMusic", dynlib: MixerLibName.} -proc PausedMusic*(): cint{.cdecl, importc: "Mix_PausedMusic", +proc pauseMusic*(){.cdecl, importc: "Mix_PauseMusic", dynlib: MixerLibName.} +proc resumeMusic*(){.cdecl, importc: "Mix_ResumeMusic", dynlib: MixerLibName.} +proc rewindMusic*(){.cdecl, importc: "Mix_RewindMusic", dynlib: MixerLibName.} +proc pausedMusic*(): cint{.cdecl, importc: "Mix_PausedMusic", dynlib: MixerLibName.} # Set the current position in the music stream. # This returns 0 if successful, or -1 if it failed or isn't implemented. @@ -308,44 +308,44 @@ proc PausedMusic*(): cint{.cdecl, importc: "Mix_PausedMusic", # order number) and for OGG music (set position in seconds), at the # moment. # -proc SetMusicPosition*(position: float64): cint{.cdecl, +proc setMusicPosition*(position: float64): cint{.cdecl, importc: "Mix_SetMusicPosition", dynlib: MixerLibName.} # Check the status of a specific channel. # If the specified channel is -1, check all channels. # -proc Playing*(channel: cint): cint{.cdecl, importc: "Mix_Playing", +proc playing*(channel: cint): cint{.cdecl, importc: "Mix_Playing", dynlib: MixerLibName.} -proc PlayingMusic*(): cint{.cdecl, importc: "Mix_PlayingMusic", +proc playingMusic*(): cint{.cdecl, importc: "Mix_PlayingMusic", dynlib: MixerLibName.} # Stop music and set external music playback command -proc SetMusicCMD*(command: cstring): cint{.cdecl, importc: "Mix_SetMusicCMD", +proc setMusicCMD*(command: cstring): cint{.cdecl, importc: "Mix_SetMusicCMD", dynlib: MixerLibName.} # Synchro value is set by MikMod from modules while playing -proc SetSynchroValue*(value: cint): cint{.cdecl, +proc setSynchroValue*(value: cint): cint{.cdecl, importc: "Mix_SetSynchroValue", dynlib: MixerLibName.} -proc GetSynchroValue*(): cint{.cdecl, importc: "Mix_GetSynchroValue", +proc getSynchroValue*(): cint{.cdecl, importc: "Mix_GetSynchroValue", dynlib: MixerLibName.} # # Get the Mix_Chunk currently associated with a mixer channel # Returns nil if it's an invalid channel, or there's no chunk associated. # -proc GetChunk*(channel: cint): PChunk{.cdecl, importc: "Mix_GetChunk", +proc getChunk*(channel: cint): PChunk{.cdecl, importc: "Mix_GetChunk", dynlib: MixerLibName.} # Close the mixer, halting all playing audio -proc CloseAudio*(){.cdecl, importc: "Mix_CloseAudio", dynlib: MixerLibName.} +proc closeAudio*(){.cdecl, importc: "Mix_CloseAudio", dynlib: MixerLibName.} # We'll use SDL for reporting errors -proc VERSION(X: var Tversion) = - X.major = MAJOR_VERSION - X.minor = MINOR_VERSION - X.patch = PATCHLEVEL +proc version(x: var Tversion) = + x.major = MAJOR_VERSION + x.minor = MINOR_VERSION + x.patch = PATCHLEVEL -proc LoadWAV(filename: cstring): PChunk = - result = LoadWAV_RW(RWFromFile(filename, "rb"), 1) +proc loadWAV(filename: cstring): PChunk = + result = LoadWAV_RW(rWFromFile(filename, "rb"), 1) -proc PlayChannel(channel: cint, chunk: PChunk, loops: cint): cint = - result = PlayChannelTimed(channel, chunk, loops, - 1) +proc playChannel(channel: cint, chunk: PChunk, loops: cint): cint = + result = playChannelTimed(channel, chunk, loops, - 1) -proc FadeInChannel(channel: cint, chunk: PChunk, loops: cint, ms: cint): cint = - result = FadeInChannelTimed(channel, chunk, loops, ms, - 1) +proc fadeInChannel(channel: cint, chunk: PChunk, loops: cint, ms: cint): cint = + result = fadeInChannelTimed(channel, chunk, loops, ms, - 1) diff --git a/lib/wrappers/sdl/sdl_net.nim b/lib/wrappers/sdl/sdl_net.nim index 742a59314..1ffdb5cca 100644 --- a/lib/wrappers/sdl/sdl_net.nim +++ b/lib/wrappers/sdl/sdl_net.nim @@ -145,15 +145,15 @@ type # SDL_net.h types #*********************************************************************** PIPAddress* = ptr TIPAddress TIPAddress*{.final.} = object #* TCP network API - host*: Uint32 # 32-bit IPv4 host address */ - port*: Uint16 # 16-bit protocol port */ + host*: uint32 # 32-bit IPv4 host address */ + port*: uint16 # 16-bit protocol port */ PTCPSocket* = ptr TTCPSocket TTCPSocket*{.final.} = object # UDP network API ready*: int channel*: int - remoteAddress*: TIPaddress - localAddress*: TIPaddress + remoteAddress*: TIPAddress + localAddress*: TIPAddress sflag*: int PUDP_Channel* = ptr TUDP_Channel @@ -196,27 +196,27 @@ type # SDL_net.h types ready*: int -proc VERSION*(X: var Tversion) +proc version*(x: var Tversion) #* Initialize/Cleanup the network API # SDL must be initialized before calls to functions in this library, # because this library uses utility functions from the SDL library. #* -proc Init*(): int{.cdecl, importc: "SDLNet_Init", dynlib: NetLibName.} -proc Quit*(){.cdecl, importc: "SDLNet_Quit", dynlib: NetLibName.} +proc init*(): int{.cdecl, importc: "SDLNet_Init", dynlib: NetLibName.} +proc quit*(){.cdecl, importc: "SDLNet_Quit", dynlib: NetLibName.} #* Resolve a host name and port to an IP address in network form. # If the function succeeds, it will return 0. # If the host couldn't be resolved, the host portion of the returned # address will be INADDR_NONE, and the function will return -1. # If 'host' is NULL, the resolved host will be set to INADDR_ANY. # * -proc ResolveHost*(address: var TIPaddress, host: cstring, port: Uint16): int{. +proc resolveHost*(address: var TIPAddress, host: cstring, port: uint16): int{. cdecl, importc: "SDLNet_ResolveHost", dynlib: NetLibName.} #* Resolve an ip address to a host name in canonical form. # If the ip couldn't be resolved, this function returns NULL, # otherwise a pointer to a static buffer containing the hostname # is returned. Note that this function is not thread-safe. #* -proc ResolveIP*(ip: var TIPaddress): cstring{.cdecl, +proc resolveIP*(ip: var TIPAddress): cstring{.cdecl, importc: "SDLNet_ResolveIP", dynlib: NetLibName.} #*********************************************************************** #* TCP network API * @@ -229,24 +229,24 @@ proc ResolveIP*(ip: var TIPaddress): cstring{.cdecl, # in the correct form). # The newly created socket is returned, or NULL if there was an error. #* -proc TCP_Open*(ip: var TIPaddress): PTCPSocket{.cdecl, +proc tcpOpen*(ip: var TIPAddress): PTCPSocket{.cdecl, importc: "SDLNet_TCP_Open", dynlib: NetLibName.} #* Accept an incoming connection on the given server socket. # The newly created socket is returned, or NULL if there was an error. #* -proc TCP_Accept*(server: PTCPsocket): PTCPSocket{.cdecl, +proc tcpAccept*(server: PTCPSocket): PTCPSocket{.cdecl, importc: "SDLNet_TCP_Accept", dynlib: NetLibName.} #* Get the IP address of the remote system associated with the socket. # If the socket is a server socket, this function returns NULL. #* -proc TCP_GetPeerAddress*(sock: PTCPsocket): PIPAddress{.cdecl, +proc tcpGetPeerAddress*(sock: PTCPSocket): PIPAddress{.cdecl, importc: "SDLNet_TCP_GetPeerAddress", dynlib: NetLibName.} #* Send 'len' bytes of 'data' over the non-server socket 'sock' # This function returns the actual amount of data sent. If the return value # is less than the amount of data sent, then either the remote connection was # closed, or an unknown socket error occurred. #* -proc TCP_Send*(sock: PTCPsocket, data: Pointer, length: int): int{.cdecl, +proc tcpSend*(sock: PTCPSocket, data: pointer, length: int): int{.cdecl, importc: "SDLNet_TCP_Send", dynlib: NetLibName.} #* Receive up to 'maxlen' bytes of data over the non-server socket 'sock', # and store them in the buffer pointed to by 'data'. @@ -254,10 +254,10 @@ proc TCP_Send*(sock: PTCPsocket, data: Pointer, length: int): int{.cdecl, # value is less than or equal to zero, then either the remote connection was # closed, or an unknown socket error occurred. #* -proc TCP_Recv*(sock: PTCPsocket, data: Pointer, maxlen: int): int{.cdecl, +proc tcpRecv*(sock: PTCPSocket, data: pointer, maxlen: int): int{.cdecl, importc: "SDLNet_TCP_Recv", dynlib: NetLibName.} #* Close a TCP network socket * -proc TCP_Close*(sock: PTCPsocket){.cdecl, importc: "SDLNet_TCP_Close", +proc tcpClose*(sock: PTCPSocket){.cdecl, importc: "SDLNet_TCP_Close", dynlib: NetLibName.} #*********************************************************************** #* UDP network API * @@ -265,26 +265,26 @@ proc TCP_Close*(sock: PTCPsocket){.cdecl, importc: "SDLNet_TCP_Close", #* Allocate/resize/free a single UDP packet 'size' bytes long. # The new packet is returned, or NULL if the function ran out of memory. # * -proc AllocPacket*(size: int): PUDPpacket{.cdecl, +proc allocPacket*(size: int): PUDPpacket{.cdecl, importc: "SDLNet_AllocPacket", dynlib: NetLibName.} -proc ResizePacket*(packet: PUDPpacket, newsize: int): int{.cdecl, +proc resizePacket*(packet: PUDPpacket, newsize: int): int{.cdecl, importc: "SDLNet_ResizePacket", dynlib: NetLibName.} -proc FreePacket*(packet: PUDPpacket){.cdecl, importc: "SDLNet_FreePacket", +proc freePacket*(packet: PUDPpacket){.cdecl, importc: "SDLNet_FreePacket", dynlib: NetLibName.} #* Allocate/Free a UDP packet vector (array of packets) of 'howmany' packets, # each 'size' bytes long. # A pointer to the first packet in the array is returned, or NULL if the # function ran out of memory. # * -proc AllocPacketV*(howmany: int, size: int): PUDPpacket{.cdecl, +proc allocPacketV*(howmany: int, size: int): PUDPpacket{.cdecl, importc: "SDLNet_AllocPacketV", dynlib: NetLibName.} -proc FreePacketV*(packetV: PUDPpacket){.cdecl, +proc freePacketV*(packetV: PUDPpacket){.cdecl, importc: "SDLNet_FreePacketV", dynlib: NetLibName.} #* Open a UDP network socket # If 'port' is non-zero, the UDP socket is bound to a local port. # This allows other systems to send to this socket via a known port. #* -proc UDP_Open*(port: Uint16): PUDPsocket{.cdecl, importc: "SDLNet_UDP_Open", +proc udpOpen*(port: uint16): PUDPSocket{.cdecl, importc: "SDLNet_UDP_Open", dynlib: NetLibName.} #* Bind the address 'address' to the requested channel on the UDP socket. # If the channel is -1, then the first unbound channel will be bound with @@ -295,10 +295,10 @@ proc UDP_Open*(port: Uint16): PUDPsocket{.cdecl, importc: "SDLNet_UDP_Open", # address, to which all outbound packets on the channel are sent. # This function returns the channel which was bound, or -1 on error. #* -proc UDP_Bind*(sock: PUDPsocket, channel: int, address: var TIPaddress): int{. +proc udpBind*(sock: PUDPSocket, channel: int, address: var TIPAddress): int{. cdecl, importc: "SDLNet_UDP_Bind", dynlib: NetLibName.} #* Unbind all addresses from the given channel * -proc UDP_Unbind*(sock: PUDPsocket, channel: int){.cdecl, +proc udpUnbind*(sock: PUDPSocket, channel: int){.cdecl, importc: "SDLNet_UDP_Unbind", dynlib: NetLibName.} #* Get the primary IP address of the remote system associated with the # socket and channel. If the channel is -1, then the primary IP port @@ -306,7 +306,7 @@ proc UDP_Unbind*(sock: PUDPsocket, channel: int){.cdecl, # opened with a specific port. # If the channel is not bound and not -1, this function returns NULL. # * -proc UDP_GetPeerAddress*(sock: PUDPsocket, channel: int): PIPAddress{.cdecl, +proc udpGetPeerAddress*(sock: PUDPSocket, channel: int): PIPAddress{.cdecl, importc: "SDLNet_UDP_GetPeerAddress", dynlib: NetLibName.} #* Send a vector of packets to the the channels specified within the packet. # If the channel specified in the packet is -1, the packet will be sent to @@ -315,7 +315,7 @@ proc UDP_GetPeerAddress*(sock: PUDPsocket, channel: int): PIPAddress{.cdecl, # been sent, -1 if the packet send failed. # This function returns the number of packets sent. #* -proc UDP_SendV*(sock: PUDPsocket, packets: PPUDPpacket, npackets: int): int{. +proc udpSendV*(sock: PUDPSocket, packets: PPUDPpacket, npackets: int): int{. cdecl, importc: "SDLNet_UDP_SendV", dynlib: NetLibName.} #* Send a single packet to the specified channel. # If the channel specified in the packet is -1, the packet will be sent to @@ -324,7 +324,7 @@ proc UDP_SendV*(sock: PUDPsocket, packets: PPUDPpacket, npackets: int): int{. # been sent. # This function returns 1 if the packet was sent, or 0 on error. #* -proc UDP_Send*(sock: PUDPsocket, channel: int, packet: PUDPpacket): int{. +proc udpSend*(sock: PUDPSocket, channel: int, packet: PUDPpacket): int{. cdecl, importc: "SDLNet_UDP_Send", dynlib: NetLibName.} #* Receive a vector of pending packets from the UDP socket. # The returned packets contain the source address and the channel they arrived @@ -336,7 +336,7 @@ proc UDP_Send*(sock: PUDPsocket, channel: int, packet: PUDPpacket): int{. # This function returns the number of packets read from the network, or -1 # on error. This function does not block, so can return 0 packets pending. #* -proc UDP_RecvV*(sock: PUDPsocket, packets: PPUDPpacket): int{.cdecl, +proc udpRecvV*(sock: PUDPSocket, packets: PPUDPpacket): int{.cdecl, importc: "SDLNet_UDP_RecvV", dynlib: NetLibName.} #* Receive a single packet from the UDP socket. # The returned packet contains the source address and the channel it arrived @@ -348,10 +348,10 @@ proc UDP_RecvV*(sock: PUDPsocket, packets: PPUDPpacket): int{.cdecl, # This function returns the number of packets read from the network, or -1 # on error. This function does not block, so can return 0 packets pending. #* -proc UDP_Recv*(sock: PUDPsocket, packet: PUDPpacket): int{.cdecl, +proc udpRecv*(sock: PUDPSocket, packet: PUDPpacket): int{.cdecl, importc: "SDLNet_UDP_Recv", dynlib: NetLibName.} #* Close a UDP network socket * -proc UDP_Close*(sock: PUDPsocket){.cdecl, importc: "SDLNet_UDP_Close", +proc udpClose*(sock: PUDPSocket){.cdecl, importc: "SDLNet_UDP_Close", dynlib: NetLibName.} #*********************************************************************** #* Hooks for checking sockets for available data * @@ -360,19 +360,19 @@ proc UDP_Close*(sock: PUDPsocket){.cdecl, importc: "SDLNet_UDP_Close", # This returns a socket set for up to 'maxsockets' sockets, or NULL if # the function ran out of memory. # * -proc AllocSocketSet*(maxsockets: int): PSocketSet{.cdecl, +proc allocSocketSet*(maxsockets: int): PSocketSet{.cdecl, importc: "SDLNet_AllocSocketSet", dynlib: NetLibName.} #* Add a socket to a set of sockets to be checked for available data * -proc AddSocket*(theSet: PSocketSet, sock: PGenericSocket): int{. +proc addSocket*(theSet: PSocketSet, sock: PGenericSocket): int{. cdecl, importc: "SDLNet_AddSocket", dynlib: NetLibName.} -proc TCP_AddSocket*(theSet: PSocketSet, sock: PTCPSocket): int -proc UDP_AddSocket*(theSet: PSocketSet, sock: PUDPSocket): int +proc tcpAddSocket*(theSet: PSocketSet, sock: PTCPSocket): int +proc udpAddSocket*(theSet: PSocketSet, sock: PUDPSocket): int #* Remove a socket from a set of sockets to be checked for available data * -proc DelSocket*(theSet: PSocketSet, sock: PGenericSocket): int{. +proc delSocket*(theSet: PSocketSet, sock: PGenericSocket): int{. cdecl, importc: "SDLNet_DelSocket", dynlib: NetLibName.} -proc TCP_DelSocket*(theSet: PSocketSet, sock: PTCPSocket): int +proc tcpDelSocket*(theSet: PSocketSet, sock: PTCPSocket): int # SDLNet_DelSocket(set, (SDLNet_GenericSocket)sock) -proc UDP_DelSocket*(theSet: PSocketSet, sock: PUDPSocket): int +proc udpDelSocket*(theSet: PSocketSet, sock: PUDPSocket): int #SDLNet_DelSocket(set, (SDLNet_GenericSocket)sock) #* This function checks to see if data is available for reading on the # given set of sockets. If 'timeout' is 0, it performs a quick poll, @@ -381,47 +381,46 @@ proc UDP_DelSocket*(theSet: PSocketSet, sock: PUDPSocket): int # first. This function returns the number of sockets ready for reading, # or -1 if there was an error with the select() system call. #* -proc CheckSockets*(theSet: PSocketSet, timeout: int32): int{.cdecl, +proc checkSockets*(theSet: PSocketSet, timeout: int32): int{.cdecl, importc: "SDLNet_CheckSockets", dynlib: NetLibName.} #* After calling SDLNet_CheckSockets(), you can use this function on a # socket that was in the socket set, to find out if data is available # for reading. #* -proc SocketReady*(sock: PGenericSocket): bool +proc socketReady*(sock: PGenericSocket): bool #* Free a set of sockets allocated by SDL_NetAllocSocketSet() * -proc FreeSocketSet*(theSet: PSocketSet){.cdecl, +proc freeSocketSet*(theSet: PSocketSet){.cdecl, importc: "SDLNet_FreeSocketSet", dynlib: NetLibName.} #*********************************************************************** #* Platform-independent data conversion functions * #*********************************************************************** #* Write a 16/32 bit value to network packet buffer * -proc Write16*(value: Uint16, area: Pointer){.cdecl, +proc write16*(value: uint16, area: pointer){.cdecl, importc: "SDLNet_Write16", dynlib: NetLibName.} -proc Write32*(value: Uint32, area: Pointer){.cdecl, +proc write32*(value: uint32, area: pointer){.cdecl, importc: "SDLNet_Write32", dynlib: NetLibName.} #* Read a 16/32 bit value from network packet buffer * -proc Read16*(area: Pointer): Uint16{.cdecl, importc: "SDLNet_Read16", +proc read16*(area: pointer): uint16{.cdecl, importc: "SDLNet_Read16", dynlib: NetLibName.} -proc Read32*(area: Pointer): Uint32{.cdecl, importc: "SDLNet_Read32", +proc read32*(area: pointer): uint32{.cdecl, importc: "SDLNet_Read32", dynlib: NetLibName.} -proc VERSION(X: var Tversion) = - X.major = MAJOR_VERSION - X.minor = MINOR_VERSION - X.patch = PATCHLEVEL +proc version(x: var Tversion) = + x.major = MAJOR_VERSION + x.minor = MINOR_VERSION + x.patch = PATCHLEVEL -proc TCP_AddSocket(theSet: PSocketSet, sock: PTCPSocket): int = - result = AddSocket(theSet, cast[PGenericSocket](sock)) +proc tcpAddSocket(theSet: PSocketSet, sock: PTCPSocket): int = + result = addSocket(theSet, cast[PGenericSocket](sock)) -proc UDP_AddSocket(theSet: PSocketSet, sock: PUDPSocket): int = - result = AddSocket(theSet, cast[PGenericSocket](sock)) +proc udpAddSocket(theSet: PSocketSet, sock: PUDPSocket): int = + result = addSocket(theSet, cast[PGenericSocket](sock)) -proc TCP_DelSocket(theSet: PSocketSet, sock: PTCPSocket): int = - result = DelSocket(theSet, cast[PGenericSocket](sock)) +proc tcpDelSocket(theSet: PSocketSet, sock: PTCPSocket): int = + result = delSocket(theSet, cast[PGenericSocket](sock)) -proc UDP_DelSocket(theSet: PSocketSet, sock: PUDPSocket): int = - result = DelSocket(theSet, cast[PGenericSocket](sock)) - -proc SocketReady(sock: PGenericSocket): bool = - result = ((sock != nil) and (sock.ready == 1)) +proc udpDelSocket(theSet: PSocketSet, sock: PUDPSocket): int = + result = delSocket(theSet, cast[PGenericSocket](sock)) +proc socketReady(sock: PGenericSocket): bool = + result = sock != nil and sock.ready == 1 diff --git a/lib/wrappers/sdl/sdl_ttf.nim b/lib/wrappers/sdl/sdl_ttf.nim index 45247df4d..e0410c798 100644 --- a/lib/wrappers/sdl/sdl_ttf.nim +++ b/lib/wrappers/sdl/sdl_ttf.nim @@ -177,78 +177,78 @@ const UNICODE_BOM_SWAPPED* = 0x0000FFFE type - PFont* = ptr Tfont - TFont{.final.} = object + PFont* = ptr TFont + TFont = object # This macro can be used to fill a version structure with the compile-time # version of the SDL_ttf library. -proc Linked_Version*(): sdl.Pversion{.cdecl, importc: "TTF_Linked_Version", +proc linkedVersion*(): sdl.Pversion{.cdecl, importc: "TTF_Linked_Version", dynlib: ttfLibName.} # This function tells the library whether UNICODE text is generally # byteswapped. A UNICODE BOM character in a string will override # this setting for the remainder of that string. # -proc ByteSwappedUNICODE*(swapped: cint){.cdecl, +proc byteSwappedUNICODE*(swapped: cint){.cdecl, importc: "TTF_ByteSwappedUNICODE", dynlib: ttfLibName.} #returns 0 on succes, -1 if error occurs -proc Init*(): cint{.cdecl, importc: "TTF_Init", dynlib: ttfLibName.} +proc init*(): cint{.cdecl, importc: "TTF_Init", dynlib: ttfLibName.} # # Open a font file and create a font of the specified point size. # Some .fon fonts will have several sizes embedded in the file, so the # point size becomes the index of choosing which size. If the value # is too high, the last indexed size will be the default. # -proc OpenFont*(filename: cstring, ptsize: cint): PFont{.cdecl, +proc openFont*(filename: cstring, ptsize: cint): PFont{.cdecl, importc: "TTF_OpenFont", dynlib: ttfLibName.} -proc OpenFontIndex*(filename: cstring, ptsize: cint, index: int32): PFont{. +proc openFontIndex*(filename: cstring, ptsize: cint, index: int32): PFont{. cdecl, importc: "TTF_OpenFontIndex", dynlib: ttfLibName.} -proc OpenFontRW*(src: PRWops, freesrc: cint, ptsize: cint): PFont{.cdecl, +proc openFontRW*(src: PRWops, freesrc: cint, ptsize: cint): PFont{.cdecl, importc: "TTF_OpenFontRW", dynlib: ttfLibName.} -proc OpenFontIndexRW*(src: PRWops, freesrc: cint, ptsize: cint, index: int32): PFont{. +proc openFontIndexRW*(src: PRWops, freesrc: cint, ptsize: cint, index: int32): PFont{. cdecl, importc: "TTF_OpenFontIndexRW", dynlib: ttfLibName.} -proc GetFontStyle*(font: PFont): cint{.cdecl, +proc getFontStyle*(font: PFont): cint{.cdecl, importc: "TTF_GetFontStyle", dynlib: ttfLibName.} -proc SetFontStyle*(font: PFont, style: cint){.cdecl, +proc setFontStyle*(font: PFont, style: cint){.cdecl, importc: "TTF_SetFontStyle", dynlib: ttfLibName.} # Get the total height of the font - usually equal to point size -proc FontHeight*(font: PFont): cint{.cdecl, importc: "TTF_FontHeight", +proc fontHeight*(font: PFont): cint{.cdecl, importc: "TTF_FontHeight", dynlib: ttfLibName.} # Get the offset from the baseline to the top of the font # This is a positive value, relative to the baseline. # -proc FontAscent*(font: PFont): cint{.cdecl, importc: "TTF_FontAscent", +proc fontAscent*(font: PFont): cint{.cdecl, importc: "TTF_FontAscent", dynlib: ttfLibName.} # Get the offset from the baseline to the bottom of the font # This is a negative value, relative to the baseline. # -proc FontDescent*(font: PFont): cint{.cdecl, importc: "TTF_FontDescent", +proc fontDescent*(font: PFont): cint{.cdecl, importc: "TTF_FontDescent", dynlib: ttfLibName.} # Get the recommended spacing between lines of text for this font -proc FontLineSkip*(font: PFont): cint{.cdecl, +proc fontLineSkip*(font: PFont): cint{.cdecl, importc: "TTF_FontLineSkip", dynlib: ttfLibName.} # Get the number of faces of the font -proc FontFaces*(font: PFont): int32{.cdecl, importc: "TTF_FontFaces", +proc fontFaces*(font: PFont): int32{.cdecl, importc: "TTF_FontFaces", dynlib: ttfLibName.} # Get the font face attributes, if any -proc FontFaceIsFixedWidth*(font: PFont): cint{.cdecl, +proc fontFaceIsFixedWidth*(font: PFont): cint{.cdecl, importc: "TTF_FontFaceIsFixedWidth", dynlib: ttfLibName.} -proc FontFaceFamilyName*(font: PFont): cstring{.cdecl, +proc fontFaceFamilyName*(font: PFont): cstring{.cdecl, importc: "TTF_FontFaceFamilyName", dynlib: ttfLibName.} -proc FontFaceStyleName*(font: PFont): cstring{.cdecl, +proc fontFaceStyleName*(font: PFont): cstring{.cdecl, importc: "TTF_FontFaceStyleName", dynlib: ttfLibName.} # Get the metrics (dimensions) of a glyph -proc GlyphMetrics*(font: PFont, ch: Uint16, minx: var cint, +proc glyphMetrics*(font: PFont, ch: uint16, minx: var cint, maxx: var cint, miny: var cint, maxy: var cint, advance: var cint): cint{.cdecl, importc: "TTF_GlyphMetrics", dynlib: ttfLibName.} # Get the dimensions of a rendered string of text -proc SizeText*(font: PFont, text: cstring, w: var cint, y: var cint): cint{. +proc sizeText*(font: PFont, text: cstring, w: var cint, y: var cint): cint{. cdecl, importc: "TTF_SizeText", dynlib: ttfLibName.} -proc SizeUTF8*(font: PFont, text: cstring, w: var cint, y: var cint): cint{. +proc sizeUTF8*(font: PFont, text: cstring, w: var cint, y: var cint): cint{. cdecl, importc: "TTF_SizeUTF8", dynlib: ttfLibName.} -proc SizeUNICODE*(font: PFont, text: PUint16, w: var cint, y: var cint): cint{. +proc sizeUNICODE*(font: PFont, text: PUInt16, w: var cint, y: var cint): cint{. cdecl, importc: "TTF_SizeUNICODE", dynlib: ttfLibName.} # Create an 8-bit palettized surface and render the given text at # fast quality with the given font and color. The 0 pixel is the @@ -256,9 +256,9 @@ proc SizeUNICODE*(font: PFont, text: PUint16, w: var cint, y: var cint): cint{. # to the text color. # This function returns the new surface, or NULL if there was an error. # -proc RenderUTF8_Solid*(font: PFont, text: cstring, fg: TColor): PSurface{. +proc renderUTF8Solid*(font: PFont, text: cstring, fg: TColor): PSurface{. cdecl, importc: "TTF_RenderUTF8_Solid", dynlib: ttfLibName.} -proc RenderUNICODE_Solid*(font: PFont, text: PUint16, fg: TColor): PSurface{. +proc renderUNICODE_Solid*(font: PFont, text: PUInt16, fg: TColor): PSurface{. cdecl, importc: "TTF_RenderUNICODE_Solid", dynlib: ttfLibName.} # #Create an 8-bit palettized surface and render the given glyph at @@ -268,20 +268,20 @@ proc RenderUNICODE_Solid*(font: PFont, text: PUint16, fg: TColor): PSurface{. # centering in the X direction, and aligned normally in the Y direction. # This function returns the new surface, or NULL if there was an error. # -proc RenderGlyph_Solid*(font: PFont, ch: Uint16, fg: TColor): PSurface{. +proc renderGlyphSolid*(font: PFont, ch: uint16, fg: TColor): PSurface{. cdecl, importc: "TTF_RenderGlyph_Solid", dynlib: ttfLibName.} # Create an 8-bit palettized surface and render the given text at # high quality with the given font and colors. The 0 pixel is background, # while other pixels have varying degrees of the foreground color. # This function returns the new surface, or NULL if there was an error. # -proc RenderText_Shaded*(font: PFont, text: cstring, fg: TColor, +proc renderTextShaded*(font: PFont, text: cstring, fg: TColor, bg: TColor): PSurface{.cdecl, importc: "TTF_RenderText_Shaded", dynlib: ttfLibName.} -proc RenderUTF8_Shaded*(font: PFont, text: cstring, fg: TColor, +proc renderUTF8Shaded*(font: PFont, text: cstring, fg: TColor, bg: TColor): PSurface{.cdecl, importc: "TTF_RenderUTF8_Shaded", dynlib: ttfLibName.} -proc RenderUNICODE_Shaded*(font: PFont, text: PUint16, fg: TColor, +proc renderUNICODE_Shaded*(font: PFont, text: PUInt16, fg: TColor, bg: TColor): PSurface{.cdecl, importc: "TTF_RenderUNICODE_Shaded", dynlib: ttfLibName.} # Create an 8-bit palettized surface and render the given glyph at @@ -291,17 +291,17 @@ proc RenderUNICODE_Shaded*(font: PFont, text: PUint16, fg: TColor, # direction, and aligned normally in the Y direction. # This function returns the new surface, or NULL if there was an error. # -proc RenderGlyph_Shaded*(font: PFont, ch: Uint16, fg: TColor, bg: TColor): PSurface{. +proc renderGlyphShaded*(font: PFont, ch: uint16, fg: TColor, bg: TColor): PSurface{. cdecl, importc: "TTF_RenderGlyph_Shaded", dynlib: ttfLibName.} # Create a 32-bit ARGB surface and render the given text at high quality, # using alpha blending to dither the font with the given color. # This function returns the new surface, or NULL if there was an error. # -proc RenderText_Blended*(font: PFont, text: cstring, fg: TColor): PSurface{. +proc renderTextBlended*(font: PFont, text: cstring, fg: TColor): PSurface{. cdecl, importc: "TTF_RenderText_Blended", dynlib: ttfLibName.} -proc RenderUTF8_Blended*(font: PFont, text: cstring, fg: TColor): PSurface{. +proc renderUTF8Blended*(font: PFont, text: cstring, fg: TColor): PSurface{. cdecl, importc: "TTF_RenderUTF8_Blended", dynlib: ttfLibName.} -proc RenderUNICODE_Blended*(font: PFont, text: PUint16, fg: TColor): PSurface{. +proc RenderUNICODE_Blended*(font: PFont, text: PUInt16, fg: TColor): PSurface{. cdecl, importc: "TTF_RenderUNICODE_Blended", dynlib: ttfLibName.} # Create a 32-bit ARGB surface and render the given glyph at high quality, # using alpha blending to dither the font with the given color. @@ -309,29 +309,29 @@ proc RenderUNICODE_Blended*(font: PFont, text: PUint16, fg: TColor): PSurface{. # direction, and aligned normally in the Y direction. # This function returns the new surface, or NULL if there was an error. # -proc RenderGlyph_Blended*(font: PFont, ch: Uint16, fg: TColor): PSurface{. +proc renderGlyphBlended*(font: PFont, ch: uint16, fg: TColor): PSurface{. cdecl, importc: "TTF_RenderGlyph_Blended", dynlib: ttfLibName.} # For compatibility with previous versions, here are the old functions - ##define TTF_RenderText(font, text, fg, bg) + # #define TTF_RenderText(font, text, fg, bg) # TTF_RenderText_Shaded(font, text, fg, bg) - ##define TTF_RenderUTF8(font, text, fg, bg) + # #define TTF_RenderUTF8(font, text, fg, bg) # TTF_RenderUTF8_Shaded(font, text, fg, bg) - ##define TTF_RenderUNICODE(font, text, fg, bg) + # #define TTF_RenderUNICODE(font, text, fg, bg) # TTF_RenderUNICODE_Shaded(font, text, fg, bg) - # Close an opened font file -proc CloseFont*(font: PFont){.cdecl, importc: "TTF_CloseFont", + # Close an opened font file +proc closeFont*(font: PFont){.cdecl, importc: "TTF_CloseFont", dynlib: ttfLibName.} - #De-initialize TTF engine -proc Quit*(){.cdecl, importc: "TTF_Quit", dynlib: ttfLibName.} + # De-initialize TTF engine +proc quit*(){.cdecl, importc: "TTF_Quit", dynlib: ttfLibName.} # Check if the TTF engine is initialized -proc WasInit*(): cint{.cdecl, importc: "TTF_WasInit", dynlib: ttfLibName.} +proc wasInit*(): cint{.cdecl, importc: "TTF_WasInit", dynlib: ttfLibName.} -proc VERSION*(X: var sdl.Tversion) = - X.major = MAJOR_VERSION - X.minor = MINOR_VERSION - X.patch = PATCHLEVEL +proc version*(x: var sdl.Tversion) = + x.major = MAJOR_VERSION + x.minor = MINOR_VERSION + x.patch = PATCHLEVEL -proc RenderText_Solid*(font: PFont, text: cstring, fg: TColor): PSurface{. +proc renderTextSolid*(font: PFont, text: cstring, fg: TColor): PSurface{. cdecl, importc: "TTF_RenderText_Solid", dynlib: ttfLibName.} diff --git a/lib/wrappers/sdl/smpeg.nim b/lib/wrappers/sdl/smpeg.nim index 33f317631..318c0b3df 100644 --- a/lib/wrappers/sdl/smpeg.nim +++ b/lib/wrappers/sdl/smpeg.nim @@ -125,7 +125,7 @@ # #****************************************************************************** -import +import sdl when defined(windows): @@ -143,29 +143,29 @@ const type TFilterInfo*{.final.} = object - yuv_mb_square_error*: PUint16 - yuv_pixel_square_error*: PUint16 + yuvMbSquareError*: PUInt16 + yuvPixelSquareError*: PUInt16 PFilterInfo* = ptr TFilterInfo # MPEG filter definition PFilter* = ptr TFilter # Callback functions for the filter TFilterCallback* = proc (dest, source: POverlay, region: PRect, - filter_info: PFilterInfo, data: Pointer): Pointer{. + filterInfo: PFilterInfo, data: pointer): pointer{. cdecl.} - TFilterDestroy* = proc (Filter: PFilter): Pointer{.cdecl.} # The filter definition itself + TFilterDestroy* = proc (filter: PFilter): pointer{.cdecl.} # The filter definition itself TFilter*{.final.} = object # The null filter (default). It simply copies the source rectangle to the video overlay. - flags*: Uint32 - data*: Pointer + flags*: uint32 + data*: pointer callback*: TFilterCallback destroy*: TFilterDestroy -proc filter_null*(): PFilter{.cdecl, importc: "SMPEGfilter_null", +proc filterNull*(): PFilter{.cdecl, importc: "SMPEGfilter_null", dynlib: SmpegLibName.} # The bilinear filter. A basic low-pass filter that will produce a smoother image. -proc filter_bilinear*(): PFilter{.cdecl, +proc filterBilinear*(): PFilter{.cdecl, importc: "SMPEGfilter_bilinear", dynlib: SmpegLibName.} # The deblocking filter. It filters block borders and non-intra coded blocks to reduce blockiness -proc filter_deblocking*(): PFilter{.cdecl, +proc filterDeblocking*(): PFilter{.cdecl, importc: "SMPEGfilter_deblocking", dynlib: SmpegLibName.} #------------------------------------------------------------------------------ # SMPEG.h @@ -175,28 +175,28 @@ const MINOR_VERSION* = 4 PATCHLEVEL* = 2 -type - TVersion*{.final.} = object +type + TVersion* = object major*: byte minor*: byte patch*: byte - Pversion* = ptr Tversion # This is the actual SMPEG object - TSMPEG*{.final.} = object + Pversion* = ptr TVersion # This is the actual SMPEG object + TSMPEG* = object PSMPEG* = ptr TSMPEG # Used to get information about the SMPEG object - TInfo*{.final.} = object - has_audio*: int32 - has_video*: int32 + TInfo* = object + hasAudio*: int32 + hasVideo*: int32 width*: int32 height*: int32 - current_frame*: int32 - current_fps*: float64 - audio_string*: array[0..79, char] - audio_current_frame*: int32 - current_offset*: UInt32 - total_size*: UInt32 - current_time*: float64 - total_time*: float64 + currentFrame*: int32 + currentFps*: float64 + audioString*: array[0..79, char] + audioCurrentFrame*: int32 + currentOffset*: uint32 + totalSize*: uint32 + currentTime*: float64 + totalTime*: float64 PInfo* = ptr TInfo # Possible MPEG status codes @@ -208,7 +208,7 @@ const type Tstatus* = int32 Pstatus* = ptr int32 # Matches the declaration of SDL_UpdateRect() - TDisplayCallback* = proc (dst: PSurface, x, y: int, w, h: int): Pointer{. + TDisplayCallback* = proc (dst: PSurface, x, y: int, w, h: int): pointer{. cdecl.} # Create a new SMPEG object from an MPEG file. # On return, if 'info' is not NULL, it will be filled with information # about the MPEG object. @@ -218,15 +218,15 @@ type # subsystem. If not, you will have to use the playaudio() function below # to extract the decoded data. -proc SMPEG_new*(theFile: cstring, info: PInfo, audio: int): PSMPEG{.cdecl, +proc new*(theFile: cstring, info: PInfo, audio: int): PSMPEG{.cdecl, importc: "SMPEG_new", dynlib: SmpegLibName.} # The same as above for a file descriptor -proc new_descr*(theFile: int, info: PInfo, audio: int): PSMPEG{. +proc newDescr*(theFile: int, info: PInfo, audio: int): PSMPEG{. cdecl, importc: "SMPEG_new_descr", dynlib: SmpegLibName.} # The same as above but for a raw chunk of data. SMPEG makes a copy of the # data, so the application is free to delete after a successful call to this # function. -proc new_data*(data: Pointer, size: int, info: PInfo, audio: int): PSMPEG{. +proc newData*(data: pointer, size: int, info: PInfo, audio: int): PSMPEG{. cdecl, importc: "SMPEG_new_data", dynlib: SmpegLibName.} # Get current information about an SMPEG object proc getinfo*(mpeg: PSMPEG, info: PInfo){.cdecl, @@ -247,13 +247,13 @@ proc status*(mpeg: PSMPEG): Tstatus{.cdecl, importc: "SMPEG_status", dynlib: SmpegLibName.} # status # Set the audio volume of an MPEG stream, in the range 0-100 -proc setvolume*(mpeg: PSMPEG, volume: int){.cdecl, +proc setVolume*(mpeg: PSMPEG, volume: int){.cdecl, importc: "SMPEG_setvolume", dynlib: SmpegLibName.} # Set the destination surface for MPEG video playback # 'surfLock' is a mutex used to synchronize access to 'dst', and can be NULL. # 'callback' is a function called when an area of 'dst' needs to be updated. # If 'callback' is NULL, the default function (SDL_UpdateRect) will be used. -proc setdisplay*(mpeg: PSMPEG, dst: PSurface, surfLock: Pmutex, +proc setDisplay*(mpeg: PSMPEG, dst: PSurface, surfLock: PMutex, callback: TDisplayCallback){.cdecl, importc: "SMPEG_setdisplay", dynlib: SmpegLibName.} # Set or clear looping play on an SMPEG object @@ -264,12 +264,12 @@ proc scaleXY*(mpeg: PSMPEG, width, height: int){.cdecl, importc: "SMPEG_scaleXY", dynlib: SmpegLibName.} proc scale*(mpeg: PSMPEG, scale: int){.cdecl, importc: "SMPEG_scale", dynlib: SmpegLibName.} -proc Double*(mpeg: PSMPEG, doubleit: bool) +proc double*(mpeg: PSMPEG, doubleit: bool) # Move the video display area within the destination surface proc move*(mpeg: PSMPEG, x, y: int){.cdecl, importc: "SMPEG_move", dynlib: SmpegLibName.} # Set the region of the video to be shown -proc setdisplayregion*(mpeg: PSMPEG, x, y, w, h: int){.cdecl, +proc setDisplayRegion*(mpeg: PSMPEG, x, y, w, h: int){.cdecl, importc: "SMPEG_setdisplayregion", dynlib: SmpegLibName.} # Play an SMPEG object proc play*(mpeg: PSMPEG){.cdecl, importc: "SMPEG_play", @@ -312,7 +312,7 @@ proc error*(mpeg: PSMPEG): cstring{.cdecl, importc: "SMPEG_error", proc playAudio*(mpeg: PSMPEG, stream: pointer, length: int): int{.cdecl, importc: "SMPEG_playAudio", dynlib: SmpegLibName.} # Wrapper for playAudio() that can be passed to SDL and SDL_mixer -proc playAudioSDL*(mpeg: Pointer, stream: pointer, length: int){.cdecl, +proc playAudioSDL*(mpeg: pointer, stream: pointer, length: int){.cdecl, importc: "SMPEG_playAudioSDL", dynlib: SmpegLibName.} # Get the best SDL audio spec for the audio stream proc wantedSpec*(mpeg: PSMPEG, wanted: PAudioSpec): int{.cdecl, @@ -322,14 +322,11 @@ proc actualSpec*(mpeg: PSMPEG, spec: PAudioSpec){.cdecl, importc: "SMPEG_actualSpec", dynlib: SmpegLibName.} # This macro can be used to fill a version structure with the compile-time # version of the SDL library. -proc GETVERSION*(X: var Tversion) -# implementation +proc getversion*(x: var TVersion) = + x.major = MAJOR_VERSION + x.minor = MINOR_VERSION + x.patch = PATCHLEVEL proc double(mpeg: PSMPEG, doubleit: bool) = if doubleit: scale(mpeg, 2) else: scale(mpeg, 1) - -proc GETVERSION(X: var Tversion) = - X.major = MAJOR_VERSION - X.minor = MINOR_VERSION - X.patch = PATCHLEVEL diff --git a/lib/wrappers/sphinx.nim b/lib/wrappers/sphinx.nim index b4e127c65..e4a282968 100644 --- a/lib/wrappers/sphinx.nim +++ b/lib/wrappers/sphinx.nim @@ -12,7 +12,7 @@ # did not, you can find it at http://www.gnu.org/ # -## Nimrod wrapper for ``sphinx``. +## Nim wrapper for ``sphinx``. {.deadCodeElim: on.} when defined(windows): diff --git a/lib/wrappers/sqlite3.nim b/lib/wrappers/sqlite3.nim index 7b7f0874e..e3a3fa0b8 100644 --- a/lib/wrappers/sqlite3.nim +++ b/lib/wrappers/sqlite3.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -88,8 +88,8 @@ const SQLITE_REINDEX* = 27 SQLITE_DENY* = 1 SQLITE_IGNORE* = 2 # Original from sqlite3.h: - ##define SQLITE_STATIC ((void(*)(void *))0) - ##define SQLITE_TRANSIENT ((void(*)(void *))-1) + #define SQLITE_STATIC ((void(*)(void *))0) + #define SQLITE_TRANSIENT ((void(*)(void *))-1) SQLITE_DETERMINISTIC* = 0x800 const @@ -178,15 +178,15 @@ proc errcode*(db: PSqlite3): int32{.cdecl, dynlib: Lib, importc: "sqlite3_errcod proc errmsg*(para1: PSqlite3): cstring{.cdecl, dynlib: Lib, importc: "sqlite3_errmsg".} proc errmsg16*(para1: PSqlite3): pointer{.cdecl, dynlib: Lib, importc: "sqlite3_errmsg16".} -proc prepare*(db: PSqlite3, zSql: cstring, nBytes: int32, ppStmt: var PStmt, +proc prepare*(db: PSqlite3, zSql: cstring, nBytes: int32, ppStmt: var Pstmt, pzTail: ptr cstring): int32{.cdecl, dynlib: Lib, importc: "sqlite3_prepare".} -proc prepare_v2*(db: PSqlite3, zSql: cstring, nByte: cint, ppStmt: var PStmt, +proc prepare_v2*(db: PSqlite3, zSql: cstring, nByte: cint, ppStmt: var Pstmt, pzTail: ptr cstring): cint {. importc: "sqlite3_prepare_v2", cdecl, dynlib: Lib.} -proc prepare16*(db: PSqlite3, zSql: pointer, nBytes: int32, ppStmt: var PStmt, +proc prepare16*(db: PSqlite3, zSql: pointer, nBytes: int32, ppStmt: var Pstmt, pzTail: var pointer): int32{.cdecl, dynlib: Lib, importc: "sqlite3_prepare16".} proc bind_blob*(para1: Pstmt, para2: int32, para3: pointer, n: int32, diff --git a/lib/wrappers/tinyc.nim b/lib/wrappers/tinyc.nim index f685c714d..ac6cb70f1 100644 --- a/lib/wrappers/tinyc.nim +++ b/lib/wrappers/tinyc.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/wrappers/zip/libzip.nim b/lib/wrappers/zip/libzip.nim index 0b8d2b3ec..86670b450 100644 --- a/lib/wrappers/zip/libzip.nim +++ b/lib/wrappers/zip/libzip.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -64,15 +64,15 @@ type TZipSourceCallback* = proc (state: pointer, data: pointer, length: int, cmd: TZipSourceCmd): int {.cdecl.} PZipStat* = ptr TZipStat - TZipStat* = object ## the 'zip_stat' struct + TZipStat* = object ## the 'zip_stat' struct name*: cstring ## name of the file index*: int32 ## index within archive crc*: int32 ## crc of file data - mtime*: TTime ## modification time + mtime*: Time ## modification time size*: int ## size of file (uncompressed) - compSize*: int ## size of file (compressed) - compMethod*: int16 ## compression method used - encryptionMethod*: int16 ## encryption method used + compSize*: int ## size of file (compressed) + compMethod*: int16 ## compression method used + encryptionMethod*: int16 ## encryption method used TZip = object TZipSource = object @@ -225,7 +225,7 @@ proc zip_source_buffer*(para1: PZip, para2: pointer, para3: int, para4: int32): cdecl, mydll, importc: "zip_source_buffer".} proc zip_source_file*(para1: PZip, para2: cstring, para3: int, para4: int): PZipSource {. cdecl, mydll, importc: "zip_source_file".} -proc zip_source_filep*(para1: PZip, para2: TFile, para3: int, para4: int): PZipSource {. +proc zip_source_filep*(para1: PZip, para2: File, para3: int, para4: int): PZipSource {. cdecl, mydll, importc: "zip_source_filep".} proc zip_source_free*(para1: PZipSource) {.cdecl, mydll, importc: "zip_source_free".} diff --git a/lib/wrappers/zip/zlib.nim b/lib/wrappers/zip/zlib.nim index cb61783d2..e3530d566 100644 --- a/lib/wrappers/zip/zlib.nim +++ b/lib/wrappers/zip/zlib.nim @@ -14,32 +14,32 @@ type Ulong* = int Ulongf* = int Pulongf* = ptr Ulongf - z_off_t* = int32 - pbyte* = cstring - pbytef* = cstring - TAllocfunc* = proc (p: pointer, items: uInt, size: uInt): pointer{.cdecl.} + ZOffT* = int32 + Pbyte* = cstring + Pbytef* = cstring + TAllocfunc* = proc (p: pointer, items: Uint, size: Uint): pointer{.cdecl.} TFreeFunc* = proc (p: pointer, address: pointer){.cdecl.} TInternalState*{.final, pure.} = object - PInternalState* = ptr TInternalstate + PInternalState* = ptr TInternalState TZStream*{.final, pure.} = object - next_in*: pbytef - avail_in*: uInt - total_in*: uLong - next_out*: pbytef - avail_out*: uInt - total_out*: uLong - msg*: pbytef + nextIn*: Pbytef + availIn*: Uint + totalIn*: Ulong + nextOut*: Pbytef + availOut*: Uint + totalOut*: Ulong + msg*: Pbytef state*: PInternalState - zalloc*: TAllocFunc + zalloc*: TAllocfunc zfree*: TFreeFunc opaque*: pointer - data_type*: int32 - adler*: uLong - reserved*: uLong + dataType*: int32 + adler*: Ulong + reserved*: Ulong TZStreamRec* = TZStream PZstream* = ptr TZStream - gzFile* = pointer + GzFile* = pointer const Z_NO_FLUSH* = 0 @@ -78,79 +78,79 @@ proc inflate*(strm: var TZStream, flush: int32): int32{.cdecl, dynlib: libz, importc: "inflate".} proc inflateEnd*(strm: var TZStream): int32{.cdecl, dynlib: libz, importc: "inflateEnd".} -proc deflateSetDictionary*(strm: var TZStream, dictionary: pbytef, - dictLength: uInt): int32{.cdecl, dynlib: libz, +proc deflateSetDictionary*(strm: var TZStream, dictionary: Pbytef, + dictLength: Uint): int32{.cdecl, dynlib: libz, importc: "deflateSetDictionary".} -proc deflateCopy*(dest, source: var TZstream): int32{.cdecl, dynlib: libz, +proc deflateCopy*(dest, source: var TZStream): int32{.cdecl, dynlib: libz, importc: "deflateCopy".} proc deflateReset*(strm: var TZStream): int32{.cdecl, dynlib: libz, importc: "deflateReset".} proc deflateParams*(strm: var TZStream, level: int32, strategy: int32): int32{. cdecl, dynlib: libz, importc: "deflateParams".} -proc inflateSetDictionary*(strm: var TZStream, dictionary: pbytef, - dictLength: uInt): int32{.cdecl, dynlib: libz, +proc inflateSetDictionary*(strm: var TZStream, dictionary: Pbytef, + dictLength: Uint): int32{.cdecl, dynlib: libz, importc: "inflateSetDictionary".} proc inflateSync*(strm: var TZStream): int32{.cdecl, dynlib: libz, importc: "inflateSync".} proc inflateReset*(strm: var TZStream): int32{.cdecl, dynlib: libz, importc: "inflateReset".} -proc compress*(dest: pbytef, destLen: puLongf, source: pbytef, sourceLen: uLong): cint{. +proc compress*(dest: Pbytef, destLen: Pulongf, source: Pbytef, sourceLen: Ulong): cint{. cdecl, dynlib: libz, importc: "compress".} -proc compress2*(dest: pbytef, destLen: puLongf, source: pbytef, - sourceLen: uLong, level: cint): cint{.cdecl, dynlib: libz, +proc compress2*(dest: Pbytef, destLen: Pulongf, source: Pbytef, + sourceLen: Ulong, level: cint): cint{.cdecl, dynlib: libz, importc: "compress2".} -proc uncompress*(dest: pbytef, destLen: puLongf, source: pbytef, - sourceLen: uLong): cint{.cdecl, dynlib: libz, +proc uncompress*(dest: Pbytef, destLen: Pulongf, source: Pbytef, + sourceLen: Ulong): cint{.cdecl, dynlib: libz, importc: "uncompress".} -proc compressBound*(sourceLen: uLong): uLong {.cdecl, dynlib: libz, importc.} -proc gzopen*(path: cstring, mode: cstring): gzFile{.cdecl, dynlib: libz, +proc compressBound*(sourceLen: Ulong): Ulong {.cdecl, dynlib: libz, importc.} +proc gzopen*(path: cstring, mode: cstring): GzFile{.cdecl, dynlib: libz, importc: "gzopen".} -proc gzdopen*(fd: int32, mode: cstring): gzFile{.cdecl, dynlib: libz, +proc gzdopen*(fd: int32, mode: cstring): GzFile{.cdecl, dynlib: libz, importc: "gzdopen".} -proc gzsetparams*(thefile: gzFile, level: int32, strategy: int32): int32{.cdecl, +proc gzsetparams*(thefile: GzFile, level: int32, strategy: int32): int32{.cdecl, dynlib: libz, importc: "gzsetparams".} -proc gzread*(thefile: gzFile, buf: pointer, length: int): int32{.cdecl, +proc gzread*(thefile: GzFile, buf: pointer, length: int): int32{.cdecl, dynlib: libz, importc: "gzread".} -proc gzwrite*(thefile: gzFile, buf: pointer, length: int): int32{.cdecl, +proc gzwrite*(thefile: GzFile, buf: pointer, length: int): int32{.cdecl, dynlib: libz, importc: "gzwrite".} -proc gzprintf*(thefile: gzFile, format: pbytef): int32{.varargs, cdecl, +proc gzprintf*(thefile: GzFile, format: Pbytef): int32{.varargs, cdecl, dynlib: libz, importc: "gzprintf".} -proc gzputs*(thefile: gzFile, s: pbytef): int32{.cdecl, dynlib: libz, +proc gzputs*(thefile: GzFile, s: Pbytef): int32{.cdecl, dynlib: libz, importc: "gzputs".} -proc gzgets*(thefile: gzFile, buf: pbytef, length: int32): pbytef{.cdecl, +proc gzgets*(thefile: GzFile, buf: Pbytef, length: int32): Pbytef{.cdecl, dynlib: libz, importc: "gzgets".} -proc gzputc*(thefile: gzFile, c: char): char{.cdecl, dynlib: libz, +proc gzputc*(thefile: GzFile, c: char): char{.cdecl, dynlib: libz, importc: "gzputc".} -proc gzgetc*(thefile: gzFile): char{.cdecl, dynlib: libz, importc: "gzgetc".} -proc gzflush*(thefile: gzFile, flush: int32): int32{.cdecl, dynlib: libz, +proc gzgetc*(thefile: GzFile): char{.cdecl, dynlib: libz, importc: "gzgetc".} +proc gzflush*(thefile: GzFile, flush: int32): int32{.cdecl, dynlib: libz, importc: "gzflush".} -proc gzseek*(thefile: gzFile, offset: z_off_t, whence: int32): z_off_t{.cdecl, +proc gzseek*(thefile: GzFile, offset: ZOffT, whence: int32): ZOffT{.cdecl, dynlib: libz, importc: "gzseek".} -proc gzrewind*(thefile: gzFile): int32{.cdecl, dynlib: libz, importc: "gzrewind".} -proc gztell*(thefile: gzFile): z_off_t{.cdecl, dynlib: libz, importc: "gztell".} -proc gzeof*(thefile: gzFile): int {.cdecl, dynlib: libz, importc: "gzeof".} -proc gzclose*(thefile: gzFile): int32{.cdecl, dynlib: libz, importc: "gzclose".} -proc gzerror*(thefile: gzFile, errnum: var int32): pbytef{.cdecl, dynlib: libz, +proc gzrewind*(thefile: GzFile): int32{.cdecl, dynlib: libz, importc: "gzrewind".} +proc gztell*(thefile: GzFile): ZOffT{.cdecl, dynlib: libz, importc: "gztell".} +proc gzeof*(thefile: GzFile): int {.cdecl, dynlib: libz, importc: "gzeof".} +proc gzclose*(thefile: GzFile): int32{.cdecl, dynlib: libz, importc: "gzclose".} +proc gzerror*(thefile: GzFile, errnum: var int32): Pbytef{.cdecl, dynlib: libz, importc: "gzerror".} -proc adler32*(adler: uLong, buf: pbytef, length: uInt): uLong{.cdecl, +proc adler32*(adler: Ulong, buf: Pbytef, length: Uint): Ulong{.cdecl, dynlib: libz, importc: "adler32".} ## **Warning**: Adler-32 requires at least a few hundred bytes to get rolling. -proc crc32*(crc: uLong, buf: pbytef, length: uInt): uLong{.cdecl, dynlib: libz, +proc crc32*(crc: Ulong, buf: Pbytef, length: Uint): Ulong{.cdecl, dynlib: libz, importc: "crc32".} proc deflateInitu*(strm: var TZStream, level: int32, version: cstring, - stream_size: int32): int32{.cdecl, dynlib: libz, + streamSize: int32): int32{.cdecl, dynlib: libz, importc: "deflateInit_".} proc inflateInitu*(strm: var TZStream, version: cstring, - stream_size: int32): int32 {. + streamSize: int32): int32 {. cdecl, dynlib: libz, importc: "inflateInit_".} proc deflateInit*(strm: var TZStream, level: int32): int32 proc inflateInit*(strm: var TZStream): int32 proc deflateInit2u*(strm: var TZStream, level: int32, `method`: int32, windowBits: int32, memLevel: int32, strategy: int32, - version: cstring, stream_size: int32): int32 {.cdecl, + version: cstring, streamSize: int32): int32 {.cdecl, dynlib: libz, importc: "deflateInit2_".} proc inflateInit2u*(strm: var TZStream, windowBits: int32, version: cstring, - stream_size: int32): int32{.cdecl, dynlib: libz, + streamSize: int32): int32{.cdecl, dynlib: libz, importc: "inflateInit2_".} proc deflateInit2*(strm: var TZStream, level, `method`, windowBits, memLevel, @@ -159,29 +159,29 @@ proc inflateInit2*(strm: var TZStream, windowBits: int32): int32 proc zError*(err: int32): cstring{.cdecl, dynlib: libz, importc: "zError".} proc inflateSyncPoint*(z: PZstream): int32{.cdecl, dynlib: libz, importc: "inflateSyncPoint".} -proc get_crc_table*(): pointer{.cdecl, dynlib: libz, importc: "get_crc_table".} +proc getCrcTable*(): pointer{.cdecl, dynlib: libz, importc: "get_crc_table".} proc deflateInit(strm: var TZStream, level: int32): int32 = - result = deflateInitu(strm, level, ZLIB_VERSION(), sizeof(TZStream).cint) + result = deflateInitu(strm, level, zlibVersion(), sizeof(TZStream).cint) proc inflateInit(strm: var TZStream): int32 = - result = inflateInitu(strm, ZLIB_VERSION(), sizeof(TZStream).cint) + result = inflateInitu(strm, zlibVersion(), sizeof(TZStream).cint) proc deflateInit2(strm: var TZStream, level, `method`, windowBits, memLevel, strategy: int32): int32 = result = deflateInit2u(strm, level, `method`, windowBits, memLevel, - strategy, ZLIB_VERSION(), sizeof(TZStream).cint) + strategy, zlibVersion(), sizeof(TZStream).cint) proc inflateInit2(strm: var TZStream, windowBits: int32): int32 = - result = inflateInit2u(strm, windowBits, ZLIB_VERSION(), + result = inflateInit2u(strm, windowBits, zlibVersion(), sizeof(TZStream).cint) -proc zlibAllocMem*(AppData: Pointer, Items, Size: int): Pointer {.cdecl.} = - result = Alloc(Items * Size) +proc zlibAllocMem*(appData: pointer, items, size: int): pointer {.cdecl.} = + result = alloc(items * size) -proc zlibFreeMem*(AppData, `Block`: Pointer) {.cdecl.} = - dealloc(`Block`) +proc zlibFreeMem*(appData, `block`: pointer) {.cdecl.} = + dealloc(`block`) proc uncompress*(sourceBuf: cstring, sourceLen: int): string = ## Given a deflated cstring returns its inflated version. @@ -202,7 +202,7 @@ proc uncompress*(sourceBuf: cstring, sourceLen: int): string = var z: TZStream # Initialize input. - z.next_in = sourceBuf + z.nextIn = sourceBuf # Input left to decompress. var left = zlib.Uint(sourceLen) @@ -220,12 +220,12 @@ proc uncompress*(sourceBuf: cstring, sourceLen: int): string = var decompressed = newStringOfCap(space) # Initialize output. - z.next_out = addr(decompressed[0]) + z.nextOut = addr(decompressed[0]) # Output generated so far. var have = 0 # Set up for gzip decoding. - z.avail_in = 0; + z.availIn = 0; var status = inflateInit2(z, (15+16)) if status != Z_OK: # Out of memory. @@ -241,10 +241,10 @@ proc uncompress*(sourceBuf: cstring, sourceLen: int): string = discard inflateReset(z) # Provide input for inflate. - if z.avail_in == 0: + if z.availIn == 0: # This only makes sense in the C version using unsigned values. - z.avail_in = left - left -= z.avail_in + z.availIn = left + left -= z.availIn # Decompress the available input. while true: @@ -260,15 +260,15 @@ proc uncompress*(sourceBuf: cstring, sourceLen: int): string = # Increase space. decompressed.setLen(space) # Update output pointer (might have moved). - z.next_out = addr(decompressed[have]) + z.nextOut = addr(decompressed[have]) # Provide output space for inflate. - z.avail_out = zlib.Uint(space - have) - have += z.avail_out; + z.availOut = zlib.Uint(space - have) + have += z.availOut; # Inflate and update the decompressed size. status = inflate(z, Z_SYNC_FLUSH); - have -= z.avail_out; + have -= z.availOut; # Bail out if any errors. if status != Z_OK and status != Z_BUF_ERROR and status != Z_STREAM_END: @@ -279,10 +279,10 @@ proc uncompress*(sourceBuf: cstring, sourceLen: int): string = # Repeat until all output is generated from provided input (note # that even if z.avail_in is zero, there may still be pending # output -- we're not done until the output buffer isn't filled) - if z.avail_out != 0: + if z.availOut != 0: break # Continue until all input consumed. - if left == 0 and z.avail_in == 0: + if left == 0 and z.availIn == 0: break # Verify that the input is a valid gzip stream. diff --git a/lib/wrappers/zip/zzip.nim b/lib/wrappers/zip/zzip.nim index a656322ee..73fd53c34 100644 --- a/lib/wrappers/zip/zzip.nim +++ b/lib/wrappers/zip/zzip.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2008 Andreas Rumpf # # See the file "copying.txt", included in this |