{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric      #-}
module Distribution.SPDX.LicenseExpression (
    LicenseExpression (..),
    SimpleLicenseExpression (..),
    simpleLicenseExpression,
    ) where

import Distribution.Compat.Prelude
import Prelude ()

import Distribution.Parsec
import Distribution.Pretty
import Distribution.SPDX.LicenseExceptionId
import Distribution.SPDX.LicenseId
import Distribution.SPDX.LicenseListVersion
import Distribution.SPDX.LicenseReference
import Distribution.Utils.Generic           (isAsciiAlphaNum)

import qualified Distribution.Compat.CharParsing as P
import qualified Text.PrettyPrint                as Disp

-- | SPDX License Expression.
--
-- @
-- idstring              = 1*(ALPHA \/ DIGIT \/ "-" \/ "." )
-- license id            = \<short form license identifier inAppendix I.1>
-- license exception id  = \<short form license exception identifier inAppendix I.2>
-- license ref           = [\"DocumentRef-"1*(idstring)":"]\"LicenseRef-"1*(idstring)
--
-- simple expression     = license id \/ license id"+" \/ license ref
--
-- compound expression   = 1*1(simple expression \/
--                         simple expression \"WITH" license exception id \/
--                         compound expression \"AND" compound expression \/
--                         compound expression \"OR" compound expression ) \/
--                         "(" compound expression ")" )
--
-- license expression    = 1*1(simple expression / compound expression)
-- @
data LicenseExpression
    = ELicense !SimpleLicenseExpression !(Maybe LicenseExceptionId)
    | EAnd !LicenseExpression !LicenseExpression
    | EOr !LicenseExpression !LicenseExpression
    deriving (Int -> LicenseExpression -> ShowS
[LicenseExpression] -> ShowS
LicenseExpression -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LicenseExpression] -> ShowS
$cshowList :: [LicenseExpression] -> ShowS
show :: LicenseExpression -> String
$cshow :: LicenseExpression -> String
showsPrec :: Int -> LicenseExpression -> ShowS
$cshowsPrec :: Int -> LicenseExpression -> ShowS
Show, ReadPrec [LicenseExpression]
ReadPrec LicenseExpression
Int -> ReadS LicenseExpression
ReadS [LicenseExpression]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [LicenseExpression]
$creadListPrec :: ReadPrec [LicenseExpression]
readPrec :: ReadPrec LicenseExpression
$creadPrec :: ReadPrec LicenseExpression
readList :: ReadS [LicenseExpression]
$creadList :: ReadS [LicenseExpression]
readsPrec :: Int -> ReadS LicenseExpression
$creadsPrec :: Int -> ReadS LicenseExpression
Read, LicenseExpression -> LicenseExpression -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LicenseExpression -> LicenseExpression -> Bool
$c/= :: LicenseExpression -> LicenseExpression -> Bool
== :: LicenseExpression -> LicenseExpression -> Bool
$c== :: LicenseExpression -> LicenseExpression -> Bool
Eq, Eq LicenseExpression
LicenseExpression -> LicenseExpression -> Bool
LicenseExpression -> LicenseExpression -> Ordering
LicenseExpression -> LicenseExpression -> LicenseExpression
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: LicenseExpression -> LicenseExpression -> LicenseExpression
$cmin :: LicenseExpression -> LicenseExpression -> LicenseExpression
max :: LicenseExpression -> LicenseExpression -> LicenseExpression
$cmax :: LicenseExpression -> LicenseExpression -> LicenseExpression
>= :: LicenseExpression -> LicenseExpression -> Bool
$c>= :: LicenseExpression -> LicenseExpression -> Bool
> :: LicenseExpression -> LicenseExpression -> Bool
$c> :: LicenseExpression -> LicenseExpression -> Bool
<= :: LicenseExpression -> LicenseExpression -> Bool
$c<= :: LicenseExpression -> LicenseExpression -> Bool
< :: LicenseExpression -> LicenseExpression -> Bool
$c< :: LicenseExpression -> LicenseExpression -> Bool
compare :: LicenseExpression -> LicenseExpression -> Ordering
$ccompare :: LicenseExpression -> LicenseExpression -> Ordering
Ord, Typeable, Typeable LicenseExpression
LicenseExpression -> DataType
LicenseExpression -> Constr
(forall b. Data b => b -> b)
-> LicenseExpression -> LicenseExpression
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u.
Int -> (forall d. Data d => d -> u) -> LicenseExpression -> u
forall u. (forall d. Data d => d -> u) -> LicenseExpression -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> LicenseExpression -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> LicenseExpression -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> LicenseExpression -> m LicenseExpression
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> LicenseExpression -> m LicenseExpression
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LicenseExpression
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LicenseExpression -> c LicenseExpression
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c LicenseExpression)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c LicenseExpression)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> LicenseExpression -> m LicenseExpression
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> LicenseExpression -> m LicenseExpression
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> LicenseExpression -> m LicenseExpression
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> LicenseExpression -> m LicenseExpression
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> LicenseExpression -> m LicenseExpression
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> LicenseExpression -> m LicenseExpression
gmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> LicenseExpression -> u
$cgmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> LicenseExpression -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> LicenseExpression -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> LicenseExpression -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> LicenseExpression -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> LicenseExpression -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> LicenseExpression -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> LicenseExpression -> r
gmapT :: (forall b. Data b => b -> b)
-> LicenseExpression -> LicenseExpression
$cgmapT :: (forall b. Data b => b -> b)
-> LicenseExpression -> LicenseExpression
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c LicenseExpression)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c LicenseExpression)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c LicenseExpression)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c LicenseExpression)
dataTypeOf :: LicenseExpression -> DataType
$cdataTypeOf :: LicenseExpression -> DataType
toConstr :: LicenseExpression -> Constr
$ctoConstr :: LicenseExpression -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LicenseExpression
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LicenseExpression
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LicenseExpression -> c LicenseExpression
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LicenseExpression -> c LicenseExpression
Data, forall x. Rep LicenseExpression x -> LicenseExpression
forall x. LicenseExpression -> Rep LicenseExpression x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep LicenseExpression x -> LicenseExpression
$cfrom :: forall x. LicenseExpression -> Rep LicenseExpression x
Generic)

