remove bin/Makefile (?!)
[nit.git] / lib / ini.nit
index a6de8f1..bf1c652 100644 (file)
@@ -32,15 +32,12 @@ module ini
 #    assert config.has_key("foo.bar")
 #    assert config["foo.bar"] == "foobar"
 class ConfigTree
-       super Streamable
+       super Writable
 
        # The ini file used to read/store data
        var ini_file: String
 
-       init(file: String) do
-               self.ini_file = file
-               if file.file_exists then load
-       end
+       init do if ini_file.file_exists then load
 
        # Get the config value for `key`
        #
@@ -103,7 +100,6 @@ class ConfigTree
        #    assert config.has_key("foo.bar")
        #    assert not config.has_key("zoo")
        fun has_key(key: String): Bool do
-               var children = roots
                var parts = key.split(".").reversed
                var node = get_root(parts.pop)
                if node == null then return false
@@ -188,28 +184,50 @@ class ConfigTree
        #     assert config["foo.bar.baz"] == "foobarbaz"
        #     assert config["goo.boo.bar"] == "gooboobar"
        #     assert config["goo.boo.baz.bar"] == "gooboobazbar"
+       #
+       # Using the array notation
+       #
+       #     str = """
+       #     foo[]=a
+       #     foo[]=b
+       #     foo[]=c"""
+       #     str.write_to_file("config4.ini")
+       #     # load file
+       #     config = new ConfigTree("config4.ini")
+       #     print config.to_map.join(":", ",")
+       #     assert config["foo.0"] == "a"
+       #     assert config["foo.1"] == "b"
+       #     assert config["foo.2"] == "c"
+       #     assert config.at("foo").values.join(",") == "a,b,c"
        fun load do
                roots.clear
-               var stream = new IFStream.open(ini_file)
+               var stream = new FileReader.open(ini_file)
                var path: nullable String = null
+               var line_number = 0
                while not stream.eof do
                        var line = stream.read_line
+                       line_number += 1
                        if line.is_empty then
                                continue
                        else if line.has_prefix(";") then
                                continue
                        else if line.has_prefix("[") then
-                               var key = line.trim.substring(1, line.length - 2)
+                               line = line.trim
+                               var key = line.substring(1, line.length - 2)
                                path = key
                                set_node(path, null)
                        else
                                var parts = line.split("=")
+                               assert parts.length > 1 else
+                                       print "Error: malformed ini at line {line_number}"
+                               end
                                var key = parts[0].trim
                                var val = parts[1].trim
-                               if path == null then
-                                       set_node(key, val)
+                               if path != null then key = "{path}.{key}"
+                               if key.has_suffix("[]") then
+                                       set_array(key, val)
                                else
-                                       set_node("{path}.{key}", val)
+                                       set_node(key,val)
                                end
                        end
                end
@@ -221,8 +239,17 @@ class ConfigTree
 
        private var roots = new Array[ConfigNode]
 
+       # Append `value` to array at `key`
+       private fun set_array(key: String, value: nullable String) do
+               key = key.substring(0, key.length - 2)
+               var len = 0
+               if has_key(key) then
+                       len = get_node(key).children.length
+               end
+               set_node("{key}.{len.to_s}", value)
+       end
+
        private fun set_node(key: String, value: nullable String) do
-               var children = roots
                var parts = key.split(".").reversed
                var k = parts.pop
                var root = get_root(k)
@@ -249,7 +276,6 @@ class ConfigTree
        end
 
        private fun get_node(key: String): nullable ConfigNode do
-               var children = roots
                var parts = key.split(".").reversed
                var node = get_root(parts.pop)
                while not parts.is_empty do
@@ -282,14 +308,11 @@ class ConfigTree
 end
 
 private class ConfigNode
-       var parent: nullable ConfigNode
+
+       var parent: nullable ConfigNode = null
        var children = new HashMap[String, ConfigNode]
        var name: String is writable
-       var value: nullable String
-
-       init(name: String) do
-               self.name = name
-       end
+       var value: nullable String = null
 
        fun key: String do
                if parent == null then