diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pure/logging.nim | 31 | ||||
-rw-r--r-- | lib/pure/os.nim | 4 | ||||
-rw-r--r-- | lib/pure/parseutils.nim | 32 | ||||
-rw-r--r-- | lib/pure/terminal.nim | 35 | ||||
-rw-r--r-- | lib/system.nim | 53 | ||||
-rw-r--r-- | lib/system/arithm.nim | 2 |
6 files changed, 110 insertions, 47 deletions
diff --git a/lib/pure/logging.nim b/lib/pure/logging.nim index 379c18e9d..b28298dfa 100644 --- a/lib/pure/logging.nim +++ b/lib/pure/logging.nim @@ -19,7 +19,12 @@ ## ============ ======================= ## $date Current date ## $time Current time +## $datetime $dateT$time ## $app ``os.getAppFilename()`` +## $appname base name of $app +## $appdir directory name of $app +## $levelid first letter of log level +## $levelname log level name ## ============ ======================= ## ## @@ -59,8 +64,8 @@ const "DEBUG", "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "NONE" ] - defaultFmtStr* = "" ## default string between log level and message per logger - verboseFmtStr* = "$date $time " + defaultFmtStr* = "$levelname " ## default format string + verboseFmtStr* = "$levelid, [$datetime] -- $appname: " type Logger* = ref object of RootObj ## abstract logger; the base type of all loggers @@ -87,12 +92,11 @@ type {.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 - ## converts $app to getAppFilename() - ## converts - result = newStringOfCap(frmt.len + 20) +proc substituteLog(frmt: string, level: Level, args: varargs[string, `$`]): string = + var msgLen = 0 + for arg in args: + msgLen += arg.len + result = newStringOfCap(frmt.len + msgLen + 20) var i = 0 while i < frmt.len: if frmt[i] != '$': @@ -108,10 +112,15 @@ proc substituteLog(frmt: string): string = case v of "date": result.add(getDateStr()) of "time": result.add(getClockStr()) + of "datetime": result.add(getDateStr() & "T" & getClockStr()) of "app": result.add(app) of "appdir": result.add(app.splitFile.dir) of "appname": result.add(app.splitFile.name) + of "levelid": result.add(LevelNames[level][0]) + of "levelname": result.add(LevelNames[level]) else: discard + for arg in args: + result.add(arg) method log*(logger: Logger, level: Level, args: varargs[string, `$`]) {. raises: [Exception], @@ -123,12 +132,12 @@ method log*(logger: Logger, level: Level, args: varargs[string, `$`]) {. method log*(logger: ConsoleLogger, level: Level, args: varargs[string, `$`]) = ## Logs to the console using ``logger`` only. if level >= logger.levelThreshold: - writeln(stdout, LevelNames[level], " ", substituteLog(logger.fmtStr), args) + writeln(stdout, substituteLog(logger.fmtStr, level, args)) method log*(logger: FileLogger, level: Level, args: varargs[string, `$`]) = ## Logs to a file using ``logger`` only. if level >= logger.levelThreshold: - writeln(logger.f, LevelNames[level], " ", substituteLog(logger.fmtStr), args) + writeln(logger.f, substituteLog(logger.fmtStr, level, args)) proc defaultFilename*(): string = ## Returns the default filename for a logger. @@ -219,7 +228,7 @@ method log*(logger: RollingFileLogger, level: Level, args: varargs[string, `$`]) logger.curLine = 0 logger.f = open(logger.baseName, logger.baseMode, bufSize = logger.bufSize) - writeln(logger.f, LevelNames[level], " ", substituteLog(logger.fmtStr), args) + writeln(logger.f, substituteLog(logger.fmtStr, level, args)) logger.curLine.inc # -------- diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 4deb79f86..f29505590 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -1304,7 +1304,9 @@ iterator walkDir*(dir: string): tuple[kind: PathComponent, path: string] {. when defined(linux) or defined(macosx) or defined(bsd): if x.d_type != DT_UNKNOWN: if x.d_type == DT_DIR: k = pcDir - if x.d_type == DT_LNK: k = succ(k) + if x.d_type == DT_LNK: + if dirExists(y): k = pcLinkToDir + else: k = succ(k) yield (k, y) continue diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim index c07b713de..b3708838a 100644 --- a/lib/pure/parseutils.nim +++ b/lib/pure/parseutils.nim @@ -26,7 +26,7 @@ proc toLower(c: char): char {.inline.} = result = if c in {'A'..'Z'}: chr(ord(c)-ord('A')+ord('a')) else: c proc parseHex*(s: string, number: var int, start = 0): int {. - rtl, extern: "npuParseHex", noSideEffect.} = + rtl, extern: "npuParseHex", noSideEffect.} = ## Parses a hexadecimal number and stores its value in ``number``. ## ## Returns the number of the parsed characters or 0 in case of an error. This @@ -49,7 +49,7 @@ proc parseHex*(s: string, number: var int, start = 0): int {. var foundDigit = false if s[i] == '0' and (s[i+1] == 'x' or s[i+1] == 'X'): inc(i, 2) elif s[i] == '#': inc(i) - while true: + while true: case s[i] of '_': discard of '0'..'9': @@ -66,13 +66,13 @@ proc parseHex*(s: string, number: var int, start = 0): int {. if foundDigit: result = i-start proc parseOct*(s: string, number: var int, start = 0): int {. - rtl, extern: "npuParseOct", noSideEffect.} = + rtl, extern: "npuParseOct", noSideEffect.} = ## parses an octal number and stores its value in ``number``. Returns ## the number of the parsed characters or 0 in case of an error. var i = start var foundDigit = false if s[i] == '0' and (s[i+1] == 'o' or s[i+1] == 'O'): inc(i, 2) - while true: + while true: case s[i] of '_': discard of '0'..'7': @@ -93,7 +93,7 @@ proc parseIdent*(s: string, ident: var string, start = 0): int = result = i-start proc parseIdent*(s: string, start = 0): string = - ## parses an identifier and stores it in ``ident``. + ## parses an identifier and stores it in ``ident``. ## Returns the parsed identifier or an empty string in case of an error. result = "" var i = start @@ -101,14 +101,14 @@ proc parseIdent*(s: string, start = 0): string = if s[i] in IdentStartChars: inc(i) while s[i] in IdentChars: inc(i) - + result = substr(s, start, i-1) proc parseToken*(s: string, token: var string, validChars: set[char], start = 0): int {.inline, deprecated.} = ## parses a token and stores it in ``token``. Returns ## the number of the parsed characters or 0 in case of an error. A token - ## consists of the characters in `validChars`. + ## consists of the characters in `validChars`. ## ## **Deprecated since version 0.8.12**: Use ``parseWhile`` instead. var i = start @@ -126,13 +126,13 @@ proc skip*(s, token: string, start = 0): int {.inline.} = ## or 0 if there was no `token` at ``s[start]``. while result < token.len and s[result+start] == token[result]: inc(result) if result != token.len: result = 0 - + proc skipIgnoreCase*(s, token: string, start = 0): int = ## same as `skip` but case is ignored for token matching. while result < token.len and toLower(s[result+start]) == toLower(token[result]): inc(result) if result != token.len: result = 0 - + proc skipUntil*(s: string, until: set[char], start = 0): int {.inline.} = ## Skips all characters until one char from the set `until` is found ## or the end is reached. @@ -154,7 +154,7 @@ proc parseUntil*(s: string, token: var string, until: set[char], start = 0): int {.inline.} = ## parses a token and stores it in ``token``. Returns ## the number of the parsed characters or 0 in case of an error. A token - ## consists of the characters notin `until`. + ## consists of the characters notin `until`. var i = start while i < s.len and s[i] notin until: inc(i) result = i-start @@ -174,7 +174,7 @@ proc parseWhile*(s: string, token: var string, validChars: set[char], start = 0): int {.inline.} = ## parses a token and stores it in ``token``. Returns ## the number of the parsed characters or 0 in case of an error. A token - ## consists of the characters in `validChars`. + ## consists of the characters in `validChars`. var i = start while s[i] in validChars: inc(i) result = i-start @@ -214,7 +214,7 @@ proc parseBiggestInt*(s: string, number: var BiggestInt, start = 0): int {. ## `EOverflow` is raised if an overflow occurs. var res: BiggestInt # use 'res' for exception safety (don't write to 'number' in case of an - # overflow exception: + # overflow exception): result = rawParseInt(s, res, start) number = res @@ -246,7 +246,7 @@ proc parseFloat*(s: string, number: var float, start = 0): int {. result = parseBiggestFloat(s, bf, start) if result != 0: number = bf - + type InterpolatedKind* = enum ## describes for `interpolatedFragments` ## which part of the interpolated string is @@ -289,12 +289,12 @@ iterator interpolatedFragments*(s: string): tuple[kind: InterpolatedKind, case s[j] of '{': inc nesting of '}': - if nesting == 0: + if nesting == 0: inc j break dec nesting of '\0': - raise newException(ValueError, + raise newException(ValueError, "Expected closing '}': " & substr(s, i, s.high)) else: discard inc j @@ -310,7 +310,7 @@ iterator interpolatedFragments*(s: string): tuple[kind: InterpolatedKind, inc i # skip $ kind = ikDollar else: - raise newException(ValueError, + raise newException(ValueError, "Unable to parse a varible name at " & substr(s, i, s.high)) else: while j < s.len and s[j] != '$': inc j diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim index 15e2eefec..2efdf72d5 100644 --- a/lib/pure/terminal.nim +++ b/lib/pure/terminal.nim @@ -406,22 +406,43 @@ proc isatty*(f: File): bool = result = isatty(getFileHandle(f)) != 0'i32 -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 +type + TerminalCmd* = enum ## commands that can be expressed as arguments + resetStyle ## reset attributes + +template styledEchoProcessArg(s: string) = write stdout, s +template styledEchoProcessArg(style: Style) = setStyle({style}) +template styledEchoProcessArg(style: set[Style]) = setStyle style +template styledEchoProcessArg(color: ForegroundColor) = setForegroundColor color +template styledEchoProcessArg(color: BackgroundColor) = setBackgroundColor color +template styledEchoProcessArg(cmd: TerminalCmd) = + when cmd == resetStyle: + resetAttributes() macro styledEcho*(m: varargs[expr]): stmt = ## to be documented. let m = callsite() + var reset = false result = newNimNode(nnkStmtList) for i in countup(1, m.len - 1): - result.add(newCall(bindSym"styledEchoProcessArg", m[i])) + let item = m[i] + case item.kind + of nnkStrLit..nnkTripleStrLit: + if i == m.len - 1: + # optimize if string literal is last, just call writeln + result.add(newCall(bindSym"writeln", bindSym"stdout", item)) + if reset: result.add(newCall(bindSym"resetAttributes")) + return + else: + # if it is string literal just call write, do not enable reset + result.add(newCall(bindSym"write", bindSym"stdout", item)) + else: + result.add(newCall(bindSym"styledEchoProcessArg", item)) + reset = true result.add(newCall(bindSym"write", bindSym"stdout", newStrLitNode("\n"))) - result.add(newCall(bindSym"resetAttributes")) + if reset: result.add(newCall(bindSym"resetAttributes")) when defined(nimdoc): proc getch*(): char = diff --git a/lib/system.nim b/lib/system.nim index 2204a5436..62c024d77 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -677,35 +677,50 @@ proc `not` *(x: int): int {.magic: "BitnotI", noSideEffect.} proc `not` *(x: int8): int8 {.magic: "BitnotI", noSideEffect.} proc `not` *(x: int16): int16 {.magic: "BitnotI", noSideEffect.} proc `not` *(x: int32): int32 {.magic: "BitnotI", noSideEffect.} -proc `not` *(x: int64): int64 {.magic: "BitnotI", noSideEffect.} ## computes the `bitwise complement` of the integer `x`. +when defined(nimnomagic64): + proc `not` *(x: int64): int64 {.magic: "BitnotI", noSideEffect.} +else: + proc `not` *(x: int64): int64 {.magic: "BitnotI64", noSideEffect.} + proc `+` *(x, y: int): int {.magic: "AddI", noSideEffect.} proc `+` *(x, y: int8): int8 {.magic: "AddI", noSideEffect.} proc `+` *(x, y: int16): int16 {.magic: "AddI", noSideEffect.} proc `+` *(x, y: int32): int32 {.magic: "AddI", noSideEffect.} -proc `+` *(x, y: int64): int64 {.magic: "AddI", noSideEffect.} ## Binary `+` operator for an integer. +when defined(nimnomagic64): + proc `+` *(x, y: int64): int64 {.magic: "AddI", noSideEffect.} +else: + proc `+` *(x, y: int64): int64 {.magic: "AddI64", noSideEffect.} + proc `-` *(x, y: int): int {.magic: "SubI", noSideEffect.} proc `-` *(x, y: int8): int8 {.magic: "SubI", noSideEffect.} proc `-` *(x, y: int16): int16 {.magic: "SubI", noSideEffect.} proc `-` *(x, y: int32): int32 {.magic: "SubI", noSideEffect.} -proc `-` *(x, y: int64): int64 {.magic: "SubI", noSideEffect.} ## Binary `-` operator for an integer. +when defined(nimnomagic64): + proc `-` *(x, y: int64): int64 {.magic: "SubI", noSideEffect.} +else: + proc `-` *(x, y: int64): int64 {.magic: "SubI64", noSideEffect.} + proc `*` *(x, y: int): int {.magic: "MulI", noSideEffect.} proc `*` *(x, y: int8): int8 {.magic: "MulI", noSideEffect.} proc `*` *(x, y: int16): int16 {.magic: "MulI", noSideEffect.} proc `*` *(x, y: int32): int32 {.magic: "MulI", noSideEffect.} -proc `*` *(x, y: int64): int64 {.magic: "MulI", noSideEffect.} ## Binary `*` operator for an integer. +when defined(nimnomagic64): + proc `*` *(x, y: int64): int64 {.magic: "MulI", noSideEffect.} +else: + proc `*` *(x, y: int64): int64 {.magic: "MulI64", noSideEffect.} + proc `div` *(x, y: int): int {.magic: "DivI", noSideEffect.} proc `div` *(x, y: int8): int8 {.magic: "DivI", noSideEffect.} proc `div` *(x, y: int16): int16 {.magic: "DivI", noSideEffect.} proc `div` *(x, y: int32): int32 {.magic: "DivI", noSideEffect.} -proc `div` *(x, y: int64): int64 {.magic: "DivI", noSideEffect.} ## computes the integer division. This is roughly the same as ## ``floor(x/y)``. ## @@ -714,14 +729,23 @@ proc `div` *(x, y: int64): int64 {.magic: "DivI", noSideEffect.} ## 2 div 2 == 1 ## 3 div 2 == 1 +when defined(nimnomagic64): + proc `div` *(x, y: int64): int64 {.magic: "DivI", noSideEffect.} +else: + proc `div` *(x, y: int64): int64 {.magic: "DivI64", noSideEffect.} + proc `mod` *(x, y: int): int {.magic: "ModI", noSideEffect.} proc `mod` *(x, y: int8): int8 {.magic: "ModI", noSideEffect.} proc `mod` *(x, y: int16): int16 {.magic: "ModI", noSideEffect.} proc `mod` *(x, y: int32): int32 {.magic: "ModI", noSideEffect.} -proc `mod` *(x, y: int64): int64 {.magic: "ModI", noSideEffect.} ## computes the integer modulo operation. This is the same as ## ``x - (x div y) * y``. +when defined(nimnomagic64): + proc `mod` *(x, y: int64): int64 {.magic: "ModI", noSideEffect.} +else: + proc `mod` *(x, y: int64): int64 {.magic: "ModI64", noSideEffect.} + proc `shr` *(x, y: int): int {.magic: "ShrI", noSideEffect.} proc `shr` *(x, y: int8): int8 {.magic: "ShrI", noSideEffect.} proc `shr` *(x, y: int16): int16 {.magic: "ShrI", noSideEffect.} @@ -2304,11 +2328,18 @@ proc abs*(x: int16): int16 {.magic: "AbsI", noSideEffect.} = if x < 0: -x else: x proc abs*(x: int32): int32 {.magic: "AbsI", noSideEffect.} = if x < 0: -x else: x -proc abs*(x: int64): int64 {.magic: "AbsI", noSideEffect.} = - ## returns the absolute value of `x`. If `x` is ``low(x)`` (that - ## is -MININT for its type), an overflow exception is thrown (if overflow - ## checking is turned on). - if x < 0: -x else: x +when defined(nimnomagic64): + proc abs*(x: int64): int64 {.magic: "AbsI", noSideEffect.} = + ## returns the absolute value of `x`. If `x` is ``low(x)`` (that + ## is -MININT for its type), an overflow exception is thrown (if overflow + ## checking is turned on). + if x < 0: -x else: x +else: + proc abs*(x: int64): int64 {.magic: "AbsI64", noSideEffect.} = + ## returns the absolute value of `x`. If `x` is ``low(x)`` (that + ## is -MININT for its type), an overflow exception is thrown (if overflow + ## checking is turned on). + if x < 0: -x else: x {.pop.} when not defined(JS): #and not defined(NimrodVM): diff --git a/lib/system/arithm.nim b/lib/system/arithm.nim index 907907e24..69c558799 100644 --- a/lib/system/arithm.nim +++ b/lib/system/arithm.nim @@ -18,7 +18,7 @@ proc raiseDivByZero {.compilerproc, noinline.} = sysFatal(DivByZeroError, "division by zero") when defined(builtinOverflow): -# Builtin compiler functions for improved performance + # Builtin compiler functions for improved performance when sizeof(clong) == 8: proc addInt64Overflow[T: int64|int](a, b: T, c: var T): bool {. importc: "__builtin_saddl_overflow", nodecl, nosideeffect.} |