{-# LANGUAGE OverloadedStrings, EmptyDataDecls, ScopedTypeVariables, TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances, GeneralizedNewtypeDeriving, DeriveDataTypeable #-}
{-# OPTIONS_GHC -fno-warn-missing-methods #-} -- Bits.popCount only introduced in 7.6
{-# OPTIONS_GHC -fno-warn-unused-imports #-} -- Applicative and Monoid required < 7.9

module Development.NSIS.Sugar(
    Compressor(..), HKEY(..), MessageBoxType(..), Page(..), Level(..), Type.Target(..), Visibility(..), FileMode(..), SectionFlag(..),
    ShowWindow(..), FinishOptions(..), DetailsPrint(..),
    module Development.NSIS.Sugar, Label, SectionId
    ) where

import Development.NSIS.Type hiding (Target)
import qualified Development.NSIS.Type as Type
import Data.Char
import Data.List
import Data.Maybe
import Data.Semigroup
import qualified Data.List.NonEmpty as NonEmpty
import Data.Monoid hiding ((<>))
import Data.String
import Data.Data
import Data.Bits
import Control.Applicative
import Control.Monad
import Control.Monad.Trans.State
import Data.Generics.Uniplate.Data


---------------------------------------------------------------------
-- INTERNALS

data S = S
    {S -> Int
uniques :: Int
    ,S -> [NSIS]
stream :: [NSIS]
    ,S -> [[(String, (TypeRep, Val))]]
scopes :: [[(String,(TypeRep,Val))]] -- nearest scope is here
    }

-- | Monad in which installers are defined. A useful command to start with is 'section'.
newtype Action a = Action (State S a)
    deriving ((forall a b. (a -> b) -> Action a -> Action b)
-> (forall a b. a -> Action b -> Action a) -> Functor Action
forall a b. a -> Action b -> Action a
forall a b. (a -> b) -> Action a -> Action b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> Action a -> Action b
fmap :: forall a b. (a -> b) -> Action a -> Action b
$c<$ :: forall a b. a -> Action b -> Action a
<$ :: forall a b. a -> Action b -> Action a
Functor, Applicative Action
Applicative Action =>
(forall a b. Action a -> (a -> Action b) -> Action b)
-> (forall a b. Action a -> Action b -> Action b)
-> (forall a. a -> Action a)
-> Monad Action
forall a. a -> Action a
forall a b. Action a -> Action b -> Action b
forall a b. Action a -> (a -> Action b) -> Action b
forall (m :: * -> *).
Applicative m =>
(forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
$c>>= :: forall a b. Action a -> (a -> Action b) -> Action b
>>= :: forall a b. Action a -> (a -> Action b) -> Action b
$c>> :: forall a b. Action a -> Action b -> Action b
>> :: forall a b. Action a -> Action b -> Action b
$creturn :: forall a. a -> Action a
return :: forall a. a -> Action a
Monad, Functor Action
Functor Action =>
(forall a. a -> Action a)
-> (forall a b. Action (a -> b) -> Action a -> Action b)
-> (forall a b c.
    (a -> b -> c) -> Action a -> Action b -> Action c)
-> (forall a b. Action a -> Action b -> Action b)
-> (forall a b. Action a -> Action b -> Action a)
-> Applicative Action
forall a. a -> Action a
forall a b. Action a -> Action b -> Action a
forall a b. Action a -> Action b -> Action b
forall a b. Action (a -> b) -> Action a -> Action b
forall a b c. (a -> b -> c) -> Action a -> Action b -> Action c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
$cpure :: forall a. a -> Action a
pure :: forall a. a -> Action a
$c<*> :: forall a b. Action (a -> b) -> Action a -> Action b
<*> :: forall a b. Action (a -> b) -> Action a -> Action b
$cliftA2 :: forall a b c. (a -> b -> c) -> Action a -> Action b -> Action c
liftA2 :: forall a b c. (a -> b -> c) -> Action a -> Action b -> Action c
$c*> :: forall a b. Action a -> Action b -> Action b
*> :: forall a b. Action a -> Action b -> Action b
$c<* :: forall a b. Action a -> Action b -> Action a
<* :: forall a b. Action a -> Action b -> Action a
Applicative)


-- | A 'Value', only used by 'Exp', which can be produced using 'return'.
--   The @ty@ argument should be one of 'String', 'Int' or 'Bool'.
newtype Value ty = Value {forall ty. Value ty -> Val
fromValue :: Val}

tyString :: TypeRep
tyString = Proxy String -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (Proxy String
forall {k} (t :: k). Proxy t
Proxy :: Proxy String)
tyInt :: TypeRep
tyInt = Proxy Int -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (Proxy Int
forall {k} (t :: k). Proxy t
Proxy :: Proxy Int)


unique :: Action Int
unique :: Action Int
unique = State S Int -> Action Int
forall a. State S a -> Action a
Action (State S Int -> Action Int) -> State S Int -> Action Int
forall a b. (a -> b) -> a -> b
$ do
    S
s <- StateT S Identity S
forall (m :: * -> *) s. Monad m => StateT s m s
get
    S -> StateT S Identity ()
forall (m :: * -> *) s. Monad m => s -> StateT s m ()
put S
s{uniques = uniques s + 1}
    Int -> State S Int
forall a. a -> StateT S Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> State S Int) -> Int -> State S Int
forall a b. (a -> b) -> a -> b
$ S -> Int
uniques S
s

var :: Action Var
var :: Action Var
var = (Int -> Var) -> Action Int -> Action Var
forall a b. (a -> b) -> Action a -> Action b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> Var
Var Action Int
unique

newSectionId :: Action SectionId
newSectionId :: Action SectionId
newSectionId = (Int -> SectionId) -> Action Int -> Action SectionId
forall a b. (a -> b) -> Action a -> Action b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> SectionId
SectionId Action Int
unique

val :: Var -> Val
val Var
x = [Var -> Val_
Var_ Var
x]
lit :: String -> Val
lit String
x = [String -> Val_
Literal String
x | String
x String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/= String
""]

-- | Create a new label, used with 'goto' and 'label' to write line jump based programming.
--   Where possible you should use structured alternatives, such as 'iff', 'while' and 'loop'.
--   Each created label must be used with one call to 'label', and any number of calls to
--   'goto'. As an example:
--
-- @
-- abort <- 'newLabel'
-- 'while' var $ do
--     'iff_' cond1 $ 'goto' abort
--     'iff_' cond2 $ 'goto' abort
--     var '@=' 'strDrop' 1 var
-- 'label' abort
-- @
--
--   Note that the above example could have been written in a simpler manner with 'loop'.
newLabel :: Action Label
newLabel :: Action Label
newLabel = (Int -> Label) -> Action Int -> Action Label
forall a b. (a -> b) -> Action a -> Action b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> Label
Label Action Int
unique

emit :: NSIS -> Action ()
emit :: NSIS -> Action ()
emit NSIS
x = StateT S Identity () -> Action ()
forall a. State S a -> Action a
Action (StateT S Identity () -> Action ())
-> StateT S Identity () -> Action ()
forall a b. (a -> b) -> a -> b
$ (S -> S) -> StateT S Identity ()
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify ((S -> S) -> StateT S Identity ())
-> (S -> S) -> StateT S Identity ()
forall a b. (a -> b) -> a -> b
$ \S
s -> S
s{stream = stream s ++ [x]}


rval :: Exp a -> Action Var
rval :: forall a. Exp a -> Action Var
rval Exp a
act = do
    ([NSIS]
xs, Value a
res) <- Exp a -> Action ([NSIS], Value a)
forall a. Action a -> Action ([NSIS], a)
capture Exp a
act
    case Value a
res of
        Value a
_ | Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [NSIS] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [NSIS]
xs -> String -> Action Var
forall a. HasCallStack => String -> a
error (String -> Action Var) -> String -> Action Var
forall a b. (a -> b) -> a -> b
$ String
"An R-value may not emit any statements: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [NSIS] -> String
forall a. Show a => a -> String
show [NSIS]
xs
        Value [Var_ Var
x] -> Var -> Action Var
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return Var
x
        Value a
_ -> String -> Action Var
forall a. HasCallStack => String -> a
error (String -> Action Var) -> String -> Action Var
forall a b. (a -> b) -> a -> b
$ String
"An R-value must be a single value, found: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Val -> String
forall a. Show a => a -> String
show (Value a -> Val
forall ty. Value ty -> Val
fromValue Value a
res)


capture :: Action a -> Action ([NSIS], a)
capture :: forall a. Action a -> Action ([NSIS], a)
capture (Action State S a
act) = State S ([NSIS], a) -> Action ([NSIS], a)
forall a. State S a -> Action a
Action (State S ([NSIS], a) -> Action ([NSIS], a))
-> State S ([NSIS], a) -> Action ([NSIS], a)
forall a b. (a -> b) -> a -> b
$ do
    S
s0 <- StateT S Identity S
forall (m :: * -> *) s. Monad m => StateT s m s
get
    S -> StateT S Identity ()
forall (m :: * -> *) s. Monad m => s -> StateT s m ()
put S
s0{stream=[]}
    a
res <- State S a
act
    S
s1 <- StateT S Identity S
forall (m :: * -> *) s. Monad m => StateT s m s
get
    S -> StateT S Identity ()
forall (m :: * -> *) s. Monad m => s -> StateT s m ()
put S
s1{stream=stream s0}
    ([NSIS], a) -> State S ([NSIS], a)
forall a. a -> StateT S Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (S -> [NSIS]
stream S
s1, a
res)

runAction :: Action () -> [NSIS]
runAction :: Action () -> [NSIS]
runAction (Action StateT S Identity ()
act) = S -> [NSIS]
stream (S -> [NSIS]) -> S -> [NSIS]
forall a b. (a -> b) -> a -> b
$ StateT S Identity () -> S -> S
forall s a. State s a -> s -> s
execState StateT S Identity ()
act S
s0
    where s0 :: S
s0 = Int -> [NSIS] -> [[(String, (TypeRep, Val))]] -> S
S Int
1 [] [(String
"NSISDIR",(TypeRep
tyString,[String -> Val_
Builtin String
"{NSISDIR}"]))(String, (TypeRep, Val))
-> [(String, (TypeRep, Val))] -> [(String, (TypeRep, Val))]
forall a. a -> [a] -> [a]
:[(String
x, (TypeRep
tyString, [String -> Val_
Builtin String
x])) | String
x <- [String]
builtin]]


builtin :: [String]
builtin = String -> [String]
words (String -> [String]) -> String -> [String]
forall a b. (a -> b) -> a -> b
$
    String
"ADMINTOOLS APPDATA CDBURN_AREA CMDLINE COMMONFILES COMMONFILES32 COMMONFILES64 COOKIES DESKTOP DOCUMENTS " String -> String -> String
forall a. [a] -> [a] -> [a]
++
    String
"EXEDIR EXEFILE EXEPATH FAVORITES FONTS HISTORY HWNDPARENT INSTDIR INTERNET_CACHE LANGUAGE LOCALAPPDATA " String -> String -> String
forall a. [a] -> [a] -> [a]
++
    String
"MUSIC NETHOOD OUTDIR PICTURES PLUGINSDIR PRINTHOOD PROFILE PROGRAMFILES PROGRAMFILES32 PROGRAMFILES64 " String -> String -> String
forall a. [a] -> [a] -> [a]
++
    String
"QUICKLAUNCH RECENT RESOURCES RESOURCES_LOCALIZED SENDTO SMPROGRAMS SMSTARTUP STARTMENU SYSDIR TEMP " String -> String -> String
forall a. [a] -> [a] -> [a]
++
    String
"TEMPLATES VIDEOS WINDIR"


-- | Set all 'file' actions to automatically take 'NonFatal'.
alwaysNonFatal :: Action () -> Action ()
alwaysNonFatal :: Action () -> Action ()
alwaysNonFatal Action ()
act = do
    ([NSIS]
xs, ()
_) <- Action () -> Action ([NSIS], ())
forall a. Action a -> Action ([NSIS], a)
capture Action ()
act
    (NSIS -> Action ()) -> [NSIS] -> Action ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ NSIS -> Action ()
emit ([NSIS] -> Action ()) -> [NSIS] -> Action ()
forall a b. (a -> b) -> a -> b
$ (NSIS -> NSIS) -> [NSIS] -> [NSIS]
forall from to. Biplate from to => (to -> to) -> from -> from
transformBi NSIS -> NSIS
f [NSIS]
xs
    where
        f :: NSIS -> NSIS
f (File AFile
x) = AFile -> NSIS
File AFile
x{fileNonFatal=True}
        f NSIS
x = NSIS
x


-- | The type of expressions - namely an 'Action' producing a 'Value'. There are instances
--   for 'Num' and 'IsString', and turning on @{-\# LANGUAGE OverloadedStrings \#-}@ is
--   strongly recommended.
--
--   The 'fromString' function converts any embedded @$VAR@ into a variable lookup, which may refer to one of
--   the builtin NSIS variables (e.g. @$SMPROGRAMS@, @$TEMP@, @$PROGRAMFILES@), or a named variable
--   created with 'constant' or 'mutable'. The string @$$@ is used to escape @$@ values.
--   Bracket the variables to put text characters afterwards (e.g. @$(SMPROGRAMS)XXX@). In contrast
--   to standard strings, @\/@ is treated as @\\@ and @\/\/@ is treated as @\/@. Remember to escape any
--   slashes occuring in URLs.
--
--   If the string is @'Exp' 'String'@ then any 'Int' variables used will be automatically shown (see 'strShow').
--   If the string is @'Exp' ty@ then it must be of the form @\"$VAR\"@ where @$VAR@ is a variable of type @ty@.
--
--   The 'Eq' and 'Ord' instances for 'Exp' throw errors for all comparisons (use '%==', '%<=' etc),
--   but 'min' and 'max' are defined. The 'Num' (arithmetic) and 'Monoid' (string concatenation) instances are both
--   fully implemented. From 'Integral' and 'Fractional', only '/', 'mod' and 'div' are implemented, and
--   all as integer arithmetic. No functions from 'Enum' or 'Real' are implemented.
--
--   When using a single expression multiple times, to ensure it is not evaluated
--   repeatedly, use 'share'.
type Exp ty = Action (Value ty)

instance forall a . Typeable a => IsString (Exp a) where
    fromString :: String -> Exp a
fromString String
o = do
        [[(String, (TypeRep, Val))]]
scopes <- State S [[(String, (TypeRep, Val))]]
-> Action [[(String, (TypeRep, Val))]]
forall a. State S a -> Action a
Action (State S [[(String, (TypeRep, Val))]]
 -> Action [[(String, (TypeRep, Val))]])
-> State S [[(String, (TypeRep, Val))]]
-> Action [[(String, (TypeRep, Val))]]
forall a b. (a -> b) -> a -> b
$ (S -> [[(String, (TypeRep, Val))]])
-> State S [[(String, (TypeRep, Val))]]
forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a
gets S -> [[(String, (TypeRep, Val))]]
scopes
        let rty :: TypeRep
rty = Proxy a -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (Proxy a
forall {k} (t :: k). Proxy t
Proxy :: Proxy a)

        let grab :: t TypeRep -> String -> Val
grab t TypeRep
good String
name = case String -> [(String, (TypeRep, Val))] -> Maybe (TypeRep, Val)
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
name ([(String, (TypeRep, Val))] -> Maybe (TypeRep, Val))
-> [(String, (TypeRep, Val))] -> Maybe (TypeRep, Val)
forall a b. (a -> b) -> a -> b
$ [[(String, (TypeRep, Val))]] -> [(String, (TypeRep, Val))]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[(String, (TypeRep, Val))]]
scopes of
                Maybe (TypeRep, Val)
Nothing -> String -> Val
forall a. HasCallStack => String -> a
error (String -> Val) -> String -> Val
forall a b. (a -> b) -> a -> b
$ String
"Couldn't find variable, $" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", in " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
o
                Just (TypeRep
ty,Val
y)
                    | TypeRep
ty TypeRep -> t TypeRep -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` t TypeRep
good -> String -> Val
forall a. HasCallStack => String -> a
error (String -> Val) -> String -> Val
forall a b. (a -> b) -> a -> b
$ String
"Type mismatch, $" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" has " String -> String -> String
forall a. [a] -> [a] -> [a]
++ TypeRep -> String
forall a. Show a => a -> String
show TypeRep
ty String -> String -> String
forall a. [a] -> [a] -> [a]
++
                                                String
", but you want one of " String -> String -> String
forall a. [a] -> [a] -> [a]
++ t TypeRep -> String
forall a. Show a => a -> String
show t TypeRep
good String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", in " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
o
                    | Bool
otherwise -> Val
y

        -- "$VAR" permits any type, everything else requires string
        case String -> [Either String String]
parseString String
o of
            [Right String
var] -> Value a -> Exp a
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value a -> Exp a) -> Value a -> Exp a
forall a b. (a -> b) -> a -> b
$ Val -> Value a
forall ty. Val -> Value ty
Value (Val -> Value a) -> Val -> Value a
forall a b. (a -> b) -> a -> b
$ [TypeRep] -> String -> Val
forall {t :: * -> *}.
(Foldable t, Show (t TypeRep)) =>
t TypeRep -> String -> Val
grab [TypeRep
rty] String
var

            [Either String String]
_ | TypeRep
rty TypeRep -> TypeRep -> Bool
forall a. Eq a => a -> a -> Bool
/= TypeRep
tyString ->
                String -> Exp a
forall a. HasCallStack => String -> a
error (String -> Exp a) -> String -> Exp a
forall a b. (a -> b) -> a -> b
$ String
"Cannot use concatenated variables/literals to produce anything other than String, but you tried " String -> String -> String
forall a. [a] -> [a] -> [a]
++ TypeRep -> String
forall a. Show a => a -> String
show TypeRep
rty String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", in " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
o
            [Either String String]
xs -> (Value String -> Value a) -> Exp String -> Exp a
forall a b. (a -> b) -> Action a -> Action b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Val -> Value a
forall ty. Val -> Value ty
Value (Val -> Value a)
-> (Value String -> Val) -> Value String -> Value a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value String -> Val
forall ty. Value ty -> Val
fromValue) (Exp String -> Exp a) -> Exp String -> Exp a
forall a b. (a -> b) -> a -> b
$ [Exp String] -> Exp String
strConcat ([Exp String] -> Exp String) -> [Exp String] -> Exp String
forall a b. (a -> b) -> a -> b
$ ((Either String String -> Exp String)
 -> [Either String String] -> [Exp String])
-> [Either String String]
-> (Either String String -> Exp String)
-> [Exp String]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Either String String -> Exp String)
-> [Either String String] -> [Exp String]
forall a b. (a -> b) -> [a] -> [b]
map [Either String String]
xs ((Either String String -> Exp String) -> [Exp String])
-> (Either String String -> Exp String) -> [Exp String]
forall a b. (a -> b) -> a -> b
$ \Either String String
i -> Value String -> Exp String
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value String -> Exp String) -> Value String -> Exp String
forall a b. (a -> b) -> a -> b
$ Val -> Value String
forall ty. Val -> Value ty
Value (Val -> Value String) -> Val -> Value String
forall a b. (a -> b) -> a -> b
$ case Either String String
i of
                    Left String
x -> String -> Val
lit String
x
                    Right String
name -> [TypeRep] -> String -> Val
forall {t :: * -> *}.
(Foldable t, Show (t TypeRep)) =>
t TypeRep -> String -> Val
grab [TypeRep
tyString,TypeRep
tyInt] String
name


parseString :: String -> [Either String String]
parseString :: String -> [Either String String]
parseString String
"" = []
parseString (Char
'/':Char
'/':String
xs) = String -> Either String String
forall a b. a -> Either a b
Left String
"/" Either String String
-> [Either String String] -> [Either String String]
forall a. a -> [a] -> [a]
: String -> [Either String String]
parseString String
xs
parseString (Char
'/':String
xs) = String -> Either String String
forall a b. a -> Either a b
Left String
"\\" Either String String
-> [Either String String] -> [Either String String]
forall a. a -> [a] -> [a]
: String -> [Either String String]
parseString String
xs
parseString (Char
'$':Char
'$':String
xs) = String -> Either String String
forall a b. a -> Either a b
Left String
"$" Either String String
-> [Either String String] -> [Either String String]
forall a. a -> [a] -> [a]
: String -> [Either String String]
parseString String
xs
parseString (Char
'$':Char
'(':String
xs) = String -> Either String String
forall a b. b -> Either a b
Right String
a Either String String
-> [Either String String] -> [Either String String]
forall a. a -> [a] -> [a]
: String -> [Either String String]
parseString (Int -> String -> String
forall a. Int -> [a] -> [a]
drop Int
1 String
b)
    where (String
a,String
b) = (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
')') String
xs
parseString (Char
'$':String
xs) = String -> Either String String
forall a b. b -> Either a b
Right String
a Either String String
-> [Either String String] -> [Either String String]
forall a. a -> [a] -> [a]
: String -> [Either String String]
parseString String
b
    where (String
a,String
b) = (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
span Char -> Bool
isAlphaNum String
xs
parseString (Char
x:String
xs) = String -> Either String String
forall a b. a -> Either a b
Left [Char
x] Either String String
-> [Either String String] -> [Either String String]
forall a. a -> [a] -> [a]
: String -> [Either String String]
parseString String
xs


instance Show (Exp a) where
    show :: Exp a -> String
show Exp a
_ = String -> String
forall a. HasCallStack => String -> a
error String
"show is not available for Exp"

instance Eq (Exp a) where
    Exp a
_ == :: Exp a -> Exp a -> Bool
== Exp a
_ = String -> Bool
forall a. HasCallStack => String -> a
error String
"(==) is not available for Exp, try (%==) instead"

instance Num (Exp Int) where
    fromInteger :: Integer -> Exp Int
fromInteger = Value Int -> Exp Int
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value Int -> Exp Int)
-> (Integer -> Value Int) -> Integer -> Exp Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Val -> Value Int
forall ty. Val -> Value ty
Value (Val -> Value Int) -> (Integer -> Val) -> Integer -> Value Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Val
lit (String -> Val) -> (Integer -> String) -> Integer -> Val
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> String
forall a. Show a => a -> String
show
    + :: Exp Int -> Exp Int -> Exp Int
(+) = String -> Exp Int -> Exp Int -> Exp Int
intOp String
"+"
    * :: Exp Int -> Exp Int -> Exp Int
(*) = String -> Exp Int -> Exp Int -> Exp Int
intOp String
"*"
    (-) = String -> Exp Int -> Exp Int -> Exp Int
intOp String
"-"
    abs :: Exp Int -> Exp Int
abs Exp Int
a = Exp Int -> (Exp Int -> Exp Int) -> Exp Int
forall t a. Exp t -> (Exp t -> Action a) -> Action a
share Exp Int
a ((Exp Int -> Exp Int) -> Exp Int)
-> (Exp Int -> Exp Int) -> Exp Int
forall a b. (a -> b) -> a -> b
$ \Exp Int
a -> Exp Int
a Exp Int -> Exp Int -> Exp Bool
%< Exp Int
0 Exp Bool -> (Exp Int, Exp Int) -> Exp Int
forall t. Exp Bool -> (Exp t, Exp t) -> Exp t
? (Exp Int -> Exp Int
forall a. Num a => a -> a
negate Exp Int
a, Exp Int
a)
    signum :: Exp Int -> Exp Int
signum Exp Int
a = Exp Int -> (Exp Int -> Exp Int) -> Exp Int
forall t a. Exp t -> (Exp t -> Action a) -> Action a
share Exp Int
a ((Exp Int -> Exp Int) -> Exp Int)
-> (Exp Int -> Exp Int) -> Exp Int
forall a b. (a -> b) -> a -> b
$ \Exp Int
a -> Exp Int
a Exp Int -> Exp Int -> Exp Bool
forall a. Exp a -> Exp a -> Exp Bool
%== Exp Int
0 Exp Bool -> (Exp Int, Exp Int) -> Exp Int
forall t. Exp Bool -> (Exp t, Exp t) -> Exp t
? (Exp Int
0, Exp Int
a Exp Int -> Exp Int -> Exp Bool
%< Exp Int
0 Exp Bool -> (Exp Int, Exp Int) -> Exp Int
forall t. Exp Bool -> (Exp t, Exp t) -> Exp t
? (-Exp Int
1, Exp Int
1))

instance Integral (Exp Int) where
    mod :: Exp Int -> Exp Int -> Exp Int
mod = String -> Exp Int -> Exp Int -> Exp Int
intOp String
"%"
    toInteger :: Exp Int -> Integer
toInteger = String -> Exp Int -> Integer
forall a. HasCallStack => String -> a
error String
"toInteger is not available for Exp"
    div :: Exp Int -> Exp Int -> Exp Int
div = String -> Exp Int -> Exp Int -> Exp Int
intOp String
"/"
    quotRem :: Exp Int -> Exp Int -> (Exp Int, Exp Int)
quotRem = String -> Exp Int -> Exp Int -> (Exp Int, Exp Int)
forall a. HasCallStack => String -> a
error String
"quotRem is not available for Exp"

instance Enum (Exp Int) where
    toEnum :: Int -> Exp Int
toEnum = String -> Int -> Exp Int
forall a. HasCallStack => String -> a
error String
"toEnum is not available for Exp"
    fromEnum :: Exp Int -> Int
fromEnum = String -> Exp Int -> Int
forall a. HasCallStack => String -> a
error String
"toEnum is not available for Exp"

instance Real (Exp Int) where
    toRational :: Exp Int -> Rational
toRational = String -> Exp Int -> Rational
forall a. HasCallStack => String -> a
error String
"toRational is not available for Exp"

instance Ord (Exp Int) where
    compare :: Exp Int -> Exp Int -> Ordering
compare = String -> Exp Int -> Exp Int -> Ordering
forall a. HasCallStack => String -> a
error String
"compare is not available for Exp"
    min :: Exp Int -> Exp Int -> Exp Int
min Exp Int
a Exp Int
b = Exp Int -> (Exp Int -> Exp Int) -> Exp Int
forall t a. Exp t -> (Exp t -> Action a) -> Action a
share Exp Int
a ((Exp Int -> Exp Int) -> Exp Int)
-> (Exp Int -> Exp Int) -> Exp Int
forall a b. (a -> b) -> a -> b
$ \Exp Int
a -> Exp Int -> (Exp Int -> Exp Int) -> Exp Int
forall t a. Exp t -> (Exp t -> Action a) -> Action a
share Exp Int
b ((Exp Int -> Exp Int) -> Exp Int)
-> (Exp Int -> Exp Int) -> Exp Int
forall a b. (a -> b) -> a -> b
$ \Exp Int
b -> Exp Int
a Exp Int -> Exp Int -> Exp Bool
%<= Exp Int
b Exp Bool -> (Exp Int, Exp Int) -> Exp Int
forall t. Exp Bool -> (Exp t, Exp t) -> Exp t
? (Exp Int
a, Exp Int
b)
    max :: Exp Int -> Exp Int -> Exp Int
max Exp Int
a Exp Int
b = Exp Int -> (Exp Int -> Exp Int) -> Exp Int
forall t a. Exp t -> (Exp t -> Action a) -> Action a
share Exp Int
a ((Exp Int -> Exp Int) -> Exp Int)
-> (Exp Int -> Exp Int) -> Exp Int
forall a b. (a -> b) -> a -> b
$ \Exp Int
a -> Exp Int -> (Exp Int -> Exp Int) -> Exp Int
forall t a. Exp t -> (Exp t -> Action a) -> Action a
share Exp Int
b ((Exp Int -> Exp Int) -> Exp Int)
-> (Exp Int -> Exp Int) -> Exp Int
forall a b. (a -> b) -> a -> b
$ \Exp Int
b -> Exp Int
a Exp Int -> Exp Int -> Exp Bool
%<= Exp Int
b Exp Bool -> (Exp Int, Exp Int) -> Exp Int
forall t. Exp Bool -> (Exp t, Exp t) -> Exp t
? (Exp Int
b, Exp Int
a)

instance Fractional (Exp Int) where
    fromRational :: Rational -> Exp Int
fromRational = String -> Rational -> Exp Int
forall a. HasCallStack => String -> a
error String
"fromRational is not available for Exp, only Int is supported"
    / :: Exp Int -> Exp Int -> Exp Int
(/) = String -> Exp Int -> Exp Int -> Exp Int
intOp String
"/"

instance Semigroup (Exp String) where
    Exp String
x <> :: Exp String -> Exp String -> Exp String
<> Exp String
y = [Exp String] -> Exp String
forall a. Monoid a => [a] -> a
mconcat [Exp String
x,Exp String
y]
    sconcat :: NonEmpty (Exp String) -> Exp String
sconcat = [Exp String] -> Exp String
forall a. Monoid a => [a] -> a
mconcat ([Exp String] -> Exp String)
-> (NonEmpty (Exp String) -> [Exp String])
-> NonEmpty (Exp String)
-> Exp String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty (Exp String) -> [Exp String]
forall a. NonEmpty a -> [a]
NonEmpty.toList

instance Monoid (Exp String) where
    mempty :: Exp String
mempty = String -> Exp String
forall a. IsString a => String -> a
fromString String
""
    mappend :: Exp String -> Exp String -> Exp String
mappend = Exp String -> Exp String -> Exp String
forall a. Semigroup a => a -> a -> a
(<>)
    mconcat :: [Exp String] -> Exp String
mconcat [Exp String]
xs = Val -> Value String
forall ty. Val -> Value ty
Value (Val -> Value String)
-> ([Value String] -> Val) -> [Value String] -> Value String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Val -> Val
f (Val -> Val) -> ([Value String] -> Val) -> [Value String] -> Val
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Value String -> Val) -> [Value String] -> Val
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Value String -> Val
forall ty. Value ty -> Val
fromValue ([Value String] -> Value String)
-> Action [Value String] -> Exp String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Exp String] -> Action [Value String]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence [Exp String]
xs
        where
            f :: Val -> Val
f (Literal String
"":Val
xs) = Val -> Val
f Val
xs
            f (Literal String
x:Literal String
y:Val
zs) = Val -> Val
f (Val -> Val) -> Val -> Val
forall a b. (a -> b) -> a -> b
$ String -> Val_
Literal (String
xString -> String -> String
forall a. [a] -> [a] -> [a]
++String
y) Val_ -> Val -> Val
forall a. a -> [a] -> [a]
: Val
zs
            f (Val_
x:Val
xs) = Val_
x Val_ -> Val -> Val
forall a. a -> [a] -> [a]
: Val -> Val
f Val
xs
            f [] = []

instance Bits (Exp Int) where
    .&. :: Exp Int -> Exp Int -> Exp Int
(.&.) = String -> Exp Int -> Exp Int -> Exp Int
intOp String
"&"
    .|. :: Exp Int -> Exp Int -> Exp Int
(.|.) = String -> Exp Int -> Exp Int -> Exp Int
intOp String
"|"
    xor :: Exp Int -> Exp Int -> Exp Int
xor = String -> Exp Int -> Exp Int -> Exp Int
intOp String
"^"
    complement :: Exp Int -> Exp Int
complement Exp Int
a = String -> Exp Int -> Exp Int -> Exp Int
intOp String
"~" Exp Int
a Exp Int
0
    shiftL :: Exp Int -> Int -> Exp Int
shiftL Exp Int
a Int
b = String -> Exp Int -> Exp Int -> Exp Int
intOp String
"<<" Exp Int
a (Integer -> Exp Int
forall a. Num a => Integer -> a
fromInteger (Integer -> Exp Int) -> Integer -> Exp Int
forall a b. (a -> b) -> a -> b
$ Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
b)
    shiftR :: Exp Int -> Int -> Exp Int
shiftR Exp Int
a Int
b = String -> Exp Int -> Exp Int -> Exp Int
intOp String
">>" Exp Int
a (Integer -> Exp Int
forall a. Num a => Integer -> a
fromInteger (Integer -> Exp Int) -> Integer -> Exp Int
forall a b. (a -> b) -> a -> b
$ Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
b)
    rotate :: Exp Int -> Int -> Exp Int
rotate = String -> Exp Int -> Int -> Exp Int
forall a. HasCallStack => String -> a
error String
"rotate is not available for Exp"
    bitSize :: Exp Int -> Int
bitSize = String -> Exp Int -> Int
forall a. HasCallStack => String -> a
error String
"bitSize is not available for Exp"
    isSigned :: Exp Int -> Bool
isSigned Exp Int
_ = Bool
True
    testBit :: Exp Int -> Int -> Bool
testBit Exp Int
i = String -> Int -> Bool
forall a. HasCallStack => String -> a
error String
"testBit is not available for Exp"
    bit :: Int -> Exp Int
bit Int
i = Integer -> Exp Int
forall a. Num a => Integer -> a
fromInteger (Integer -> Exp Int) -> Integer -> Exp Int
forall a b. (a -> b) -> a -> b
$ Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Int -> Int
forall a. Bits a => Int -> a
bit Int
i :: Int)

intOp :: String -> Exp Int -> Exp Int -> Exp Int
intOp :: String -> Exp Int -> Exp Int -> Exp Int
intOp String
cmd Exp Int
x Exp Int
y = do Value Val
x <- Exp Int
x; Value Val
y <- Exp Int
y; Var
v <- Action Var
var; NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Var -> Val -> String -> Val -> NSIS
IntOp Var
v Val
x String
cmd Val
y; Value Int -> Exp Int
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value Int -> Exp Int) -> Value Int -> Exp Int
forall a b. (a -> b) -> a -> b
$ Val -> Value Int
forall ty. Val -> Value ty
Value (Val -> Value Int) -> Val -> Value Int
forall a b. (a -> b) -> a -> b
$ Var -> Val
val Var
v

emit1 :: (Val -> NSIS) -> Exp a -> Action ()
emit1 :: forall a. (Val -> NSIS) -> Exp a -> Action ()
emit1 Val -> NSIS
f Exp a
x1 = do Value Val
x1 <- Exp a
x1; NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Val -> NSIS
f Val
x1

emit2 :: (Val -> Val -> NSIS) -> Exp a -> Exp b -> Action ()
emit2 :: forall a b. (Val -> Val -> NSIS) -> Exp a -> Exp b -> Action ()
emit2 Val -> Val -> NSIS
f Exp a
x1 Exp b
x2 = do Value Val
x1 <- Exp a
x1; Value Val
x2 <- Exp b
x2; NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Val -> Val -> NSIS
f Val
x1 Val
x2

emit3 :: (Val -> Val -> Val -> NSIS) -> Exp a -> Exp b -> Exp c -> Action ()
emit3 :: forall a b c.
(Val -> Val -> Val -> NSIS) -> Exp a -> Exp b -> Exp c -> Action ()
emit3 Val -> Val -> Val -> NSIS
f Exp a
x1 Exp b
x2 Exp c
x3 = do Value Val
x1 <- Exp a
x1; Value Val
x2 <- Exp b
x2; Value Val
x3 <- Exp c
x3; NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Val -> Val -> Val -> NSIS
f Val
x1 Val
x2 Val
x3


infix 1 @=

-- | Assign a value to a mutable variable. The variable must have been originally created with
--   'mutable' or 'mutable_', or there will be an error when generating the install file.
(@=) :: Exp t -> Exp t -> Action ()
@= :: forall t. Exp t -> Exp t -> Action ()
(@=) Exp t
v Exp t
w = do Var
v <- Exp t -> Action Var
forall a. Exp a -> Action Var
rval Exp t
v; Value Val
w <- Exp t
w; NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Var -> Val -> NSIS
Assign Var
v Val
w


-- | Introduce a variable scope. Scopes are automatically introduced by operations
--   such as 'iff', 'loop', 'while' etc. Inside a scope you may define new variables
--   whose names may clash with variables outside the scope, but the local versions will be used.
--
--   If you have any non-evaluated expressions, before introducing any potentially clashing
--   variables in the scope you should 'share' them or use 'constant_' on them. For example:
--
-- @
-- operate x = do
--     x <- 'constant_' x
--     'scope' $ do
--         'constant' \"TEST\" 0
-- @
--
--   It is important to turn @x@ into a 'constant_' before defining a new constant @$TEST@, since
--   if @x@ refers to @$TEST@ after the new definition, it will pick up the wrong variable.
scope :: Action a -> Action a
scope :: forall a. Action a -> Action a
scope (Action State S a
act) = State S a -> Action a
forall a. State S a -> Action a
Action (State S a -> Action a) -> State S a -> Action a
forall a b. (a -> b) -> a -> b
$ do
    S
s0 <- StateT S Identity S
forall (m :: * -> *) s. Monad m => StateT s m s
get
    S -> StateT S Identity ()
forall (m :: * -> *) s. Monad m => s -> StateT s m ()
put S
s0{scopes=[] : scopes s0}
    a
res <- State S a
act
    (S -> S) -> StateT S Identity ()
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify ((S -> S) -> StateT S Identity ())
-> (S -> S) -> StateT S Identity ()
forall a b. (a -> b) -> a -> b
$ \S
s -> S
s{scopes = scopes s0}
    a -> State S a
forall a. a -> StateT S Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return a
res


addScope :: forall t . Typeable t => String -> Value t -> Action ()
addScope :: forall t. Typeable t => String -> Value t -> Action ()
addScope String
name Value t
v = StateT S Identity () -> Action ()
forall a. State S a -> Action a
Action (StateT S Identity () -> Action ())
-> StateT S Identity () -> Action ()
forall a b. (a -> b) -> a -> b
$
    (S -> S) -> StateT S Identity ()
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify ((S -> S) -> StateT S Identity ())
-> (S -> S) -> StateT S Identity ()
forall a b. (a -> b) -> a -> b
$ \S
s -> let [(String, (TypeRep, Val))]
now:[[(String, (TypeRep, Val))]]
rest = S -> [[(String, (TypeRep, Val))]]
scopes S
s in
                   if String
name String -> [String] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ((String, (TypeRep, Val)) -> String)
-> [(String, (TypeRep, Val))] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, (TypeRep, Val)) -> String
forall a b. (a, b) -> a
fst [(String, (TypeRep, Val))]
now
                   then String -> S
forall a. HasCallStack => String -> a
error (String -> S) -> String -> S
forall a b. (a -> b) -> a -> b
$ String
"Defined twice in one scope, " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
name
                   else S
s{scopes=((name,(typeRep (Proxy :: Proxy t), fromValue v)):now):rest}



-- | Create a mutable variable a name, which can be modified with '@='.
--   After defining the expression, you can refer to it with @$NAME@ in a 'String'.
--   To introduce a new scope, see 'scope'.
--
-- @
-- h <- 'mutable' \"HELLO\" \"Hello World\"
-- \"$HELLO\" '@=' \"$HELLO!\"
-- h        '@=' \"$HELLO!\" -- equivalent to the above
-- 'alert' \"$HELLO\"        -- with 2 exclamation marks
-- @
mutable :: Typeable t => String -> Exp t -> Action (Exp t)
mutable :: forall t. Typeable t => String -> Exp t -> Action (Exp t)
mutable String
name Exp t
x = do
    Exp t
v <- Exp t -> Action (Exp t)
forall t. Exp t -> Action (Exp t)
mutable_ Exp t
x
    Value t
vv <- Exp t
v
    String -> Value t -> Action ()
forall t. Typeable t => String -> Value t -> Action ()
addScope String
name Value t
vv
    Exp t -> Action (Exp t)
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return Exp t
v

-- | Create an unnamed mutable variable, which can be modified with '@='.
--
-- @
-- h <- 'mutable' \"Hello World\"
-- h '@=' 'h' '&' \"!\"
-- 'alert' h
-- @
mutable_ :: Exp t -> Action (Exp t)
mutable_ :: forall t. Exp t -> Action (Exp t)
mutable_ Exp t
x = do
    Var
v <- Action Var
var
    let v2 :: Action (Value ty)
v2 = Value ty -> Action (Value ty)
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value ty -> Action (Value ty)) -> Value ty -> Action (Value ty)
forall a b. (a -> b) -> a -> b
$ Val -> Value ty
forall ty. Val -> Value ty
Value (Val -> Value ty) -> Val -> Value ty
forall a b. (a -> b) -> a -> b
$ Var -> Val
val Var
v
    Exp t
forall {ty}. Action (Value ty)
v2 Exp t -> Exp t -> Action ()
forall t. Exp t -> Exp t -> Action ()
@= Exp t
x
    Exp t -> Action (Exp t)
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return Exp t
forall {ty}. Action (Value ty)
v2


-- | Create a constant with a name, ensuring the expression is shared.
--   After defining the expression, you can refer to it with @$NAME@ in a 'String'.
--   To introduce a new scope, see 'scope'.
--
-- @
-- 'constant' \"HELLO\" \"Hello World\"
-- 'alert' \"$HELLO!\"
-- @
constant :: Typeable t => String -> Exp t -> Action (Exp t)
constant :: forall t. Typeable t => String -> Exp t -> Action (Exp t)
constant String
name Exp t
x = do Exp t
x <- Exp t -> Action (Exp t)
forall t. Exp t -> Action (Exp t)
constant_ Exp t
x; Value t
xx <- Exp t
x; String -> Value t -> Action ()
forall t. Typeable t => String -> Value t -> Action ()
addScope String
name Value t
xx; Exp t -> Action (Exp t)
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return Exp t
x

-- | Create a constant with no name, ensuring the expression is shared.
--   Equivalent to @'share' 'return'@.
constant_ :: Exp t -> Action (Exp t)
constant_ :: forall t. Exp t -> Action (Exp t)
constant_ Exp t
x = do
    -- either the expression is entirely constant, or has mutable variables inside it
    Value Val
x <- Exp t
x
    if [()] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [() | Var_{} <- Val
x] then
        -- if it's totally constant, we want to leave it that way so it works in non-eval settings (e.g. file)
        Exp t -> Action (Exp t)
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Exp t -> Action (Exp t)) -> Exp t -> Action (Exp t)
forall a b. (a -> b) -> a -> b
$ Value t -> Exp t
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value t -> Exp t) -> Value t -> Exp t
forall a b. (a -> b) -> a -> b
$ Val -> Value t
forall ty. Val -> Value ty
Value Val
x
     else do
        -- if it's mutable, we want to share the value, but also snapshot it so that the mutable variables
        -- don't change afterwards
        Var
v <- Action Var
var
        Value Any -> Action (Value Any)
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Val -> Value Any
forall ty. Val -> Value ty
Value (Val -> Value Any) -> Val -> Value Any
forall a b. (a -> b) -> a -> b
$ Var -> Val
val Var
v) Action (Value Any) -> Action (Value Any) -> Action ()
forall t. Exp t -> Exp t -> Action ()
@= Value Any -> Action (Value Any)
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Val -> Value Any
forall ty. Val -> Value ty
Value Val
x)
        -- add the Literal so that assignment throws an error in future
        Exp t -> Action (Exp t)
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Exp t -> Action (Exp t)) -> Exp t -> Action (Exp t)
forall a b. (a -> b) -> a -> b
$ Value t -> Exp t
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value t -> Exp t) -> Value t -> Exp t
forall a b. (a -> b) -> a -> b
$ Val -> Value t
forall ty. Val -> Value ty
Value [Var -> Val_
Var_ Var
v, String -> Val_
Literal String
""]


-- | The 'Exp' language is call-by-name, meaning you must use share to avoid evaluating an exression
--   multiple times. Using 'share', if the expression has any side effects
--   they will be run immediately, but not on subsequent uses. When defining functions operating on
--   'Exp', if you use the same input expression twice, you should share it. For example:
--
-- @
-- strPalindrom x = 'share' x $ \\x -> x '%==' strReverse x
-- @
--
--   If the expression was not shared, and @x@ read from a file, then the file would be read twice.
share :: Exp t -> (Exp t -> Action a) -> Action a
share :: forall t a. Exp t -> (Exp t -> Action a) -> Action a
share Exp t
v Exp t -> Action a
act = do Exp t
v <- Exp t -> Action (Exp t)
forall t. Exp t -> Action (Exp t)
constant_ Exp t
v; Exp t -> Action a
act Exp t
v


-- | Versions of 'mutable' and 'constant' restricted to 'Exp' 'Int', used to avoid
--   ambiguous type errors.
mutableInt, constantInt :: String -> Exp Int -> Action (Exp Int)
mutableInt :: String -> Exp Int -> Action (Exp Int)
mutableInt = String -> Exp Int -> Action (Exp Int)
forall t. Typeable t => String -> Exp t -> Action (Exp t)
mutable
constantInt :: String -> Exp Int -> Action (Exp Int)
constantInt = String -> Exp Int -> Action (Exp Int)
forall t. Typeable t => String -> Exp t -> Action (Exp t)
constant

-- | Versions of 'mutable_' and 'constant_' restricted to 'Exp' 'Int', used to avoid
--   ambiguous type errors.
mutableInt_, constantInt_ :: Exp Int -> Action (Exp Int)
mutableInt_ :: Exp Int -> Action (Exp Int)
mutableInt_ = Exp Int -> Action (Exp Int)
forall t. Exp t -> Action (Exp t)
mutable_
constantInt_ :: Exp Int -> Action (Exp Int)
constantInt_ = Exp Int -> Action (Exp Int)
forall t. Exp t -> Action (Exp t)
constant_

-- | Versions of 'mutable' and 'constant' restricted to 'Exp' 'String', used to avoid
--   ambiguous type errors.
mutableStr, constantStr :: String -> Exp String -> Action (Exp String)
mutableStr :: String -> Exp String -> Action (Exp String)
mutableStr = String -> Exp String -> Action (Exp String)
forall t. Typeable t => String -> Exp t -> Action (Exp t)
mutable
constantStr :: String -> Exp String -> Action (Exp String)
constantStr = String -> Exp String -> Action (Exp String)
forall t. Typeable t => String -> Exp t -> Action (Exp t)
constant

-- | Versions of 'mutable_' and 'constant_' restricted to 'Exp' 'String', used to avoid
--   ambiguous type errors.
mutableStr_, constantStr_ :: Exp String -> Action (Exp String)
mutableStr_ :: Exp String -> Action (Exp String)
mutableStr_ = Exp String -> Action (Exp String)
forall t. Exp t -> Action (Exp t)
mutable_
constantStr_ :: Exp String -> Action (Exp String)
constantStr_ = Exp String -> Action (Exp String)
forall t. Exp t -> Action (Exp t)
constant_


---------------------------------------------------------------------
-- EXPRESSION WRAPPERS

-- | Perform string concatenation on a list of expressions.
strConcat :: [Exp String] -> Exp String
strConcat :: [Exp String] -> Exp String
strConcat = [Exp String] -> Exp String
forall a. Monoid a => [a] -> a
mconcat

-- | Boolean negation.
not_ :: Exp Bool -> Exp Bool
not_ :: Exp Bool -> Exp Bool
not_ Exp Bool
a = Exp Bool
a Exp Bool -> (Exp Bool, Exp Bool) -> Exp Bool
forall t. Exp Bool -> (Exp t, Exp t) -> Exp t
? (Exp Bool
false, Exp Bool
true)

infix 4 %==, %/=, %<=, %<, %>=, %>

-- | The standard equality operators, lifted to 'Exp'.
(%==), (%/=) :: Exp a -> Exp a -> Exp Bool
%== :: forall a. Exp a -> Exp a -> Exp Bool
(%==) Exp a
a Exp a
b = do
    Value Val
a <- Exp a
a
    Value Val
b <- Exp a
b
    Exp Bool
v <- Exp Bool -> Action (Exp Bool)
forall t. Exp t -> Action (Exp t)
mutable_ Exp Bool
false
    Label
eq <- Action Label
newLabel
    Label
end <- Action Label
newLabel
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Val -> Val -> Label -> Label -> NSIS
StrCmpS Val
a Val
b Label
eq Label
end
    Label -> Action ()
label Label
eq
    Exp Bool
v Exp Bool -> Exp Bool -> Action ()
forall t. Exp t -> Exp t -> Action ()
@= Exp Bool
true
    Label -> Action ()
label Label
end
    Exp Bool
v

%/= :: forall a. Exp a -> Exp a -> Exp Bool
(%/=) Exp a
a Exp a
b = Exp Bool -> Exp Bool
not_ (Exp a
a Exp a -> Exp a -> Exp Bool
forall a. Exp a -> Exp a -> Exp Bool
%== Exp a
b)

-- | The standard comparison operators, lifted to 'Exp'.
(%<=), (%<), (%>=), (%>) :: Exp Int -> Exp Int -> Exp Bool
%<= :: Exp Int -> Exp Int -> Exp Bool
(%<=) = Bool -> Bool -> Bool -> Exp Int -> Exp Int -> Exp Bool
comp Bool
True  Bool
True  Bool
False
%< :: Exp Int -> Exp Int -> Exp Bool
(%<)  = Bool -> Bool -> Bool -> Exp Int -> Exp Int -> Exp Bool
comp Bool
False Bool
True  Bool
False
%>= :: Exp Int -> Exp Int -> Exp Bool
(%>=) = Bool -> Bool -> Bool -> Exp Int -> Exp Int -> Exp Bool
comp Bool
True  Bool
False Bool
True
%> :: Exp Int -> Exp Int -> Exp Bool
(%>)  = Bool -> Bool -> Bool -> Exp Int -> Exp Int -> Exp Bool
comp Bool
False Bool
False Bool
True


comp :: Bool -> Bool -> Bool -> Exp Int -> Exp Int -> Exp Bool
comp :: Bool -> Bool -> Bool -> Exp Int -> Exp Int -> Exp Bool
comp Bool
eq Bool
lt Bool
gt Exp Int
a Exp Int
b = do
    Value Val
a <- Exp Int
a
    Value Val
b <- Exp Int
b
    Exp Bool
v <- Exp Bool -> Action (Exp Bool)
forall t. Exp t -> Action (Exp t)
mutable_ Exp Bool
false
    Label
yes <- Action Label
newLabel
    Label
end <- Action Label
newLabel
    let f :: Bool -> Label
f Bool
b = if Bool
b then Label
yes else Label
end
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Val -> Val -> Label -> Label -> Label -> NSIS
IntCmp Val
a Val
b (Bool -> Label
f Bool
eq) (Bool -> Label
f Bool
lt) (Bool -> Label
f Bool
gt)
    Label -> Action ()
label Label
yes
    Exp Bool
v Exp Bool -> Exp Bool -> Action ()
forall t. Exp t -> Exp t -> Action ()
@= Exp Bool
true
    Label -> Action ()
label Label
end
    Exp Bool
v


-- | Boolean constants corresponding to 'True' and 'False'
true, false :: Exp Bool
false :: Exp Bool
false = Value Bool -> Exp Bool
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value Bool -> Exp Bool) -> Value Bool -> Exp Bool
forall a b. (a -> b) -> a -> b
$ Val -> Value Bool
forall ty. Val -> Value ty
Value []
true :: Exp Bool
true = Value Bool -> Exp Bool
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value Bool -> Exp Bool) -> Value Bool -> Exp Bool
forall a b. (a -> b) -> a -> b
$ Val -> Value Bool
forall ty. Val -> Value ty
Value [String -> Val_
Literal String
"1"]

-- | Lift a 'Bool' into an 'Exp'
bool :: Bool -> Exp Bool
bool :: Bool -> Exp Bool
bool Bool
x = if Bool
x then Exp Bool
true else Exp Bool
false

-- | Lift a 'String' into an 'Exp'
str :: String -> Exp String
str :: String -> Exp String
str = Value String -> Exp String
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value String -> Exp String)
-> (String -> Value String) -> String -> Exp String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Val -> Value String
forall ty. Val -> Value ty
Value (Val -> Value String) -> (String -> Val) -> String -> Value String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Val
lit

-- | Lift an 'Int' into an 'Exp'
int :: Int -> Exp Int
int :: Int -> Exp Int
int = Value Int -> Exp Int
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value Int -> Exp Int) -> (Int -> Value Int) -> Int -> Exp Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Val -> Value Int
forall ty. Val -> Value ty
Value (Val -> Value Int) -> (Int -> Val) -> Int -> Value Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Val
lit (String -> Val) -> (Int -> String) -> Int -> Val
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String
forall a. Show a => a -> String
show

-- | Erase the type of an Exp, only useful with 'plugin'.
exp_ :: Exp a -> Exp ()
exp_ :: forall a. Exp a -> Exp ()
exp_ = (Value a -> Value ()) -> Action (Value a) -> Exp ()
forall a b. (a -> b) -> Action a -> Action b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Val -> Value ()
forall ty. Val -> Value ty
Value (Val -> Value ()) -> (Value a -> Val) -> Value a -> Value ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value a -> Val
forall ty. Value ty -> Val
fromValue)

-- | Pop a value off the stack, will set an error if there is nothing on the stack.
--   Only useful with 'plugin'.
pop :: Exp String
pop :: Exp String
pop = do Var
v <- Action Var
var; NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Var -> NSIS
Pop Var
v; Value String -> Exp String
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value String -> Exp String) -> Value String -> Exp String
forall a b. (a -> b) -> a -> b
$ Val -> Value String
forall ty. Val -> Value ty
Value (Val -> Value String) -> Val -> Value String
forall a b. (a -> b) -> a -> b
$ Var -> Val
val Var
v

-- | Push a value onto the stack. Only useful with 'plugin'.
push :: Exp a -> Action ()
push :: forall a. Exp a -> Action ()
push Exp a
a = do Value Val
a <- Exp a
a; NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Val -> NSIS
Push Val
a

-- | Call a plugin. If the arguments are of different types use 'exp_'. As an example:
--
-- @
-- encrypt x = 'share' x $ \\x -> do
--     'plugin' \"Base64\" \"Encrypt\" ['exp_' x, 'exp_' $ 'strLength' x]
-- @
--
--   The only thing to be careful about is that we use the @x@ parameter twice, so should 'share'
--   it to ensure it is only evaluated once.
plugin :: String -> String -> [Exp a] -> Action ()
plugin :: forall a. String -> String -> [Exp a] -> Action ()
plugin String
dll String
name [Exp a]
args = do [Val]
args <- (Exp a -> Action Val) -> [Exp a] -> Action [Val]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM ((Value a -> Val) -> Exp a -> Action Val
forall a b. (a -> b) -> Action a -> Action b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Value a -> Val
forall ty. Value ty -> Val
fromValue) [Exp a]
args; NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ String -> String -> [Val] -> NSIS
Plugin String
dll String
name [Val]
args

-- | Add a plugin directory
addPluginDir :: Exp String -> Action ()
addPluginDir :: Exp String -> Action ()
addPluginDir Exp String
a = do Value Val
a <- Exp String
a; NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Val -> NSIS
AddPluginDir Val
a


-- | Return the length of a string, @strLength \"test\" '%==' 4@.
strLength :: Exp String -> Exp Int
strLength :: Exp String -> Exp Int
strLength Exp String
a = do Value Val
a <- Exp String
a; Var
v <- Action Var
var; NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Var -> Val -> NSIS
StrLen Var
v Val
a; Value Int -> Exp Int
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value Int -> Exp Int) -> Value Int -> Exp Int
forall a b. (a -> b) -> a -> b
$ Val -> Value Int
forall ty. Val -> Value ty
Value (Val -> Value Int) -> Val -> Value Int
forall a b. (a -> b) -> a -> b
$ Var -> Val
val Var
v

-- | Take the first @n@ characters from a string, @strTake 2 \"test\" '%==' \"te\"@.
strTake :: Exp Int -> Exp String -> Exp String
strTake :: Exp Int -> Exp String -> Exp String
strTake Exp Int
n Exp String
x = do Value Val
n <- Exp Int
n; Value Val
x <- Exp String
x; Var
v <- Action Var
var; NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Var -> Val -> Val -> Val -> NSIS
StrCpy Var
v Val
x Val
n (String -> Val
lit String
""); Value String -> Exp String
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value String -> Exp String) -> Value String -> Exp String
forall a b. (a -> b) -> a -> b
$ Val -> Value String
forall ty. Val -> Value ty
Value (Val -> Value String) -> Val -> Value String
forall a b. (a -> b) -> a -> b
$ Var -> Val
val Var
v

-- | Drop the first @n@ characters from a string, @strDrop 2 \"test\" '%==' \"st\"@.
strDrop :: Exp Int -> Exp String -> Exp String
strDrop :: Exp Int -> Exp String -> Exp String
strDrop Exp Int
n Exp String
x = do Value Val
n <- Exp Int
n; Value Val
x <- Exp String
x; Var
v <- Action Var
var; NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Var -> Val -> Val -> Val -> NSIS
StrCpy Var
v Val
x (String -> Val
lit String
"") Val
n; Value String -> Exp String
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value String -> Exp String) -> Value String -> Exp String
forall a b. (a -> b) -> a -> b
$ Val -> Value String
forall ty. Val -> Value ty
Value (Val -> Value String) -> Val -> Value String
forall a b. (a -> b) -> a -> b
$ Var -> Val
val Var
v

-- | Gets the last write time of the file, you should only use the result to compare for equality
--   with other results from 'getFileTime'. On failure the error flag is set.
getFileTime :: Exp FilePath -> Exp String
getFileTime :: Exp String -> Exp String
getFileTime Exp String
x = do Value Val
x <- Exp String
x; Var
v1 <- Action Var
var; Var
v2 <- Action Var
var; NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Val -> Var -> Var -> NSIS
GetFileTime Val
x Var
v1 Var
v2; [Exp String] -> Exp String
strConcat [Value String -> Exp String
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value String -> Exp String) -> Value String -> Exp String
forall a b. (a -> b) -> a -> b
$ Val -> Value String
forall ty. Val -> Value ty
Value (Val -> Value String) -> Val -> Value String
forall a b. (a -> b) -> a -> b
$ Var -> Val
val Var
v1, Exp String
"#", Value String -> Exp String
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value String -> Exp String) -> Value String -> Exp String
forall a b. (a -> b) -> a -> b
$ Val -> Value String
forall ty. Val -> Value ty
Value (Val -> Value String) -> Val -> Value String
forall a b. (a -> b) -> a -> b
$ Var -> Val
val Var
v2]

readRegStr :: HKEY -> Exp String -> Exp String -> Exp String
readRegStr :: HKEY -> Exp String -> Exp String -> Exp String
readRegStr HKEY
k Exp String
a Exp String
b = do Var
v <- Action Var
var; (Val -> Val -> NSIS) -> Exp String -> Exp String -> Action ()
forall a b. (Val -> Val -> NSIS) -> Exp a -> Exp b -> Action ()
emit2 (Var -> HKEY -> Val -> Val -> NSIS
ReadRegStr Var
v HKEY
k) Exp String
a Exp String
b; Value String -> Exp String
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value String -> Exp String) -> Value String -> Exp String
forall a b. (a -> b) -> a -> b
$ Val -> Value String
forall ty. Val -> Value ty
Value (Val -> Value String) -> Val -> Value String
forall a b. (a -> b) -> a -> b
$ Var -> Val
val Var
v

deleteRegKey :: HKEY -> Exp String -> Action ()
deleteRegKey :: HKEY -> Exp String -> Action ()
deleteRegKey HKEY
k = (Val -> NSIS) -> Exp String -> Action ()
forall a. (Val -> NSIS) -> Exp a -> Action ()
emit1 ((Val -> NSIS) -> Exp String -> Action ())
-> (Val -> NSIS) -> Exp String -> Action ()
forall a b. (a -> b) -> a -> b
$ HKEY -> Val -> NSIS
DeleteRegKey HKEY
k

deleteRegValue :: HKEY -> Exp String -> Exp String -> Action ()
deleteRegValue :: HKEY -> Exp String -> Exp String -> Action ()
deleteRegValue HKEY
k = (Val -> Val -> NSIS) -> Exp String -> Exp String -> Action ()
forall a b. (Val -> Val -> NSIS) -> Exp a -> Exp b -> Action ()
emit2 ((Val -> Val -> NSIS) -> Exp String -> Exp String -> Action ())
-> (Val -> Val -> NSIS) -> Exp String -> Exp String -> Action ()
forall a b. (a -> b) -> a -> b
$ HKEY -> Val -> Val -> NSIS
DeleteRegValue HKEY
k

envVar :: Exp String -> Exp String
envVar :: Exp String -> Exp String
envVar Exp String
a = do Var
v <- Action Var
var; (Val -> NSIS) -> Exp String -> Action ()
forall a. (Val -> NSIS) -> Exp a -> Action ()
emit1 (Var -> Val -> NSIS
ReadEnvStr Var
v) Exp String
a; Value String -> Exp String
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value String -> Exp String) -> Value String -> Exp String
forall a b. (a -> b) -> a -> b
$ Val -> Value String
forall ty. Val -> Value ty
Value (Val -> Value String) -> Val -> Value String
forall a b. (a -> b) -> a -> b
$ Var -> Val
val Var
v


---------------------------------------------------------------------
-- ATTRIBUTES

data Attrib
    = Solid
    | Final
    | RebootOK
    | Silent
    | FilesOnly
    | NonFatal
    | Recursive
    | Unselected
    | Expanded
    | Description (Exp String)
    | Required
    | Target (Exp String)
    | Parameters (Exp String)
    | IconFile (Exp String)
    | IconIndex (Exp Int)
    | StartOptions String
    | KeyboardShortcut String
    | Id SectionId
    | Timeout Int
    | OName (Exp String)
      deriving Int -> Attrib -> String -> String
[Attrib] -> String -> String
Attrib -> String
(Int -> Attrib -> String -> String)
-> (Attrib -> String)
-> ([Attrib] -> String -> String)
-> Show Attrib
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> Attrib -> String -> String
showsPrec :: Int -> Attrib -> String -> String
$cshow :: Attrib -> String
show :: Attrib -> String
$cshowList :: [Attrib] -> String -> String
showList :: [Attrib] -> String -> String
Show


---------------------------------------------------------------------
-- STATEMENT WRAPPERS

-- | Define the location of a 'label', see 'newLabel' for details. This function will fail
--   if the same 'Label' is passed to 'label' more than once.
label :: Label -> Action ()
label :: Label -> Action ()
label Label
lbl = NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Label -> NSIS
Labeled Label
lbl

-- | Jump to a 'label', see 'newLabel' for details. This function will fail
--   if 'label' is not used on the 'Label'.
goto :: Label -> Action ()
goto :: Label -> Action ()
goto Label
lbl = NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Label -> NSIS
Goto Label
lbl


infix 2 ?

-- | An expression orientated version of 'iff', returns the first component if
--   the first argument is 'true' or the second if it is 'false'.
--
-- @
-- x '%==' 12 '?' (x, x '+' 5)
-- @
(?) :: Exp Bool -> (Exp t, Exp t) -> Exp t
? :: forall t. Exp Bool -> (Exp t, Exp t) -> Exp t
(?) Exp Bool
test (Exp t
true, Exp t
false) = do
    Var
v <- Action Var
var
    let v2 :: Action (Value ty)
v2 = Value ty -> Action (Value ty)
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value ty -> Action (Value ty)) -> Value ty -> Action (Value ty)
forall a b. (a -> b) -> a -> b
$ Val -> Value ty
forall ty. Val -> Value ty
Value (Val -> Value ty) -> Val -> Value ty
forall a b. (a -> b) -> a -> b
$ Var -> Val
val Var
v
    Exp Bool -> Action () -> Action () -> Action ()
iff Exp Bool
test (Exp t
forall {ty}. Action (Value ty)
v2 Exp t -> Exp t -> Action ()
forall t. Exp t -> Exp t -> Action ()
@= Exp t
true) (Exp t
forall {ty}. Action (Value ty)
v2 Exp t -> Exp t -> Action ()
forall t. Exp t -> Exp t -> Action ()
@= Exp t
false)
    Exp t
forall {ty}. Action (Value ty)
v2

-- | Test a boolean expression, reunning the first action if it is 'true' and the second if it is 'false'.
--   The appropriate branch action will be run within a 'scope'. See '?' for an expression orientated version.
--
-- @
-- 'iff' (x '%==' 12) ('alert' \"is 12\") ('alert' \"is not 12\")
-- @
iff :: Exp Bool -> Action () -> Action () -> Action ()
iff :: Exp Bool -> Action () -> Action () -> Action ()
iff Exp Bool
test Action ()
true Action ()
false = do
    Label
thn <- Action Label
newLabel
    Label
els <- Action Label
newLabel
    Label
end <- Action Label
newLabel
    Value Val
t <- Exp Bool
test
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Val -> Val -> Label -> Label -> NSIS
StrCmpS Val
t (String -> Val
lit String
"") Label
thn Label
els
    Label -> Action ()
label Label
thn
    Action () -> Action ()
forall a. Action a -> Action a
scope Action ()
false
    Label -> Action ()
goto Label
end
    Label -> Action ()
label Label
els
    Action () -> Action ()
forall a. Action a -> Action a
scope Action ()
true
    Label -> Action ()
label Label
end


-- | A version of 'iff' where there is no else action.
iff_ :: Exp Bool -> Action () -> Action ()
iff_ :: Exp Bool -> Action () -> Action ()
iff_ Exp Bool
test Action ()
true = Exp Bool -> Action () -> Action () -> Action ()
iff Exp Bool
test Action ()
true (() -> Action ()
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return ())


-- | A while loop, run the second argument while the first argument is true.
--   The action is run in a 'scope'. See also 'loop'.
--
-- @
-- x <- 'mutable_' x
-- 'while' (x '%<' 10) $ do
--    x '@=' x '+' 1
-- @
while :: Exp Bool -> Action () -> Action ()
while :: Exp Bool -> Action () -> Action ()
while Exp Bool
test Action ()
act = do
    Label
start <- Action Label
newLabel
    Label -> Action ()
label Label
start
    Exp Bool -> Action () -> Action ()
iff_ Exp Bool
test (Action () -> Action ()
forall a. Action a -> Action a
scope Action ()
act Action () -> Action () -> Action ()
forall a b. Action a -> Action b -> Action b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Label -> Action ()
goto Label
start)

-- | A loop with a @break@ command. Run the action repeatedly until the breaking action
--   is called. The action is run in a 'scope'. See also 'while'.
--
-- @
-- x <- 'mutable_' x
-- 'loop' $ \\break -> do
--     'iff_' (x '%>=' 10) break
--     x '@=' x '+' 1
-- @
loop :: (Action () -> Action ()) -> Action ()
loop :: (Action () -> Action ()) -> Action ()
loop Action () -> Action ()
body = do
    Label
end <- Action Label
newLabel
    Label
beg <- Action Label
newLabel
    Label -> Action ()
label Label
beg
    Action () -> Action ()
forall a. Action a -> Action a
scope (Action () -> Action ()) -> Action () -> Action ()
forall a b. (a -> b) -> a -> b
$ Action () -> Action ()
body (Action () -> Action ()) -> Action () -> Action ()
forall a b. (a -> b) -> a -> b
$ Label -> Action ()
goto Label
end
    Label -> Action ()
goto Label
beg
    Label -> Action ()
label Label
end

-- | Run an intitial action, and if that action causes an error, run the second action.
--   Unlike other programming languages, any uncaught errors are silently ignored.
--   All actions are run in 'scope'.
--
-- @
-- 'onError' ('exec' \"\\\"$WINDIR/notepad.exe\\\"\") ('alert' \"Failed to run notepad\")
-- @
onError :: Action () -> Action () -> Action ()
onError :: Action () -> Action () -> Action ()
onError Action ()
act Action ()
catch = do
    NSIS -> Action ()
emit NSIS
ClearErrors
    Action () -> Action ()
forall a. Action a -> Action a
scope Action ()
act
    Label
end <- Action Label
newLabel
    Label
err <- Action Label
newLabel
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Label -> Label -> NSIS
IfErrors Label
err Label
end
    Label -> Action ()
label Label
err
    Action () -> Action ()
forall a. Action a -> Action a
scope Action ()
catch
    Label -> Action ()
label Label
end


-- | Checks for existence of file(s) (which can be a wildcard, or a directory).
--   If you want to check to see if a file is a directory, use @fileExists "DIRECTORY/*.*"@.
--
-- > iff_ (fileExists "$WINDIR/notepad.exe") $
-- >     messageBox [MB_OK] "notepad is installed"
fileExists :: Exp FilePath -> Exp Bool
fileExists :: Exp String -> Exp Bool
fileExists Exp String
x = do
    Exp Bool
v <- Exp Bool -> Action (Exp Bool)
forall t. Exp t -> Action (Exp t)
mutable_ Exp Bool
false
    Value Val
x <- Exp String
x
    Label
yes <- Action Label
newLabel
    Label
end <- Action Label
newLabel
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Val -> Label -> Label -> NSIS
IfFileExists Val
x Label
yes Label
end
    Label -> Action ()
label Label
yes
    Exp Bool
v Exp Bool -> Exp Bool -> Action ()
forall t. Exp t -> Exp t -> Action ()
@= Exp Bool
true
    Label -> Action ()
label Label
end
    Exp Bool
v


-- | Performs a search for filespec, running the action with each file found.
--   If no files are found the error flag is set. Note that the filename output is without path.
--
-- > findEach "$INSTDIR/*.txt" $ \x ->
-- >     detailPrint x
--
--   If you jump from inside the loop to after the loop then you may leak a search handle.
findEach :: Exp FilePath -> (Exp FilePath -> Action ()) -> Action ()
findEach :: Exp String -> (Exp String -> Action ()) -> Action ()
findEach Exp String
spec Exp String -> Action ()
act = do
    Value Val
spec <- Exp String
spec
    Var
hdl <- Action Var
var
    Var
v <- Action Var
var
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Var -> Var -> Val -> NSIS
FindFirst Var
hdl Var
v Val
spec
    Exp Bool -> Action () -> Action ()
while (Value Bool -> Exp Bool
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Val -> Value Bool
forall ty. Val -> Value ty
Value (Val -> Value Bool) -> Val -> Value Bool
forall a b. (a -> b) -> a -> b
$ Var -> Val
val Var
v)) (Action () -> Action ()) -> Action () -> Action ()
forall a b. (a -> b) -> a -> b
$ do
        Action () -> Action ()
forall a. Action a -> Action a
scope (Action () -> Action ()) -> Action () -> Action ()
forall a b. (a -> b) -> a -> b
$ Exp String -> Action ()
act (Exp String -> Action ()) -> Exp String -> Action ()
forall a b. (a -> b) -> a -> b
$ Value String -> Exp String
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value String -> Exp String) -> Value String -> Exp String
forall a b. (a -> b) -> a -> b
$ Val -> Value String
forall ty. Val -> Value ty
Value (Val -> Value String) -> Val -> Value String
forall a b. (a -> b) -> a -> b
$ Var -> Val
val Var
v
        NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Val -> Var -> NSIS
FindNext (Var -> Val
val Var
hdl) Var
v
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Val -> NSIS
FindClose (Val -> NSIS) -> Val -> NSIS
forall a b. (a -> b) -> a -> b
$ Var -> Val
val Var
hdl


infixr 5 &

-- | Concatenate two strings, for example @\"$FOO\" & \"$BAR\"@ is equivalent
--   to @\"$FOO$BAR\"@.
(&) :: Exp String -> Exp String -> Exp String
& :: Exp String -> Exp String -> Exp String
(&) Exp String
a Exp String
b = [Exp String] -> Exp String
strConcat [Exp String
a,Exp String
b]


-- | Convert an 'Int' to a 'String' by showing it.
strShow :: Exp Int -> Exp String
strShow :: Exp Int -> Exp String
strShow = (Value Int -> Value String) -> Exp Int -> Exp String
forall a b. (a -> b) -> Action a -> Action b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Val -> Value String
forall ty. Val -> Value ty
Value (Val -> Value String)
-> (Value Int -> Val) -> Value Int -> Value String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value Int -> Val
forall ty. Value ty -> Val
fromValue)


-- | Convert a 'String' to an 'Int', any errors are silently ignored.
strRead :: Exp String -> Exp Int
strRead :: Exp String -> Exp Int
strRead = (Value String -> Value Int) -> Exp String -> Exp Int
forall a b. (a -> b) -> Action a -> Action b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Val -> Value Int
forall ty. Val -> Value ty
Value (Val -> Value Int)
-> (Value String -> Val) -> Value String -> Value Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value String -> Val
forall ty. Value ty -> Val
fromValue)


-- | Show an alert, equivalent to @messageBox [MB_ICONEXCLAMATION]@.
alert :: Exp String -> Action ()
alert :: Exp String -> Action ()
alert Exp String
x = do
    Exp String
_ <- [MessageBoxType] -> Exp String -> Action (Exp String)
messageBox [MessageBoxType
MB_ICONEXCLAMATION] Exp String
x
    () -> Action ()
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return ()




---------------------------------------------------------------------
-- SETTINGS WRAPPERS

-- | Sets the name of the installer. The name is usually simply the product name such as \'MyApp\' or \'Company MyApp\'.
--
-- > name "MyApp"
name :: Exp String -> Action ()
name :: Exp String -> Action ()
name = (Val -> NSIS) -> Exp String -> Action ()
forall a. (Val -> NSIS) -> Exp a -> Action ()
emit1 Val -> NSIS
Name

-- | Specifies the output file that @MakeNSIS@ should write the installer to.
--   This is just the file that MakeNSIS writes, it doesn't affect the contents of the installer.
--   Usually should end with @.exe@.
--
-- > outFile "installer.exe"
outFile :: Exp FilePath -> Action ()
outFile :: Exp String -> Action ()
outFile = (Val -> NSIS) -> Exp String -> Action ()
forall a. (Val -> NSIS) -> Exp a -> Action ()
emit1 Val -> NSIS
OutFile

-- | Sets the output path (@$OUTDIR@) and creates it (recursively if necessary), if it does not exist.
--   Must be a full pathname, usually is just @$INSTDIR@.
--
-- > setOutPath "$INSTDIR"
setOutPath :: Exp FilePath -> Action ()
setOutPath :: Exp String -> Action ()
setOutPath = (Val -> NSIS) -> Exp String -> Action ()
forall a. (Val -> NSIS) -> Exp a -> Action ()
emit1 Val -> NSIS
SetOutPath

-- | Sets the default installation directory.
--   Note that the part of this string following the last @\\@ will be used if the user selects 'browse', and
--   may be appended back on to the string at install time (to disable this, end the directory with a @\\@).
--   If this doesn't make any sense, play around with the browse button a bit.
--
-- > installDir "$PROGRAMFILES/MyApp"
installDir :: Exp FilePath -> Action ()
installDir :: Exp String -> Action ()
installDir = (Val -> NSIS) -> Exp String -> Action ()
forall a. (Val -> NSIS) -> Exp a -> Action ()
emit1 Val -> NSIS
InstallDir

-- | Writes the uninstaller to the filename (and optionally path) specified.
--   Only valid from within an install section, and requires that you have an 'uninstall' section in your script.
--   You can call this one or more times to write out one or more copies of the uninstaller.
--
-- > writeUninstaller "$INSTDIR/uninstaller.exe"
writeUninstaller :: Exp FilePath -> Action ()
writeUninstaller :: Exp String -> Action ()
writeUninstaller = (Val -> NSIS) -> Exp String -> Action ()
forall a. (Val -> NSIS) -> Exp a -> Action ()
emit1 Val -> NSIS
WriteUninstaller

-- | Set the icon used for the installer\/uninstaller.
--
-- > installIcon "$NSISDIR/Contrib/Graphics/Icons/modern-install.ico"
installIcon, uninstallIcon :: Exp FilePath -> Action ()
installIcon :: Exp String -> Action ()
installIcon = (Val -> NSIS) -> Exp String -> Action ()
forall a. (Val -> NSIS) -> Exp a -> Action ()
emit1 Val -> NSIS
InstallIcon
uninstallIcon :: Exp String -> Action ()
uninstallIcon = (Val -> NSIS) -> Exp String -> Action ()
forall a. (Val -> NSIS) -> Exp a -> Action ()
emit1 Val -> NSIS
UninstallIcon

-- | Set the image used for the header splash. Pass 'Nothing' to use the default header image.
--
-- > headerImage $ Just "$NSISDIR/Contrib/Graphics/Header/win.bmp"
headerImage :: Maybe (Exp FilePath) -> Action ()
headerImage :: Maybe (Exp String) -> Action ()
headerImage Maybe (Exp String)
Nothing = NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Maybe Val -> NSIS
HeaderImage Maybe Val
forall a. Maybe a
Nothing
headerImage (Just Exp String
x) = (Val -> NSIS) -> Exp String -> Action ()
forall a. (Val -> NSIS) -> Exp a -> Action ()
emit1 (Maybe Val -> NSIS
HeaderImage (Maybe Val -> NSIS) -> (Val -> Maybe Val) -> Val -> NSIS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Val -> Maybe Val
forall a. a -> Maybe a
Just) Exp String
x

-- | Creates (recursively if necessary) the specified directory. Errors can be caught
--   using 'onError'. You should always specify an absolute path.
--
-- > createDirectory "$INSTDIR/some/directory"
createDirectory :: Exp FilePath -> Action ()
createDirectory :: Exp String -> Action ()
createDirectory = (Val -> NSIS) -> Exp String -> Action ()
forall a. (Val -> NSIS) -> Exp a -> Action ()
emit1 Val -> NSIS
CreateDirectory

-- | This attribute tells the installer to check a string in the registry,
--   and use it for the install dir if that string is valid. If this attribute is present,
--   it will override the 'installDir' attribute if the registry key is valid, otherwise
--   it will fall back to the 'installDir' default. When querying the registry, this command
--   will automatically remove any quotes. If the string ends in \".exe\", it will automatically
--   remove the filename component of the string (i.e. if the string is \"C:/program files/foo/foo.exe\",
--   it will know to use \"C:/program files/foo\").
--
-- > installDirRegKey HKLM "Software/NSIS" ""
-- > installDirRegKey HKLM "Software/ACME/Thingy" "InstallLocation"
installDirRegKey :: HKEY -> Exp String -> Exp String -> Action ()
installDirRegKey :: HKEY -> Exp String -> Exp String -> Action ()
installDirRegKey HKEY
k = (Val -> Val -> NSIS) -> Exp String -> Exp String -> Action ()
forall a b. (Val -> Val -> NSIS) -> Exp a -> Exp b -> Action ()
emit2 ((Val -> Val -> NSIS) -> Exp String -> Exp String -> Action ())
-> (Val -> Val -> NSIS) -> Exp String -> Exp String -> Action ()
forall a b. (a -> b) -> a -> b
$ HKEY -> Val -> Val -> NSIS
InstallDirRegKey HKEY
k

-- | Execute the specified program and continue immediately. Note that the file specified
--   must exist on the target system, not the compiling system. @$OUTDIR@ is used for the working
--   directory. Errors can be caught using 'onError'. Note, if the command could have spaces,
--   you should put it in quotes to delimit it from parameters. e.g.: @exec \"\\\"$INSTDIR/command.exe\\\" parameters\"@.
--   If you don't put it in quotes it will not work on Windows 9x with or without parameters.
--
-- > exec "\"$INSTDIR/someprogram.exe\""
-- > exec "\"$INSTDIR/someprogram.exe\" some parameters"
exec :: Exp String -> Action ()
exec :: Exp String -> Action ()
exec = (Val -> NSIS) -> Exp String -> Action ()
forall a. (Val -> NSIS) -> Exp a -> Action ()
emit1 Val -> NSIS
Exec

execWait :: Exp String -> Action ()
execWait :: Exp String -> Action ()
execWait = (Val -> NSIS) -> Exp String -> Action ()
forall a. (Val -> NSIS) -> Exp a -> Action ()
emit1 Val -> NSIS
ExecWait

execShell :: [ShowWindow] -> Exp String -> Action ()
execShell :: [ShowWindow] -> Exp String -> Action ()
execShell [ShowWindow]
sw Exp String
x = do
    Value Val
x <- Exp String
x
    let d :: AExecShell
d = AExecShell
forall a. Default a => a
def{esCommand=x}
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ AExecShell -> NSIS
ExecShell (AExecShell -> NSIS) -> AExecShell -> NSIS
forall a b. (a -> b) -> a -> b
$ if [ShowWindow] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ShowWindow]
sw then AExecShell
d else AExecShell
d{esShow=last sw}

execShellWait :: [ShowWindow] -> Exp String -> Action ()
execShellWait :: [ShowWindow] -> Exp String -> Action ()
execShellWait [ShowWindow]
sw Exp String
x = do
    Value Val
x <- Exp String
x
    let d :: AExecShell
d = AExecShell
forall a. Default a => a
def{esCommand=x}
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ AExecShell -> NSIS
ExecShellWait (AExecShell -> NSIS) -> AExecShell -> NSIS
forall a b. (a -> b) -> a -> b
$ if [ShowWindow] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ShowWindow]
sw then AExecShell
d else AExecShell
d{esShow=last sw}

sectionSetText :: SectionId -> Exp String -> Action ()
sectionSetText :: SectionId -> Exp String -> Action ()
sectionSetText SectionId
x = (Val -> NSIS) -> Exp String -> Action ()
forall a. (Val -> NSIS) -> Exp a -> Action ()
emit1 ((Val -> NSIS) -> Exp String -> Action ())
-> (Val -> NSIS) -> Exp String -> Action ()
forall a b. (a -> b) -> a -> b
$ SectionId -> Val -> NSIS
SectionSetText SectionId
x

sectionGetText :: SectionId -> Exp String
sectionGetText :: SectionId -> Exp String
sectionGetText SectionId
x = do Var
v <- Action Var
var; NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ SectionId -> Var -> NSIS
SectionGetText SectionId
x Var
v; Value String -> Exp String
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value String -> Exp String) -> Value String -> Exp String
forall a b. (a -> b) -> a -> b
$ Val -> Value String
forall ty. Val -> Value ty
Value (Val -> Value String) -> Val -> Value String
forall a b. (a -> b) -> a -> b
$ Var -> Val
val Var
v

data SectionFlag
    = SF_Selected
    | SF_SectionGroup
    | SF_SectionGroupEnd
    | SF_Bold
    | SF_ReadOnly
    | SF_Expand
    | SF_PartiallySelected
      deriving (Int -> SectionFlag -> String -> String
[SectionFlag] -> String -> String
SectionFlag -> String
(Int -> SectionFlag -> String -> String)
-> (SectionFlag -> String)
-> ([SectionFlag] -> String -> String)
-> Show SectionFlag
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> SectionFlag -> String -> String
showsPrec :: Int -> SectionFlag -> String -> String
$cshow :: SectionFlag -> String
show :: SectionFlag -> String
$cshowList :: [SectionFlag] -> String -> String
showList :: [SectionFlag] -> String -> String
Show,Typeable SectionFlag
Typeable SectionFlag =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> SectionFlag -> c SectionFlag)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c SectionFlag)
-> (SectionFlag -> Constr)
-> (SectionFlag -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c SectionFlag))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c SectionFlag))
-> ((forall b. Data b => b -> b) -> SectionFlag -> SectionFlag)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> SectionFlag -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> SectionFlag -> r)
-> (forall u. (forall d. Data d => d -> u) -> SectionFlag -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> SectionFlag -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> SectionFlag -> m SectionFlag)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> SectionFlag -> m SectionFlag)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> SectionFlag -> m SectionFlag)
-> Data SectionFlag
SectionFlag -> Constr
SectionFlag -> DataType
(forall b. Data b => b -> b) -> SectionFlag -> SectionFlag
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) -> SectionFlag -> u
forall u. (forall d. Data d => d -> u) -> SectionFlag -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SectionFlag -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SectionFlag -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SectionFlag -> m SectionFlag
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SectionFlag -> m SectionFlag
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SectionFlag
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SectionFlag -> c SectionFlag
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SectionFlag)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c SectionFlag)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SectionFlag -> c SectionFlag
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SectionFlag -> c SectionFlag
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SectionFlag
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SectionFlag
$ctoConstr :: SectionFlag -> Constr
toConstr :: SectionFlag -> Constr
$cdataTypeOf :: SectionFlag -> DataType
dataTypeOf :: SectionFlag -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SectionFlag)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SectionFlag)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c SectionFlag)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c SectionFlag)
$cgmapT :: (forall b. Data b => b -> b) -> SectionFlag -> SectionFlag
gmapT :: (forall b. Data b => b -> b) -> SectionFlag -> SectionFlag
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SectionFlag -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SectionFlag -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SectionFlag -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SectionFlag -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> SectionFlag -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> SectionFlag -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> SectionFlag -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> SectionFlag -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SectionFlag -> m SectionFlag
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SectionFlag -> m SectionFlag
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SectionFlag -> m SectionFlag
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SectionFlag -> m SectionFlag
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SectionFlag -> m SectionFlag
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SectionFlag -> m SectionFlag
Data,Typeable,ReadPrec [SectionFlag]
ReadPrec SectionFlag
Int -> ReadS SectionFlag
ReadS [SectionFlag]
(Int -> ReadS SectionFlag)
-> ReadS [SectionFlag]
-> ReadPrec SectionFlag
-> ReadPrec [SectionFlag]
-> Read SectionFlag
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS SectionFlag
readsPrec :: Int -> ReadS SectionFlag
$creadList :: ReadS [SectionFlag]
readList :: ReadS [SectionFlag]
$creadPrec :: ReadPrec SectionFlag
readPrec :: ReadPrec SectionFlag
$creadListPrec :: ReadPrec [SectionFlag]
readListPrec :: ReadPrec [SectionFlag]
Read,SectionFlag
SectionFlag -> SectionFlag -> Bounded SectionFlag
forall a. a -> a -> Bounded a
$cminBound :: SectionFlag
minBound :: SectionFlag
$cmaxBound :: SectionFlag
maxBound :: SectionFlag
Bounded,Int -> SectionFlag
SectionFlag -> Int
SectionFlag -> [SectionFlag]
SectionFlag -> SectionFlag
SectionFlag -> SectionFlag -> [SectionFlag]
SectionFlag -> SectionFlag -> SectionFlag -> [SectionFlag]
(SectionFlag -> SectionFlag)
-> (SectionFlag -> SectionFlag)
-> (Int -> SectionFlag)
-> (SectionFlag -> Int)
-> (SectionFlag -> [SectionFlag])
-> (SectionFlag -> SectionFlag -> [SectionFlag])
-> (SectionFlag -> SectionFlag -> [SectionFlag])
-> (SectionFlag -> SectionFlag -> SectionFlag -> [SectionFlag])
-> Enum SectionFlag
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: SectionFlag -> SectionFlag
succ :: SectionFlag -> SectionFlag
$cpred :: SectionFlag -> SectionFlag
pred :: SectionFlag -> SectionFlag
$ctoEnum :: Int -> SectionFlag
toEnum :: Int -> SectionFlag
$cfromEnum :: SectionFlag -> Int
fromEnum :: SectionFlag -> Int
$cenumFrom :: SectionFlag -> [SectionFlag]
enumFrom :: SectionFlag -> [SectionFlag]
$cenumFromThen :: SectionFlag -> SectionFlag -> [SectionFlag]
enumFromThen :: SectionFlag -> SectionFlag -> [SectionFlag]
$cenumFromTo :: SectionFlag -> SectionFlag -> [SectionFlag]
enumFromTo :: SectionFlag -> SectionFlag -> [SectionFlag]
$cenumFromThenTo :: SectionFlag -> SectionFlag -> SectionFlag -> [SectionFlag]
enumFromThenTo :: SectionFlag -> SectionFlag -> SectionFlag -> [SectionFlag]
Enum,SectionFlag -> SectionFlag -> Bool
(SectionFlag -> SectionFlag -> Bool)
-> (SectionFlag -> SectionFlag -> Bool) -> Eq SectionFlag
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SectionFlag -> SectionFlag -> Bool
== :: SectionFlag -> SectionFlag -> Bool
$c/= :: SectionFlag -> SectionFlag -> Bool
/= :: SectionFlag -> SectionFlag -> Bool
Eq,Eq SectionFlag
Eq SectionFlag =>
(SectionFlag -> SectionFlag -> Ordering)
-> (SectionFlag -> SectionFlag -> Bool)
-> (SectionFlag -> SectionFlag -> Bool)
-> (SectionFlag -> SectionFlag -> Bool)
-> (SectionFlag -> SectionFlag -> Bool)
-> (SectionFlag -> SectionFlag -> SectionFlag)
-> (SectionFlag -> SectionFlag -> SectionFlag)
-> Ord SectionFlag
SectionFlag -> SectionFlag -> Bool
SectionFlag -> SectionFlag -> Ordering
SectionFlag -> SectionFlag -> SectionFlag
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
$ccompare :: SectionFlag -> SectionFlag -> Ordering
compare :: SectionFlag -> SectionFlag -> Ordering
$c< :: SectionFlag -> SectionFlag -> Bool
< :: SectionFlag -> SectionFlag -> Bool
$c<= :: SectionFlag -> SectionFlag -> Bool
<= :: SectionFlag -> SectionFlag -> Bool
$c> :: SectionFlag -> SectionFlag -> Bool
> :: SectionFlag -> SectionFlag -> Bool
$c>= :: SectionFlag -> SectionFlag -> Bool
>= :: SectionFlag -> SectionFlag -> Bool
$cmax :: SectionFlag -> SectionFlag -> SectionFlag
max :: SectionFlag -> SectionFlag -> SectionFlag
$cmin :: SectionFlag -> SectionFlag -> SectionFlag
min :: SectionFlag -> SectionFlag -> SectionFlag
Ord)

sectionGet :: SectionId -> SectionFlag -> Exp Bool
sectionGet :: SectionId -> SectionFlag -> Exp Bool
sectionGet SectionId
sec SectionFlag
flag = do
    Var
v <- Action Var
var
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ SectionId -> Var -> NSIS
SectionGetFlags SectionId
sec Var
v
    let b :: Exp Int
b = Int -> Exp Int
forall a. Bits a => Int -> a
bit (Int -> Exp Int) -> Int -> Exp Int
forall a b. (a -> b) -> a -> b
$ SectionFlag -> Int
forall a. Enum a => a -> Int
fromEnum SectionFlag
flag :: Exp Int
    Exp Int
b Exp Int -> Exp Int -> Exp Bool
forall a. Exp a -> Exp a -> Exp Bool
%== (Value Int -> Exp Int
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Val -> Value Int
forall ty. Val -> Value ty
Value (Val -> Value Int) -> Val -> Value Int
forall a b. (a -> b) -> a -> b
$ Var -> Val
val Var
v) Exp Int -> Exp Int -> Exp Int
forall a. Bits a => a -> a -> a
.&. Exp Int
b)

sectionSet :: SectionId -> SectionFlag -> Exp Bool -> Action ()
sectionSet :: SectionId -> SectionFlag -> Exp Bool -> Action ()
sectionSet SectionId
sec SectionFlag
flag Exp Bool
set = do
    Var
v <- Action Var
var
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ SectionId -> Var -> NSIS
SectionGetFlags SectionId
sec Var
v
    Exp Int
v <- Exp Int -> Action (Exp Int)
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value Int -> Exp Int
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value Int -> Exp Int) -> Value Int -> Exp Int
forall a b. (a -> b) -> a -> b
$ Val -> Value Int
forall ty. Val -> Value ty
Value (Val -> Value Int) -> Val -> Value Int
forall a b. (a -> b) -> a -> b
$ Var -> Val
val Var
v :: Exp Int)
    Exp Bool -> Action () -> Action () -> Action ()
iff Exp Bool
set
        ((Val -> NSIS) -> Exp Int -> Action ()
forall a. (Val -> NSIS) -> Exp a -> Action ()
emit1 (SectionId -> Val -> NSIS
SectionSetFlags SectionId
sec) (Exp Int -> Action ()) -> Exp Int -> Action ()
forall a b. (a -> b) -> a -> b
$ Exp Int -> Int -> Exp Int
forall a. Bits a => a -> Int -> a
setBit   Exp Int
v (SectionFlag -> Int
forall a. Enum a => a -> Int
fromEnum SectionFlag
flag))
        ((Val -> NSIS) -> Exp Int -> Action ()
forall a. (Val -> NSIS) -> Exp a -> Action ()
emit1 (SectionId -> Val -> NSIS
SectionSetFlags SectionId
sec) (Exp Int -> Action ()) -> Exp Int -> Action ()
forall a b. (a -> b) -> a -> b
$ Exp Int -> Int -> Exp Int
forall a. Bits a => a -> Int -> a
clearBit Exp Int
v (SectionFlag -> Int
forall a. Enum a => a -> Int
fromEnum SectionFlag
flag))


-- don't want to accidentally dupe the message box, so make it in Action Exp
messageBox :: [MessageBoxType] -> Exp String -> Action (Exp String)
messageBox :: [MessageBoxType] -> Exp String -> Action (Exp String)
messageBox [MessageBoxType]
ty Exp String
x = do
    let a
a* :: a -> String -> (a, [String])
*String
b = (a
a, String -> [String]
words String
b)
    let alts :: [(MessageBoxType, [String])]
alts = [MessageBoxType
MB_OK MessageBoxType -> String -> (MessageBoxType, [String])
forall {a}. a -> String -> (a, [String])
* String
"OK"
               ,MessageBoxType
MB_OKCANCEL MessageBoxType -> String -> (MessageBoxType, [String])
forall {a}. a -> String -> (a, [String])
* String
"OK CANCEL"
               ,MessageBoxType
MB_ABORTRETRYIGNORE MessageBoxType -> String -> (MessageBoxType, [String])
forall {a}. a -> String -> (a, [String])
* String
"ABORT RETRY IGNORE"
               ,MessageBoxType
MB_RETRYCANCEL MessageBoxType -> String -> (MessageBoxType, [String])
forall {a}. a -> String -> (a, [String])
* String
"RETRY CANCEL"
               ,MessageBoxType
MB_YESNO MessageBoxType -> String -> (MessageBoxType, [String])
forall {a}. a -> String -> (a, [String])
* String
"YES NO"
               ,MessageBoxType
MB_YESNOCANCEL MessageBoxType -> String -> (MessageBoxType, [String])
forall {a}. a -> String -> (a, [String])
* String
"YES NO CANCEL"]
    let ([MessageBoxType]
btns,[MessageBoxType]
rest) = (MessageBoxType -> Bool)
-> [MessageBoxType] -> ([MessageBoxType], [MessageBoxType])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (MessageBoxType -> [MessageBoxType] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ((MessageBoxType, [String]) -> MessageBoxType)
-> [(MessageBoxType, [String])] -> [MessageBoxType]
forall a b. (a -> b) -> [a] -> [b]
map (MessageBoxType, [String]) -> MessageBoxType
forall a b. (a, b) -> a
fst [(MessageBoxType, [String])]
alts) [MessageBoxType]
ty
    let btn :: MessageBoxType
btn = [MessageBoxType] -> MessageBoxType
forall a. HasCallStack => [a] -> a
last ([MessageBoxType] -> MessageBoxType)
-> [MessageBoxType] -> MessageBoxType
forall a b. (a -> b) -> a -> b
$ MessageBoxType
MB_OK MessageBoxType -> [MessageBoxType] -> [MessageBoxType]
forall a. a -> [a] -> [a]
: [MessageBoxType]
btns
    let alt :: [String]
alt = Maybe [String] -> [String]
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe [String] -> [String]) -> Maybe [String] -> [String]
forall a b. (a -> b) -> a -> b
$ MessageBoxType -> [(MessageBoxType, [String])] -> Maybe [String]
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup MessageBoxType
btn [(MessageBoxType, [String])]
alts

    Label
end <- Action Label
newLabel
    [Label]
lbls <- Int -> Action Label -> Action [Label]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM ([String] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
alt) Action Label
newLabel
    Exp String
v <- Exp String -> Action (Exp String)
forall t. Exp t -> Action (Exp t)
mutable_ Exp String
""
    Value Val
x <- Exp String
x
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ [MessageBoxType] -> Val -> [(String, Label)] -> NSIS
MessageBox (MessageBoxType
btnMessageBoxType -> [MessageBoxType] -> [MessageBoxType]
forall a. a -> [a] -> [a]
:[MessageBoxType]
rest) Val
x ([(String, Label)] -> NSIS) -> [(String, Label)] -> NSIS
forall a b. (a -> b) -> a -> b
$ [String] -> [Label] -> [(String, Label)]
forall a b. [a] -> [b] -> [(a, b)]
zip [String]
alt [Label]
lbls
    [(String, Label)] -> ((String, Label) -> Action ()) -> Action ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ ([String] -> [Label] -> [(String, Label)]
forall a b. [a] -> [b] -> [(a, b)]
zip [String]
alt [Label]
lbls) (((String, Label) -> Action ()) -> Action ())
-> ((String, Label) -> Action ()) -> Action ()
forall a b. (a -> b) -> a -> b
$ \(String
a,Label
l) -> do
        Label -> Action ()
label Label
l
        Exp String
v Exp String -> Exp String -> Action ()
forall t. Exp t -> Exp t -> Action ()
@= String -> Exp String
forall a. IsString a => String -> a
fromString String
a
        Label -> Action ()
goto Label
end
    Label -> Action ()
label Label
end
    Exp String -> Action (Exp String)
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return Exp String
v

writeRegStr :: HKEY -> Exp String -> Exp String -> Exp String -> Action ()
writeRegStr :: HKEY -> Exp String -> Exp String -> Exp String -> Action ()
writeRegStr HKEY
k = (Val -> Val -> Val -> NSIS)
-> Exp String -> Exp String -> Exp String -> Action ()
forall a b c.
(Val -> Val -> Val -> NSIS) -> Exp a -> Exp b -> Exp c -> Action ()
emit3 ((Val -> Val -> Val -> NSIS)
 -> Exp String -> Exp String -> Exp String -> Action ())
-> (Val -> Val -> Val -> NSIS)
-> Exp String
-> Exp String
-> Exp String
-> Action ()
forall a b. (a -> b) -> a -> b
$ HKEY -> Val -> Val -> Val -> NSIS
WriteRegStr HKEY
k

writeRegExpandStr :: HKEY -> Exp String -> Exp String -> Exp String -> Action ()
writeRegExpandStr :: HKEY -> Exp String -> Exp String -> Exp String -> Action ()
writeRegExpandStr HKEY
k = (Val -> Val -> Val -> NSIS)
-> Exp String -> Exp String -> Exp String -> Action ()
forall a b c.
(Val -> Val -> Val -> NSIS) -> Exp a -> Exp b -> Exp c -> Action ()
emit3 ((Val -> Val -> Val -> NSIS)
 -> Exp String -> Exp String -> Exp String -> Action ())
-> (Val -> Val -> Val -> NSIS)
-> Exp String
-> Exp String
-> Exp String
-> Action ()
forall a b. (a -> b) -> a -> b
$ HKEY -> Val -> Val -> Val -> NSIS
WriteRegExpandStr HKEY
k

writeRegDWORD :: HKEY -> Exp String -> Exp String -> Exp Int -> Action ()
writeRegDWORD :: HKEY -> Exp String -> Exp String -> Exp Int -> Action ()
writeRegDWORD HKEY
k = (Val -> Val -> Val -> NSIS)
-> Exp String -> Exp String -> Exp Int -> Action ()
forall a b c.
(Val -> Val -> Val -> NSIS) -> Exp a -> Exp b -> Exp c -> Action ()
emit3 ((Val -> Val -> Val -> NSIS)
 -> Exp String -> Exp String -> Exp Int -> Action ())
-> (Val -> Val -> Val -> NSIS)
-> Exp String
-> Exp String
-> Exp Int
-> Action ()
forall a b. (a -> b) -> a -> b
$ HKEY -> Val -> Val -> Val -> NSIS
WriteRegDWORD HKEY
k

writeRegMultiStr :: HKEY -> Exp String -> Exp String -> Exp String -> Action ()
writeRegMultiStr :: HKEY -> Exp String -> Exp String -> Exp String -> Action ()
writeRegMultiStr HKEY
k = (Val -> Val -> Val -> NSIS)
-> Exp String -> Exp String -> Exp String -> Action ()
forall a b c.
(Val -> Val -> Val -> NSIS) -> Exp a -> Exp b -> Exp c -> Action ()
emit3 ((Val -> Val -> Val -> NSIS)
 -> Exp String -> Exp String -> Exp String -> Action ())
-> (Val -> Val -> Val -> NSIS)
-> Exp String
-> Exp String
-> Exp String
-> Action ()
forall a b. (a -> b) -> a -> b
$ HKEY -> Val -> Val -> Val -> NSIS
WriteRegMultiStr HKEY
k

-- | While the action is executing, do not update the progress bar.
--   Useful for functions which do a large amount of computation, or have loops.
hideProgress :: Action a -> Action a
hideProgress :: forall a. Action a -> Action a
hideProgress Action a
act = do
    Fun
fun <- (Int -> Fun) -> Action Int -> Action Fun
forall a b. (a -> b) -> Action a -> Action b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> Fun
newFun Action Int
unique
    ([NSIS]
xs, a
v) <- Action a -> Action ([NSIS], a)
forall a. Action a -> Action ([NSIS], a)
capture Action a
act
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Fun -> [NSIS] -> NSIS
Function Fun
fun [NSIS]
xs
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Fun -> NSIS
Call Fun
fun
    a -> Action a
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return a
v

-- | Sleep time in milliseconds
sleep :: Exp Int -> Action ()
sleep :: Exp Int -> Action ()
sleep = (Val -> NSIS) -> Exp Int -> Action ()
forall a. (Val -> NSIS) -> Exp a -> Action ()
emit1 Val -> NSIS
Sleep

-- | Create a function, useful for registering actions
event :: String -> Action () -> Action ()
event :: String -> Action () -> Action ()
event String
name Action ()
act = do
    ([NSIS]
xs, ()
_) <- Action () -> Action ([NSIS], ())
forall a. Action a -> Action ([NSIS], a)
capture Action ()
act
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Fun -> [NSIS] -> NSIS
Function (String -> Fun
Fun String
name) [NSIS]
xs

onSelChange :: Action () -> Action ()
onSelChange :: Action () -> Action ()
onSelChange = String -> Action () -> Action ()
event String
".onSelChange"

onPageShow, onPagePre, onPageLeave :: Page -> Action () -> Action ()
-- these names are special and bound by Show
onPageShow :: Page -> Action () -> Action ()
onPageShow  Page
p = String -> Action () -> Action ()
event (String -> Action () -> Action ())
-> String -> Action () -> Action ()
forall a b. (a -> b) -> a -> b
$ String
"Show" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Page -> String
showPageCtor Page
p
onPagePre :: Page -> Action () -> Action ()
onPagePre   Page
p = String -> Action () -> Action ()
event (String -> Action () -> Action ())
-> String -> Action () -> Action ()
forall a b. (a -> b) -> a -> b
$ String
"Pre" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Page -> String
showPageCtor Page
p
onPageLeave :: Page -> Action () -> Action ()
onPageLeave Page
p = String -> Action () -> Action ()
event (String -> Action () -> Action ())
-> String -> Action () -> Action ()
forall a b. (a -> b) -> a -> b
$ String
"Show" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Page -> String
showPageCtor Page
p

allowRootDirInstall :: Bool -> Action ()
allowRootDirInstall :: Bool -> Action ()
allowRootDirInstall = NSIS -> Action ()
emit (NSIS -> Action ()) -> (Bool -> NSIS) -> Bool -> Action ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> NSIS
AllowRootDirInstall

caption :: Exp String -> Action ()
caption :: Exp String -> Action ()
caption = (Val -> NSIS) -> Exp String -> Action ()
forall a. (Val -> NSIS) -> Exp a -> Action ()
emit1 Val -> NSIS
Caption

detailPrint :: Exp String -> Action ()
detailPrint :: Exp String -> Action ()
detailPrint = (Val -> NSIS) -> Exp String -> Action ()
forall a. (Val -> NSIS) -> Exp a -> Action ()
emit1 Val -> NSIS
DetailPrint

setDetailsPrint :: DetailsPrint -> Action ()
setDetailsPrint :: DetailsPrint -> Action ()
setDetailsPrint = NSIS -> Action ()
emit (NSIS -> Action ())
-> (DetailsPrint -> NSIS) -> DetailsPrint -> Action ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DetailsPrint -> NSIS
SetDetailsPrint

showInstDetails :: Visibility -> Action ()
showInstDetails :: Visibility -> Action ()
showInstDetails = NSIS -> Action ()
emit (NSIS -> Action ())
-> (Visibility -> NSIS) -> Visibility -> Action ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Visibility -> NSIS
ShowInstDetails

showUninstDetails :: Visibility -> Action ()
showUninstDetails :: Visibility -> Action ()
showUninstDetails = NSIS -> Action ()
emit (NSIS -> Action ())
-> (Visibility -> NSIS) -> Visibility -> Action ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Visibility -> NSIS
ShowUninstDetails

-- | Note: Requires NSIS 3.0
unicode :: Bool -> Action ()
unicode :: Bool -> Action ()
unicode = NSIS -> Action ()
emit (NSIS -> Action ()) -> (Bool -> NSIS) -> Bool -> Action ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> NSIS
Unicode

-- | The type of a file handle, created by 'fileOpen'.
data FileHandle deriving Typeable

-- | Open a file, which must be closed explicitly with 'fileClose'.
--   Often it is better to use 'Development.NSIS.Sugar.writeFile'' or
--   'Development.NSIS.Sugar.withFile' instead.
--
-- @
-- h <- 'fileOpen' 'ModeWrite' \"C:/log.txt\"
-- 'fileWrite' h \"Hello world!\"
-- 'fileClose' h
-- @
fileOpen :: FileMode -> Exp FilePath -> Action (Exp FileHandle)
fileOpen :: FileMode -> Exp String -> Action (Exp FileHandle)
fileOpen FileMode
mode Exp String
name = do
    Value Val
name <- Exp String
name
    Var
v <- Action Var
var
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Var -> Val -> FileMode -> NSIS
FileOpen Var
v Val
name FileMode
mode
    Exp FileHandle -> Action (Exp FileHandle)
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Exp FileHandle -> Action (Exp FileHandle))
-> Exp FileHandle -> Action (Exp FileHandle)
forall a b. (a -> b) -> a -> b
$ Value FileHandle -> Exp FileHandle
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value FileHandle -> Exp FileHandle)
-> Value FileHandle -> Exp FileHandle
forall a b. (a -> b) -> a -> b
$ Val -> Value FileHandle
forall ty. Val -> Value ty
Value (Val -> Value FileHandle) -> Val -> Value FileHandle
forall a b. (a -> b) -> a -> b
$ Var -> Val
val Var
v

-- | Write a string to a file openned with 'fileOpen'.
fileWrite :: Exp FileHandle -> Exp String -> Action ()
fileWrite :: Exp FileHandle -> Exp String -> Action ()
fileWrite = (Val -> Val -> NSIS) -> Exp FileHandle -> Exp String -> Action ()
forall a b. (Val -> Val -> NSIS) -> Exp a -> Exp b -> Action ()
emit2 Val -> Val -> NSIS
FileWrite

-- | Close a file file openned with 'fileOpen'.
fileClose :: Exp FileHandle -> Action ()
fileClose :: Exp FileHandle -> Action ()
fileClose = (Val -> NSIS) -> Exp FileHandle -> Action ()
forall a. (Val -> NSIS) -> Exp a -> Action ()
emit1 Val -> NSIS
FileClose

setCompressor :: Compressor -> [Attrib] -> Action ()
setCompressor :: Compressor -> [Attrib] -> Action ()
setCompressor Compressor
x [Attrib]
as = NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ ACompressor -> NSIS
SetCompressor (ACompressor -> NSIS) -> ACompressor -> NSIS
forall a b. (a -> b) -> a -> b
$ (ACompressor -> Attrib -> ACompressor)
-> ACompressor -> [Attrib] -> ACompressor
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl ACompressor -> Attrib -> ACompressor
f ACompressor
forall a. Default a => a
def{compType=x} [Attrib]
as
    where
        f :: ACompressor -> Attrib -> ACompressor
f ACompressor
c Attrib
Final = ACompressor
c{compFinal=True}
        f ACompressor
c Attrib
Solid = ACompressor
c{compSolid=True}
        f ACompressor
c Attrib
x = String -> ACompressor
forall a. HasCallStack => String -> a
error (String -> ACompressor) -> String -> ACompressor
forall a b. (a -> b) -> a -> b
$ String
"Invalid attribute to setCompress: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Attrib -> String
forall a. Show a => a -> String
show Attrib
x

file :: [Attrib] -> Exp FilePath -> Action ()
file :: [Attrib] -> Exp String -> Action ()
file [Attrib]
as Exp String
x = do Value Val
x <- Exp String
x; NSIS -> Action ()
emit (NSIS -> Action ()) -> (AFile -> NSIS) -> AFile -> Action ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AFile -> NSIS
File (AFile -> Action ()) -> Action AFile -> Action ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (AFile -> Attrib -> Action AFile)
-> AFile -> [Attrib] -> Action AFile
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM AFile -> Attrib -> Action AFile
f AFile
forall a. Default a => a
def{filePath=x} [Attrib]
as
    where
        f :: AFile -> Attrib -> Action AFile
f AFile
c Attrib
Recursive = AFile -> Action AFile
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return AFile
c{fileRecursive=True}
        f AFile
c Attrib
NonFatal = AFile -> Action AFile
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return AFile
c{fileNonFatal=True}
        f AFile
c (OName Exp String
x) = do Value Val
x <- Exp String
x; AFile -> Action AFile
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return AFile
c{fileOName=Just x}
        f AFile
c Attrib
x = String -> Action AFile
forall a. HasCallStack => String -> a
error (String -> Action AFile) -> String -> Action AFile
forall a b. (a -> b) -> a -> b
$ String
"Invalid attribute to file: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Attrib -> String
forall a. Show a => a -> String
show Attrib
x

section :: Exp String -> [Attrib] -> Action () -> Action SectionId
section :: Exp String -> [Attrib] -> Action () -> Action SectionId
section Exp String
name [Attrib]
as Action ()
act = do
    SectionId
sec <- Action SectionId
newSectionId
    Value Val
name <- Exp String
name
    ([NSIS]
xs, ()
_) <- Action () -> Action ([NSIS], ())
forall a. Action a -> Action ([NSIS], a)
capture (Action () -> Action ([NSIS], ()))
-> Action () -> Action ([NSIS], ())
forall a b. (a -> b) -> a -> b
$ Action () -> Action ()
forall a. Action a -> Action a
scope Action ()
act
    ASection
x <- (ASection -> Attrib -> Action ASection)
-> ASection -> [Attrib] -> Action ASection
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM ASection -> Attrib -> Action ASection
f ASection
forall a. Default a => a
def{secId=sec, secName=name} [Attrib]
as
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ ASection -> [NSIS] -> NSIS
Section ASection
x [NSIS]
xs
    SectionId -> Action SectionId
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (SectionId -> Action SectionId) -> SectionId -> Action SectionId
forall a b. (a -> b) -> a -> b
$ ASection -> SectionId
secId ASection
x
    where
        f :: ASection -> Attrib -> Action ASection
f ASection
c Attrib
Unselected = ASection -> Action ASection
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return ASection
c{secUnselected=True}
        f ASection
c Attrib
Required = ASection -> Action ASection
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return ASection
c{secRequired=True}
        f ASection
c (Description Exp String
x) = do Value Val
x <- Exp String
x; ASection -> Action ASection
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return ASection
c{secDescription=x}
        f ASection
c (Id SectionId
x) = ASection -> Action ASection
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return ASection
c{secId=x}
        f ASection
c Attrib
x = String -> Action ASection
forall a. HasCallStack => String -> a
error (String -> Action ASection) -> String -> Action ASection
forall a b. (a -> b) -> a -> b
$ String
"Invalid attribute to section: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Attrib -> String
forall a. Show a => a -> String
show Attrib
x

sectionGroup :: Exp String -> [Attrib] -> Action () -> Action SectionId
sectionGroup :: Exp String -> [Attrib] -> Action () -> Action SectionId
sectionGroup Exp String
name [Attrib]
as Action ()
act = do
    SectionId
sec <- Action SectionId
newSectionId
    Value Val
name <- Exp String
name
    ([NSIS]
xs, ()
_) <- Action () -> Action ([NSIS], ())
forall a. Action a -> Action ([NSIS], a)
capture (Action () -> Action ([NSIS], ()))
-> Action () -> Action ([NSIS], ())
forall a b. (a -> b) -> a -> b
$ Action () -> Action ()
forall a. Action a -> Action a
scope Action ()
act
    ASectionGroup
x <- (ASectionGroup -> Attrib -> Action ASectionGroup)
-> ASectionGroup -> [Attrib] -> Action ASectionGroup
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM ASectionGroup -> Attrib -> Action ASectionGroup
f ASectionGroup
forall a. Default a => a
def{secgId=sec, secgName=name} [Attrib]
as
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ ASectionGroup -> [NSIS] -> NSIS
SectionGroup ASectionGroup
x [NSIS]
xs
    SectionId -> Action SectionId
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (SectionId -> Action SectionId) -> SectionId -> Action SectionId
forall a b. (a -> b) -> a -> b
$ ASectionGroup -> SectionId
secgId ASectionGroup
x
    where
        f :: ASectionGroup -> Attrib -> Action ASectionGroup
f ASectionGroup
c Attrib
Expanded = ASectionGroup -> Action ASectionGroup
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return ASectionGroup
c{secgExpanded=True}
        f ASectionGroup
c (Description Exp String
x) = do Value Val
x <- Exp String
x; ASectionGroup -> Action ASectionGroup
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return ASectionGroup
c{secgDescription=x}
        f ASectionGroup
c (Id SectionId
x) = ASectionGroup -> Action ASectionGroup
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return ASectionGroup
c{secgId=x}
        f ASectionGroup
c Attrib
x = String -> Action ASectionGroup
forall a. HasCallStack => String -> a
error (String -> Action ASectionGroup) -> String -> Action ASectionGroup
forall a b. (a -> b) -> a -> b
$ String
"Invalid attribute to sectionGroup: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Attrib -> String
forall a. Show a => a -> String
show Attrib
x

uninstall :: Action () -> Action ()
uninstall :: Action () -> Action ()
uninstall = Action SectionId -> Action ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Action SectionId -> Action ())
-> (Action () -> Action SectionId) -> Action () -> Action ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Exp String -> [Attrib] -> Action () -> Action SectionId
section Exp String
"Uninstall" []

-- | Delete file (which can be a file or wildcard, but should be specified with a full path) from the target system.
--   If 'RebootOK' is specified and the file cannot be deleted then the file is deleted when the system reboots --
--   if the file will be deleted on a reboot, the reboot flag will be set. The error flag is set if files are found
--   and cannot be deleted. The error flag is not set from trying to delete a file that does not exist.
--
-- > delete [] "$INSTDIR/somefile.dat"
delete :: [Attrib] -> Exp FilePath -> Action ()
delete :: [Attrib] -> Exp String -> Action ()
delete [Attrib]
as Exp String
x = do
    Value Val
x <- Exp String
x
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ ADelete -> NSIS
Delete (ADelete -> NSIS) -> ADelete -> NSIS
forall a b. (a -> b) -> a -> b
$ (ADelete -> Attrib -> ADelete) -> ADelete -> [Attrib] -> ADelete
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl ADelete -> Attrib -> ADelete
f ADelete
forall a. Default a => a
def{delFile=x} [Attrib]
as
    where
        f :: ADelete -> Attrib -> ADelete
f ADelete
c Attrib
RebootOK = ADelete
c{delRebootOK=True}
        f ADelete
c Attrib
x = String -> ADelete
forall a. HasCallStack => String -> a
error (String -> ADelete) -> String -> ADelete
forall a b. (a -> b) -> a -> b
$ String
"Invalid attribute to delete: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Attrib -> String
forall a. Show a => a -> String
show Attrib
x

-- | Remove the specified directory (fully qualified path with no wildcards). Without 'Recursive',
--   the directory will only be removed if it is completely empty. If 'Recursive' is specified, the
--   directory will be removed recursively, so all directories and files in the specified directory
--   will be removed. If 'RebootOK' is specified, any file or directory which could not have been
--   removed during the process will be removed on reboot -- if any file or directory will be
--   removed on a reboot, the reboot flag will be set.
--   The error flag is set if any file or directory cannot be removed.
--
-- > rmdir [] "$INSTDIR"
-- > rmdir [] "$INSTDIR/data"
-- > rmdir [Recursive, RebootOK] "$INSTDIR"
-- > rmdir [RebootOK] "$INSTDIR/DLLs"
--
--   Note that the current working directory can not be deleted. The current working directory is
--   set by 'setOutPath'. For example, the following example will not delete the directory.
--
-- > setOutPath "$TEMP/dir"
-- > rmdir [] "$TEMP/dir"
--
--   The next example will succeed in deleting the directory.
--
-- > setOutPath "$TEMP/dir"
-- > setOutPath "$TEMP"
-- > rmdir [] "$TEMP/dir"
--
--   Warning: using @rmdir [Recursive] "$INSTDIR"@ in 'uninstall' is not safe. Though it is unlikely,
--   the user might select to install to the Program Files folder and so this command will wipe out
--   the entire Program Files folder, including other programs that has nothing to do with the uninstaller.
--   The user can also put other files but the program's files and would expect them to get deleted with
--   the program. Solutions are available for easily uninstalling only files which were installed by the installer.
rmdir :: [Attrib] -> Exp FilePath -> Action ()
rmdir :: [Attrib] -> Exp String -> Action ()
rmdir [Attrib]
as Exp String
x = do
    Value Val
x <- Exp String
x
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ ARMDir -> NSIS
RMDir (ARMDir -> NSIS) -> ARMDir -> NSIS
forall a b. (a -> b) -> a -> b
$ (ARMDir -> Attrib -> ARMDir) -> ARMDir -> [Attrib] -> ARMDir
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl ARMDir -> Attrib -> ARMDir
f ARMDir
forall a. Default a => a
def{rmDir=x} [Attrib]
as
    where
        f :: ARMDir -> Attrib -> ARMDir
f ARMDir
c Attrib
RebootOK = ARMDir
c{rmRebootOK=True}
        f ARMDir
c Attrib
Recursive = ARMDir
c{rmRecursive=True}
        f ARMDir
c Attrib
x = String -> ARMDir
forall a. HasCallStack => String -> a
error (String -> ARMDir) -> String -> ARMDir
forall a b. (a -> b) -> a -> b
$ String
"Invalid attribute to rmdir: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Attrib -> String
forall a. Show a => a -> String
show Attrib
x

-- | Both file paths are on the installing system. Do not use relative paths.
copyFiles :: [Attrib] -> Exp FilePath -> Exp FilePath -> Action ()
copyFiles :: [Attrib] -> Exp String -> Exp String -> Action ()
copyFiles [Attrib]
as Exp String
from Exp String
to = do
    Value Val
from <- Exp String
from
    Value Val
to <- Exp String
to
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ ACopyFiles -> NSIS
CopyFiles (ACopyFiles -> NSIS) -> ACopyFiles -> NSIS
forall a b. (a -> b) -> a -> b
$ (ACopyFiles -> Attrib -> ACopyFiles)
-> ACopyFiles -> [Attrib] -> ACopyFiles
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl ACopyFiles -> Attrib -> ACopyFiles
f ACopyFiles
forall a. Default a => a
def{cpFrom=from, cpTo=to} [Attrib]
as
    where
        f :: ACopyFiles -> Attrib -> ACopyFiles
f ACopyFiles
c Attrib
Silent = ACopyFiles
c{cpSilent=True}
        f ACopyFiles
c Attrib
FilesOnly = ACopyFiles
c{cpFilesOnly=True}
        f ACopyFiles
c Attrib
x = String -> ACopyFiles
forall a. HasCallStack => String -> a
error (String -> ACopyFiles) -> String -> ACopyFiles
forall a b. (a -> b) -> a -> b
$ String
"Invalid attribute to copyFiles: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Attrib -> String
forall a. Show a => a -> String
show Attrib
x

-- | Creates a shortcut file that links to a 'Traget' file, with optional 'Parameters'. The icon used for the shortcut
--   is 'IconFile','IconIndex'. 'StartOptions' should be one of: SW_SHOWNORMAL, SW_SHOWMAXIMIZED, SW_SHOWMINIMIZED.
--   'KeyboardShortcut' should be in the form of 'flag|c' where flag can be a combination (using |) of: ALT, CONTROL, EXT, or SHIFT.
--   c is the character to use (a-z, A-Z, 0-9, F1-F24, etc). Note that no spaces are allowed in this string. A good example is
--   \"ALT|CONTROL|F8\". @$OUTDIR@ is used for the working directory. You can change it by using 'setOutPath' before creating
--   the Shortcut. 'Description' should be the description of the shortcut, or comment as it is called under XP.
--   The error flag is set if the shortcut cannot be created (i.e. either of the paths (link or target) does not exist, or some other error).
--
-- > createDirectory "$SMPROGRAMS/My Company"
-- > createShortcut "$SMPROGRAMS/My Company/My Program.lnk"
-- >    [Target "$INSTDIR/My Program.exe"
-- >    ,Parameters "some command line parameters"
-- >    ,IconFile "$INSTDIR/My Program.exe", IconIndex 2
-- >    ,StartOptions "SW_SHOWNORMAL"
-- >    ,KeyboardShortcut "ALT|CONTROL|SHIFT|F5"
-- >    ,Description "a description"]
createShortcut :: Exp FilePath -> [Attrib] -> Action ()
createShortcut :: Exp String -> [Attrib] -> Action ()
createShortcut Exp String
name [Attrib]
as = do Value Val
name <- Exp String
name; AShortcut
x <- (AShortcut -> Attrib -> Action AShortcut)
-> AShortcut -> [Attrib] -> Action AShortcut
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM AShortcut -> Attrib -> Action AShortcut
f AShortcut
forall a. Default a => a
def{scFile=name} [Attrib]
as; NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ AShortcut -> NSIS
CreateShortcut AShortcut
x
    where
        f :: AShortcut -> Attrib -> Action AShortcut
f AShortcut
c (Target Exp String
x) = do Value Val
x <- Exp String
x; AShortcut -> Action AShortcut
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return AShortcut
c{scTarget=x}
        f AShortcut
c (Parameters Exp String
x) = do Value Val
x <- Exp String
x; AShortcut -> Action AShortcut
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return AShortcut
c{scParameters=x}
        f AShortcut
c (IconFile Exp String
x) = do Value Val
x <- Exp String
x; AShortcut -> Action AShortcut
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return AShortcut
c{scIconFile=x}
        f AShortcut
c (IconIndex Exp Int
x) = do Value Val
x <- Exp Int
x; AShortcut -> Action AShortcut
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return AShortcut
c{scIconIndex=x}
        f AShortcut
c (StartOptions String
x) = AShortcut -> Action AShortcut
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return AShortcut
c{scStartOptions=x}
        f AShortcut
c (KeyboardShortcut String
x) = AShortcut -> Action AShortcut
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return AShortcut
c{scKeyboardShortcut=x}
        f AShortcut
c (Description Exp String
x) = do Value Val
x <- Exp String
x; AShortcut -> Action AShortcut
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return AShortcut
c{scDescription=x}
        f AShortcut
c Attrib
x = String -> Action AShortcut
forall a. HasCallStack => String -> a
error (String -> Action AShortcut) -> String -> Action AShortcut
forall a b. (a -> b) -> a -> b
$ String
"Invalid attribute to shortcut: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Attrib -> String
forall a. Show a => a -> String
show Attrib
x


page :: Page -> Action ()
page :: Page -> Action ()
page = NSIS -> Action ()
emit (NSIS -> Action ()) -> (Page -> NSIS) -> Page -> Action ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Page -> NSIS
Page

finishOptions :: FinishOptions
finishOptions :: FinishOptions
finishOptions = FinishOptions
forall a. Default a => a
def

unpage :: Page -> Action ()
unpage :: Page -> Action ()
unpage = NSIS -> Action ()
emit (NSIS -> Action ()) -> (Page -> NSIS) -> Page -> Action ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Page -> NSIS
Unpage

requestExecutionLevel :: Level -> Action ()
requestExecutionLevel :: Level -> Action ()
requestExecutionLevel = NSIS -> Action ()
emit (NSIS -> Action ()) -> (Level -> NSIS) -> Level -> Action ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Level -> NSIS
RequestExecutionLevel

target :: Type.Target -> Action ()
target :: Target -> Action ()
target = NSIS -> Action ()
emit (NSIS -> Action ()) -> (Target -> NSIS) -> Target -> Action ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Target -> NSIS
Type.Target

type HWND = Exp Int

hwndParent :: HWND
hwndParent :: Exp Int
hwndParent = Value Int -> Exp Int
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value Int -> Exp Int) -> Value Int -> Exp Int
forall a b. (a -> b) -> a -> b
$ Val -> Value Int
forall ty. Val -> Value ty
Value [String -> Val_
Builtin String
"HWNDPARENT"]

findWindow :: Exp String -> Exp String -> Maybe HWND -> Action HWND
findWindow :: Exp String -> Exp String -> Maybe (Exp Int) -> Action (Exp Int)
findWindow Exp String
a Exp String
b Maybe (Exp Int)
c = do
    Var
v <- Action Var
var
    Value Val
a <- Exp String
a
    Value Val
b <- Exp String
b
    Maybe Val
c <- Action (Maybe Val)
-> (Exp Int -> Action (Maybe Val))
-> Maybe (Exp Int)
-> Action (Maybe Val)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Maybe Val -> Action (Maybe Val)
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Val
forall a. Maybe a
Nothing) ((Value Int -> Maybe Val) -> Exp Int -> Action (Maybe Val)
forall a b. (a -> b) -> Action a -> Action b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Val -> Maybe Val
forall a. a -> Maybe a
Just (Val -> Maybe Val) -> (Value Int -> Val) -> Value Int -> Maybe Val
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value Int -> Val
forall ty. Value ty -> Val
fromValue)) Maybe (Exp Int)
c
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Var -> Val -> Val -> Maybe Val -> Maybe Val -> NSIS
FindWindow Var
v Val
a Val
b Maybe Val
c Maybe Val
forall a. Maybe a
Nothing
    Exp Int -> Action (Exp Int)
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Exp Int -> Action (Exp Int)) -> Exp Int -> Action (Exp Int)
forall a b. (a -> b) -> a -> b
$ Value Int -> Exp Int
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value Int -> Exp Int) -> Value Int -> Exp Int
forall a b. (a -> b) -> a -> b
$ Val -> Value Int
forall ty. Val -> Value ty
Value (Val -> Value Int) -> Val -> Value Int
forall a b. (a -> b) -> a -> b
$ Var -> Val
val Var
v

getDlgItem :: HWND -> Exp Int -> Action HWND
getDlgItem :: Exp Int -> Exp Int -> Action (Exp Int)
getDlgItem Exp Int
a Exp Int
b = do
    Var
v <- Action Var
var
    Value Val
a <- Exp Int
a
    Value Val
b <- Exp Int
b
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Var -> Val -> Val -> NSIS
GetDlgItem Var
v Val
a Val
b
    Exp Int -> Action (Exp Int)
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Exp Int -> Action (Exp Int)) -> Exp Int -> Action (Exp Int)
forall a b. (a -> b) -> a -> b
$ Value Int -> Exp Int
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value Int -> Exp Int) -> Value Int -> Exp Int
forall a b. (a -> b) -> a -> b
$ Val -> Value Int
forall ty. Val -> Value ty
Value (Val -> Value Int) -> Val -> Value Int
forall a b. (a -> b) -> a -> b
$ Var -> Val
val Var
v

sendMessage :: [Attrib] -> HWND -> Exp Int -> Exp a -> Exp b -> Action (Exp Int)
sendMessage :: forall a b.
[Attrib]
-> Exp Int -> Exp Int -> Exp a -> Exp b -> Action (Exp Int)
sendMessage [Attrib]
as Exp Int
a Exp Int
b Exp a
c Exp b
d = do
    Var
v <- Action Var
var
    Value Val
a <- Exp Int
a
    Value Val
b <- Exp Int
b
    Value Val
c <- Exp a
c
    Value Val
d <- Exp b
d
    Maybe Int
as <- Maybe Int -> Action (Maybe Int)
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Int -> Action (Maybe Int))
-> Maybe Int -> Action (Maybe Int)
forall a b. (a -> b) -> a -> b
$ (Maybe Int -> Attrib -> Maybe Int)
-> Maybe Int -> [Attrib] -> Maybe Int
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl Maybe Int -> Attrib -> Maybe Int
forall {p}. p -> Attrib -> Maybe Int
f Maybe Int
forall a. Maybe a
Nothing [Attrib]
as
    NSIS -> Action ()
emit (NSIS -> Action ()) -> NSIS -> Action ()
forall a b. (a -> b) -> a -> b
$ Val -> Val -> Val -> Val -> Var -> Maybe Int -> NSIS
SendMessage Val
a Val
b Val
c Val
d Var
v Maybe Int
as
    Exp Int -> Action (Exp Int)
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Exp Int -> Action (Exp Int)) -> Exp Int -> Action (Exp Int)
forall a b. (a -> b) -> a -> b
$ Value Int -> Exp Int
forall a. a -> Action a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value Int -> Exp Int) -> Value Int -> Exp Int
forall a b. (a -> b) -> a -> b
$ Val -> Value Int
forall ty. Val -> Value ty
Value (Val -> Value Int) -> Val -> Value Int
forall a b. (a -> b) -> a -> b
$ Var -> Val
val Var
v
    where
        f :: p -> Attrib -> Maybe Int
f p
c (Timeout Int
x) = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
x
        f p
c Attrib
x = String -> Maybe Int
forall a. HasCallStack => String -> a
error (String -> Maybe Int) -> String -> Maybe Int
forall a b. (a -> b) -> a -> b
$ String
"Invalid attribute to sendMessage: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Attrib -> String
forall a. Show a => a -> String
show Attrib
x

abort :: Exp String -> Action ()
abort :: Exp String -> Action ()
abort = (Val -> NSIS) -> Exp String -> Action ()
forall a. (Val -> NSIS) -> Exp a -> Action ()
emit1 Val -> NSIS
Abort

-- | Inject arbitrary text into a non-global section of the script.
unsafeInject :: String -> Action ()
unsafeInject :: String -> Action ()
unsafeInject = NSIS -> Action ()
emit (NSIS -> Action ()) -> (String -> NSIS) -> String -> Action ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> NSIS
UnsafeInject

-- | Inject arbitrary text into the script's global header section.
unsafeInjectGlobal :: String -> Action ()
unsafeInjectGlobal :: String -> Action ()
unsafeInjectGlobal = NSIS -> Action ()
emit (NSIS -> Action ()) -> (String -> NSIS) -> String -> Action ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> NSIS
UnsafeInjectGlobal