1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
module GetOpt2 (module GetOpt, module GetOpt2) where
import GetOpt
import List (intercalate, maximum)
import Utils (rpad)
type OptErr opts = (opts, [String])
type OptTable opts = [(String, String, opts -> opts)]
onOpts :: (opts -> opts) -> OptErr opts -> OptErr opts
onOpts f (opts, errs) = (f opts, errs)
onOptsArg :: (String -> opts -> opts) -> String -> OptErr opts -> OptErr opts
onOptsArg f arg (opts, errs) = (f arg opts, errs)
addErr :: String -> OptErr opts -> OptErr opts
addErr err (opts, errs) = (opts, errs ++ [err])
option :: String -> [String] -> OptTable opts -> String -> String
-> OptDescr (OptErr opts -> OptErr opts)
option flags longFlags tbl arg what = Option flags longFlags
(ReqArg (parseOptErr what tbl) arg)
("set " ++ what ++ " `" ++ arg ++ "', where `" ++ arg ++ "' is one of\n"
++ renderOptErrTable tbl)
parseOptErr :: String -> OptTable opts -> String -> OptErr opts -> OptErr opts
parseOptErr what table opt = case lookup3 opt table of
Just f -> onOpts f
Nothing -> addErr $ "unrecognized " ++ what ++ '`' : opt ++ "'\n"
where
lookup3 _ [] = Nothing
lookup3 k ((k', _, v2) : kvs)
| k == k' = Just v2
| otherwise = lookup3 k kvs
renderOptErrTable :: OptTable opts -> String
renderOptErrTable ds = intercalate "\n"
$ map (\(k, d, _) -> " " ++ rpad maxLen k ++ ": " ++ d) ds
where maxLen = maximum $ map (\(k, _, _) -> length k) ds
|