lib/core: `is_numeric` returns false on empty strings
[nit.git] / lib / core / text / abstract_text.nit
index fc8ec5b..401f32c 100644 (file)
@@ -305,26 +305,33 @@ abstract class Text
                end
        end
 
-       # Returns `true` if the string contains only Numeric values (and one "," or one "." character)
+       # Is this string in a valid numeric format compatible with `to_f`?
        #
        #     assert "123".is_numeric  == true
        #     assert "1.2".is_numeric  == true
+       #     assert "-1.2".is_numeric == true
        #     assert "1,2".is_numeric  == true
+       #     assert "-1.23e-2".is_numeric == true
        #     assert "1..2".is_numeric == false
+       #     assert "".is_numeric     == false
        fun is_numeric: Bool
        do
                var has_point_or_comma = false
+               var e_index = -1
                for i in [0..length[ do
                        var c = chars[i]
                        if not c.is_numeric then
                                if (c == '.' or c == ',') and not has_point_or_comma then
                                        has_point_or_comma = true
+                               else if c == 'e' and e_index == -1 and i > 0 and i < length - 1 and chars[i-1] != '-' then
+                                       e_index = i
+                               else if c == '-' and i == e_index + 1 and i < length - 1 then
                                else
                                        return false
                                end
                        end
                end
-               return true
+               return not is_empty
        end
 
        # Returns `true` if the string contains only Hex chars
@@ -852,7 +859,7 @@ abstract class Text
                        l += 1
                end
 
-               return buf.to_s_with_length(l)
+               return buf.to_s_unsafe(l)
        end
 
        # Escape the characters `<`, `>`, `&`, `"`, `'` and `/` as HTML/XML entity references.
@@ -1062,7 +1069,7 @@ abstract class Text
        #
        #       var ns = new NativeString(8)
        #       "Text is String".copy_to_native(ns, 8, 2, 0)
-       #       assert ns.to_s_with_length(8) == "xt is St"
+       #       assert ns.to_s_unsafe(8) == "xt is St"
        #
        fun copy_to_native(dest: NativeString, n, src_offset, dest_offset: Int) do
                var mypos = src_offset
@@ -1541,7 +1548,7 @@ redef class Byte
                var ns = new NativeString(nslen + 1)
                ns[nslen] = 0u8
                native_byte_to_s(ns, nslen + 1)
-               return ns.to_s_with_length(nslen)
+               return ns.to_s_unsafe(nslen)
        end
 end
 
@@ -1702,7 +1709,7 @@ redef class Char
                var ln = u8char_len
                var ns = new NativeString(ln + 1)
                u8char_tos(ns, ln)
-               return ns.to_s_with_length(ln)
+               return ns.to_s_unsafe(ln)
        end
 
        # Returns `self` escaped to UTF-16
@@ -2001,6 +2008,12 @@ redef class NativeString
        # Returns `self` as a String of `length`.
        fun to_s_with_length(length: Int): String is abstract
 
+       # Returns a new instance of `String` with self as `_items`
+       #
+       # /!\: Does not clean the items for compliance with UTF-8,
+       # Use only if you know what you are doing
+       fun to_s_unsafe(len: nullable Int): String is abstract
+
        # Returns `self` as a String with `bytelen` and `length` set
        #
        # SEE: `abstract_text::Text` for more infos on the difference