-- | Simple License Expressions.
data SimpleLicenseExpression
    = ELicenseId LicenseId
      -- ^ An SPDX License List Short Form Identifier. For example: @GPL-2.0-only@
    | ELicenseIdPlus LicenseId
      -- ^ An SPDX License List Short Form Identifier with a unary"+" operator suffix to represent the current version of the license or any later version.  For example: @GPL-2.0+@
    | ELicenseRef LicenseRef
      -- ^ A SPDX user defined license reference: For example: @LicenseRef-23@, @LicenseRef-MIT-Style-1@, or @DocumentRef-spdx-tool-1.2:LicenseRef-MIT-Style-2@
    deriving (Int -> SimpleLicenseExpression -> ShowS
[SimpleLicenseExpression] -> ShowS
SimpleLicenseExpression -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SimpleLicenseExpression] -> ShowS
$cshowList :: [SimpleLicenseExpression] -> ShowS
show :: SimpleLicenseExpression -> String
$cshow :: SimpleLicenseExpression -> String
showsPrec :: Int -> SimpleLicenseExpression -> ShowS
$cshowsPrec :: Int -> SimpleLicenseExpression -> ShowS
Show, ReadPrec [SimpleLicenseExpression]
ReadPrec SimpleLicenseExpression
Int -> ReadS SimpleLicenseExpression
ReadS [SimpleLicenseExpression]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [SimpleLicenseExpression]
$creadListPrec :: ReadPrec [SimpleLicenseExpression]
readPrec :: ReadPrec SimpleLicenseExpression
$creadPrec :: ReadPrec SimpleLicenseExpression
readList :: ReadS [SimpleLicenseExpression]
$creadList :: ReadS [SimpleLicenseExpression]
readsPrec :: Int -> ReadS SimpleLicenseExpression
$creadsPrec :: Int -> ReadS SimpleLicenseExpression
Read, SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
$c/= :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
== :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
$c== :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
Eq, Eq SimpleLicenseExpression
SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
SimpleLicenseExpression -> SimpleLicenseExpression -> Ordering
SimpleLicenseExpression
-> SimpleLicenseExpression -> SimpleLicenseExpression
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SimpleLicenseExpression
-> SimpleLicenseExpression -> SimpleLicenseExpression
$cmin :: SimpleLicenseExpression
-> SimpleLicenseExpression -> SimpleLicenseExpression
max :: SimpleLicenseExpression
-> SimpleLicenseExpression -> SimpleLicenseExpression
$cmax :: SimpleLicenseExpression
-> SimpleLicenseExpression -> SimpleLicenseExpression
>= :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
$c>= :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
> :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
$c> :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
<= :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
$c<= :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
< :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
$c< :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
compare :: SimpleLicenseExpression -> SimpleLicenseExpression -> Ordering
$ccompare :: SimpleLicenseExpression -> SimpleLicenseExpression -> Ordering
Ord, Typeable, Typeable SimpleLicenseExpression
SimpleLicenseExpression -> DataType
SimpleLicenseExpression -> Constr
(forall b. Data b => b -> b)
-> SimpleLicenseExpression -> SimpleLicenseExpression
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u.
Int -> (forall d. Data d => d -> u) -> SimpleLicenseExpression -> u
forall u.
(forall d. Data d => d -> u) -> SimpleLicenseExpression -> [u]
forall r r'.
(r -> r' -> r)
-> r
-> (forall d. Data d => d -> r')
-> SimpleLicenseExpression
-> r
forall r r'.
(r' -> r -> r)
-> r
-> (forall d. Data d => d -> r')
-> SimpleLicenseExpression
-> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> SimpleLicenseExpression -> m SimpleLicenseExpression
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> SimpleLicenseExpression -> m SimpleLicenseExpression
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SimpleLicenseExpression
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> SimpleLicenseExpression
-> c SimpleLicenseExpression
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SimpleLicenseExpression)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c SimpleLicenseExpression)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> SimpleLicenseExpression -> m SimpleLicenseExpression
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> SimpleLicenseExpression -> m SimpleLicenseExpression
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> SimpleLicenseExpression -> m SimpleLicenseExpression
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> SimpleLicenseExpression -> m SimpleLicenseExpression
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> SimpleLicenseExpression -> m SimpleLicenseExpression
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> SimpleLicenseExpression -> m SimpleLicenseExpression
gmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> SimpleLicenseExpression -> u
$cgmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> SimpleLicenseExpression -> u
gmapQ :: forall u.
(forall d. Data d => d -> u) -> SimpleLicenseExpression -> [u]
$cgmapQ :: forall u.
(forall d. Data d => d -> u) -> SimpleLicenseExpression -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r
-> (forall d. Data d => d -> r')
-> SimpleLicenseExpression
-> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r
-> (forall d. Data d => d -> r')
-> SimpleLicenseExpression
-> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r
-> (forall d. Data d => d -> r')
-> SimpleLicenseExpression
-> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r
-> (forall d. Data d => d -> r')
-> SimpleLicenseExpression
-> r
gmapT :: (forall b. Data b => b -> b)
-> SimpleLicenseExpression -> SimpleLicenseExpression
$cgmapT :: (forall b. Data b => b -> b)
-> SimpleLicenseExpression -> SimpleLicenseExpression
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c SimpleLicenseExpression)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c SimpleLicenseExpression)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SimpleLicenseExpression)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SimpleLicenseExpression)
dataTypeOf :: SimpleLicenseExpression -> DataType
$cdataTypeOf :: SimpleLicenseExpression -> DataType
toConstr :: SimpleLicenseExpression -> Constr
$ctoConstr :: SimpleLicenseExpression -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SimpleLicenseExpression
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SimpleLicenseExpression
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> SimpleLicenseExpression
-> c SimpleLicenseExpression
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> SimpleLicenseExpression
-> c SimpleLicenseExpression
Data, forall x. Rep SimpleLicenseExpression x -> SimpleLicenseExpression
forall x. SimpleLicenseExpression -> Rep SimpleLicenseExpression x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SimpleLicenseExpression x -> SimpleLicenseExpression
$cfrom :: forall x. SimpleLicenseExpression -> Rep SimpleLicenseExpression x
Generic)

simpleLicenseExpression :: LicenseId -> LicenseExpression
simpleLicenseExpression :: LicenseId -> LicenseExpression
simpleLicenseExpression LicenseId
i = SimpleLicenseExpression
-> Maybe LicenseExceptionId -> LicenseExpression
ELicense (LicenseId -> SimpleLicenseExpression
ELicenseId LicenseId
i) forall a. Maybe a
Nothing

instance Binary LicenseExpression
instance Binary SimpleLicenseExpression
instance Structured SimpleLicenseExpression
instance Structured LicenseExpression

instance Pretty LicenseExpression where
    pretty :: LicenseExpression -> Doc
pretty = Int -> LicenseExpression -> Doc
go Int
0
      where
        go :: Int -> LicenseExpression -> Disp.Doc
        go :: Int -> LicenseExpression -> Doc
go Int
_ (ELicense SimpleLicenseExpression
lic Maybe LicenseExceptionId
exc) =
            let doc :: Doc
doc = forall a. Pretty a => a -> Doc
pretty SimpleLicenseExpression
lic
            in forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. a -> a
id (\LicenseExceptionId
e Doc
d -> Doc
d Doc -> Doc -> Doc
<+> String -> Doc
Disp.text String
"WITH" Doc -> Doc -> Doc
<+> forall a. Pretty a => a -> Doc
pretty LicenseExceptionId
e) Maybe LicenseExceptionId
exc Doc
doc
        go Int
d (EAnd LicenseExpression
e1 LicenseExpression
e2) = Bool -> Doc -> Doc
parens (Int
d forall a. Ord a => a -> a -> Bool
< Int
0) forall a b. (a -> b) -> a -> b
$ Int -> LicenseExpression -> Doc
go Int
0 LicenseExpression
e1 Doc -> Doc -> Doc
<+> String -> Doc
Disp.text String
"AND" Doc -> Doc -> Doc
<+> Int -> LicenseExpression -> Doc
go Int
0 LicenseExpression
e2
        go Int
d (EOr  LicenseExpression
e1 LicenseExpression
e2) = Bool -> Doc -> Doc
parens (Int
d forall a. Ord a => a -> a -> Bool
< Int
1) forall a b. (a -> b) -> a -> b
$ Int -> LicenseExpression -> Doc
go Int
1 LicenseExpression
e1 Doc -> Doc -> Doc
<+> String -> Doc
Disp.text String
"OR" Doc -> Doc -> Doc
<+> Int -> LicenseExpression -> Doc
go Int
1 LicenseExpression
e2


        parens :: Bool -> Doc -> Doc
parens Bool
False Doc
doc = Doc
doc
        parens Bool
True  Doc
doc = Doc -> Doc
Disp.parens Doc
doc

instance Pretty SimpleLicenseExpression where
    pretty :: SimpleLicenseExpression -> Doc
pretty (ELicenseId LicenseId
i)     = forall a. Pretty a => a -> Doc
pretty LicenseId
i
    pretty (ELicenseIdPlus LicenseId
i) = forall a. Pretty a => a -> Doc
pretty LicenseId
i Doc -> Doc -> Doc
<<>> Char -> Doc
Disp.char Char
'+'
    pretty (ELicenseRef LicenseRef
r)    = forall a. Pretty a => a -> Doc
pretty LicenseRef
r

instance Parsec SimpleLicenseExpression where
    parsec :: forall (m :: * -> *). CabalParsing m => m SimpleLicenseExpression
parsec = forall (m :: * -> *). CharParsing m => m String
idstring forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall {m :: * -> *}.
CabalParsing m =>
String -> m SimpleLicenseExpression
simple where
        simple :: String -> m SimpleLicenseExpression
simple String
n
            | Just String
l <- String
"LicenseRef-" forall a. Eq a => [a] -> [a] -> Maybe [a]
`isPrefixOfMaybe` String
n =
                forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"Incorrect LicenseRef format: " forall a. [a] -> [a] -> [a]
++ String
n) (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. LicenseRef -> SimpleLicenseExpression
ELicenseRef) forall a b. (a -> b) -> a -> b
$ Maybe String -> String -> Maybe LicenseRef
mkLicenseRef forall a. Maybe a
Nothing String
l
            | Just String
