module UHC.Shuffle.Common
( module Data.Maybe
, module Data.Char
, module UHC.Util.Nm
, module UHC.Util.FPath
, module UHC.Util.Pretty
, module UHC.Shuffle.AspectExpr
, Err(..), ErrM, ppErr, showUndef
, openURI
, Opts(..), defaultOpts, optsHasNoVariantRefOrder
, URef
, CRef, CPos(..)
, ChKind(..), ChDest(..), ChWrap(..)
, VariantRef(..)
, variantRefIsPre
, AspectRefs(..)
, variantReqmRef, mbVariantReqmRef
, variantRefFromTop
, variantReqmUpdRef
, VariantOffer(..)
, variantOfferIsPre
, VariantReqm(..)
, variantReqmIsPre
, variantOfferFromRef, variantReqmFromRef
, variantOfferFromTop
, variantOfferRef, variantOfferRefTop
, VariantRefOrder
, ChunkRef(..)
, chunkRefFromOfferNm
, variantReqmMatchOffer
, VariantRefOrderMp, sortOnVariantRefOrderMp, sortOnVariantRefOrderMp'
, KVMap
, CompilerRestriction(..)
, t2tChKinds
)
where
import Data.Maybe
import Data.Char
import qualified Data.Map as Map
import qualified Data.Set as Set
import Data.Map(Map)
import Data.Set(Set)
import Network.URI
import System.IO
import System.Directory
import System.Console.GetOpt
import UHC.Util.Pretty
import UHC.Util.FPath
import UHC.Util.Utils
import UHC.Util.Nm
import UHC.Shuffle.AspectExpr
import UHC.Shuffle.AspectExprEval
data Err
= Err_UndefNm CPos String [Nm]
| Err_UndefURI CPos String
| Err_Exec CPos String String
deriving Show
type ErrM = Map.Map CPos Err
ppErr :: CPos -> PP_Doc -> PP_Doc
ppErr pos p
= "*** ERROR ***"
>-< show pos >|< ":"
>-< indent 4 p
instance PP Err where
pp (Err_UndefNm pos knd nmL)
= ppErr pos (knd >|< "(s) are undefined:" >#< ppCommas' nmL)
pp (Err_UndefURI pos u)
= ppErr pos ("could not open:" >#< u)
pp (Err_Exec pos f e)
= ppErr pos ( "execution of:" >#< f
>-< "failed :" >#< e
)
showUndef :: Show r => r -> String
showUndef r = "<<<<" ++ show r ++ ">>>>"
openURI :: URI -> IO (Maybe Handle)
openURI u
= case uriScheme u of
"file:" -> do { ex <- doesFileExist p
; if ex
then do { h <- openFile p ReadMode
; return (Just h)
}
else return Nothing
}
_ -> return Nothing
where p = uriPath u
type KVMap = Map.Map String String
data Opts
= Opts
{ optAG :: Bool
, optHS :: Bool
, optPlain :: Bool
, optLaTeX :: Bool
, optPreamble :: Bool
, optLinePragmas :: Bool
, optIndex :: Bool
, optCompiler :: [Int]
, optHelp :: Bool
, optVersion :: Bool
, optGenDeps :: Bool
, optGenText2Text :: Bool
, optChDest :: (ChDest,String)
, optGenReqm :: VariantReqm
, optBaseName :: Maybe String
, optBaseFPath :: FPath
, optWrapLhs2tex :: ChWrap
, optMbXRefExcept :: Maybe String
, optVariantRefOrder :: VariantRefOrder
, optDefs :: KVMap
, optDepNamePrefix :: String
, optDepSrcVar :: String
, optDepDstVar :: String
, optDepMainVar :: String
, optDepDpdsVar :: String
, optDepOrigDpdsVar :: String
, optDepDerivDpdsVar :: String
, optDepBaseDir :: String
, optDepTerm :: Map String [String]
, optDepIgn :: Set String
, optAGModHeader :: Bool
} deriving (Show)
defaultOpts
= Opts
{ optAG = False
, optHS = False
, optLaTeX = False
, optPreamble = True
, optLinePragmas = False
, optPlain = False
, optIndex = False
, optCompiler = []
, optHelp = False
, optVersion = False
, optGenDeps = False
, optGenText2Text = False
, optChDest = (ChHere,"")
, optGenReqm = VReqmNone
, optBaseName = Nothing
, optBaseFPath = emptyFPath
, optWrapLhs2tex = ChWrapCode
, optMbXRefExcept = Nothing
, optVariantRefOrder = [[]]
, optDefs = Map.empty
, optDepNamePrefix = error "optDepNamePrefix not set"
, optDepSrcVar = error "optDepSrcVar not set"
, optDepDstVar = error "optDepDstVar not set"
, optDepMainVar = error "optDepMainVar not set"
, optDepDpdsVar = error "optDepDpdsVar not set"
, optDepOrigDpdsVar = error "optDepOrigDpdsVar not set"
, optDepDerivDpdsVar = error "optDepDerivDpdsVar not set"
, optDepBaseDir = error "optDepBaseDir not set"
, optDepTerm = Map.empty
, optDepIgn = Set.empty
, optAGModHeader = True
}
optsHasNoVariantRefOrder :: Opts -> Bool
optsHasNoVariantRefOrder = null . head . optVariantRefOrder
type URef = String
type CRef = Nm
data CPos = CPos FPath Int
deriving (Eq,Ord)
instance Show CPos where
show (CPos fp l) = fpathToStr fp ++ ":" ++ show l
data ChKind
= ChAG
| ChHS
| ChPlain
| ChDocLaTeX
| ChLhs2TeX
| ChHaddock
deriving (Show,Eq,Ord)
data ChDest
= ChHere | ChHide
deriving (Show,Eq,Ord)
data ChWrap
= ChWrapCode
| ChWrapHsBox
| ChWrapBoxCode (Maybe String)
| ChWrapBeamerBlockCode String
| ChWrapTT
| ChWrapTTtiny
| ChWrapVerbatim
| ChWrapVerbatimSmall
| ChWrapPlain
| ChWrapT2T ChKind
| ChWrapComp ChWrap ChWrap
| ChWrapNone
deriving (Show,Eq,Ord)
t2tChKinds :: Map.Map ChKind String
t2tChKinds
= Map.fromList
[ ( ChDocLaTeX, "doclatex" )
]
data VariantRef
= VarRef {vrefRefs :: ![Int]}
deriving (Show,Eq,Ord)
variantRefIsPre :: VariantRef -> Bool
variantRefIsPre (VarRef (0:_)) = True
variantRefIsPre _ = False
instance NM VariantRef where
mkNm (VarRef l) = nmApdL $ map mkNm l
variantRefFromTop :: Int -> VariantRef
variantRefFromTop i = VarRef [i]
data AspectRefs
= AspectAll
| AspectRefs !AspectRefReqd
| AspectOfferExpr !AspectExpr
deriving (Show,Eq,Ord)
aspectRefsMatch :: AspectRefs -> AspectRefs -> Bool
aspectRefsMatch AspectAll _ = True
aspectRefsMatch _ AspectAll = True
aspectRefsMatch (AspectRefs r1) (AspectRefs r2) = Set.isSubsetOf r1 r2
aspectRefsMatch (AspectOfferExpr r1) (AspectRefs r2) = aspexpIsAccepted r2 r1
data VariantOfferForCompare
= VariantOfferForCompare !Int !AspectRefs
deriving (Eq,Ord)
data VariantOffer
= VOfferAll
| VOfferPre { vofferAspect :: !AspectRefs}
| VOfferRef {vofferVariant :: !VariantRef, vofferAspect :: !AspectRefs}
deriving (Show,Eq,Ord)
variantOfferIsPre :: VariantOffer -> Bool
variantOfferIsPre o = case o of
VOfferPre _ -> True
_ -> False
type VariantRefOrder = [[VariantRef]]
type VariantRefOrderMp = Map.Map VariantRef Int
variantOfferFromRef :: VariantRef -> VariantOffer
variantOfferFromRef r
| variantRefIsPre r = VOfferPre AspectAll
| otherwise = VOfferRef r AspectAll
variantOfferFromTop :: Int -> VariantOffer
variantOfferFromTop i = variantOfferFromRef (variantRefFromTop i)
variantOfferRef :: VariantOffer -> VariantRef
variantOfferRef (VOfferPre _) = VarRef [0]
variantOfferRef (VOfferRef r _) = r
variantOfferAsp :: VariantOffer -> AspectRefs
variantOfferAsp (VOfferPre a) = a
variantOfferAsp (VOfferRef _ a) = a
variantOfferRefTop :: VariantOffer -> Int
variantOfferRefTop (VOfferRef (VarRef (i:_)) _) = i
sortOnVariantRefOrderMp' :: VariantRefOrderMp -> [(VariantOffer,x)] -> [((VariantOffer,Bool),x)]
sortOnVariantRefOrderMp' m l
= map snd
$ sortOnLazy fst
$ [ ( VariantOfferForCompare (maybe 0 id o) (variantOfferAsp v)
, ((v,isJust o || v == VOfferAll),x)
)
| (v,x) <- l, let o = Map.lookup (variantOfferRef v) m
]
sortOnVariantRefOrderMp :: VariantRefOrderMp -> [(VariantOffer,x)] -> [x]
sortOnVariantRefOrderMp m vo
= map snd
$ sortOnLazy fst
$ [ ( VariantOfferForCompare o (variantOfferAsp v)
, x
)
| (v,x) <- vo, let o = Map.findWithDefault 0 (variantOfferRef v) m
]
instance NM VariantOffer where
mkNm (VOfferPre _) = mkNm "pre"
mkNm VOfferAll = mkNm "*"
mkNm (VOfferRef r _) = mkNm r
data VariantReqm
= VReqmAll
| VReqmNone
| VReqmRef { vreqmVariant :: !VariantRef, vreqmAspects :: !AspectRefs }
deriving (Show,Eq,Ord)
variantReqmIsPre :: VariantReqm -> Bool
variantReqmIsPre (VReqmRef r _) = variantRefIsPre r
variantReqmIsPre _ = False
variantReqmFromRef :: VariantRef -> VariantReqm
variantReqmFromRef r = VReqmRef r AspectAll
mbVariantReqmRef :: VariantReqm -> Maybe VariantRef
mbVariantReqmRef (VReqmRef r _) = Just r
mbVariantReqmRef _ = Nothing
variantReqmRef :: VariantReqm -> VariantRef
variantReqmRef = maybe (error "variantReqmRef") id . mbVariantReqmRef
variantReqmUpdRef :: VariantReqm -> VariantRef -> VariantReqm
variantReqmUpdRef v@(VReqmRef _ _) r = v {vreqmVariant = r}
variantReqmUpdRef v _ = v
variantReqmMatchOffer :: Maybe VariantRefOrderMp -> VariantReqm -> VariantOffer -> Bool
variantReqmMatchOffer _ VReqmAll _ = True
variantReqmMatchOffer _ VReqmNone _ = False
variantReqmMatchOffer _ _ VOfferAll = True
variantReqmMatchOffer Nothing (VReqmRef rr ra) (VOfferRef or oa) = rr == or && aspectRefsMatch oa ra
variantReqmMatchOffer (Just m) (VReqmRef rr ra) (VOfferRef or oa) = Map.member or m && aspectRefsMatch oa ra
variantReqmMatchOffer _ (VReqmRef rr ra) (VOfferPre oa) = variantRefIsPre rr && aspectRefsMatch oa ra
instance NM VariantReqm where
mkNm VReqmAll = mkNm "*"
mkNm VReqmNone = mkNm "-"
mkNm (VReqmRef r _) = mkNm r
data ChunkRef
= ChunkRef {chunkRefVar :: !VariantRef, chunkRefNm :: !Nm}
deriving (Show,Eq,Ord)
chunkRefFromOfferNm :: VariantOffer -> Nm -> ChunkRef
chunkRefFromOfferNm o n = ChunkRef (variantOfferRef o) n
instance NM ChunkRef where
mkNm (ChunkRef v n) = mkNm v `nmApd` n
data CompilerRestriction
= Restricted (Maybe [Int]) (Maybe [Int])
deriving Show