lib/re: rename `optimize_is_in` to `optimize_has`
[nit.git] / lib / core / re.nit
index 7d588ca..99421f8 100644 (file)
@@ -22,6 +22,7 @@
 module re
 
 import text
+intrude import text::flat
 import gc
 import error
 
@@ -35,7 +36,7 @@ in "C Header" `{
 # It is recommanded to use the higher level API offered by the class `Regex`,
 # but it can still be used for advanced purpose or in optimized code.
 #
-# To use this class and other `private` entities of this module, use `intrude import standard::re`
+# To use this class and other `private` entities of this module, use `intrude import core::re`
 private extern class NativeRegex `{ regex_t* `}
        # Allocate a new `NativeRegex`, it must then be compiled using `regcomp` before calling `regexec`
        new malloc `{ return malloc(sizeof(regex_t)); `}
@@ -152,11 +153,11 @@ class Regex
        # Ignore case when matching letters
        var ignore_case = false is writable
 
-       # Optimize `self` for `is_in` and `String::has`, but do not support searches
+       # Optimize `self` for `String::has` and `is_in`, but do not support searches
        #
        # If `true`, `self` cannont be used with `String::search_all`, `String::replace`
        # or `String::split`.
-       var optimize_is_in = false is writable
+       var optimize_has = false is writable
 
        # Treat a newline in string as dividing string into multiple lines
        #
@@ -207,7 +208,7 @@ class Regex
                var cflags = 0
                if extended then cflags |= flag_extended
                if ignore_case then cflags |= flag_icase
-               if optimize_is_in then cflags |= flag_nosub
+               if optimize_has then cflags |= flag_nosub
                if newline then cflags |= flag_newline
 
                var native = self.native
@@ -306,7 +307,7 @@ class Regex
                abort
        end
 
-       # require: not optimize_is_in
+       # require: not optimize_has
        #
        #     assert "l".to_re.search_index_in("hello world", 0) == 2
        #     assert "el+o".to_re.search_index_in("hello world", 0) == 1
@@ -314,7 +315,7 @@ class Regex
        #     assert "z".to_re.search_index_in("hello world", 0) == -1
        redef fun search_index_in(text, from)
        do
-               assert not optimize_is_in
+               assert not optimize_has
 
                var comp_res = compile
                assert comp_res == null else "Regex compilation failed with: {comp_res.message}\n".output
@@ -339,7 +340,7 @@ class Regex
                abort
        end
 
-       # require: not optimize_is_in
+       # require: not optimize_has
        #
        #     assert "l".to_re.search_in("hello world", 0).from == 2
        #     assert "el+o".to_re.search_in("hello world", 0).from == 1
@@ -347,14 +348,16 @@ class Regex
        #     assert "z".to_re.search_in("hello world", 0) == null
        redef fun search_in(text, from)
        do
-               assert not optimize_is_in
+               assert not optimize_has
 
                var comp_res = compile
                assert comp_res == null else "Regex compilation failed with: {comp_res.message}\n".output
 
                # Actually execute
                text = text.to_s
-               var cstr = text.substring_from(from).to_cstring
+               var sub = text.substring_from(from)
+               var cstr = sub.to_cstring
+               var bstr = new FlatString.full(cstr, sub.bytelen, 0, sub.bytelen - 1, text.length - from)
                var eflags = gather_eflags
                var native_match = self.native_match
 
@@ -363,15 +366,19 @@ class Regex
 
                # Found one?
                if res == 0 then
+                       var bso = bstr.byte_to_char_index(native_match.rm_so)
+                       var ln = bstr.byte_to_char_index(native_match.rm_eo - native_match.rm_so - 1)
                        var match = new Match(text,
-                               from + native_match.rm_so,
-                               native_match.rm_eo - native_match.rm_so)
+                               from + bso,
+                               ln + 1)
 
                        # Add sub expressions
-                       for i in [1..nsub] do
+                       for i in [1 .. nsub] do
+                               bso = bstr.byte_to_char_index(native_match[i].rm_so)
+                               ln = bstr.byte_to_char_index(native_match[i].rm_eo - native_match[i].rm_so - 1)
                                match.subs.add new Match( text,
-                                       native_match[i].rm_so,
-                                       native_match[i].rm_eo - native_match[i].rm_so)
+                                       bso ,
+                                       ln + 1)
                        end
 
                        return match
@@ -386,13 +393,13 @@ class Regex
                abort
        end
 
-       # require: not optimize_is_in
+       # require: not optimize_has
        #
        #     assert "ab".to_re.search_all_in("abbab").join(", ") == "ab, ab"
        #     assert "b+".to_re.search_all_in("abbabaabbbbbcab").join(", ") == "bb, b, bbbbb, b"
        redef fun search_all_in(text)
        do
-               assert not optimize_is_in
+               assert not optimize_has
 
                var comp_res = compile
                assert comp_res == null else "Regex compilation failed with: {comp_res.message}\n".output