     (if (and gets sets) (fail (msgs :get+set)))
     (if (and sets (:no-prefix options)) (fail (msgs :set+no-prefix)))
     (if (and (:create options) (:in options)) (fail (msgs :create+in)))
-    (let [m (nml-map (if (:create options) "" (read-file in)))]
+    (let [fmt (let [f (:format options)] (if f (formats f) fmt-namelist))
+          m   (nml-map (if (:create options) "" (read-file in)))]
       (cond gets  (nml-out out (nml-gets m gets (:no-prefix options)))
             sets  (nml-out out (fmt (nml-sets m sets)))
             :else (nml-out out (fmt m))))))

  (let [sets (:set m [])]
    (assoc m :set (into sets [v]))))

(defn- parse-get [x]
  (string/split x #":" 2))

(defn- parse-set [x]
  (let [[nml+key val] (string/split x #"=" 2)
        [nml key] (parse-get nml+key)]
    [nml key val]))

(def cliopts
  [["-c" "--create"    "Create new namelist"                                                                ]
   ["-g" "--get n:k"   "Get value of key 'k' in namelist 'n'"         :assoc-fn assoc-g :parse-fn parse-get ]
   ["-h" "--help"      "Show usage information"                                                             ]
   ["-i" "--in file"   "Input file (default: stdin)"                  :assoc-fn assoc-i                     ]
   ["-n" "--no-prefix" "Report values without 'namelist:key=' prefix"                                       ]
   ["-o" "--out file"  "Output file (default: stdout)"                :assoc-fn assoc-o                     ]
   ["-s" "--set n:k=v" "Set value of key 'k' in namelist 'n' to 'v'"  :assoc-fn assoc-s :parse-fn parse-set ]
   ["-v" "--version"   "Show version information"                                                           ]])

;; formatting

(defn- fmt-bash [m fname]
  (let [ms  (sort m)
        eq #(string/replace % "\"" "\\\"")
        f0  (fn [[dataref values]]
              (let [v (eq values)]
                (str "'" dataref "') echo \"" v "\";;")))
        f1  (fn [[name nvseq]]
              (let [x (strmap f0 nvseq)]
                (str "'" name "') case \"$2\" in " x "*) echo '';;esac;;" )))]
    (str fname "(){ case \"$1\" in " (strmap f1 ms) "*) echo '';;esac; }\n")))

(defn- fmt-namelist [m]
  (let [f0 (fn [[dataref values]]
             (str "  " dataref "=" values "\n"))
        f1 (fn [[name nvseq]]
             (str "&" name "\n" (strmap f0 (sort nvseq)) "/\n"))]
    (strmap f1 (sort m))))

;; main

(defn -main [& args]
  (alter-var-root #'*read-eval* (constantly false))
  (let [{:keys [options arguments summary]} (cli/parse-opts args cliopts)
        fmt  fmt-namelist
        gets (:get options)
        sets (:set options)
        in   (or (:in  options) *in* )


;; cli

(defn- assoc-f [m k v]
  (if (k m) (fail (msgs :multi-format)))
  (assoc m k v))

(defn- assoc-g [m k v]
  (let [gets (:get m [])]
    (assoc m :get (into gets [v]))))
