hsini 0.5.2.1 → 0.5.2.2
raw patch · 6 files changed
+54/−58 lines, 6 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- hsini.cabal +1/−1
- src/Data/Ini.hs +5/−3
- src/Data/Ini/Reader.hs +9/−11
- src/Data/Ini/Reader/Internals.hs +24/−38
- src/Data/Ini/Types.hs +3/−1
- tst/ReaderI.hs +12/−4
hsini.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: hsini-version: 0.5.2.1+version: 0.5.2.2 synopsis: ini configuration files description: Library for reading and writing configuration files in INI format (see <https://en.wikipedia.org/wiki/INI_file>).
src/Data/Ini.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE ImportQualifiedPost #-}+ {- | Module : Data.Ini Copyright : 2011-2014 Magnus Therning@@ -13,10 +15,10 @@ module Data.Ini where -- {{{1 imports-import qualified Data.Map as M-import Data.Maybe+import Data.Map qualified as M+import Data.Maybe (isJust) -import Data.Ini.Types+import Data.Ini.Types (Config, OptionName, OptionValue, Section, SectionName) -- {{{1 configurations
src/Data/Ini/Reader.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE ImportQualifiedPost #-}+ {- | Module : Data.Ini.Reader Copyright : 2011-2014 Magnus Therning@@ -11,18 +13,14 @@ IniParseResult, ) where -import Control.Monad.Except-import qualified Text.ParserCombinators.Parsec as P+import Control.Monad.Except (throwError)+import Text.ParserCombinators.Parsec qualified as P -import Data.Ini.Reader.Internals-import Data.Ini.Types+import Data.Ini.Reader.Internals (IniParseResult, IniReaderError (..), buildConfig, iniParser)+import Data.Ini.Types (Config) -- | Parser for a configuration contained in a 'String'. parse :: String -> IniParseResult Config-parse s =- let- pr = P.parse iniParser "ini" s- in- case pr of- Left e -> throwError . IniParserError $ show e- Right is -> buildConfig is+parse s = case P.parse iniParser "ini" s of+ Left e -> throwError . IniParserError $ show e+ Right is -> buildConfig is
src/Data/Ini/Reader/Internals.hs view
@@ -9,11 +9,12 @@ -} module Data.Ini.Reader.Internals where -import Control.Monad (void) import Control.Monad.Except (MonadError (throwError)) import Control.Monad.State (evalState, get, put)+import Data.Functor (($>)) import Text.Parsec as P ( anyChar,+ between, char, choice, many,@@ -25,8 +26,10 @@ ) import Text.Parsec.String (Parser) -import Data.Ini-import Data.Ini.Types+import Data.Char (isSpace)+import Data.Ini (emptyConfig, setOption)+import Data.Ini.Types (Config)+import Data.List (dropWhileEnd) data IniReaderError = IniParserError String@@ -81,18 +84,12 @@ surrounded by any number of white space characters (see 'eatWhiteSpace'). -} secParser :: Parser IniFile-secParser =- let- validSecNameChrs = ['a' .. 'z'] ++ ['A' .. 'Z'] ++ ['0' .. '9'] ++ "._-/@\" "- in- do- void $ char '['- void eatWhiteSpace- sn <- many1 $ oneOf validSecNameChrs- void eatWhiteSpace- void $ char ']'- void $ manyTill anyChar newline- return $ SectionL sn+secParser = SectionL <$> between sectionNameOpen sectionNameClose sectionName+ where+ sectionNameOpen = char '[' *> eatWhiteSpace+ sectionNameClose = eatWhiteSpace *> char ']' *> manyTill anyChar newline+ sectionName = many1 $ oneOf validSecNameChrs+ validSecNameChrs = ['a' .. 'z'] ++ ['A' .. 'Z'] ++ ['0' .. '9'] ++ "._-/@\" " {- | Parser for a single line of an option. The line must start with an option name, then a @=@ must be found, and finally the rest of the line is taken as@@ -100,18 +97,12 @@ space characters (see 'eatWhiteSpace'). -} optLineParser :: Parser IniFile-optLineParser =- let- validOptNameChrs = ['a' .. 'z'] ++ ['A' .. 'Z'] ++ ['0' .. '9'] ++ "_-/@ "- in- do- void eatWhiteSpace- on <- many1 $ oneOf validOptNameChrs- void eatWhiteSpace- void $ char '='- void eatWhiteSpace- ov <- manyTill anyChar newline- return $ OptionL on ov+optLineParser = OptionL <$> optionName <*> (optionEqual *> optionValue)+ where+ optionName = dropWhileEnd isSpace <$> (eatWhiteSpace *> many1 (oneOf validOptNameChrs))+ optionEqual = eatWhiteSpace *> char '=' *> eatWhiteSpace+ optionValue = manyTill anyChar newline+ validOptNameChrs = ['a' .. 'z'] ++ ['A' .. 'Z'] ++ ['0' .. '9'] ++ "_-/@ " {- | Parser for an option-value continuation line. The line must start with either a space or a tab character (\"@ \t@\"). Everything else on the line,@@ -119,12 +110,9 @@ value. -} optContParser :: Parser IniFile-optContParser = do- void $ oneOf " \t"- void eatWhiteSpace- oc <- noneOf " \t"- ov <- manyTill anyChar newline- return $ OptionContL $ oc : ov+optContParser = OptionContL <$> value+ where+ value = (:) <$> (oneOf " \t" *> eatWhiteSpace *> noneOf " \t") <*> manyTill anyChar newline {- | Parser for "noise" in the configuration file, such as comments and empty lines. (Note that lines containing only space characters will be@@ -133,12 +121,10 @@ noiseParser :: Parser IniFile noiseParser = let- commentP = do- void $ oneOf "#;"- manyTill anyChar newline- emptyL = newline >> return ""+ commentP = oneOf "#;" *> manyTill anyChar newline+ emptyL = (newline $> "") in- choice [commentP, emptyL] >> return CommentL+ choice [commentP, emptyL] $> CommentL iniParser :: Parser [IniFile] iniParser =
src/Data/Ini/Types.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE ImportQualifiedPost #-}+ {- | Module : Data.Ini.Types Copyright : 2011-2014 Magnus Therning@@ -6,7 +8,7 @@ module Data.Ini.Types where import Control.Arrow (second)-import qualified Data.Map as M+import Data.Map qualified as M type Config = M.Map SectionName Section
tst/ReaderI.hs view
@@ -10,7 +10,7 @@ import Test.Tasty (TestTree) import Test.Tasty.HUnit (Assertion, testCase, (@=?)) import Test.Tasty.TH (testGroupGenerator)-import Text.ParserCombinators.Parsec as P (parse, Parser)+import Text.ParserCombinators.Parsec as P (Parser, parse) import Data.Ini.Reader.Internals ( IniFile (CommentL, OptionContL, OptionL, SectionL),@@ -23,7 +23,7 @@ -- Convenience function that translates a parser result to something that's -- easier to check.-p2E :: Parser a -> String -> String -> Either String a+p2E :: Parser a -> String -> String -> Either String a p2E p s t = let res = P.parse p s t@@ -162,8 +162,16 @@ in expected @=? actual -case_optLineParserDropSpace :: Assertion-case_optLineParserDropSpace =+case_optLineParserDropSpace1 :: Assertion+case_optLineParserDropSpace1 =+ let+ expected = Right $ OptionL "foo" "bar"+ actual = p2E optLineParser "optLine" " foo = bar\n"+ in+ expected @=? actual++case_optLineParserDropSpace2 :: Assertion+case_optLineParserDropSpace2 = let expected = Right $ OptionL "foo" "bar" actual = p2E optLineParser "optLine" " \tfoo\t \t=\t \t bar\n"