diff options
Diffstat (limited to 'lib/impure')
-rw-r--r-- | lib/impure/db_mysql.nim | 35 | ||||
-rw-r--r-- | lib/impure/db_postgres.nim | 7 | ||||
-rw-r--r-- | lib/impure/db_sqlite.nim | 10 | ||||
-rw-r--r-- | lib/impure/nre.nim | 29 | ||||
-rw-r--r-- | lib/impure/nre/private/util.nim | 6 | ||||
-rw-r--r-- | lib/impure/rdstdin.nim | 2 | ||||
-rw-r--r-- | lib/impure/re.nim | 64 |
7 files changed, 65 insertions, 88 deletions
diff --git a/lib/impure/db_mysql.nim b/lib/impure/db_mysql.nim index 3b461d2f6..26bc7d0ad 100644 --- a/lib/impure/db_mysql.nim +++ b/lib/impure/db_mysql.nim @@ -128,10 +128,7 @@ proc dbFormat(formatstr: SqlQuery, args: varargs[string]): string = var a = 0 for c in items(string(formatstr)): if c == '?': - if args[a] == nil: - add(result, "NULL") - else: - add(result, dbQuote(args[a])) + add(result, dbQuote(args[a])) inc(a) else: add(result, c) @@ -183,24 +180,8 @@ iterator fastRows*(db: DbConn, query: SqlQuery, row = mysql.fetchRow(sqlres) if row == nil: break for i in 0..L-1: - if row[i] == nil: - if backup == nil: - newSeq(backup, L) - if backup[i] == nil and result[i] != nil: - shallowCopy(backup[i], result[i]) - result[i] = nil - else: - if result[i] == nil: - if backup != nil: - if backup[i] == nil: - backup[i] = "" - shallowCopy(result[i], backup[i]) - setLen(result[i], 0) - else: - result[i] = "" - else: - setLen(result[i], 0) - add(result[i], row[i]) + setLen(result[i], 0) + result[i].add row[i] yield result properFreeResult(sqlres, row) @@ -323,10 +304,7 @@ proc getRow*(db: DbConn, query: SqlQuery, if row != nil: for i in 0..L-1: setLen(result[i], 0) - if row[i] == nil: - result[i] = nil - else: - add(result[i], row[i]) + add(result[i], row[i]) properFreeResult(sqlres, row) proc getAllRows*(db: DbConn, query: SqlQuery, @@ -345,10 +323,7 @@ proc getAllRows*(db: DbConn, query: SqlQuery, setLen(result, j+1) newSeq(result[j], L) for i in 0..L-1: - if row[i] == nil: - result[j][i] = nil - else: - result[j][i] = $row[i] + result[j][i] = $row[i] inc(j) mysql.freeResult(sqlres) diff --git a/lib/impure/db_postgres.nim b/lib/impure/db_postgres.nim index 1459f0d7e..e765cc197 100644 --- a/lib/impure/db_postgres.nim +++ b/lib/impure/db_postgres.nim @@ -103,10 +103,7 @@ proc dbFormat(formatstr: SqlQuery, args: varargs[string]): string = else: for c in items(string(formatstr)): if c == '?': - if args[a] == nil: - add(result, "NULL") - else: - add(result, dbQuote(args[a])) + add(result, dbQuote(args[a])) inc(a) else: add(result, c) @@ -179,7 +176,7 @@ proc setRow(res: PPGresult, r: var Row, line, cols: int32) = setLen(r[col], 0) let x = pqgetvalue(res, line, col) if x.isNil: - r[col] = nil + r[col] = "" else: add(r[col], x) diff --git a/lib/impure/db_sqlite.nim b/lib/impure/db_sqlite.nim index 21049571f..a40c88a11 100644 --- a/lib/impure/db_sqlite.nim +++ b/lib/impure/db_sqlite.nim @@ -31,7 +31,7 @@ ## ## .. code-block:: Nim ## import db_sqlite -## let db = open("localhost", "user", "password", "dbname") +## let db = open("mytest.db", nil, nil, nil) # user, password, database name can be nil ## db.close() ## ## Creating a table @@ -57,7 +57,7 @@ ## ## import db_sqlite, math ## -## let theDb = open("mytest.db", nil, nil, nil) +## let theDb = open("mytest.db", "", "", "") ## ## theDb.exec(sql"Drop table if exists myTestTbl") ## theDb.exec(sql("""create table myTestTbl ( @@ -81,7 +81,7 @@ ## ## theDb.close() -{.deadCodeElim:on.} +{.deadCodeElim: on.} # dce option deprecated import strutils, sqlite3 @@ -105,7 +105,6 @@ proc dbError*(db: DbConn) {.noreturn.} = proc dbQuote*(s: string): string = ## DB quotes the string. - if s.isNil: return "NULL" result = "'" for c in items(s): if c == '\'': add(result, "''") @@ -126,6 +125,7 @@ proc tryExec*(db: DbConn, query: SqlQuery, args: varargs[string, `$`]): bool {. tags: [ReadDbEffect, WriteDbEffect].} = ## tries to execute the query and returns true if successful, false otherwise. + assert(not db.isNil, "Database not connected.") var q = dbFormat(query, args) var stmt: sqlite3.Pstmt if prepare_v2(db, q, q.len.cint, stmt, nil) == SQLITE_OK: @@ -144,6 +144,7 @@ proc newRow(L: int): Row = proc setupQuery(db: DbConn, query: SqlQuery, args: varargs[string]): Pstmt = + assert(not db.isNil, "Database not connected.") var q = dbFormat(query, args) if prepare_v2(db, q, q.len.cint, result, nil) != SQLITE_OK: dbError(db) @@ -267,6 +268,7 @@ proc tryInsertID*(db: DbConn, query: SqlQuery, {.tags: [WriteDbEffect], raises: [].} = ## executes the query (typically "INSERT") and returns the ## generated ID for the row or -1 in case of an error. + assert(not db.isNil, "Database not connected.") var q = dbFormat(query, args) var stmt: sqlite3.Pstmt result = -1 diff --git a/lib/impure/nre.nim b/lib/impure/nre.nim index 3d4afc0ae..32b1d0255 100644 --- a/lib/impure/nre.nim +++ b/lib/impure/nre.nim @@ -10,7 +10,7 @@ from pcre import nil import nre.private.util import tables -from strutils import toLower, `%` +from strutils import `%` from math import ceil import options from unicode import runeLenAt @@ -267,7 +267,7 @@ proc `[]`*(pattern: Captures, i: int): string = let bounds = bounds.get return pattern.str.substr(bounds.a, bounds.b) else: - return nil + return "" proc match*(pattern: RegexMatch): string = return pattern.captures[-1] @@ -291,9 +291,9 @@ template toTableImpl(cond: untyped) {.dirty.} = else: result[key] = nextVal -proc toTable*(pattern: Captures, default: string = nil): Table[string, string] = +proc toTable*(pattern: Captures, default: string = ""): Table[string, string] = result = initTable[string, string]() - toTableImpl(nextVal == nil) + toTableImpl(nextVal.len == 0) proc toTable*(pattern: CaptureBounds, default = none(HSlice[int, int])): Table[string, Option[HSlice[int, int]]] = @@ -312,13 +312,13 @@ template itemsImpl(cond: untyped) {.dirty.} = iterator items*(pattern: CaptureBounds, default = none(HSlice[int, int])): Option[HSlice[int, int]] = itemsImpl(nextVal.isNone) -iterator items*(pattern: Captures, default: string = nil): string = - itemsImpl(nextVal == nil) +iterator items*(pattern: Captures, default: string = ""): string = + itemsImpl(nextVal.len == 0) proc toSeq*(pattern: CaptureBounds, default = none(HSlice[int, int])): seq[Option[HSlice[int, int]]] = accumulateResult(pattern.items(default)) -proc toSeq*(pattern: Captures, default: string = nil): seq[string] = +proc toSeq*(pattern: Captures, default: string = ""): seq[string] = accumulateResult(pattern.items(default)) proc `$`*(pattern: RegexMatch): string = @@ -326,15 +326,15 @@ proc `$`*(pattern: RegexMatch): string = proc `==`*(a, b: Regex): bool = if not a.isNil and not b.isNil: - return a.pattern == b.pattern and - a.pcreObj == b.pcreObj and + return a.pattern == b.pattern and + a.pcreObj == b.pcreObj and a.pcreExtra == b.pcreExtra else: return system.`==`(a, b) proc `==`*(a, b: RegexMatch): bool = return a.pattern == b.pattern and - a.str == b.str + a.str == b.str # }}} # Creation & Destruction {{{ @@ -645,7 +645,6 @@ template replaceImpl(str: string, pattern: Regex, let bounds = match.matchBounds result.add(str.substr(lastIdx, bounds.a - 1)) let nextVal = replacement - assert(nextVal != nil) result.add(nextVal) lastIdx = bounds.b + 1 @@ -655,17 +654,17 @@ template replaceImpl(str: string, pattern: Regex, proc replace*(str: string, pattern: Regex, subproc: proc (match: RegexMatch): string): string = - ## Replaces each match of Regex in the string with ``sub``, which should + ## Replaces each match of Regex in the string with ``subproc``, which should ## never be or return ``nil``. ## - ## If ``sub`` is a ``proc (RegexMatch): string``, then it is executed with + ## If ``subproc`` is a ``proc (RegexMatch): string``, then it is executed with ## each match and the return value is the replacement value. ## - ## If ``sub`` is a ``proc (string): string``, then it is executed with the + ## If ``subproc`` is a ``proc (string): string``, then it is executed with the ## full text of the match and and the return value is the replacement ## value. ## - ## If ``sub`` is a string, the syntax is as follows: + ## If ``subproc`` is a string, the syntax is as follows: ## ## - ``$$`` - literal ``$`` ## - ``$123`` - capture number ``123`` diff --git a/lib/impure/nre/private/util.nim b/lib/impure/nre/private/util.nim index 12d2506ea..a3ae84007 100644 --- a/lib/impure/nre/private/util.nim +++ b/lib/impure/nre/private/util.nim @@ -10,11 +10,7 @@ proc fget*[K, V](self: Table[K, V], key: K): V = const Ident = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\128'..'\255'} const StartIdent = Ident - {'0'..'9'} -proc checkNil(arg: string): string = - if arg == nil: - raise newException(ValueError, "Cannot use nil capture") - else: - return arg +template checkNil(arg: string): string = arg template formatStr*(howExpr, namegetter, idgetter): untyped = let how = howExpr diff --git a/lib/impure/rdstdin.nim b/lib/impure/rdstdin.nim index 5aa4cfcc3..54bab82f0 100644 --- a/lib/impure/rdstdin.nim +++ b/lib/impure/rdstdin.nim @@ -13,7 +13,7 @@ ## is used. This suffices because Windows' console already provides the ## wanted functionality. -{.deadCodeElim: on.} +{.deadCodeElim: on.} # dce option deprecated when defined(Windows): proc readLineFromStdin*(prompt: string): TaintedString {. diff --git a/lib/impure/re.nim b/lib/impure/re.nim index c7f8f336b..a60f70828 100644 --- a/lib/impure/re.nim +++ b/lib/impure/re.nim @@ -7,18 +7,14 @@ # distribution, for details about the copyright. # -## Regular expression support for Nim. This module still has some -## obscure bugs and limitations, -## consider using the ``nre`` or ``pegs`` modules instead. -## We had to de-deprecate this module since too much code relies on it -## and many people prefer its API over ``nre``'s. +## Regular expression support for Nim. ## ## This module is implemented by providing a wrapper around the -## `PRCE (Perl-Compatible Regular Expressions) <http://www.pcre.org>`_ -## C library. This means that your application will depend on the PRCE +## `PCRE (Perl-Compatible Regular Expressions) <http://www.pcre.org>`_ +## C library. This means that your application will depend on the PCRE ## library's licence when using this module, which should not be a problem ## though. -## PRCE's licence follows: +## PCRE's licence follows: ## ## .. include:: ../../doc/regexprs.txt ## @@ -117,7 +113,7 @@ proc matchOrFind(buf: cstring, pattern: Regex, matches: var openArray[string], var b = rawMatches[i * 2 + 1] if a >= 0'i32: matches[i-1] = bufSubstr(buf, int(a), int(b)) - else: matches[i-1] = nil + else: matches[i-1] = "" return rawMatches[1] - rawMatches[0] proc findBounds*(buf: cstring, pattern: Regex, matches: var openArray[string], @@ -137,7 +133,7 @@ proc findBounds*(buf: cstring, pattern: Regex, matches: var openArray[string], var a = rawMatches[i * 2] var b = rawMatches[i * 2 + 1] if a >= 0'i32: matches[i-1] = bufSubstr(buf, int(a), int(b)) - else: matches[i-1] = nil + else: matches[i-1] = "" return (rawMatches[0].int, rawMatches[1].int - 1) proc findBounds*(s: string, pattern: Regex, matches: var openArray[string], @@ -291,7 +287,7 @@ proc find*(buf: cstring, pattern: Regex, matches: var openArray[string], var a = rawMatches[i * 2] var b = rawMatches[i * 2 + 1] if a >= 0'i32: matches[i-1] = bufSubstr(buf, int(a), int(b)) - else: matches[i-1] = nil + else: matches[i-1] = "" return rawMatches[0] proc find*(s: string, pattern: Regex, matches: var openArray[string], @@ -460,8 +456,6 @@ proc replacef*(s: string, sub: Regex, by: string): string = 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 @@ -502,7 +496,7 @@ proc transformFile*(infile, outfile: string, var x = readFile(infile).string writeFile(outfile, x.multiReplace(subs)) -iterator split*(s: string, sep: Regex): string = +iterator split*(s: string, sep: Regex; maxsplit = -1): string = ## Splits the string ``s`` into substrings. ## ## Substrings are separated by the regular expression ``sep`` @@ -524,22 +518,28 @@ iterator split*(s: string, sep: Regex): string = ## "example" ## "" ## - var - first = -1 - last = -1 - while last < len(s): - var x = matchLen(s, sep, last) - if x > 0: inc(last, x) - first = last - if x == 0: inc(last) + var last = 0 + var splits = maxsplit + var x: int + while last <= len(s): + var first = last + var sepLen = 1 while last < len(s): x = matchLen(s, sep, last) - if x >= 0: break + if x >= 0: + sepLen = x + break inc(last) - if first <= last: - yield substr(s, first, last-1) - -proc split*(s: string, sep: Regex): seq[string] {.inline.} = + if x == 0: + if last >= len(s): break + inc last + if splits == 0: last = len(s) + yield substr(s, first, last-1) + if splits == 0: break + dec(splits) + inc(last, sepLen) + +proc split*(s: string, sep: Regex, maxsplit = -1): seq[string] {.inline.} = ## Splits the string ``s`` into a seq of substrings. ## ## The portion matched by ``sep`` is not returned. @@ -613,7 +613,7 @@ when isMainModule: doAssert false if "abc" =~ re"(cba)?.*": - doAssert matches[0] == nil + doAssert matches[0] == "" else: doAssert false if "abc" =~ re"().*": @@ -636,6 +636,14 @@ when isMainModule: accum.add(word) doAssert(accum == @["AAA", "", "BBB"]) + doAssert(split("abc", re"") == @["a", "b", "c"]) + doAssert(split("", re"") == @[]) + + doAssert(split("a;b;c", re";") == @["a", "b", "c"]) + doAssert(split(";a;b;c", re";") == @["", "a", "b", "c"]) + doAssert(split(";a;b;c;", re";") == @["", "a", "b", "c", ""]) + doAssert(split("a;b;c;", re";") == @["a", "b", "c", ""]) + for x in findAll("abcdef", re"^{.}", 3): doAssert x == "d" accum = @[] |