1{-# LANGUAGE LambdaCase #-} 2 3module Mach.Util where 4 5import Data.List (elemIndices) 6import qualified Mach.Types as T 7import System.Environment (getEnvironment) 8 9-- Strip a file name extension (suffix) from a file name.10stripSuffix :: FilePath -> String11stripSuffix name =12 let indices = elemIndices '.' name13 in if null indices14 then name15 else take (last indices) name1617-- | Like 'find', but allows the predicate to run in a monadic context18-- and, furthermore, enables the predicate to compute some additional19-- information.20--21-- Inspired by https://hackage.haskell.org/package/extra-1.7.14/docs/Control-Monad-Extra.html#v:firstJustM22firstJustM :: (Monad m) => (a -> m (Maybe b)) -> [a] -> m (Maybe b)23firstJustM _ [] = pure Nothing24firstJustM p (x : xs) = do25 p x >>= \case26 Just y -> pure $ Just y27 Nothing -> firstJustM p xs2829-- Returns true if the target name is a special target.30isSpecial :: String -> Bool31isSpecial = flip elem special32 where33 special :: [String]34 special =35 [ ".DEFAULT",36 ".IGNORE",37 ".PHONY",38 ".NOTPARALLEL",39 ".POSIX",40 ".PRECIOUS",41 ".SILENT",42 ".SUFFIXES",43 ".WAIT"44 ]4546-- Returns environment variables as macro assignments.47getEnvMarcos :: IO T.MkFile48getEnvMarcos = do49 env <- filter ((not . flip elem excluded) . fst) <$> getEnvironment50 pure $ map (\(k, v) -> T.MkAssign $ T.Assign (T.Lit k) T.Immediate (T.Lit v)) env51 where52 excluded :: [String]53 excluded = ["SHELL", "MAKEFLAGS"]