make nre compile with --gc:arc
This commit is contained in:
parent
a10cc18247
commit
6900da314c
1 changed files with 54 additions and 66 deletions
|
|
@ -65,7 +65,6 @@ from unicode import runeLenAt
|
||||||
|
|
||||||
export options
|
export options
|
||||||
|
|
||||||
# Type definitions {{{
|
|
||||||
type
|
type
|
||||||
Regex* = ref object
|
Regex* = ref object
|
||||||
## Represents the pattern that things are matched against, constructed with
|
## Represents the pattern that things are matched against, constructed with
|
||||||
|
|
@ -229,7 +228,12 @@ runnableExamples:
|
||||||
doAssert 0 in "abc".match(re"(\w)").get.captureBounds == true
|
doAssert 0 in "abc".match(re"(\w)").get.captureBounds == true
|
||||||
doAssert "abc".match(re"").get.captureBounds[-1] == 0 .. -1
|
doAssert "abc".match(re"").get.captureBounds[-1] == 0 .. -1
|
||||||
doAssert "abc".match(re"abc").get.captureBounds[-1] == 0 .. 2
|
doAssert "abc".match(re"abc").get.captureBounds[-1] == 0 .. 2
|
||||||
# }}}
|
|
||||||
|
|
||||||
|
proc destroyRegex(pattern: Regex) =
|
||||||
|
pcre.free_substring(cast[cstring](pattern.pcreObj))
|
||||||
|
if pattern.pcreExtra != nil:
|
||||||
|
pcre.free_study(pattern.pcreExtra)
|
||||||
|
|
||||||
proc getinfo[T](pattern: Regex, opt: cint): T =
|
proc getinfo[T](pattern: Regex, opt: cint): T =
|
||||||
let retcode = pcre.fullinfo(pattern.pcreObj, pattern.pcreExtra, opt, addr result)
|
let retcode = pcre.fullinfo(pattern.pcreObj, pattern.pcreExtra, opt, addr result)
|
||||||
|
|
@ -238,7 +242,53 @@ proc getinfo[T](pattern: Regex, opt: cint): T =
|
||||||
# XXX Error message that doesn't expose implementation details
|
# XXX Error message that doesn't expose implementation details
|
||||||
raise newException(FieldError, "Invalid getinfo for $1, errno $2" % [$opt, $retcode])
|
raise newException(FieldError, "Invalid getinfo for $1, errno $2" % [$opt, $retcode])
|
||||||
|
|
||||||
# Regex accessors {{{
|
proc getNameToNumberTable(pattern: Regex): Table[string, int] =
|
||||||
|
let entryCount = getinfo[cint](pattern, pcre.INFO_NAMECOUNT)
|
||||||
|
let entrySize = getinfo[cint](pattern, pcre.INFO_NAMEENTRYSIZE)
|
||||||
|
let table = cast[ptr UncheckedArray[uint8]](
|
||||||
|
getinfo[int](pattern, pcre.INFO_NAMETABLE))
|
||||||
|
|
||||||
|
result = initTable[string, int]()
|
||||||
|
|
||||||
|
for i in 0 ..< entryCount:
|
||||||
|
let pos = i * entrySize
|
||||||
|
let num = (int(table[pos]) shl 8) or int(table[pos + 1]) - 1
|
||||||
|
var name = ""
|
||||||
|
|
||||||
|
var idx = 2
|
||||||
|
while table[pos + idx] != 0:
|
||||||
|
name.add(char(table[pos + idx]))
|
||||||
|
idx += 1
|
||||||
|
|
||||||
|
result[name] = num
|
||||||
|
|
||||||
|
proc initRegex(pattern: string, flags: int, study = true): Regex =
|
||||||
|
new(result, destroyRegex)
|
||||||
|
result.pattern = pattern
|
||||||
|
|
||||||
|
var errorMsg: cstring
|
||||||
|
var errOffset: cint
|
||||||
|
|
||||||
|
result.pcreObj = pcre.compile(cstring(pattern),
|
||||||
|
# better hope int is at least 4 bytes..
|
||||||
|
cint(flags), addr errorMsg,
|
||||||
|
addr errOffset, nil)
|
||||||
|
if result.pcreObj == nil:
|
||||||
|
# failed to compile
|
||||||
|
raise SyntaxError(msg: $errorMsg, pos: errOffset, pattern: pattern)
|
||||||
|
|
||||||
|
if study:
|
||||||
|
var options: cint = 0
|
||||||
|
var hasJit: cint
|
||||||
|
if pcre.config(pcre.CONFIG_JIT, addr hasJit) == 0:
|
||||||
|
if hasJit == 1'i32:
|
||||||
|
options = pcre.STUDY_JIT_COMPILE
|
||||||
|
result.pcreExtra = pcre.study(result.pcreObj, options, addr errorMsg)
|
||||||
|
if errorMsg != nil:
|
||||||
|
raise StudyError(msg: $errorMsg)
|
||||||
|
|
||||||
|
result.captureNameToId = result.getNameToNumberTable()
|
||||||
|
|
||||||
proc captureCount*(pattern: Regex): int =
|
proc captureCount*(pattern: Regex): int =
|
||||||
return getinfo[cint](pattern, pcre.INFO_CAPTURECOUNT)
|
return getinfo[cint](pattern, pcre.INFO_CAPTURECOUNT)
|
||||||
|
|
||||||
|
|
@ -265,9 +315,8 @@ proc matchesCrLf(pattern: Regex): bool =
|
||||||
of -2: return true
|
of -2: return true
|
||||||
of -1: return true
|
of -1: return true
|
||||||
else: return false
|
else: return false
|
||||||
# }}}
|
|
||||||
|
|
||||||
# Capture accessors {{{
|
|
||||||
func captureBounds*(pattern: RegexMatch): CaptureBounds = return CaptureBounds(pattern)
|
func captureBounds*(pattern: RegexMatch): CaptureBounds = return CaptureBounds(pattern)
|
||||||
|
|
||||||
func captures*(pattern: RegexMatch): Captures = return Captures(pattern)
|
func captures*(pattern: RegexMatch): Captures = return Captures(pattern)
|
||||||
|
|
@ -379,10 +428,7 @@ proc `==`*(a, b: Regex): bool =
|
||||||
proc `==`*(a, b: RegexMatch): bool =
|
proc `==`*(a, b: RegexMatch): bool =
|
||||||
return a.pattern == b.pattern and
|
return a.pattern == b.pattern and
|
||||||
a.str == b.str
|
a.str == b.str
|
||||||
# }}}
|
|
||||||
|
|
||||||
# Creation & Destruction {{{
|
|
||||||
# PCRE Options {{{
|
|
||||||
const PcreOptions = {
|
const PcreOptions = {
|
||||||
"NEVER_UTF": pcre.NEVER_UTF,
|
"NEVER_UTF": pcre.NEVER_UTF,
|
||||||
"ANCHORED": pcre.ANCHORED,
|
"ANCHORED": pcre.ANCHORED,
|
||||||
|
|
@ -438,66 +484,10 @@ proc extractOptions(pattern: string): tuple[pattern: string, flags: int, study:
|
||||||
|
|
||||||
result.pattern.add pattern[optionStart .. pattern.high]
|
result.pattern.add pattern[optionStart .. pattern.high]
|
||||||
|
|
||||||
# }}}
|
|
||||||
|
|
||||||
proc destroyRegex(pattern: Regex) =
|
|
||||||
pcre.free_substring(cast[cstring](pattern.pcreObj))
|
|
||||||
if pattern.pcreExtra != nil:
|
|
||||||
pcre.free_study(pattern.pcreExtra)
|
|
||||||
|
|
||||||
proc getNameToNumberTable(pattern: Regex): Table[string, int] =
|
|
||||||
let entryCount = getinfo[cint](pattern, pcre.INFO_NAMECOUNT)
|
|
||||||
let entrySize = getinfo[cint](pattern, pcre.INFO_NAMEENTRYSIZE)
|
|
||||||
let table = cast[ptr UncheckedArray[uint8]](
|
|
||||||
getinfo[int](pattern, pcre.INFO_NAMETABLE))
|
|
||||||
|
|
||||||
result = initTable[string, int]()
|
|
||||||
|
|
||||||
for i in 0 ..< entryCount:
|
|
||||||
let pos = i * entrySize
|
|
||||||
let num = (int(table[pos]) shl 8) or int(table[pos + 1]) - 1
|
|
||||||
var name = ""
|
|
||||||
|
|
||||||
var idx = 2
|
|
||||||
while table[pos + idx] != 0:
|
|
||||||
name.add(char(table[pos + idx]))
|
|
||||||
idx += 1
|
|
||||||
|
|
||||||
result[name] = num
|
|
||||||
|
|
||||||
proc initRegex(pattern: string, flags: int, study = true): Regex =
|
|
||||||
new(result, destroyRegex)
|
|
||||||
result.pattern = pattern
|
|
||||||
|
|
||||||
var errorMsg: cstring
|
|
||||||
var errOffset: cint
|
|
||||||
|
|
||||||
result.pcreObj = pcre.compile(cstring(pattern),
|
|
||||||
# better hope int is at least 4 bytes..
|
|
||||||
cint(flags), addr errorMsg,
|
|
||||||
addr errOffset, nil)
|
|
||||||
if result.pcreObj == nil:
|
|
||||||
# failed to compile
|
|
||||||
raise SyntaxError(msg: $errorMsg, pos: errOffset, pattern: pattern)
|
|
||||||
|
|
||||||
if study:
|
|
||||||
var options: cint = 0
|
|
||||||
var hasJit: cint
|
|
||||||
if pcre.config(pcre.CONFIG_JIT, addr hasJit) == 0:
|
|
||||||
if hasJit == 1'i32:
|
|
||||||
options = pcre.STUDY_JIT_COMPILE
|
|
||||||
result.pcreExtra = pcre.study(result.pcreObj, options, addr errorMsg)
|
|
||||||
if errorMsg != nil:
|
|
||||||
raise StudyError(msg: $errorMsg)
|
|
||||||
|
|
||||||
result.captureNameToId = result.getNameToNumberTable()
|
|
||||||
|
|
||||||
proc re*(pattern: string): Regex =
|
proc re*(pattern: string): Regex =
|
||||||
let (pattern, flags, study) = extractOptions(pattern)
|
let (pattern, flags, study) = extractOptions(pattern)
|
||||||
initRegex(pattern, flags, study)
|
initRegex(pattern, flags, study)
|
||||||
# }}}
|
|
||||||
|
|
||||||
# Operations {{{
|
|
||||||
proc matchImpl(str: string, pattern: Regex, start, endpos: int, flags: int): Option[RegexMatch] =
|
proc matchImpl(str: string, pattern: Regex, start, endpos: int, flags: int): Option[RegexMatch] =
|
||||||
var myResult = RegexMatch(pattern : pattern, str : str)
|
var myResult = RegexMatch(pattern : pattern, str : str)
|
||||||
# See PCRE man pages.
|
# See PCRE man pages.
|
||||||
|
|
@ -741,8 +731,6 @@ proc replace*(str: string, pattern: Regex, sub: string): string =
|
||||||
replaceImpl(str, pattern,
|
replaceImpl(str, pattern,
|
||||||
formatStr(sub, match.captures[name], match.captures[id - 1]))
|
formatStr(sub, match.captures[name], match.captures[id - 1]))
|
||||||
|
|
||||||
# }}}
|
|
||||||
|
|
||||||
let SpecialCharMatcher = re"([\\+*?[^\]$(){}=!<>|:-])"
|
let SpecialCharMatcher = re"([\\+*?[^\]$(){}=!<>|:-])"
|
||||||
proc escapeRe*(str: string): string =
|
proc escapeRe*(str: string): string =
|
||||||
## Escapes the string so it doesn’t match any special characters.
|
## Escapes the string so it doesn’t match any special characters.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue