mirror of
https://github.com/nim-lang/Nim.git
synced 2026-05-23 05:09:54 +00:00
Throw an exception when replacing with a nil value
This commit is contained in:
@@ -95,6 +95,8 @@ If `sub` is a string, the syntax is as follows:
|
||||
- `$#` - first capture
|
||||
- `$0` - full match
|
||||
|
||||
If a given capture is missing, a `ValueError` exception is thrown.
|
||||
|
||||
[[proc-escapere]]
|
||||
==== escapeRe(string): string
|
||||
|
||||
|
||||
@@ -9,6 +9,12 @@ 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 formatStr*(howExpr, namegetter, idgetter: expr): expr =
|
||||
let how = howExpr
|
||||
var val = newStringOfCap(how.len)
|
||||
@@ -19,37 +25,38 @@ template formatStr*(howExpr, namegetter, idgetter: expr): expr =
|
||||
if how[i] != '$':
|
||||
val.add(how[i])
|
||||
i += 1
|
||||
elif how[i + 1] == '$':
|
||||
val.add('$')
|
||||
i += 2
|
||||
elif how[i + 1] == '#':
|
||||
var id {.inject.} = lastNum
|
||||
val.add(idgetter)
|
||||
lastNum += 1
|
||||
i += 2
|
||||
elif how[i + 1] in {'0'..'9'}:
|
||||
i += 1
|
||||
var id {.inject.} = 0
|
||||
while i < how.len and how[i] in {'0'..'9'}:
|
||||
id += (id * 10) + (ord(how[i]) - ord('0'))
|
||||
i += 1
|
||||
val.add(idgetter)
|
||||
lastNum = id + 1
|
||||
elif how[i + 1] in StartIdent:
|
||||
i += 1
|
||||
var name {.inject.} = ""
|
||||
while i < how.len and how[i] in Ident:
|
||||
name.add(how[i])
|
||||
i += 1
|
||||
val.add(namegetter)
|
||||
elif how[i + 1] == '{':
|
||||
i += 2
|
||||
var name {.inject.} = ""
|
||||
while i < how.len and how[i] != '}':
|
||||
name.add(how[i])
|
||||
i += 1
|
||||
i += 1
|
||||
val.add(namegetter)
|
||||
else:
|
||||
raise newException(Exception, "Syntax error in format string at " & $i)
|
||||
if how[i + 1] == '$':
|
||||
val.add('$')
|
||||
i += 2
|
||||
elif how[i + 1] == '#':
|
||||
var id {.inject.} = lastNum
|
||||
val.add(checkNil(idgetter))
|
||||
lastNum += 1
|
||||
i += 2
|
||||
elif how[i + 1] in {'0'..'9'}:
|
||||
i += 1
|
||||
var id {.inject.} = 0
|
||||
while i < how.len and how[i] in {'0'..'9'}:
|
||||
id += (id * 10) + (ord(how[i]) - ord('0'))
|
||||
i += 1
|
||||
val.add(checkNil(idgetter))
|
||||
lastNum = id + 1
|
||||
elif how[i + 1] in StartIdent:
|
||||
i += 1
|
||||
var name {.inject.} = ""
|
||||
while i < how.len and how[i] in Ident:
|
||||
name.add(how[i])
|
||||
i += 1
|
||||
val.add(checkNil(namegetter))
|
||||
elif how[i + 1] == '{':
|
||||
i += 2
|
||||
var name {.inject.} = ""
|
||||
while i < how.len and how[i] != '}':
|
||||
name.add(how[i])
|
||||
i += 1
|
||||
i += 1
|
||||
val.add(checkNil(namegetter))
|
||||
else:
|
||||
raise newException(Exception, "Syntax error in format string at " & $i)
|
||||
val
|
||||
|
||||
@@ -14,3 +14,7 @@ suite "replace":
|
||||
check("123".replace(re"(\d)(\d)", "$#$#") == "123")
|
||||
check("123".replace(re"(?<foo>\d)(\d)", "$foo$#$#") == "1123")
|
||||
check("123".replace(re"(?<foo>\d)(\d)", "${foo}$#$#") == "1123")
|
||||
|
||||
test "replacing missing captures should throw instead of segfaulting":
|
||||
expect ValueError: discard "ab".replace(re"(a)|(b)", "$1$2")
|
||||
expect ValueError: discard "b".replace(re"(a)?(b)", "$1$2")
|
||||
|
||||
Reference in New Issue
Block a user