inidata = spaces, {section} .
section = "[", ident, "]", stringSpaces, "\n", {entry} .
entry = ident, stringSpaces, "=", stringSpaces, value, "\n", spaces .
ident = identChar, {identChar} .
identChar = letter | digit | "_" | "." | "," | ":" | "(" | ")" | "{" | "}" | "-" | "#" | "@" | "&" | "*" | "|" .
value = {not "\n"} .
stringSpaces = {" " | "\t"} .
spaces = {" " | "\t" | "\n" | "\r"} .
1 module Main where
2
3 import System.Environment
4 import Data.Char
5 import Data.List
6 import Text.ParserCombinators.Parsec
8 type Entry = (String, String)
9 type Section = (String, [Entry])
10 type IniData = [Section]
12 inidata = spaces >> many section >>= return
14 section = do
15 char '['
16 name <- ident
17 char ']'
18 stringSpaces
19 char ' \n '
20 spaces
21 el <- many entry
22 return (name, el)
24 entry = do
25 k <- ident
26 stringSpaces
27 char '='
28 stringSpaces
29 v <- value
30 spaces
31 return (k, v)
32 ident = many1 (letter <|> digit <|> oneOf "_.,:(){}-#@&*|" ) >>= return . trim
34 value = many (noneOf " \n " ) >>= return . trim
36 stringSpaces = many (char ' ' <|> char ' \t ' )
38 trim = f . f
39 where f = reverse . dropWhile isSpace
41 split delim = foldr f [[]]
42 where
43 f x rest @ (r : rs)
44 | x == delim = [delim] : rest
45 | otherwise = (x : r) : rs
47 removeComments = foldr ( ++ ) [] . filter comment . split ' \n '
48 where comment [] = False
49 comment (x : _) = (x /= ';' ) && (x /= ' \n ' )
51 findValue ini s p = do
52 el <- find ( \ x -> fst x == s) ini
53 v <- find ( \ x -> fst x == p) (snd el)
54 return $ snd $ v
56 main = do
57 args <- getArgs
58 prog <- getProgName
59 if (length args) /= 3
60 then putStrLn $ "Usage: " ++ prog ++ " <file.ini> <section> <parameter>"
61 else do
62 file <- readFile $ head args
63 [s,p] <- return $ tail args
64 lns <- return ( removeComments file )
65 case (parse inidata "some text" lns) of
66 Left err -> putStr "Parse error: " >> print err
67 Right x -> case (findValue x s p) of
68 Just x -> putStrLn x
69 Nothing -> putStrLn "Can't find requested parameter"
70 return ()
$ ghc --make ini.hs -o ini_hs
[1 of 1] Compiling Main ( ini.hs, ini.o )
Linking ini_hs ...
$ ./ini_hs /usr/lib/firefox-3.0.5/application.ini App ID
{ec8030f7-c20a-464f-9b0e-13a3a9e97384}
$ ./ini_hs /usr/lib/firefox-3.0.5/application.ini App IDD
Can't find requested parameter
Source: https://habr.com/ru/post/50337/