Read a configuration file: Difference between revisions

Content added Content deleted
m (Added missing word in description)
(New Clojure solution; removed old solution and warning)
Line 810: Line 810:


=={{header|Clojure}}==
=={{header|Clojure}}==
Tested with Clojure 1.9.0
{{Incorrect|Clojure|Makes no attempt to parse the configuration file of the task description.}}
<lang clojure>(ns read-conf-file.core
One simple approach would be to use the [https://github.com/edn-format/edn edn-format] instead of the task's proposed config file. Example <tt>config.edn</tt>:
(:require [clojure.java.io :as io]
<pre>; This is a config file in edn format
[clojure.string :as str])
; Blank lines and lines beginning with a semicolon are ignored.
(:gen-class))
{
:fullname "Foo Barber"
:favorite-fruit "banana"
:needs-peeling true
; :seeds-removed false
:other-family ["Rhu Barber" "Harry Barber"]
}
</pre>


(def conf-keys ["fullname"
In Clojure we can read the config directly into a map in our program.
"favouritefruit"
<lang clojure>(let [cfg (read-string (slurp "config.edn"))]
"needspeeling"
(clojure.pprint/pprint cfg))</lang>
"seedsremoved"
"otherfamily"])

(defn get-lines
"Read file returning vec of lines."
[file]
(try
(with-open [rdr (io/reader file)]
(into [] (line-seq rdr)))
(catch Exception e (.getMessage e))))

(defn parse-line
"Parse passed line returning vec: token, vec of values."
[line]
(if-let [[_ k v] (re-matches #"(?i)^\s*([a-z]+)(?:\s+|=)?(.+)?$" line)]
(let [k (str/lower-case k)]
(if v
[k (str/split v #",\s*")]
[k [true]]))))

(defn mk-conf
"Build configuration map from parsed lines."
[lines]
(->> (map parse-line lines)
(filter (comp not nil?))
(reduce (fn
[m [k v]]
(assoc m k v)) {})))

(defn output
[conf-keys conf]
(doseq [k conf-keys]
(let [v (get conf k)]
(if v
(println (format "%s = %s" k (str/join ", " v)))
(println (format "%s = %s" k "false"))))))

(defn -main
[filename]
(output conf-keys (mk-conf (get-lines filename))))</lang>


{{out}}
{{out}}
<pre>
<pre>{:fullname "Foo Barber",
fullname = Foo Barber
:favorite-fruit "banana",
favouritefruit = banana
:needs-peeling true,
needspeeling = true
:other-family ["Rhu Barber" "Harry Barber"]}</pre>
seedsremoved = false
otherfamily = Rhu Barber, Harry Barber
</pre>


=={{header|Common Lisp}}==
=={{header|Common Lisp}}==