-- | Preprocessor Configuration module Hpp.Config where import Data.Functor.Identity import Data.Time.Clock (getCurrentTime, UTCTime) import Data.Time.Format -- | A 'String' representing a time. newtype TimeString = TimeString { getTimeString :: String } deriving (Eq, Ord, Show) -- | A 'String' representing a date. newtype DateString = DateString { getDateString :: String } deriving (Eq, Ord, Show) -- | Pre-processor configuration parameterized over a functor. This is -- used to normalize partial configurations, @ConfigF Maybe@, and -- configurations suitable for the pre-processor logic, @ConfigF -- Identity@. Specifically, the source file name of the file being -- processed /must/ be set. data ConfigF f = Config { curFileNameF :: f FilePath , includePathsF :: f [FilePath] , spliceLongLinesF :: f Bool , eraseCCommentsF :: f Bool , inhibitLinemarkersF :: f Bool , prepDateF :: f DateString , prepTimeF :: f TimeString } -- | A fully-populated configuration for the pre-processor. type Config = ConfigF Identity -- | Ensure that required configuration fields are supplied. realizeConfig :: ConfigF Maybe -> Maybe Config realizeConfig (Config (Just fileName) (Just paths) (Just spliceLines) (Just comments) (Just inhibitLines) (Just pdate) (Just ptime)) = Just (Config (pure fileName) (pure paths) (pure spliceLines) (pure comments) (pure inhibitLines) (pure pdate) (pure ptime)) realizeConfig _ = Nothing -- | Extract the current file name from a configuration. curFileName :: Config -> FilePath curFileName = runIdentity . curFileNameF -- | Extract the include paths name from a configuration. includePaths :: Config -> [FilePath] includePaths = runIdentity . includePathsF -- | Determine if continued long lines should be spliced. spliceLongLines :: Config -> Bool spliceLongLines = runIdentity . spliceLongLinesF -- | Determine if C-style comments should be erased. eraseCComments :: Config -> Bool eraseCComments = runIdentity . eraseCCommentsF -- | Determine if generation of linemarkers should be inhibited. inhibitLinemarkers :: Config -> Bool inhibitLinemarkers = runIdentity . inhibitLinemarkersF -- | The date the pre-processor was run on. prepDate :: Config -> DateString prepDate = runIdentity . prepDateF -- | The time of the active pre-processor invocation. prepTime :: Config -> TimeString prepTime = runIdentity . prepTimeF -- | A default configuration with no current file name set. defaultConfigF :: ConfigF Maybe defaultConfigF = Config Nothing (Just []) (Just False) (Just False) (Just False) (Just (DateString "??? ?? ????")) (Just (TimeString "??:??:??")) -- | Format a date according to the C spec. formatPrepDate :: UTCTime -> DateString formatPrepDate = DateString . formatTime defaultTimeLocale "%b %e %Y" -- | Format a time according to the C spec. formatPrepTime :: UTCTime -> TimeString formatPrepTime = TimeString . formatTime defaultTimeLocale "%T" -- | A default preprocessor configuration with date and time stamps -- taken from the current system time. defaultConfigFNow :: IO (ConfigF Maybe) defaultConfigFNow = do now <- getCurrentTime let d = formatPrepDate now t = formatPrepTime now return $ defaultConfigF { prepDateF = Just d , prepTimeF = Just t }