Merge: Nitsmell : Adding new code smells and print console updated
[nit.git] / lib / core / re.nit
index 9b6b0fd..048eed3 100644 (file)
@@ -42,7 +42,7 @@ private extern class NativeRegex `{ regex_t* `}
        new malloc `{ return malloc(sizeof(regex_t)); `}
 
        # Compile the regular expression `regex` into a form that is suitable for subsequent `regexec` searches
-       fun regcomp(regex: NativeString, cflags: Int): Int `{
+       fun regcomp(regex: CString, cflags: Int): Int `{
                return regcomp(self, regex, cflags);
        `}
 
@@ -50,14 +50,14 @@ private extern class NativeRegex `{ regex_t* `}
        #
        # `nmatch` and `pmatch` are used to provide information regarding the location of any matches.
        # `eflags` may be the bitwise-or of one or both of `flag_notbol` and `flag_noteol`.
-       fun regexec(string: NativeString, nmatch: Int, pmatch: NativeMatchArray, eflags: Int): Int `{
+       fun regexec(string: CString, nmatch: Int, pmatch: NativeMatchArray, eflags: Int): Int `{
                return regexec(self, string, nmatch, pmatch, eflags);
        `}
 
        # Match `string` against the precompiled pattern buffer of `self`, do not locate matches
        #
        # `eflags` may be the bitwise-or of one or both of `flag_notbol` and `flag_noteol`.
-       fun regexec_match_only(string: NativeString, eflags: Int): Int `{
+       fun regexec_match_only(string: CString, eflags: Int): Int `{
                return regexec(self, string, 0, NULL, eflags);
        `}
 
@@ -67,7 +67,7 @@ private extern class NativeRegex `{ regex_t* `}
        fun regfree `{ regfree(self); `}
 
        # Turn the error codes that can be returned by both `regcomp` and `regexec` into error message strings
-       fun regerror(errcode: Int): NativeString `{
+       fun regerror(errcode: Int): CString `{
                size_t len = regerror(errcode, self, NULL, 0);
                char *message = malloc(len);
                regerror(errcode, self, message, len);
@@ -115,8 +115,8 @@ private extern class NativeMatchArray `{ regmatch_t* `}
        fun [](index: Int): NativeMatchArray `{ return self + index; `}
 end
 
-redef extern class NativeString
-       private fun substring_from(index: Int): NativeString `{ return self + index; `}
+redef extern class CString
+       private fun substring_from(index: Int): CString `{ return self + index; `}
 end
 
 redef class Text
@@ -183,7 +183,7 @@ class Regex
        # Cache of a single `regmatch_t` to prevent many calls to `malloc`
        private var native_match: NativeMatchArray is lazy do
                native_match_is_init = true
-               return new NativeMatchArray.malloc(native.re_nsub+1)
+               return new NativeMatchArray.malloc(native.as(not null).re_nsub+1)
        end
 
        private var native_match_is_init = false
@@ -239,7 +239,7 @@ class Regex
                        var error_cstr = native.regerror(res)
 
                        # We leave it to the lib to decide how to allocate the string that we keep
-                       var error_str = error_cstr.to_s_with_copy
+                       var error_str = error_cstr.to_s
                        error_cstr.free
 
                        return new Error(error_str)
@@ -279,7 +279,7 @@ class Regex
                var error_cstr = native.regerror(errcode)
 
                # We leave it to the lib to decide how to allocate the string that we keep
-               var error_str = error_cstr.to_s_with_copy
+               var error_str = error_cstr.to_s
                error_cstr.free
 
                return error_str
@@ -368,7 +368,7 @@ class Regex
 
                # Actually execute
                var cstr = text.to_cstring
-               var rets = cstr.to_s_with_length(text.bytelen)
+               var rets = cstr.to_s_unsafe(text.byte_length, copy=false)
                var bytefrom = cstr.char_to_byte_index_cached(charfrom, 0, 0)
                var subcstr = cstr.fast_cstring(bytefrom)
                var eflags = gather_eflags
@@ -382,17 +382,21 @@ class Regex
                        var bfrom = native_match.rm_so + bytefrom
                        var bto = native_match.rm_eo - 1 + bytefrom
                        var cpos = cstr.byte_to_char_index_cached(bfrom, charfrom, bytefrom)
-                       var len = cstr.utf8_length(bfrom, bto)
+                       var len = cstr.utf8_length(bfrom, bto - bfrom + 1)
                        var match = new Match(rets, cpos, len)
+                       var subs = match.subs
 
                        # Add sub expressions
                        for i in [1 .. nsub] do
-                               if native_match[i].rm_so < 0 then continue
+                               if native_match[i].rm_so < 0 then
+                                       subs.add null
+                                       continue
+                               end
                                var sub_bfrom = native_match[i].rm_so + bytefrom
                                var sub_bto = native_match[i].rm_eo - 1 + bytefrom
                                var sub_cpos = cstr.byte_to_char_index_cached(sub_bfrom, cpos, bfrom)
-                               var sub_len = cstr.utf8_length(sub_bfrom, sub_bto)
-                               match.subs.add(new Match(rets, sub_cpos, sub_len))
+                               var sub_len = cstr.utf8_length(sub_bfrom, sub_bto - sub_bfrom + 1)
+                               subs.add(new Match(rets, sub_cpos, sub_len))
                        end
 
                        return match
@@ -424,7 +428,7 @@ class Regex
                # Actually execute
                var cstr = text.to_cstring
                var subcstr = cstr
-               var rets = cstr.to_s_with_length(text.bytelen)
+               var rets = cstr.to_s_unsafe(text.byte_length, copy=false)
                var eflags = gather_eflags
                var eflags_or_notbol = eflags | flag_notbol
                var native_match = self.native_match
@@ -438,18 +442,22 @@ class Regex
                        var bfrom = native_match.rm_so + bytesub
                        var bto = native_match.rm_eo - 1 + bytesub
                        var cstart = cstr.byte_to_char_index_cached(bfrom, charsub, bytesub)
-                       var len = cstr.utf8_length(bfrom, bto)
+                       var len = cstr.utf8_length(bfrom, bto - bfrom + 1)
                        var match = new Match(rets, cstart, len)
                        matches.add match
+                       var subs = match.subs
 
                        # Add sub expressions
                        for i in [1 .. nsub] do
-                               if native_match[i].rm_so < 0 then continue
+                               if native_match[i].rm_so < 0 then
+                                       subs.add null
+                                       continue
+                               end
                                var sub_bfrom = native_match[i].rm_so + bytesub
                                var sub_bto = native_match[i].rm_eo - 1 + bytesub
                                var sub_cstart = cstr.byte_to_char_index_cached(sub_bfrom, cstart, bfrom)
-                               var sub_len = cstr.utf8_length(sub_bfrom, sub_bto)
-                               match.subs.add(new Match(rets, sub_cstart, sub_len))
+                               var sub_len = cstr.utf8_length(sub_bfrom, sub_bto - sub_bfrom + 1)
+                               subs.add(new Match(rets, sub_cstart, sub_len))
                        end
 
                        bytesub = bto + 1
@@ -479,7 +487,7 @@ redef class Match
        # assert match.subs.length == 1
        # assert match.subs.first.to_s == "d eee"
        # ~~~
-       var subs = new Array[Match] is lazy
+       var subs = new Array[nullable Match] is lazy
 
        # Get the `n`th expression in this match
        #
@@ -494,7 +502,7 @@ redef class Match
        # assert match[0].to_s == "c d eee f"
        # assert match[1].to_s == "d eee"
        # ~~~
-       fun [](n: Int): Match do
+       fun [](n: Int): nullable Match do
                if n == 0 then return self
                assert n > 0 and n <= subs.length
                return subs[n-1]