diff options
author | Araq <rumpf_a@web.de> | 2020-01-26 11:13:24 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2020-01-26 13:43:02 +0100 |
commit | 6900da314ccd8c3f97dbeb340858b870bccadc89 (patch) | |
tree | 2776da41dd12911ee930c328f2e3bb1a75489128 /lib/impure | |
parent | a10cc18247cb576aa409e9056ed99f23539d14f9 (diff) | |
download | Nim-6900da314ccd8c3f97dbeb340858b870bccadc89.tar.gz |
make nre compile with --gc:arc
Diffstat (limited to 'lib/impure')
-rw-r--r-- | lib/impure/nre.nim | 120 |
1 files changed, 54 insertions, 66 deletions
diff --git a/lib/impure/nre.nim b/lib/impure/nre.nim index 728b9ef30..1d0952274 100644 --- a/lib/impure/nre.nim +++ b/lib/impure/nre.nim @@ -65,7 +65,6 @@ from unicode import runeLenAt export options -# Type definitions {{{ type Regex* = ref object ## 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 "abc".match(re"").get.captureBounds[-1] == 0 .. -1 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 = 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 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 = return getinfo[cint](pattern, pcre.INFO_CAPTURECOUNT) @@ -265,9 +315,8 @@ proc matchesCrLf(pattern: Regex): bool = of -2: return true of -1: return true else: return false -# }}} -# Capture accessors {{{ + func captureBounds*(pattern: RegexMatch): CaptureBounds = return CaptureBounds(pattern) func captures*(pattern: RegexMatch): Captures = return Captures(pattern) @@ -379,10 +428,7 @@ proc `==`*(a, b: Regex): bool = proc `==`*(a, b: RegexMatch): bool = return a.pattern == b.pattern and a.str == b.str -# }}} -# Creation & Destruction {{{ -# PCRE Options {{{ const PcreOptions = { "NEVER_UTF": pcre.NEVER_UTF, "ANCHORED": pcre.ANCHORED, @@ -438,66 +484,10 @@ proc extractOptions(pattern: string): tuple[pattern: string, flags: int, study: 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 = let (pattern, flags, study) = extractOptions(pattern) initRegex(pattern, flags, study) -# }}} -# Operations {{{ proc matchImpl(str: string, pattern: Regex, start, endpos: int, flags: int): Option[RegexMatch] = var myResult = RegexMatch(pattern : pattern, str : str) # See PCRE man pages. @@ -741,8 +731,6 @@ proc replace*(str: string, pattern: Regex, sub: string): string = replaceImpl(str, pattern, formatStr(sub, match.captures[name], match.captures[id - 1])) -# }}} - let SpecialCharMatcher = re"([\\+*?[^\]$(){}=!<>|:-])" proc escapeRe*(str: string): string = ## Escapes the string so it doesn’t match any special characters. |