kit-0.2: Kit/XCode/XCConfig.hs
module Kit.XCode.XCConfig where
import Kit.Util
import qualified Data.Map as M
import Data.Maybe
import Data.Either
import Data.List
import Data.String.Utils
type XCCSetting = (String, String)
type XCCInclude = String
data XCConfig = XCC { configName :: String, configSettings :: M.Map String String, configIncludes :: [XCCInclude] } deriving (Eq, Show)
includeStart = "#include "
parseLine :: String -> Maybe (Either XCCSetting XCCInclude)
parseLine l | includeStart `isPrefixOf` l = Just . Right . fromJust $ stripPrefix includeStart l
parseLine l | "=" `isInfixOf` l = fmap (Left) $ breakAround '=' l
where breakAround a xs = let (q,r) = break (a ==) xs in nonEmptyPair (strip q, strip $ drop 1 r)
nonEmptyPair ([], _) = Nothing
nonEmptyPair (_, []) = Nothing
nonEmptyPair a@_ = Just a
parseLine _ = Nothing
settingToString :: XCCSetting -> String
settingToString (a, b) = a ++ " = " ++ b
includeToString :: XCCInclude -> String
includeToString a = includeStart ++ a
-- TODO incorporate the config name
configToString :: XCConfig -> String
configToString (XCC _ settings includes) = stringJoin "\n" $ (map includeToString includes) ++ (map settingToString $ M.toList settings)
fileContentsToXCC :: String -> String -> XCConfig
fileContentsToXCC name content = let ls = lines content
(settings, includes) = partitionEithers (ls >>= (maybeToList . parseLine))
in XCC name (M.fromList settings) includes
configAsMap :: XCConfig -> M.Map String [(String, String)]
configAsMap (XCC name settings _) = M.map (return . (,) name) settings
multiConfig :: String -> [XCConfig] -> XCConfig
multiConfig name configs = XCC name settings includes
where includes = configs >>= configIncludes
settingsWithName = foldl (M.unionWith (++)) M.empty (map configAsMap configs)
aggregateSettings = M.mapWithKey f settingsWithName
where f key namesAndValues = stringJoin " " $ map ((\x -> "$(" ++ x ++ "_" ++ key ++ ")") . fst) namesAndValues
individualSettings = M.fromList $ concatMap f $ M.toList settingsWithName
where f (key, namesAndValues) = map (g key) namesAndValues
g key (n, v) = (n ++ "_" ++ key, v)
settings = M.union aggregateSettings individualSettings