diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pure/collections/deques.nim | 5 | ||||
-rw-r--r-- | lib/pure/collections/queues.nim | 5 | ||||
-rw-r--r-- | lib/pure/collections/sets.nim | 4 | ||||
-rw-r--r-- | lib/pure/collections/tableimpl.nim | 7 | ||||
-rw-r--r-- | lib/pure/collections/tables.nim | 4 | ||||
-rw-r--r-- | lib/pure/osproc.nim | 14 | ||||
-rw-r--r-- | lib/pure/strscans.nim | 6 | ||||
-rw-r--r-- | lib/pure/terminal.nim | 48 | ||||
-rw-r--r-- | lib/pure/times.nim | 29 | ||||
-rw-r--r-- | lib/system.nim | 10 | ||||
-rw-r--r-- | lib/system/gc.nim | 16 | ||||
-rw-r--r-- | lib/system/mmdisp.nim | 2 | ||||
-rw-r--r-- | lib/system/sysio.nim | 4 | ||||
-rw-r--r-- | lib/wrappers/openssl.nim | 2 |
14 files changed, 120 insertions, 36 deletions
diff --git a/lib/pure/collections/deques.nim b/lib/pure/collections/deques.nim index c25429778..495d7896c 100644 --- a/lib/pure/collections/deques.nim +++ b/lib/pure/collections/deques.nim @@ -160,7 +160,10 @@ proc peekLast*[T](deq: Deque[T]): T {.inline.} = emptyCheck(deq) result = deq.data[(deq.tail - 1) and deq.mask] -proc default[T](t: typedesc[T]): T {.inline.} = discard +template default[T](t: typedesc[T]): T = + var v: T + v + proc popFirst*[T](deq: var Deque[T]): T {.inline, discardable.} = ## Remove and returns the first element of the `deq`. emptyCheck(deq) diff --git a/lib/pure/collections/queues.nim b/lib/pure/collections/queues.nim index e4d7eeef1..0490ae494 100644 --- a/lib/pure/collections/queues.nim +++ b/lib/pure/collections/queues.nim @@ -154,7 +154,10 @@ proc add*[T](q: var Queue[T], item: T) = q.data[q.wr] = item q.wr = (q.wr + 1) and q.mask -proc default[T](t: typedesc[T]): T {.inline.} = discard +template default[T](t: typedesc[T]): T = + var v: T + v + proc pop*[T](q: var Queue[T]): T {.inline, discardable.} = ## Remove and returns the first (oldest) element of the queue `q`. emptyCheck(q) diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim index 552e41ef7..b2ffbe58d 100644 --- a/lib/pure/collections/sets.nim +++ b/lib/pure/collections/sets.nim @@ -261,7 +261,9 @@ template doWhile(a, b) = b if not a: break -proc default[T](t: typedesc[T]): T {.inline.} = discard +template default[T](t: typedesc[T]): T = + var v: T + v proc excl*[A](s: var HashSet[A], key: A) = ## Excludes `key` from the set `s`. diff --git a/lib/pure/collections/tableimpl.nim b/lib/pure/collections/tableimpl.nim index 674fdddd2..5e871f08b 100644 --- a/lib/pure/collections/tableimpl.nim +++ b/lib/pure/collections/tableimpl.nim @@ -116,16 +116,15 @@ template hasKeyOrPutImpl(enlarge) {.dirty.} = maybeRehashPutImpl(enlarge) else: result = true -proc default[T](t: typedesc[T]): T {.inline.} = discard +template default[T](t: typedesc[T]): T = + var v: T + v template delImpl() {.dirty.} = var hc: Hash var i = rawGet(t, key, hc) let msk = maxHash(t) if i >= 0: - t.data[i].hcode = 0 - t.data[i].key = default(type(t.data[i].key)) - t.data[i].val = default(type(t.data[i].val)) dec(t.counter) block outer: while true: # KnuthV3 Algo6.4R adapted for i=i+1 instead of i=i-1 diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index e6e72d9ed..57e98bf5c 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -954,7 +954,7 @@ proc inc*[A](t: var CountTable[A], key: A, val = 1) = inc(t.counter) proc smallest*[A](t: CountTable[A]): tuple[key: A, val: int] = - ## returns the largest (key,val)-pair. Efficiency: O(n) + ## returns the (key,val)-pair with the smallest `val`. Efficiency: O(n) assert t.len > 0 var minIdx = 0 for h in 1..high(t.data): @@ -1080,7 +1080,7 @@ proc inc*[A](t: CountTableRef[A], key: A, val = 1) = t[].inc(key, val) proc smallest*[A](t: CountTableRef[A]): (A, int) = - ## returns the largest (key,val)-pair. Efficiency: O(n) + ## returns the (key,val)-pair with the smallest `val`. Efficiency: O(n) t[].smallest proc largest*[A](t: CountTableRef[A]): (A, int) = diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 76bd2dfe1..1d43bb321 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -965,10 +965,16 @@ elif not defined(useNimRtl): var ret : int var status : cint = 1 ret = waitpid(p.id, status, WNOHANG) - if WIFEXITED(status): - p.exitStatus = status - if ret == 0: return true # Can't establish status. Assume running. - result = ret == int(p.id) + if ret == int(p.id): + if WIFEXITED(status): + p.exitStatus = status + return false + else: + return true + elif ret == 0: + return true # Can't establish status. Assume running. + else: + return false proc terminate(p: Process) = if kill(p.id, SIGTERM) != 0'i32: diff --git a/lib/pure/strscans.nim b/lib/pure/strscans.nim index 246f018c5..fc400173f 100644 --- a/lib/pure/strscans.nim +++ b/lib/pure/strscans.nim @@ -76,7 +76,7 @@ to a variable (that was passed to the ``scanf`` macro) while ``$[]`` merely optional tokens. -In this example, we define a helper proc ``skipSep`` that skips some separators +In this example, we define a helper proc ``someSep`` that skips some separators which we then use in our scanf pattern to help us in the matching process: .. code-block:: nim @@ -86,14 +86,14 @@ which we then use in our scanf pattern to help us in the matching process: result = 0 while input[start+result] in seps: inc result - if scanf(input, "$w${someSep}$w", key, value): + if scanf(input, "$w$[someSep]$w", key, value): ... It also possible to pass arguments to a user definable matcher: .. code-block:: nim - proc ndigits(input: string; start: int; intVal: var int; n: int): int = + proc ndigits(input: string; intVal: var int; start: int; n: int): int = # matches exactly ``n`` digits. Matchers need to return 0 if nothing # matched or otherwise the number of processed chars. var x = 0 diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim index 16cf91d40..7a8113b2a 100644 --- a/lib/pure/terminal.nim +++ b/lib/pure/terminal.nim @@ -83,6 +83,13 @@ when defined(windows): return int(csbi.srWindow.Right - csbi.srWindow.Left + 1) return 0 + proc terminalHeightIoctl*(handles: openArray[Handle]): int = + var csbi: CONSOLE_SCREEN_BUFFER_INFO + for h in handles: + if getConsoleScreenBufferInfo(h, addr csbi) != 0: + return int(csbi.srWindow.Bottom - csbi.srWindow.Top + 1) + return 0 + proc terminalWidth*(): int = var w: int = 0 w = terminalWidthIoctl([ getStdHandle(STD_INPUT_HANDLE), @@ -91,6 +98,14 @@ when defined(windows): if w > 0: return w return 80 + proc terminalHeight*(): int = + var h: int = 0 + h = terminalHeightIoctl([ getStdHandle(STD_INPUT_HANDLE), + getStdHandle(STD_OUTPUT_HANDLE), + getStdHandle(STD_ERROR_HANDLE) ] ) + if h > 0: return h + return 0 + proc setConsoleCursorPosition(hConsoleOutput: HANDLE, dwCursorPosition: COORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "SetConsoleCursorPosition".} @@ -177,7 +192,17 @@ else: return int(win.ws_col) return 0 + proc terminalHeightIoctl*(fds: openArray[int]): int = + ## Returns terminal height from first fd that supports the ioctl. + + var win: IOctl_WinSize + for fd in fds: + if ioctl(cint(fd), TIOCGWINSZ, addr win) != -1: + return int(win.ws_row) + return 0 + var L_ctermid{.importc, header: "<stdio.h>".}: cint + proc terminalWidth*(): int = ## Returns some reasonable terminal width from either standard file ## descriptors, controlling terminal, environment variables or tradition. @@ -195,6 +220,29 @@ else: return w return 80 #Finally default to venerable value + proc terminalHeight*(): int = + ## Returns some reasonable terminal height from either standard file + ## descriptors, controlling terminal, environment variables or tradition. + ## Zero is returned if the height could not be determined. + + var h = terminalHeightIoctl([0, 1, 2]) # Try standard file descriptors + if h > 0: return h + var cterm = newString(L_ctermid) # Try controlling tty + var fd = open(ctermid(cstring(cterm)), O_RDONLY) + if fd != -1: + h = terminalHeightIoctl([ int(fd) ]) + discard close(fd) + if h > 0: return h + var s = getEnv("LINES") # Try standard env var + if len(s) > 0 and parseInt(string(s), h) > 0 and h > 0: + return h + return 0 # Could not determine height + +proc terminalSize*(): tuple[w, h: int] = + ## Returns the terminal width and height as a tuple. Internally calls + ## `terminalWidth` and `terminalHeight`, so the same assumptions apply. + result = (terminalWidth(), terminalHeight()) + when defined(windows): proc setCursorVisibility(f: File, visible: bool) = var ccsi: CONSOLE_CURSOR_INFO diff --git a/lib/pure/times.nim b/lib/pure/times.nim index 1767a37be..cf4e7dde6 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -436,6 +436,11 @@ when not defined(JS): TimeInfoPtr = ptr StructTM Clock {.importc: "clock_t".} = distinct int + when not defined(windows): + # This is not ANSI C, but common enough + proc timegm(t: StructTM): Time {. + importc: "timegm", header: "<time.h>", tags: [].} + proc localtime(timer: ptr Time): TimeInfoPtr {. importc: "localtime", header: "<time.h>", tags: [].} proc gmtime(timer: ptr Time): TimeInfoPtr {. @@ -515,20 +520,22 @@ when not defined(JS): # the conversion is not expensive 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 - result = mktime(timeInfoToTM(cTimeInfo)) - # mktime is defined to interpret the input as local time. As timeInfoToTM - # does ignore the timezone, we need to adjust this here. - result = Time(TimeImpl(result) - getTimezone() + timeInfo.timezone) + toTime(timeInfo) proc toTime(timeInfo: TimeInfo): Time = - var cTimeInfo = timeInfo # for C++ we have to make a copy, + var cTimeInfo = timeInfo # for C++ we have to make a copy # because the header of mktime is broken in my version of libc - result = mktime(timeInfoToTM(cTimeInfo)) - # mktime is defined to interpret the input as local time. As timeInfoToTM - # does ignore the timezone, we need to adjust this here. - result = Time(TimeImpl(result) - getTimezone() + timeInfo.timezone) + + when defined(windows): + # On Windows `mktime` is broken enough to make this work. + result = mktime(timeInfoToTM(cTimeInfo)) + # mktime is defined to interpret the input as local time. As timeInfoToTM + # does ignore the timezone, we need to adjust this here. + result = Time(TimeImpl(result) - getTimezone() + timeInfo.timezone) + else: + result = timegm(timeInfoToTM(cTimeInfo)) + # As timeInfoToTM does ignore the timezone, we need to adjust this here. + result = Time(TimeImpl(result) + timeInfo.timezone) const epochDiff = 116444736000000000'i64 diff --git a/lib/system.nim b/lib/system.nim index 69d3db291..8209dbc23 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2595,6 +2595,14 @@ else: if x < 0: -x else: x {.pop.} +type + FileSeekPos* = enum ## Position relative to which seek should happen + # The values are ordered so that they match with stdio + # SEEK_SET, SEEK_CUR and SEEK_END respectively. + fspSet ## Seek to absolute value + fspCur ## Seek relative to current position + fspEnd ## Seek relative to end + when not defined(JS): #and not defined(nimscript): {.push stack_trace: off, profiler:off.} @@ -2858,7 +2866,7 @@ when not defined(JS): #and not defined(nimscript): ## file `f`. Returns the number of actual written bytes, which may be less ## than `len` in case of an error. - proc setFilePos*(f: File, pos: int64) {.benign.} + proc setFilePos*(f: File, pos: int64, relativeTo: FileSeekPos = fspSet) {.benign.} ## sets the position of the file pointer that is used for read/write ## operations. The file's first byte has the index zero. diff --git a/lib/system/gc.nim b/lib/system/gc.nim index 7fb4c7ac7..6c418cc3a 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -153,13 +153,19 @@ template setColor(c, col) = proc writeCell(msg: cstring, c: PCell) = var kind = -1 - if c.typ != nil: kind = ord(c.typ.kind) + var typName: cstring = "nil" + if c.typ != nil: + kind = ord(c.typ.kind) + when defined(nimTypeNames): + if not c.typ.name.isNil: + typName = c.typ.name + when leakDetector: - c_fprintf(stdout, "[GC] %s: %p %d rc=%ld from %s(%ld)\n", - msg, c, kind, c.refcount shr rcShift, c.filename, c.line) + c_fprintf(stdout, "[GC] %s: %p %d %s rc=%ld from %s(%ld)\n", + msg, c, kind, typName, c.refcount shr rcShift, c.filename, c.line) else: - c_fprintf(stdout, "[GC] %s: %p %d rc=%ld; color=%ld\n", - msg, c, kind, c.refcount shr rcShift, c.color) + c_fprintf(stdout, "[GC] %s: %p %d %s rc=%ld; color=%ld\n", + msg, c, kind, typName, c.refcount shr rcShift, c.color) template gcTrace(cell, state: expr): stmt {.immediate.} = when traceGC: traceCell(cell, state) diff --git a/lib/system/mmdisp.nim b/lib/system/mmdisp.nim index 63af49e35..431f84bfd 100644 --- a/lib/system/mmdisp.nim +++ b/lib/system/mmdisp.nim @@ -20,7 +20,7 @@ const alwaysCycleGC = defined(smokeCycles) alwaysGC = defined(fulldebug) # collect after every memory # allocation (for debugging) - leakDetector = false + leakDetector = defined(leakDetector) overwriteFree = defined(nimBurnFree) # overwrite memory with 0xFF before free trackAllocationSource = leakDetector diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim index 5c10392f1..29c5777cc 100644 --- a/lib/system/sysio.nim +++ b/lib/system/sysio.nim @@ -336,8 +336,8 @@ proc open(f: var File, filehandle: FileHandle, mode: FileMode): bool = f = c_fdopen(filehandle, FormatOpen[mode]) result = f != nil -proc setFilePos(f: File, pos: int64) = - if c_fseek(f, clong(pos), 0) != 0: +proc setFilePos(f: File, pos: int64, relativeTo: FileSeekPos = fspSet) = + if c_fseek(f, clong(pos), cint(relativeTo)) != 0: raiseEIO("cannot set file position") proc getFilePos(f: File): int64 = diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim index 1bd02eaf0..5521476d9 100644 --- a/lib/wrappers/openssl.nim +++ b/lib/wrappers/openssl.nim @@ -293,6 +293,8 @@ proc SSL_get_error*(s: SslPtr, ret_code: cInt): cInt{.cdecl, dynlib: DLLSSLName, proc SSL_accept*(ssl: SslPtr): cInt{.cdecl, dynlib: DLLSSLName, importc.} proc SSL_pending*(ssl: SslPtr): cInt{.cdecl, dynlib: DLLSSLName, importc.} +proc BIO_new_mem_buf*(data: pointer, len: cint): BIO{.cdecl, + dynlib: DLLSSLName, importc.} proc BIO_new_ssl_connect*(ctx: SslCtx): BIO{.cdecl, dynlib: DLLSSLName, importc.} proc BIO_ctrl*(bio: BIO, cmd: cint, larg: int, arg: cstring): int{.cdecl, |