diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pure/collections/sequtils.nim | 4 | ||||
-rwxr-xr-x | lib/pure/math.nim | 31 | ||||
-rwxr-xr-x | lib/pure/strutils.nim | 40 | ||||
-rwxr-xr-x | lib/system.nim | 47 | ||||
-rwxr-xr-x | lib/wrappers/gtk/gtk2.nim | 17 |
5 files changed, 127 insertions, 12 deletions
diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim index 73713eec9..298e7f27e 100644 --- a/lib/pure/collections/sequtils.nim +++ b/lib/pure/collections/sequtils.nim @@ -12,8 +12,8 @@ ## This module implements operations for the built-in `seq`:idx: type which ## were inspired by functional programming languages. If you are looking for ## the typical `map` function which applies a function to every element in a -## sequence, it already exists as the `each` proc in the `system -## <system.html>`_ module in both mutable and immutable styles. +## sequence, it already exists in the `system <system.html>`_ module in both +## mutable and immutable styles. ## ## Also, for functional style programming you may want to pass `anonymous procs ## <manual.html#anonymous-procs>`_ to procs like ``filter`` to reduce typing. diff --git a/lib/pure/math.nim b/lib/pure/math.nim index 53594db62..f9ab6d0f8 100755 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -141,6 +141,11 @@ proc randomize*() ## number, i.e. a tickcount. Note: Does nothing for the ECMAScript target, ## as ECMAScript does not support this. +proc randomize*(seed: int) + ## initializes the random number generator with a specific seed. + ## Note: Does nothing for the ECMAScript target, + ## as ECMAScript does not support this. + when not defined(ECMAScript): proc sqrt*(x: float): float {.importc: "sqrt", header: "<math.h>".} ## computes the square root of `x`. @@ -190,15 +195,17 @@ when not defined(ECMAScript): proc rand(): cint {.importc: "rand", nodecl.} when not defined(windows): - proc srand48(seed: cint) {.importc: "srand48", nodecl.} + proc srand48(seed: clong) {.importc: "srand48", nodecl.} proc drand48(): float {.importc: "drand48", nodecl.} proc random(max: float): float = result = drand48() * max proc randomize() = - let x = gettime(nil) - srand(x) - when defined(srand48): srand48(x) + randomize(gettime(nil)) + + proc randomize(seed: int) = + srand(cint(seed)) + when defined(srand48): srand48(seed) proc random(max: int): int = result = int(rand()) mod max @@ -217,6 +224,7 @@ else: proc random(max: float): float = result = float(mathrandom() * float(max)) proc randomize() = nil + proc randomize(seed: int) = nil proc sqrt*(x: float): float {.importc: "Math.sqrt", nodecl.} proc ln*(x: float): float {.importc: "Math.log", nodecl.} @@ -301,3 +309,18 @@ proc standardDeviation*(s: TRunningStat): float = {.pop.} {.pop.} + +when isMainModule and not defined(ECMAScript): + # Verifies random seed initialization. + let seed = gettime(nil) + randomize(seed) + const SIZE = 10 + var buf : array[0..SIZE, int] + # Fill the buffer with random values + for i in 0..SIZE-1: + buf[i] = random(high(int)) + # Check that the second random calls are the same for each position. + randomize(seed) + for i in 0..SIZE-1: + assert buf[i] == random(high(int)), "non deterministic random seeding" + echo "random values equal after reseeding" diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 8a5061037..8b64434d8 100755 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -850,13 +850,51 @@ proc escape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect, for c in items(s): case c of '\0'..'\31', '\128'..'\255': - add(result, '\\') + add(result, "\\x") add(result, toHex(ord(c), 2)) of '\\': add(result, "\\\\") of '\'': add(result, "\\'") of '\"': add(result, "\\\"") else: add(result, c) add(result, suffix) + +proc unescape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect, + rtl, extern: "nsuUnescape".} = + ## Unescapes a string `s`. This complements ``escape`` as it performs the + ## opposite operations. + ## + ## If `s` does not begin with ``prefix`` and end with ``suffix`` a EInvalidValue + ## exception will be raised. + result = newStringOfCap(s.len) + var i = 0 + if s[0 .. prefix.len-1] != prefix: + raise newException(EInvalidValue, + "String does not start with a prefix of: " & prefix) + i.inc() + while True: + if i == s.len-suffix.len: break + case s[i] + of '\\': + case s[i+1]: + of 'x': + let j = parseHexInt(s[i+2 .. i+3]) + result.add(chr(j)) + inc(i, 2) + of '\\': + result.add('\\') + of '\'': + result.add('\'') + of '\"': + result.add('\"') + else: result.add("\\" & s[i+1]) + inc(i) + of '\0': break + else: + result.add(s[i]) + i.inc() + if s[i .. -1] != suffix: + raise newException(EInvalidValue, + "String does not end with a suffix of: " & suffix) proc validIdentifier*(s: string): bool {.noSideEffect, rtl, extern: "nsuValidIdentifier".} = diff --git a/lib/system.nim b/lib/system.nim index f32b575e9..892f4f8c5 100755 --- a/lib/system.nim +++ b/lib/system.nim @@ -38,7 +38,8 @@ type char* {.magic: Char.} ## built-in 8 bit character type (unsigned) string* {.magic: String.} ## built-in string type cstring* {.magic: Cstring.} ## built-in cstring (*compatible string*) type - pointer* {.magic: Pointer.} ## built-in pointer type + pointer* {.magic: Pointer.} ## built-in pointer type, use the ``addr`` + ## operator to get a pointer to a variable const on* = true ## alias for ``true`` @@ -1460,15 +1461,51 @@ proc pop*[T](s: var seq[T]): T {.inline, noSideEffect.} = result = s[L] setLen(s, L) -proc each*[T, S](data: openArray[T], op: proc (x: T): S {.closure.}): seq[S] = - ## The well-known `map`:idx: operation from functional programming. Applies +proc each*[T, S](data: openArray[T], op: proc (x: T): S {.closure.}): seq[S] {. + deprecated.} = + ## The well-known ``map`` operation from functional programming. Applies ## `op` to every item in `data` and returns the result as a sequence. + ## + ## **Deprecated since version 0.9:** Use the ``map`` proc instead. newSeq(result, data.len) for i in 0..data.len-1: result[i] = op(data[i]) -proc each*[T](data: var openArray[T], op: proc (x: var T) {.closure.}) = - ## The well-known `map`:idx: operation from functional programming. Applies +proc each*[T](data: var openArray[T], op: proc (x: var T) {.closure.}) {. + deprecated.} = + ## The well-known ``map`` operation from functional programming. Applies ## `op` to every item in `data` modifying it directly. + ## + ## **Deprecated since version 0.9:** Use the ``map`` proc instead. + for i in 0..data.len-1: op(data[i]) + +proc map*[T, S](data: openArray[T], op: proc (x: T): S {.closure.}): seq[S] = + ## Returns a new sequence with the results of `op` applied to every item in + ## `data`. + ## + ## 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 + ## let + ## a = @[1, 2, 3, 4] + ## b = map(a, proc(x: int): string = $x) + ## assert b == @["1", "2", "3", "4"] + newSeq(result, data.len) + for i in 0..data.len-1: result[i] = op(data[i]) + +proc map*[T](data: var openArray[T], op: proc (x: var T) {.closure.}) = + ## Applies `op` to every item in `data` modifying it directly. + ## + ## Note that this version of ``map`` requires your input and output types to + ## be the same, since they are modified in-place. Example: + ## + ## .. code-block:: nimrod + ## var a = @["1", "2", "3", "4"] + ## echo repr(a) + ## # --> ["1", "2", "3", "4"] + ## map(a, proc(x: var string) = x &= "42") + ## echo repr(a) + ## # --> ["142", "242", "342", "442"] for i in 0..data.len-1: op(data[i]) iterator fields*[T: tuple](x: T): TObject {. diff --git a/lib/wrappers/gtk/gtk2.nim b/lib/wrappers/gtk/gtk2.nim index 7094bfd5d..6b418024e 100755 --- a/lib/wrappers/gtk/gtk2.nim +++ b/lib/wrappers/gtk/gtk2.nim @@ -16598,6 +16598,7 @@ proc message_dialog_new*(parent: PWindow, flags: TDialogFlags, cdecl, importc: "gtk_message_dialog_new", dynlib: lib.} proc set_markup*(msgDialog: PMessageDialog, str: cstring) {.cdecl, importc: "gtk_message_dialog_set_markup", dynlib: lib.} + proc signal_new*(name: cstring, signal_flags: TSignalRunType, object_type: TType, function_offset: guint, marshaller: TSignalMarshaller, return_val: TType, n_args: guint): guint{. @@ -16895,6 +16896,15 @@ type proc set_tooltip_text*(w: PWidget, t: cstring){.cdecl, dynlib: lib, importc: "gtk_widget_set_tooltip_text".} +proc get_tooltip_text*(w: PWidget): cstring{.cdecl, + dynlib: lib, importc: "gtk_widget_get_tooltip_text".} + +proc set_tooltip_markup*(w: PWidget, m: cstring) {.cdecl, dynlib: lib, + importc: "gtk_widget_set_tooltip_markup".} + +proc get_tooltip_markup*(w: PWidget): cstring {.cdecl, dynlib: lib, + importc: "gtk_widget_get_tooltip_markup".} + proc set_tooltip_column*(w: PTreeview, column: gint){.cdecl, dynlib: lib, importc: "gtk_tree_view_set_tooltip_column".} @@ -16907,6 +16917,9 @@ proc trigger_tooltip_query*(widg: PTooltip){.cdecl, dynlib: lib, proc set_has_tooltip*(widget: PWidget, b: gboolean){.cdecl, dynlib: lib, importc: "gtk_widget_set_has_tooltip".} +proc get_has_tooltip*(widget: PWidget): gboolean{.cdecl, dynlib: lib, + importc: "gtk_widget_get_has_tooltip".} + proc set_markup*(tp: PTooltip, mk: cstring){.cdecl, dynlib: lib, importc: "gtk_tooltip_set_markup".} @@ -17037,6 +17050,10 @@ proc remove*(combo_box: PComboBoxText; position: gint){.cdecl, importc: "gtk_combo_box_text_remove", dynlib: lib.} proc get_active_text*(combo_box: PComboBoxText): cstring{.cdecl, importc: "gtk_combo_box_text_get_active_text", dynlib: lib.} +proc is_active*(win: PWindow): gboolean{.cdecl, + importc: "gtk_window_is_active", dynlib: lib.} +proc has_toplevel_focus*(win: PWindow): gboolean{.cdecl, + importc: "gtk_window_has_toplevel_focus", dynlib: lib.} proc nimrod_init*() = var |