summary refs log tree commit diff stats
path: root/src/nre.nim
diff options
context:
space:
mode:
authorFlaviu Tamas <tamasflaviu@gmail.com>2015-01-10 14:11:43 -0500
committerFlaviu Tamas <tamasflaviu@gmail.com>2015-01-10 14:11:43 -0500
commit2db1a54710db4684f5f816ea4541f0998c11de9e (patch)
tree53675f8d3930a8acf937393d3cc0b61af334a2ae /src/nre.nim
parent613d12c7bfc9e191c1dfcf697d55dbe434e47d06 (diff)
downloadNim-2db1a54710db4684f5f816ea4541f0998c11de9e.tar.gz
Implement regex execution
Diffstat (limited to 'src/nre.nim')
-rw-r--r--src/nre.nim32
1 files changed, 29 insertions, 3 deletions
diff --git a/src/nre.nim b/src/nre.nim
index 1cd534cc0..5839cab2a 100644
--- a/src/nre.nim
+++ b/src/nre.nim
@@ -3,6 +3,8 @@ import private.util
 import tables
 import unsigned
 from strutils import toLower, `%`
+from math import ceil
+import optional_t
 
 # PCRE Options {{{
 
@@ -70,7 +72,9 @@ type
 
   RegexMatch* = object
     pattern: Regex
-    matchBounds: Slice[int]
+    matchBounds: seq[Slice[cint]] ## First item is the bounds of the match
+                                  ## Other items are the captures
+                                  ## `a` is inclusive start, `b` is exclusive end
 
   SyntaxError* = ref object of Exception
     pos*: int  ## the location of the syntax error in bytes
@@ -141,5 +145,27 @@ proc getNameToNumberTable(self: Regex): Table[string, int] =
 
     result[name] = num
 
-proc exec*(self: Regex, str: string): RegexMatch =
-  discard
+proc exec*(self: Regex, str: string, start = 0): Option[RegexMatch] =
+  var result: RegexMatch
+  result.pattern = self
+  # See PCRE man pages.
+  # 2x capture count to make room for start-end pairs
+  # 1x capture count as slack space for PCRE
+  let vecsize = (self.getCaptureCount() + 1) * 3
+  # div 2 because each element is 2 cints long
+  result.matchBounds = newSeq[Slice[cint]](ceil(vecsize / 2).int)
+  result.matchBounds.setLen(vecsize div 3)
+
+  let execRet = pcre.exec(self.pcreObj,
+                          self.pcreExtra,
+                          cstring(str),
+                          cint(str.len),
+                          cint(start),
+                          cint(0),
+                          cast[ptr cint](addr result.matchBounds[0]), cint(vecsize))
+  if execRet >= 0:
+    return Some(result)
+  elif execRet == pcre.ERROR_NOMATCH:
+    return None[RegexMatch]()
+  else:
+    raise newException(AssertionError, "Internal error: errno " & $execRet)