system-locale 0.2.0.0 → 0.3.0.0
raw patch · 4 files changed
+48/−24 lines, 4 filesdep +bytestringdep ~basedep ~process
Dependencies added: bytestring
Dependency ranges changed: base, process
Files
- CHANGELOG.md +6/−0
- README.md +1/−1
- src/System/Locale/Read.hs +36/−19
- system-locale.cabal +5/−4
CHANGELOG.md view
@@ -1,3 +1,9 @@+# 0.3.0.0++* Inherit all environment except for LC_TIME in call to locale+* More explicitly handle UTF8-decoding+* Fail on non-zero exitcodes from locale+ # 0.2.0.0 * Switch to attoparsec to reduce dependency footprint
README.md view
@@ -1,6 +1,6 @@ # system-locale -+[]() [](https://hackage.haskell.org/package/system-locale) Read system locales from Haskell.
src/System/Locale/Read.hs view
@@ -12,14 +12,21 @@ import Control.Applicative import Control.Exception import Data.Attoparsec.Text-import qualified Data.Text as Text+import qualified Data.Text.Encoding as Text+import qualified Data.Text.Encoding.Error as Text+import qualified Data.ByteString as BS import Data.Time.Format (TimeLocale(..)) import Data.Typeable import System.Process+import System.Environment+import System.Exit (ExitCode(..))+import Data.List (isPrefixOf) -- | Thrown when the locale cannot be parsed-data LocaleParseException =- LocaleParseException String+data LocaleParseException+ = LocaleParseException String+ | LocaleUtf8Exception Text.UnicodeException+ | LocaleExitException ExitCode deriving (Show,Eq,Typeable) instance Exception LocaleParseException@@ -57,8 +64,16 @@ -- > getLocale (Just "en_US.UTF-8") getLocale :: Maybe String -> IO TimeLocale getLocale localeName = do- output <- readCreateProcess (getLocaleProcess localeName) ""- case parseOnly (parseLocale <* endOfInput) (Text.pack output) of+ process <- getLocaleProcess localeName+ output <- withCreateProcess process $+ \_stdin (Just stdout) _stderr ph -> do+ bsOutput <- BS.hGetContents stdout+ exitCode <- waitForProcess ph+ case exitCode of+ ExitSuccess -> return ()+ e@(ExitFailure _) -> throwIO $ LocaleExitException e+ either (throwIO . LocaleUtf8Exception) return $ Text.decodeUtf8' bsOutput+ case parseOnly (parseLocale <* endOfInput) output of Left err -> throwIO (LocaleParseException err) Right locale -> pure locale @@ -71,18 +86,20 @@ getCurrentLocale :: IO TimeLocale getCurrentLocale = getLocale Nothing -getLocaleProcess :: Maybe String -> CreateProcess-getLocaleProcess localeName =- (proc "locale"- ["abday"- ,"day"- ,"abmon"- ,"mon"- ,"am_pm"- ,"d_t_fmt"- ,"d_fmt"- ,"t_fmt"- ,"t_fmt_ampm"]) {env = toLangEnv <$> localeName}+getLocaleProcess :: Maybe String -> IO CreateProcess+getLocaleProcess localeName = do+ oldEnv <- getEnvironment+ return $ (proc "locale"+ [ "abday"+ , "day"+ , "abmon"+ , "mon"+ , "am_pm"+ , "d_t_fmt"+ , "d_fmt"+ , "t_fmt"+ , "t_fmt_ampm"+ ]) { std_out = CreatePipe, env = toLangEnv oldEnv <$> localeName} newline :: Parser Char newline = char '\n'@@ -93,5 +110,5 @@ where finalChar c = c == ';' || c == '\n' -toLangEnv :: String -> [(String,String)]-toLangEnv s = [("LC_TIME",s)]+toLangEnv :: [(String, String)] -> String -> [(String,String)]+toLangEnv oldEnv s = ("LC_ALL", s) : [ e | e@(k, _) <- oldEnv, not $ "LC_" `isPrefixOf` k ]
system-locale.cabal view
@@ -1,5 +1,5 @@ name: system-locale-version: 0.2.0.0+version: 0.3.0.0 synopsis: Get system locales description: Get system locales in a format suitable for the time library homepage: https://github.com/cocreature/system-locale@@ -13,16 +13,17 @@ extra-source-files: CHANGELOG.md README.md cabal-version: >=1.10-tested-with: GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.2, GHC == 8.2.1+tested-with: GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.3 library hs-source-dirs: src exposed-modules: System.Locale.Read build-depends: attoparsec >= 0.13 && < 0.14- , base >= 4.7 && < 5- , process >= 1.2 && < 1.7+ , base >= 4.9 && < 5+ , process >= 1.4.3.0 && < 1.7 , time >= 1.5 && < 1.9 , text >= 1.2 && < 1.3+ , bytestring >= 0.10 && < 0.11 ghc-options: -Wall default-language: Haskell2010