Skip to content

Instantly share code, notes, and snippets.

@tonsky
Created December 12, 2012 10:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tonsky/4266779 to your computer and use it in GitHub Desktop.
Save tonsky/4266779 to your computer and use it in GitHub Desktop.
(ns ini
(require [clojure.string :as str]
[clojure.tools.logging :as log])
(use clojure.test))
(defn read [content]
(-> content
(str/replace #"\\\s*($|\n\s*)" "")
(str/split-lines)))
(defn parse-line [l]
(condp re-matches (str/trim l)
#"\[\s*(.+?)\s*\]" :>> (fn [[_ s]] {:section s})
#"([^=]+?)\s*=\s*([^\s].*)" :>> (fn [[_ k v]] {:k k :v v})
#"\s*" nil
{:error l}))
(defn parse-conf [lines]
(loop [lines lines, sec "default", res {}]
(if-not lines
res
(let [{:keys [section k v error] :as l} (parse-line (first lines))
lines (next lines)]
(cond
section (recur lines section res)
error (do
(log/debug "Bad line: " error)
(recur lines sec res))
(and k v) (recur lines sec (assoc-in res [sec k] v))
:else (recur lines sec res))))))
(deftest test-read
(are [s r] (= (read s) r)
"abc \\ \n def" ["abc def"]
"abc\\\n def" ["abcdef"]
"abc\\\ndef" ["abcdef"]
"abc\\\n" ["abc"]
"abc\\" ["abc"]
"abc\\\ndef\\" ["abcdef"]))
(deftest test-parse-line
(testing "kv"
(are [s r] (= (parse-line s) r)
"k=v" {:k "k" :v "v"}
" k = v " {:k "k" :v "v"}
"k=v=v1=v2" {:k "k" :v "v=v1=v2"}))
(testing "sections"
(are [s r] (= (parse-line s) r)
"[sec]" {:section "sec"}
" [ s e c ] " {:section "s e c"}
"[ k = v ]" {:section "k = v"}))
(testing "errors"
(are [s r] (= (parse-line s) r)
"[sec" {:error "[sec"}
"sec]" {:error "sec]"}
"k" {:error "k"}
"k = " {:error "k = "}
" " nil)))
(deftest test-parse
(are [s r] (= (parse-conf s) r)
["k=v"] {"default" {"k" "v"}}
["k=v" "x=y"] {"default" {"k" "v" "x" "y"}}
["k=v" "k=v1"] {"default" {"k" "v1"}}
["[s1]" "k=v" "[s2]" "x=y"] {"s1" {"k" "v"} "s2" {"x" "y"}}
["[s1]" "k=v" "" "[s2]" "k=w" "" "[s1]" "l=u"] {"s1" {"k" "v" "l" "u"} "s2" {"k" "w"}}
["[s1]" "k=v" "[s2]" "k=w" "[s1]" "k=v1"] {"s1" {"k" "v1"} "s2" {"k" "w"}}))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment