Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re CLC issue 292 Avoid using partial init and last #263

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions lib/Data/Format.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE Safe #-}

module Data.Format (
Expand Down Expand Up @@ -26,6 +27,9 @@ module Data.Format (

import Control.Monad.Fail
import Data.Char
#if MIN_VERSION_base(4,19,0)
import Data.List (unsnoc)
#endif
import Data.Void
import Text.ParserCombinators.ReadP
import Prelude hiding (fail)
Expand Down Expand Up @@ -227,11 +231,17 @@ zeroPad Nothing s = s
zeroPad (Just i) s = replicate (i - length s) '0' ++ s

trimTrailing :: String -> String
trimTrailing "" = ""
trimTrailing "." = ""
trimTrailing s
| last s == '0' = trimTrailing $ init s
trimTrailing s = s
trimTrailing s = case unsnoc s of
Nothing -> ""
Just (initial, '0') -> trimTrailing initial
_ -> s

#if !MIN_VERSION_base(4,19,0)
unsnoc :: [a] -> Maybe ([a], a)
unsnoc = foldr (\x -> Just . maybe ([], x) (\(~(a, b)) -> (x : a, b))) Nothing
{-# INLINABLE unsnoc #-}
#endif

showNumber :: Show t => SignOption -> Maybe Int -> t -> Maybe String
showNumber signOpt mdigitcount t =
Expand Down
33 changes: 23 additions & 10 deletions test/unix/Test/Format/Format.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE CPP #-}
{-# OPTIONS -fno-warn-orphans #-}

module Test.Format.Format (
Expand All @@ -6,6 +7,9 @@ module Test.Format.Format (

import Data.Char
import Data.Fixed as F
#if MIN_VERSION_base(4,19,0)
import Data.List (unsnoc)
#endif
import Data.Time
import Data.Time.Clock.POSIX
import Foreign
Expand Down Expand Up @@ -151,16 +155,25 @@ unixWorkarounds fmt s
unixWorkarounds _ s = s

compareFormat :: (String -> String) -> String -> TimeZone -> UTCTime -> Result
compareFormat _modUnix fmt zone _time
| last fmt == 'Z' && timeZoneName zone == "" = rejected
compareFormat modUnix fmt zone time =
let
ctime = utcToZonedTime zone time
haskellText = formatTime locale fmt ctime
unixText = unixFormatTime fmt zone time
expectedText = unixWorkarounds fmt (modUnix unixText)
in
assertEqualQC (show time ++ " with " ++ show zone) expectedText haskellText
compareFormat modUnix fmt zone time = case unsnoc fmt of
Nothing ->
error "compareFormat: The impossible happened! Format string is \"\"."
Just (_, lastChar)
| lastChar == 'Z' && timeZoneName zone == "" -> rejected
| otherwise ->
let
ctime = utcToZonedTime zone time
haskellText = formatTime locale fmt ctime
unixText = unixFormatTime fmt zone time
expectedText = unixWorkarounds fmt (modUnix unixText)
in
assertEqualQC (show time ++ " with " ++ show zone) expectedText haskellText

#if !MIN_VERSION_base(4,19,0)
unsnoc :: [a] -> Maybe ([a], a)
unsnoc = foldr (\x -> Just . maybe ([], x) (\(~(a, b)) -> (x : a, b))) Nothing
{-# INLINABLE unsnoc #-}
#endif

-- as found in http://www.opengroup.org/onlinepubs/007908799/xsh/strftime.html
-- plus FgGklz
Expand Down