opportunity: Added Makefile and README
[nit.git] / lib / standard / string.nit
index d41ab1a..3eede86 100644 (file)
@@ -16,6 +16,7 @@ module string
 
 import math
 import collection
+intrude import collection::array
 
 `{
 #include <stdio.h>
@@ -156,13 +157,6 @@ abstract class Text
                return self.chars.iterator
        end
 
-       # Is 'c' contained in self ?
-       #
-       # DEPRECATED : Use self.chars.has instead
-       fun has(c: Char): Bool
-       do
-               return self.chars.has(c)
-       end
 
        # Gets an Array containing the chars of self
        #
@@ -630,6 +624,14 @@ abstract class Text
                end
        end
 
+       # Escape string used in labels for graphviz
+       #
+       #   assert ">><<".escape_to_dot == "\\>\\>\\<\\<"
+       fun escape_to_dot: String
+       do
+               return escape_more_to_c("|\{\}<>")
+       end
+
        # Flat representation of self
        fun flatten: FlatText is abstract
 
@@ -657,7 +659,11 @@ end
 abstract class FlatText
        super Text
 
-       private var items: NativeString
+       # Underlying C-String (`char*`)
+       #
+       # Warning : Might be void in some subclasses, be sure to check
+       # if set before using it.
+       private var items: NativeString is noinit
 
        # Real items, used as cache for to_cstring is called
        private var real_items: nullable NativeString = null
@@ -824,6 +830,38 @@ abstract class String
 
                return new_str.to_s
        end
+
+       # Returns a capitalized `self`
+       #
+       # Letters that follow a letter are lowercased
+       # Letters that follow a non-letter are upcased.
+       #
+       # SEE : `Char::is_letter` for the definition of letter.
+       #
+       #    assert "jAVASCRIPT".capitalized == "Javascript"
+       #    assert "i am root".capitalized == "I Am Root"
+       #    assert "ab_c -ab0c ab\nc".capitalized == "Ab_C -Ab0C Ab\nC"
+       fun capitalized: SELFTYPE do
+               if length == 0 then return self
+
+               var buf = new FlatBuffer.with_capacity(length)
+
+               var curr = chars[0].to_upper
+               var prev = curr
+               buf[0] = curr
+
+               for i in [1 .. length[ do
+                       prev = curr
+                       curr = self[i]
+                       if prev.is_letter then
+                               buf[i] = curr.to_lower
+                       else
+                               buf[i] = curr.to_upper
+                       end
+               end
+
+               return buf.to_s
+       end
 end
 
 private class FlatSubstringsIter
@@ -849,10 +887,10 @@ class FlatString
        super String
 
        # Index in _items of the start of the string
-       private var index_from: Int
+       private var index_from: Int is noinit
 
        # Indes in _items of the last item of the string
-       private var index_to: Int
+       private var index_to: Int is noinit
 
        redef var chars: SequenceRead[Char] = new FlatStringCharView(self)
 
@@ -1271,6 +1309,38 @@ abstract class Buffer
        #     assert b == "hello world!"
        fun lower is abstract
 
+       # Capitalizes each word in `self`
+       #
+       # Letters that follow a letter are lowercased
+       # Letters that follow a non-letter are upcased.
+       #
+       # SEE: `Char::is_letter` for the definition of a letter.
+       #
+       #    var b = new FlatBuffer.from("jAVAsCriPt")"
+       #    b.capitalize
+       #    assert b == "Javascript"
+       #    b = new FlatBuffer.from("i am root")
+       #    b.capitalize
+       #    assert b == "I Am Root"
+       #    b = new FlatBuffer.from("ab_c -ab0c ab\nc")
+       #    b.capitalize
+       #    assert b == "Ab_C -Ab0C Ab\nC"
+       fun capitalize do
+               if length == 0 then return
+               var c = self[0].to_upper
+               self[0] = c
+               var prev: Char = c
+               for i in [1 .. length[ do
+                       prev = c
+                       c = self[i]
+                       if prev.is_letter then
+                               self[i] = c.to_lower
+                       else
+                               self[i] = c.to_upper
+                       end
+               end
+       end
+
        redef fun hash
        do
                if is_dirty then hash_cache = null
@@ -1358,6 +1428,7 @@ class FlatBuffer
        redef fun to_s: String
        do
                written = true
+               if length == 0 then items = new NativeString(1)
                return new FlatString.with_infos(items, length, 0, length - 1)
        end
 
@@ -1978,7 +2049,9 @@ extern class NativeString `{ char* `}
        fun to_s_with_length(length: Int): FlatString
        do
                assert length >= 0
-               return new FlatString.with_infos(self, length, 0, length - 1)
+               var str = new FlatString.with_infos(self, length, 0, length - 1)
+               str.real_items = self
+               return str
        end
 
        fun to_s_with_copy: FlatString
@@ -1986,7 +2059,9 @@ extern class NativeString `{ char* `}
                var length = cstring_length
                var new_self = calloc_string(length + 1)
                copy_to(new_self, length, 0, 0)
-               return new FlatString.with_infos(new_self, length, 0, length - 1)
+               var str = new FlatString.with_infos(new_self, length, 0, length - 1)
+               str.real_items = self
+               return str
        end
 end
 
@@ -1996,7 +2071,7 @@ interface StringCapable
 end
 
 redef class Sys
-       var _args_cache: nullable Sequence[String]
+       private var args_cache: nullable Sequence[String]
 
        # The arguments of the program as given by the OS
        fun program_args: Sequence[String]