d <- String
"DocumentRef-" forall a. Eq a => [a] -> [a] -> Maybe [a]
`isPrefixOfMaybe` String
n = do
                String
_ <- forall (m :: * -> *). CharParsing m => String -> m String
P.string String
":LicenseRef-"
                String
l <- forall (m :: * -> *). CharParsing m => m String
idstring
                forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"Incorrect LicenseRef format:" forall a. [a] -> [a] -> [a]
++ String
n) (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. LicenseRef -> SimpleLicenseExpression
ELicenseRef) forall a b. (a -> b) -> a -> b
$ Maybe String -> String -> Maybe LicenseRef
mkLicenseRef (forall a. a -> Maybe a
Just String
d) String
l
            | Bool
otherwise = do
                CabalSpecVersion
v <- forall (m :: * -> *). CabalParsing m => m CabalSpecVersion
askCabalSpecVersion
                LicenseId
l <- forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"Unknown SPDX license identifier: '" forall a. [a] -> [a] -> [a]
++  String
n forall a. [a] -> [a] -> [a]
++ String
"' " forall a. [a] -> [a] -> [a]
++ ShowS
licenseIdMigrationMessage String
n) forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
                    LicenseListVersion -> String -> Maybe LicenseId
mkLicenseId (CabalSpecVersion -> LicenseListVersion
cabalSpecVersionToSPDXListVersion CabalSpecVersion
v) String
n
                Bool
