[backport] run nimpretty on string stuff

This commit is contained in:
narimiran 2019-09-27 11:20:18 +02:00
commit dcf3181bd1
11 changed files with 421 additions and 371 deletions

View file

@ -34,7 +34,9 @@ when defined(windows):
while i < a.len and j < b.len: while i < a.len and j < b.len:
if a[i] in {'-', '_'}: inc i if a[i] in {'-', '_'}: inc i
if b[j] in {'-', '_'}: inc j if b[j] in {'-', '_'}: inc j
if i < a.len and j < b.len and a[i].toLowerAscii != b[j].toLowerAscii: return false if i < a.len and j < b.len and
a[i].toLowerAscii != b[j].toLowerAscii:
return false
inc i inc i
inc j inc j
result = i == a.len and j == b.len result = i == a.len and j == b.len
@ -231,7 +233,8 @@ when defined(windows):
result = "" result = ""
proc getACP(): CodePage {.stdcall, importc: "GetACP", dynlib: "kernel32".} proc getACP(): CodePage {.stdcall, importc: "GetACP", dynlib: "kernel32".}
proc getGetConsoleCP(): CodePage {.stdcall, importc: "GetConsoleCP", dynlib: "kernel32".} proc getGetConsoleCP(): CodePage {.stdcall, importc: "GetConsoleCP",
dynlib: "kernel32".}
proc multiByteToWideChar( proc multiByteToWideChar(
codePage: CodePage, codePage: CodePage,
@ -394,7 +397,8 @@ when defined(windows):
else: else:
assert(false) # cannot happen assert(false) # cannot happen
proc convertWin(codePageFrom: CodePage, codePageTo: CodePage, s: string): string = proc convertWin(codePageFrom: CodePage, codePageTo: CodePage,
s: string): string =
# special case: empty string: needed because MultiByteToWideChar, WideCharToMultiByte # special case: empty string: needed because MultiByteToWideChar, WideCharToMultiByte
# return 0 in case of error # return 0 in case of error
if s.len == 0: return "" if s.len == 0: return ""
@ -410,8 +414,10 @@ when defined(windows):
raise newException(EncodingError, message) raise newException(EncodingError, message)
# in case it's already UTF-16 little endian - conversion can be simplified # in case it's already UTF-16 little endian - conversion can be simplified
let wideString = if int(codePageFrom) == 1200: s else: convertToWideString(codePageFrom, s) let wideString = if int(codePageFrom) == 1200: s
return if int(codePageTo) == 1200: wideString else: convertFromWideString(codePageTo, wideString) else: convertToWideString(codePageFrom, s)
return if int(codePageTo) == 1200: wideString
else: convertFromWideString(codePageTo, wideString)
proc convert*(c: EncodingConverter, s: string): string = proc convert*(c: EncodingConverter, s: string): string =
## converts `s` to `destEncoding` that was given to the converter `c`. It ## converts `s` to `destEncoding` that was given to the converter `c`. It

View file

@ -56,7 +56,8 @@ when defined(windows):
wProcessorLevel: uint16 wProcessorLevel: uint16
wProcessorRevision: uint16 wProcessorRevision: uint16
proc getSystemInfo(lpSystemInfo: ptr SYSTEM_INFO) {.stdcall, dynlib: "kernel32", importc: "GetSystemInfo".} proc getSystemInfo(lpSystemInfo: ptr SYSTEM_INFO) {.stdcall,
dynlib: "kernel32", importc: "GetSystemInfo".}
proc getAllocationGranularity: uint = proc getAllocationGranularity: uint =
var sysInfo: SYSTEM_INFO var sysInfo: SYSTEM_INFO
@ -125,10 +126,12 @@ proc init*(T: type ReservedMem,
let commitSize = nextAlignedOffset(initCommitLen, allocationGranularity) let commitSize = nextAlignedOffset(initCommitLen, allocationGranularity)
when defined(windows): when defined(windows):
result.memStart = virtualAlloc(memStart, maxLen, MEM_RESERVE, accessFlags.cint) result.memStart = virtualAlloc(memStart, maxLen, MEM_RESERVE,
accessFlags.cint)
check result.memStart check result.memStart
if commitSize > 0: if commitSize > 0:
check virtualAlloc(result.memStart, commitSize, MEM_COMMIT, accessFlags.cint) check virtualAlloc(result.memStart, commitSize, MEM_COMMIT,
accessFlags.cint)
else: else:
var allocFlags = MAP_PRIVATE or MAP_ANONYMOUS # or MAP_NORESERVE var allocFlags = MAP_PRIVATE or MAP_ANONYMOUS # or MAP_NORESERVE
# if memStart != nil: # if memStart != nil:
@ -164,7 +167,8 @@ proc setLen*(m: var ReservedMem, newLen: int) =
check virtualAlloc(m.committedMemEnd, commitExtensionSize, check virtualAlloc(m.committedMemEnd, commitExtensionSize,
MEM_COMMIT, m.accessFlags.cint) MEM_COMMIT, m.accessFlags.cint)
else: else:
check mprotect(m.committedMemEnd, commitExtensionSize, m.accessFlags.cint) == 0 check mprotect(m.committedMemEnd, commitExtensionSize,
m.accessFlags.cint) == 0
else: else:
let d = distance(m.usedMemEnd, m.committedMemEnd) - let d = distance(m.usedMemEnd, m.committedMemEnd) -
m.maxCommittedAndUnusedPages * allocationGranularity m.maxCommittedAndUnusedPages * allocationGranularity

View file

@ -1259,7 +1259,8 @@ else:
result.writeDataImpl = fsWriteData result.writeDataImpl = fsWriteData
result.flushImpl = fsFlush result.flushImpl = fsFlush
proc newFileStream*(filename: string, mode: FileMode = fmRead, bufSize: int = -1): owned FileStream = proc newFileStream*(filename: string, mode: FileMode = fmRead,
bufSize: int = -1): owned FileStream =
## Creates a new stream from the file named `filename` with the mode `mode`. ## Creates a new stream from the file named `filename` with the mode `mode`.
## ##
## If the file cannot be opened, `nil` is returned. See the `io module ## If the file cannot be opened, `nil` is returned. See the `io module
@ -1296,7 +1297,8 @@ else:
var f: File var f: File
if open(f, filename, mode, bufSize): result = newFileStream(f) if open(f, filename, mode, bufSize): result = newFileStream(f)
proc openFileStream*(filename: string, mode: FileMode = fmRead, bufSize: int = -1): owned FileStream = proc openFileStream*(filename: string, mode: FileMode = fmRead,
bufSize: int = -1): owned FileStream =
## Creates a new stream from the file named `filename` with the mode `mode`. ## Creates a new stream from the file named `filename` with the mode `mode`.
## If the file cannot be opened, an IO exception is raised. ## If the file cannot be opened, an IO exception is raised.
## ##

View file

@ -273,7 +273,8 @@ proc mkDigit(v: int, typ: char): string {.inline.} =
else: else:
result = $chr(ord(if typ == 'x': 'a' else: 'A') + v - 10) result = $chr(ord(if typ == 'x': 'a' else: 'A') + v - 10)
proc alignString*(s: string, minimumWidth: int; align = '\0'; fill = ' '): string = proc alignString*(s: string, minimumWidth: int; align = '\0';
fill = ' '): string =
## Aligns ``s`` using ``fill`` char. ## Aligns ``s`` using ``fill`` char.
## This is only of interest if you want to write a custom ``format`` proc that ## This is only of interest if you want to write a custom ``format`` proc that
## should support the standard format specifiers. ## should support the standard format specifiers.
@ -304,7 +305,8 @@ type
endPosition*: int ## End position in the format specifier after endPosition*: int ## End position in the format specifier after
## ``parseStandardFormatSpecifier`` returned. ## ``parseStandardFormatSpecifier`` returned.
proc formatInt(n: SomeNumber; radix: int; spec: StandardFormatSpecifier): string = proc formatInt(n: SomeNumber; radix: int;
spec: StandardFormatSpecifier): string =
## Converts ``n`` to string. If ``n`` is `SomeFloat`, it casts to `int64`. ## Converts ``n`` to string. If ``n`` is `SomeFloat`, it casts to `int64`.
## Conversion is done using ``radix``. If result's length is lesser than ## Conversion is done using ``radix``. If result's length is lesser than
## ``minimumWidth``, it aligns result to the right or left (depending on ``a``) ## ``minimumWidth``, it aligns result to the right or left (depending on ``a``)
@ -415,7 +417,8 @@ proc parseStandardFormatSpecifier*(s: string; start = 0;
raise newException(ValueError, raise newException(ValueError,
"invalid format string, cannot parse: " & s[i..^1]) "invalid format string, cannot parse: " & s[i..^1])
proc formatValue*[T: SomeInteger](result: var string; value: T; specifier: string) = proc formatValue*[T: SomeInteger](result: var string; value: T;
specifier: string) =
## Standard format implementation for ``SomeInteger``. It makes little ## Standard format implementation for ``SomeInteger``. It makes little
## sense to call this directly, but it is required to exist ## sense to call this directly, but it is required to exist
## by the ``&`` macro. ## by the ``&`` macro.
@ -509,7 +512,8 @@ proc formatValue*(result: var string; value: string; specifier: string) =
setLen(value, runeOffset(value, spec.precision)) setLen(value, runeOffset(value, spec.precision))
result.add alignString(value, spec.minimumWidth, spec.align, spec.fill) result.add alignString(value, spec.minimumWidth, spec.align, spec.fill)
proc formatValue[T: not SomeInteger](result: var string; value: T; specifier: string) = proc formatValue[T: not SomeInteger](result: var string; value: T;
specifier: string) =
mixin `$` mixin `$`
formatValue(result, $value, specifier) formatValue(result, $value, specifier)
@ -531,7 +535,8 @@ macro `&`*(pattern: string): untyped =
# When compiling with -d:useNimRtl, certain procs such as `count` from the strutils # When compiling with -d:useNimRtl, certain procs such as `count` from the strutils
# module are not accessible at compile-time: # module are not accessible at compile-time:
let expectedGrowth = when defined(useNimRtl): 0 else: count(f, '{') * 10 let expectedGrowth = when defined(useNimRtl): 0 else: count(f, '{') * 10
result.add newVarStmt(res, newCall(bindSym"newStringOfCap", newLit(f.len + expectedGrowth))) result.add newVarStmt(res, newCall(bindSym"newStringOfCap",
newLit(f.len + expectedGrowth)))
var strlit = "" var strlit = ""
while i < f.len: while i < f.len:
if f[i] == '{': if f[i] == '{':

View file

@ -325,7 +325,8 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b
var idx = genSym(nskVar, "idx") var idx = genSym(nskVar, "idx")
var res = genSym(nskVar, "res") var res = genSym(nskVar, "res")
let inp = genSym(nskLet, "inp") let inp = genSym(nskLet, "inp")
result = newTree(nnkStmtListExpr, newLetStmt(inp, input), newVarStmt(idx, newLit 0), newVarStmt(res, newLit false)) result = newTree(nnkStmtListExpr, newLetStmt(inp, input),
newVarStmt(idx, newLit 0), newVarStmt(res, newLit false))
var conds = newTree(nnkStmtList) var conds = newTree(nnkStmtList)
var fullMatch = false var fullMatch = false
while p < pattern.len: while p < pattern.len:
@ -334,7 +335,8 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b
case pattern[p] case pattern[p]
of '$': of '$':
var resLen = genSym(nskLet, "resLen") var resLen = genSym(nskLet, "resLen")
conds.add newLetStmt(resLen, newCall(bindSym"skip", inp, newLit($pattern[p]), idx)) conds.add newLetStmt(resLen, newCall(bindSym"skip", inp,
newLit($pattern[p]), idx))
conds.add resLen.notZero conds.add resLen.notZero
conds.add resLen conds.add resLen
of 'w': of 'w':
@ -374,7 +376,8 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b
matchError matchError
inc i inc i
of 's': of 's':
conds.add newCall(bindSym"inc", idx, newCall(bindSym"skipWhitespace", inp, idx)) conds.add newCall(bindSym"inc", idx,
newCall(bindSym"skipWhitespace", inp, idx))
conds.add newEmptyNode() conds.add newEmptyNode()
conds.add newEmptyNode() conds.add newEmptyNode()
of '.': of '.':
@ -391,7 +394,8 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b
token.add pattern[q] token.add pattern[q]
inc q inc q
var resLen = genSym(nskLet, "resLen") var resLen = genSym(nskLet, "resLen")
conds.add newLetStmt(resLen, newCall(bindSym"parseUntil", inp, results[i], newLit(token), idx)) conds.add newLetStmt(resLen, newCall(bindSym"parseUntil", inp,
results[i], newLit(token), idx))
conds.add newCall(bindSym"!=", resLen, newLit min) conds.add newCall(bindSym"!=", resLen, newLit min)
conds.add resLen conds.add resLen
else: else:
@ -563,8 +567,8 @@ macro scanp*(input, idx: typed; pattern: varargs[untyped]): bool =
if a.cond.kind == nnkEmpty or b.cond.kind == nnkEmpty: if a.cond.kind == nnkEmpty or b.cond.kind == nnkEmpty:
error("'|' operator applied to a non-condition") error("'|' operator applied to a non-condition")
else: else:
result = (newStmtList(a.init, result = (newStmtList(a.init, newIfStmt((a.cond, a.action),
newIfStmt((a.cond, a.action), (newTree(nnkStmtListExpr, b.init, b.cond), b.action))), (newTree(nnkStmtListExpr, b.init, b.cond), b.action))),
newEmptyNode(), newEmptyNode()) newEmptyNode(), newEmptyNode())
elif it.kind == nnkInfix and it[0].eqIdent"^*": elif it.kind == nnkInfix and it[0].eqIdent"^*":
# a ^* b is rewritten to: (a *(b a))? # a ^* b is rewritten to: (a *(b a))?
@ -582,18 +586,22 @@ macro scanp*(input, idx: typed; pattern: varargs[untyped]): bool =
else: else:
var resLen = genSym(nskLet, "resLen") var resLen = genSym(nskLet, "resLen")
result = (newLetStmt(resLen, placeholder(it, input, idx)), result = (newLetStmt(resLen, placeholder(it, input, idx)),
newCall(interf"success", resLen), !!newCall(interf"nxt", input, idx, resLen)) newCall(interf"success", resLen),
!!newCall(interf"nxt", input, idx, resLen))
of nnkStrLit..nnkTripleStrLit: of nnkStrLit..nnkTripleStrLit:
var resLen = genSym(nskLet, "resLen") var resLen = genSym(nskLet, "resLen")
result = (newLetStmt(resLen, newCall(interf"skip", input, it, idx)), result = (newLetStmt(resLen, newCall(interf"skip", input, it, idx)),
newCall(interf"success", resLen), !!newCall(interf"nxt", input, idx, resLen)) newCall(interf"success", resLen),
!!newCall(interf"nxt", input, idx, resLen))
of nnkCurly, nnkAccQuoted, nnkCharLit: of nnkCurly, nnkAccQuoted, nnkCharLit:
result = (newEmptyNode(), newCall(interf"atom", input, idx, it), !!newCall(interf"nxt", input, idx)) result = (newEmptyNode(), newCall(interf"atom", input, idx, it),
!!newCall(interf"nxt", input, idx))
of nnkCurlyExpr: of nnkCurlyExpr:
if it.len == 3 and it[1].kind == nnkIntLit and it[2].kind == nnkIntLit: if it.len == 3 and it[1].kind == nnkIntLit and it[2].kind == nnkIntLit:
var h = newTree(nnkTupleConstr, it[0]) var h = newTree(nnkTupleConstr, it[0])
for count in 2i64 .. it[1].intVal: h.add(it[0]) for count in 2i64 .. it[1].intVal: h.add(it[0])
for count in it[1].intVal .. it[2].intVal-1: h.add(newTree(nnkPrefix, ident"?", it[0])) for count in it[1].intVal .. it[2].intVal-1:
h.add(newTree(nnkPrefix, ident"?", it[0]))
result = atm(h, input, idx, attached) result = atm(h, input, idx, attached)
elif it.len == 2 and it[1].kind == nnkIntLit: elif it.len == 2 and it[1].kind == nnkIntLit:
var h = newTree(nnkTupleConstr, it[0]) var h = newTree(nnkTupleConstr, it[0])
@ -689,21 +697,25 @@ when isMainModule:
let xx2 = scanf("$1234", "$$$i", intval) let xx2 = scanf("$1234", "$$$i", intval)
doAssert xx2 doAssert xx2
let yy = scanf(";.--Breakpoint00 [output]", "$[someSep]Breakpoint${twoDigits}$[someSep({';','.','-'})] [$+]$.", intVal, key) let yy = scanf(";.--Breakpoint00 [output]",
"$[someSep]Breakpoint${twoDigits}$[someSep({';','.','-'})] [$+]$.",
intVal, key)
doAssert yy doAssert yy
doAssert key == "output" doAssert key == "output"
doAssert intVal == 13 doAssert intVal == 13
var ident = "" var ident = ""
var idx = 0 var idx = 0
let zz = scanp("foobar x x x xWZ", idx, +{'a'..'z'} -> add(ident, $_), *(*{' ', '\t'}, "x"), ~'U', "Z") let zz = scanp("foobar x x x xWZ", idx, +{'a'..'z'} -> add(ident, $_), *(*{
' ', '\t'}, "x"), ~'U', "Z")
doAssert zz doAssert zz
doAssert ident == "foobar" doAssert ident == "foobar"
const digits = {'0'..'9'} const digits = {'0'..'9'}
var year = 0 var year = 0
var idx2 = 0 var idx2 = 0
if scanp("201655-8-9", idx2, `digits`{4,6} -> (year = year * 10 + ord($_) - ord('0')), "-8", "-9"): if scanp("201655-8-9", idx2, `digits`{4, 6} -> (year = year * 10 + ord($_) -
ord('0')), "-8", "-9"):
doAssert year == 201655 doAssert year == 201655
const gdbOut = """ const gdbOut = """

View file

@ -168,7 +168,8 @@ proc `[]`*(t: StringTableRef, key: string): var string {.
echo t["occupation"] echo t["occupation"]
get(t, key) get(t, key)
proc getOrDefault*(t: StringTableRef; key: string, default: string = ""): string = proc getOrDefault*(t: StringTableRef; key: string,
default: string = ""): string =
## Retrieves the location at ``t[key]``. ## Retrieves the location at ``t[key]``.
## ##
## If `key` is not in `t`, the default value is returned (if not specified, ## If `key` is not in `t`, the default value is returned (if not specified,
@ -191,7 +192,8 @@ proc getOrDefault*(t: StringTableRef; key: string, default: string = ""): string
if index >= 0: result = t.data[index].val if index >= 0: result = t.data[index].val
else: result = default else: result = default
proc hasKey*(t: StringTableRef, key: string): bool {.rtlFunc, extern: "nst$1".} = proc hasKey*(t: StringTableRef, key: string): bool {.rtlFunc,
extern: "nst$1".} =
## Returns true if `key` is in the table `t`. ## Returns true if `key` is in the table `t`.
## ##
## See also: ## See also:

View file

@ -763,7 +763,8 @@ proc split*(s: string, sep: string, maxsplit: int = -1): seq[string] {.noSideEff
doAssert "a,b,c".split(",") == @["a", "b", "c"] doAssert "a,b,c".split(",") == @["a", "b", "c"]
doAssert "a man a plan a canal panama".split("a ") == @["", "man ", "plan ", "canal panama"] doAssert "a man a plan a canal panama".split("a ") == @["", "man ", "plan ", "canal panama"]
doAssert "".split("Elon Musk") == @[""] doAssert "".split("Elon Musk") == @[""]
doAssert "a largely spaced sentence".split(" ") == @["a", "", "largely", "", "", "", "spaced", "sentence"] doAssert "a largely spaced sentence".split(" ") == @["a", "", "largely",
"", "", "", "spaced", "sentence"]
doAssert "a largely spaced sentence".split(" ", maxsplit = 1) == @["a", " largely spaced sentence"] doAssert "a largely spaced sentence".split(" ", maxsplit = 1) == @["a", " largely spaced sentence"]
doAssert(sep.len > 0) doAssert(sep.len > 0)
@ -849,11 +850,14 @@ proc rsplit*(s: string, sep: string, maxsplit: int = -1): seq[string]
## * `splitLines proc<#splitLines,string>`_ ## * `splitLines proc<#splitLines,string>`_
## * `splitWhitespace proc<#splitWhitespace,string,int>`_ ## * `splitWhitespace proc<#splitWhitespace,string,int>`_
runnableExamples: runnableExamples:
doAssert "a largely spaced sentence".rsplit(" ", maxsplit=1) == @["a largely spaced", "sentence"] doAssert "a largely spaced sentence".rsplit(" ", maxsplit = 1) == @[
"a largely spaced", "sentence"]
doAssert "a,b,c".rsplit(",") == @["a", "b", "c"] doAssert "a,b,c".rsplit(",") == @["a", "b", "c"]
doAssert "a man a plan a canal panama".rsplit("a ") == @["", "man ", "plan ", "canal panama"] doAssert "a man a plan a canal panama".rsplit("a ") == @["", "man ",
"plan ", "canal panama"]
doAssert "".rsplit("Elon Musk") == @[""] doAssert "".rsplit("Elon Musk") == @[""]
doAssert "a largely spaced sentence".rsplit(" ") == @["a", "", "largely", "", "", "", "spaced", "sentence"] doAssert "a largely spaced sentence".rsplit(" ") == @["a", "",
"largely", "", "", "", "spaced", "sentence"]
accResult(rsplit(s, sep, maxsplit)) accResult(rsplit(s, sep, maxsplit))
result.reverse() result.reverse()
@ -1346,7 +1350,8 @@ proc align*(s: string, count: Natural, padding = ' '): string {.
else: else:
result = s result = s
proc alignLeft*(s: string, count: Natural, padding = ' '): string {.noSideEffect.} = proc alignLeft*(s: string, count: Natural, padding = ' '): string {.
noSideEffect.} =
## Left-Aligns a string `s` with `padding`, so that it is of length `count`. ## Left-Aligns a string `s` with `padding`, so that it is of length `count`.
## ##
## `padding` characters (by default spaces) are added after `s` resulting in ## `padding` characters (by default spaces) are added after `s` resulting in
@ -2140,7 +2145,8 @@ proc replaceWord*(s, sub: string, by = ""): string {.noSideEffect,
# copy the rest: # copy the rest:
add result, substr(s, i) add result, substr(s, i)
proc multiReplace*(s: string, replacements: varargs[(string, string)]): string {.noSideEffect.} = proc multiReplace*(s: string, replacements: varargs[(string, string)]):
string {.noSideEffect.} =
## Same as replace, but specialized for doing multiple replacements in a single ## Same as replace, but specialized for doing multiple replacements in a single
## pass through the input string. ## pass through the input string.
## ##
@ -2467,7 +2473,8 @@ proc formatSize*(bytes: int64,
break break
# xb has the integer number for the latest value; index should be correct # xb has the integer number for the latest value; index should be correct
fbytes = bytes.float / (1'i64 shl (matchedIndex*10)).float fbytes = bytes.float / (1'i64 shl (matchedIndex*10)).float
result = formatFloat(fbytes, format=ffDecimal, precision=3, decimalSep=decimalSep) result = formatFloat(fbytes, format = ffDecimal, precision = 3,
decimalSep = decimalSep)
result.trimZeros() result.trimZeros()
if includeSpace: if includeSpace:
result &= " " result &= " "
@ -2551,7 +2558,8 @@ proc formatEng*(f: BiggestFloat,
## Get the SI prefix for a given exponent ## Get the SI prefix for a given exponent
## ##
## Assumes exponent is a multiple of 3; returns ' ' if no prefix found ## Assumes exponent is a multiple of 3; returns ' ' if no prefix found
const siPrefixes = ['a','f','p','n','u','m',' ','k','M','G','T','P','E'] const siPrefixes = ['a', 'f', 'p', 'n', 'u', 'm', ' ', 'k', 'M', 'G', 'T',
'P', 'E']
var index: int = (exp div 3) + 6 var index: int = (exp div 3) + 6
result = ' ' result = ' '
if index in low(siPrefixes)..high(siPrefixes): if index in low(siPrefixes)..high(siPrefixes):
@ -2564,7 +2572,8 @@ proc formatEng*(f: BiggestFloat,
if absolute == 0.0: if absolute == 0.0:
# Simple case: just format it and force the exponent to 0 # Simple case: just format it and force the exponent to 0
exponent = 0 exponent = 0
result = significand.formatBiggestFloat(ffDecimal, precision, decimalSep='.') result = significand.formatBiggestFloat(ffDecimal, precision,
decimalSep = '.')
else: else:
# Find the best exponent that's a multiple of 3 # Find the best exponent that's a multiple of 3
fexponent = floor(log10(absolute)) fexponent = floor(log10(absolute))
@ -2579,7 +2588,8 @@ proc formatEng*(f: BiggestFloat,
significand *= 0.001 significand *= 0.001
fexponent += 3 fexponent += 3
# Components of the result: # Components of the result:
result = significand.formatBiggestFloat(ffDecimal, precision, decimalSep='.') result = significand.formatBiggestFloat(ffDecimal, precision,
decimalSep = '.')
exponent = fexponent.int() exponent = fexponent.int()
splitResult = result.split('.') splitResult = result.split('.')
@ -2952,7 +2962,8 @@ proc isNilOrEmpty*(s: string): bool {.noSideEffect, procvar, rtl,
## Checks if `s` is nil or empty. ## Checks if `s` is nil or empty.
result = len(s) == 0 result = len(s) == 0
proc isNilOrWhitespace*(s: string): bool {.noSideEffect, procvar, rtl, extern: "nsuIsNilOrWhitespace".} = proc isNilOrWhitespace*(s: string): bool {.noSideEffect, procvar, rtl,
extern: "nsuIsNilOrWhitespace".} =
## Checks if `s` is nil or consists entirely of whitespace characters. ## Checks if `s` is nil or consists entirely of whitespace characters.
result = true result = true
for c in s: for c in s:
@ -3161,18 +3172,22 @@ when isMainModule:
doAssert formatEng(-52731234, 1, decimalSep = ',') == "-52,7e6" doAssert formatEng(-52731234, 1, decimalSep = ',') == "-52,7e6"
doAssert formatEng(4100, siPrefix = true, unit = "V") == "4.1 kV" doAssert formatEng(4100, siPrefix = true, unit = "V") == "4.1 kV"
doAssert formatEng(4.1, siPrefix=true, unit="V", useUnitSpace=true) == "4.1 V" doAssert formatEng(4.1, siPrefix = true, unit = "V",
useUnitSpace = true) == "4.1 V"
doAssert formatEng(4.1, siPrefix = true) == "4.1" # Note lack of space doAssert formatEng(4.1, siPrefix = true) == "4.1" # Note lack of space
doAssert formatEng(4100, siPrefix = true) == "4.1 k" doAssert formatEng(4100, siPrefix = true) == "4.1 k"
doAssert formatEng(4.1, siPrefix=true, unit="", useUnitSpace=true) == "4.1 " # Includes space doAssert formatEng(4.1, siPrefix = true, unit = "",
useUnitSpace = true) == "4.1 " # Includes space
doAssert formatEng(4100, siPrefix = true, unit = "") == "4.1 k" doAssert formatEng(4100, siPrefix = true, unit = "") == "4.1 k"
doAssert formatEng(4100) == "4.1e3" doAssert formatEng(4100) == "4.1e3"
doAssert formatEng(4100, unit = "V", useUnitSpace = true) == "4.1e3 V" doAssert formatEng(4100, unit = "V", useUnitSpace = true) == "4.1e3 V"
doAssert formatEng(4100, unit = "", useUnitSpace = true) == "4.1e3 " doAssert formatEng(4100, unit = "", useUnitSpace = true) == "4.1e3 "
# Don't use SI prefix as number is too big # Don't use SI prefix as number is too big
doAssert formatEng(3.1e22, siPrefix=true, unit="a", useUnitSpace=true) == "31e21 a" doAssert formatEng(3.1e22, siPrefix = true, unit = "a",
useUnitSpace = true) == "31e21 a"
# Don't use SI prefix as number is too small # Don't use SI prefix as number is too small
doAssert formatEng(3.1e-25, siPrefix=true, unit="A", useUnitSpace=true) == "310e-27 A" doAssert formatEng(3.1e-25, siPrefix = true, unit = "A",
useUnitSpace = true) == "310e-27 A"
proc staticTests = proc staticTests =
doAssert align("abc", 4) == " abc" doAssert align("abc", 4) == " abc"
@ -3232,7 +3247,8 @@ when isMainModule:
doAssert " foo\n bar".indent(4, "Q") == "QQQQ foo\nQQQQ bar" doAssert " foo\n bar".indent(4, "Q") == "QQQQ foo\nQQQQ bar"
doAssert "abba".multiReplace(("a", "b"), ("b", "a")) == "baab" doAssert "abba".multiReplace(("a", "b"), ("b", "a")) == "baab"
doAssert "Hello World.".multiReplace(("ello", "ELLO"), ("World.", "PEOPLE!")) == "HELLO PEOPLE!" doAssert "Hello World.".multiReplace(("ello", "ELLO"), ("World.",
"PEOPLE!")) == "HELLO PEOPLE!"
doAssert "aaaa".multiReplace(("a", "aa"), ("aa", "bb")) == "aaaaaaaa" doAssert "aaaa".multiReplace(("a", "aa"), ("aa", "bb")) == "aaaaaaaa"
doAssert isAlphaAscii('r') doAssert isAlphaAscii('r')
@ -3270,7 +3286,8 @@ when isMainModule:
doAssert rsplit("foo bar", seps = Whitespace) == @["foo", "bar"] doAssert rsplit("foo bar", seps = Whitespace) == @["foo", "bar"]
doAssert rsplit(" foo bar", seps = Whitespace, maxsplit = 1) == @[" foo", "bar"] doAssert rsplit(" foo bar", seps = Whitespace, maxsplit = 1) == @[" foo", "bar"]
doAssert rsplit(" foo bar ", seps=Whitespace, maxsplit=1) == @[" foo bar", ""] doAssert rsplit(" foo bar ", seps = Whitespace, maxsplit = 1) == @[
" foo bar", ""]
doAssert rsplit(":foo:bar", sep = ':') == @["", "foo", "bar"] doAssert rsplit(":foo:bar", sep = ':') == @["", "foo", "bar"]
doAssert rsplit(":foo:bar", sep = ':', maxsplit = 2) == @["", "foo", "bar"] doAssert rsplit(":foo:bar", sep = ':', maxsplit = 2) == @["", "foo", "bar"]
doAssert rsplit(":foo:bar", sep = ':', maxsplit = 3) == @["", "foo", "bar"] doAssert rsplit(":foo:bar", sep = ':', maxsplit = 3) == @["", "foo", "bar"]
@ -3315,7 +3332,8 @@ bar
let s2 = ":this;is;an:example;;" let s2 = ":this;is;an:example;;"
doAssert s.split() == @["", "this", "is", "an", "example", "", ""] doAssert s.split() == @["", "this", "is", "an", "example", "", ""]
doAssert s2.split(seps={':', ';'}) == @["", "this", "is", "an", "example", "", ""] doAssert s2.split(seps = {':', ';'}) == @["", "this", "is", "an", "example",
"", ""]
doAssert s.split(maxsplit = 4) == @["", "this", "is", "an", "example "] doAssert s.split(maxsplit = 4) == @["", "this", "is", "an", "example "]
doAssert s.split(' ', maxsplit = 1) == @["", "this is an example "] doAssert s.split(' ', maxsplit = 1) == @["", "this is an example "]
doAssert s.split(" ", maxsplit = 4) == @["", "this", "is", "an", "example "] doAssert s.split(" ", maxsplit = 4) == @["", "this", "is", "an", "example "]

View file

@ -1039,8 +1039,8 @@ iterator split*(s: string, sep: Rune, maxsplit: int = -1): string =
## ##
splitCommon(s, sep, maxsplit, sep.size) splitCommon(s, sep, maxsplit, sep.size)
proc split*(s: string, seps: openArray[Rune] = unicodeSpaces, maxsplit: int = -1): seq[string] {. proc split*(s: string, seps: openArray[Rune] = unicodeSpaces, maxsplit: int = -1):
noSideEffect, rtl, extern: "nucSplitRunes".} = seq[string] {.noSideEffect, rtl, extern: "nucSplitRunes".} =
## The same as the `split iterator <#split.i,string,openArray[Rune],int>`_, ## The same as the `split iterator <#split.i,string,openArray[Rune],int>`_,
## but is a proc that returns a sequence of substrings. ## but is a proc that returns a sequence of substrings.
accResult(split(s, seps, maxsplit)) accResult(split(s, seps, maxsplit))
@ -1232,8 +1232,7 @@ proc isUpper*(s: string, skipNonAlpha: bool): bool {.
## an empty string. ## an empty string.
runeCaseCheck(s, isUpper, skipNonAlpha) runeCaseCheck(s, isUpper, skipNonAlpha)
proc isTitle*(s: string): bool {.noSideEffect, procvar, proc isTitle*(s: string): bool {.noSideEffect, procvar, rtl, extern: "nuc$1Str",
rtl, extern: "nuc$1Str",
deprecated: "Deprecated since version 0.20 since its semantics are unclear".} = deprecated: "Deprecated since version 0.20 since its semantics are unclear".} =
## **Deprecated since version 0.20 since its semantics are unclear** ## **Deprecated since version 0.20 since its semantics are unclear**
## ##
@ -1419,8 +1418,10 @@ when isMainModule:
let s2 = ":this;is;an:example;;" let s2 = ":this;is;an:example;;"
let s3 = ":this×is×an:example××" let s3 = ":this×is×an:example××"
doAssert s.split() == @["", "this", "is", "an", "example", "", ""] doAssert s.split() == @["", "this", "is", "an", "example", "", ""]
doAssert s2.split(seps = [':'.Rune, ';'.Rune]) == @["", "this", "is", "an", "example", "", ""] doAssert s2.split(seps = [':'.Rune, ';'.Rune]) == @["", "this", "is", "an",
doAssert s3.split(seps = [':'.Rune, "×".asRune]) == @["", "this", "is", "an", "example", "", ""] "example", "", ""]
doAssert s3.split(seps = [':'.Rune, "×".asRune]) == @["", "this", "is",
"an", "example", "", ""]
doAssert s.split(maxsplit = 4) == @["", "this", "is", "an", "example "] doAssert s.split(maxsplit = 4) == @["", "this", "is", "an", "example "]
doAssert s.split(' '.Rune, maxsplit = 1) == @["", "this is an example "] doAssert s.split(' '.Rune, maxsplit = 1) == @["", "this is an example "]