orLater <- forall a. Maybe a -> Bool
isJust forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
P.optional (forall (m :: * -> *). CharParsing m => Char -> m Char
P.char Char
'+')
                if Bool
orLater
                then forall (m :: * -> *) a. Monad m => a -> m a
return (LicenseId -> SimpleLicenseExpression
ELicenseIdPlus LicenseId
l)
                else forall (m :: * -> *) a. Monad m => a -> m a
return (LicenseId -> SimpleLicenseExpression
ELicenseId LicenseId
l)

idstring :: P.CharParsing m => m String
idstring :: forall (m :: * -> *). CharParsing m => m String
idstring = forall (m :: * -> *). CharParsing m => (Char -> Bool) -> m String
P.munch1 forall a b. (a -> b) -> a -> b
$ \Char
c -> Char -> Bool
isAsciiAlphaNum Char
c Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
'-' Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
'.'

-- returns suffix part
isPrefixOfMaybe :: Eq a => [a] -> [a] -> Maybe [a]
isPrefixOfMaybe :: forall a. Eq a => [a] -> [a] -> Maybe [a]
isPrefixOfMaybe [a]
pfx [a]
s
    | [a]
pfx forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` [a]
s = forall a. a -> Maybe a
Just (forall a. Int -> [a] -> [a]
drop (forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
pfx) [a]
s)
    | Bool
otherwise          = forall a. Maybe a
Nothing

instance Parsec LicenseExpression where
    parsec :: forall (m :: * -> *). CabalParsing m => m LicenseExpression
parsec = m LicenseExpression
expr
      where
        expr :: m LicenseExpression
expr = m LicenseExpression
compoundOr

        simple :: m LicenseExpression
simple = do
            SimpleLicenseExpression
s <- forall a (m :: * -> *). (Parsec a, CabalParsing m) => m a
parsec
            Maybe LicenseExceptionId
exc <- m (Maybe LicenseExceptionId)
exception
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ SimpleLicenseExpression
-> Maybe LicenseExceptionId -> LicenseExpression
ELicense SimpleLicenseExpression
s Maybe LicenseExceptionId
exc

        exception :: m (Maybe LicenseExceptionId)
exception = forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
P.optional forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Parsing m => m a -> m a
P.try (m ()
spaces1 forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall (m :: * -> *). CharParsing m => String -> m String
P.string String
"WITH" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> m ()
spaces1) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall a (m :: * -> *). (Parsec a, CabalParsing m) => m a
parsec

        compoundOr :: m LicenseExpression
compoundOr = do
            LicenseExpression
x <- m LicenseExpression
compoundAnd
            Maybe LicenseExpression
l <- forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
P.optional forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Parsing m => m a -> m a
P.try (m ()
spaces1 forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall (m :: * -> *). CharParsing m => String -> m String
P.string String
"OR" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> m ()
spaces1) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> m LicenseExpression
compoundOr
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. a -> a
id (forall a b c. (a -> b -> c) -> b -> a -> c
flip LicenseExpression -> LicenseExpression -> LicenseExpression
EOr) Maybe LicenseExpression
l LicenseExpression
x

        compoundAnd :: m LicenseExpression
compoundAnd = do
            LicenseExpression
x <- m LicenseExpression
compound
            Maybe LicenseExpression
l <- forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
P.optional forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Parsing m => m a -> m a
P.try (m ()
spaces1 forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall (m :: * -> *). CharParsing m => String -> m String
P.string String
"AND" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> m ()
spaces1) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> m LicenseExpression
compoundAnd
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. a -> a
id (forall a b c. (a -> b -> c) -> b -> a -> c
flip LicenseExpression -> LicenseExpression -> LicenseExpression
EAnd) Maybe LicenseExpression
l LicenseExpression
x

        compound :: m LicenseExpression
compound = m LicenseExpression
braces forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> m LicenseExpression
simple

        -- NOTE: we require that there's a space around AND & OR operators,
        -- i.e. @(MIT)AND(MIT)@ will cause parse-error.
        braces :: m LicenseExpression
braces = do
            Char
_ <- forall (m :: * -> *). CharParsing m => Char -> m Char
P.char Char
'('
            ()
_ <- forall (m :: * -> *). CharParsing m => m ()
P.spaces
            LicenseExpression
x <- m LicenseExpression
expr
            Char
_ <- forall (m :: * -> *). CharParsing m => Char -> m Char
P.char Char
')'
            forall (m :: * -> *) a. Monad m => a -> m a
return LicenseExpression
x

        spaces1 :: m ()
spaces1 = forall (m :: * -> *). CharParsing m => m Char
P.space forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall (m :: * -> *). CharParsing m => m ()
P.spaces

-- notes:
--
-- There MUST NOT be whitespace between a license­id and any following "+".  This supports easy parsing and
-- backwards compatibility.  There MUST be whitespace on either side of the operator "WITH".  There MUST be
-- whitespace and/or parentheses on either side of the operators "AND" and "OR".
--
-- We handle that by having greedy 'idstring' parser, so MITAND would parse as invalid license identifier.

instance NFData LicenseExpression where
    rnf :: LicenseExpression -> ()
rnf (ELicense SimpleLicenseExpression
s Maybe LicenseExceptionId
e) = forall a. NFData a => a -> ()
rnf SimpleLicenseExpression
s seq :: forall a b. a -> b -> b
`seq` forall a. NFData a => a -> ()
rnf Maybe LicenseExceptionId
e
    rnf (EAnd LicenseExpression
x LicenseExpression
y)     = forall a. NFData a => a -> ()
rnf LicenseExpression
x seq :: forall a b. a -> b -> b
`seq` forall a. NFData a => a -> ()
rnf LicenseExpression
y
    rnf (EOr LicenseExpression
x LicenseExpression
y)      = forall a. NFData a => a -> ()
rnf LicenseExpression
x seq :: forall a b. a -> b -> b
`seq` forall a. NFData a => a -> ()
rnf LicenseExpression
y

instance NFData SimpleLicenseExpression where
    rnf :: SimpleLicenseExpression -> ()
rnf (ELicenseId LicenseId
i)     = forall a. NFData a => a -> ()
rnf LicenseId
i
    rnf (ELicenseIdPlus LicenseId
i) = forall a. NFData a => a -> ()
rnf LicenseId
i
    rnf (ELicenseRef LicenseRef
r)    = forall a. NFData a => a -> ()
rnf LicenseRef
r