{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE MultiWayIf #-}
module GHC.StgToJS.Linker.Utils
( getOptionsFromJsFile
, JSOption(..)
, jsExeFileName
, getInstalledPackageLibDirs
, getInstalledPackageHsLibs
, commonCppDefs
)
where
import System.FilePath
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as Char8
import Data.ByteString (ByteString)
import GHC.Driver.Session
import GHC.Data.ShortText
import GHC.Unit.State
import GHC.Unit.Types
import GHC.StgToJS.Types
import Prelude
import GHC.Platform
import Data.List (isPrefixOf)
import System.IO
import Data.Char (isSpace)
import qualified Control.Exception as Exception
getInstalledPackageLibDirs :: UnitState -> UnitId -> [ShortText]
getInstalledPackageLibDirs :: UnitState -> UnitId -> [ShortText]
getInstalledPackageLibDirs UnitState
us = forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall srcpkgid srcpkgname uid modulename mod.
GenericUnitInfo srcpkgid srcpkgname uid modulename mod
-> [ShortText]
unitLibraryDirs forall b c a. (b -> c) -> (a -> b) -> a -> c
. UnitState -> UnitId -> Maybe UnitInfo
lookupUnitId UnitState
us
getInstalledPackageHsLibs :: UnitState -> UnitId -> [ShortText]
getInstalledPackageHsLibs :: UnitState -> UnitId -> [ShortText]
getInstalledPackageHsLibs UnitState
us = forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall srcpkgid srcpkgname uid modulename mod.
GenericUnitInfo srcpkgid srcpkgname uid modulename mod
-> [ShortText]
unitLibraries forall b c a. (b -> c) -> (a -> b) -> a -> c
. UnitState -> UnitId -> Maybe UnitInfo
lookupUnitId UnitState
us
jsexeExtension :: String
jsexeExtension :: [Char]
jsexeExtension = [Char]
"jsexe"
commonCppDefs :: Bool -> ByteString
commonCppDefs :: Bool -> ByteString
commonCppDefs Bool
profiling = case Bool
profiling of
Bool
True -> ByteString
commonCppDefs_profiled
Bool
False -> ByteString
commonCppDefs_vanilla
commonCppDefs_vanilla, commonCppDefs_profiled :: ByteString
commonCppDefs_vanilla :: ByteString
commonCppDefs_vanilla = Bool -> ByteString
genCommonCppDefs Bool
False
commonCppDefs_profiled :: ByteString
commonCppDefs_profiled = Bool -> ByteString
genCommonCppDefs Bool
True
genCommonCppDefs :: Bool -> ByteString
genCommonCppDefs :: Bool -> ByteString
genCommonCppDefs Bool
profiling = forall a. Monoid a => [a] -> a
mconcat
[
let mk_int_def :: [Char] -> a -> ByteString
mk_int_def [Char]
n a
v = ByteString
"#define " forall a. Semigroup a => a -> a -> a
<> [Char] -> ByteString
Char8.pack [Char]
n forall a. Semigroup a => a -> a -> a
<> ByteString
" (" forall a. Semigroup a => a -> a -> a
<> [Char] -> ByteString
Char8.pack (forall a. Show a => a -> [Char]
show a
v) forall a. Semigroup a => a -> a -> a
<> ByteString
")\n"
mk_closure_def :: ClosureType -> ByteString
mk_closure_def ClosureType
t = forall {a}. Show a => [Char] -> a -> ByteString
mk_int_def (ClosureType -> [Char]
ctJsName ClosureType
t) (ClosureType -> Int
ctNum ClosureType
t)
closure_defs :: [ByteString]
closure_defs = forall a b. (a -> b) -> [a] -> [b]
map ClosureType -> ByteString
mk_closure_def [forall a. Bounded a => a
minBound..forall a. Bounded a => a
maxBound]
mk_thread_def :: ThreadStatus -> ByteString
mk_thread_def ThreadStatus
t = forall {a}. Show a => [Char] -> a -> ByteString
mk_int_def (ThreadStatus -> [Char]
threadStatusJsName ThreadStatus
t) (ThreadStatus -> Int
threadStatusNum ThreadStatus
t)
thread_defs :: [ByteString]
thread_defs = forall a b. (a -> b) -> [a] -> [b]
map ThreadStatus -> ByteString
mk_thread_def [forall a. Bounded a => a
minBound..forall a. Bounded a => a
maxBound]
in forall a. Monoid a => [a] -> a
mconcat ([ByteString]
closure_defs forall a. [a] -> [a] -> [a]
++ [ByteString]
thread_defs)
, if Bool
profiling
then forall a. Monoid a => [a] -> a
mconcat
[ ByteString
"#define MK_TUP2(x1,x2) (h$c2(h$ghczmprimZCGHCziTupleziPrimziZLz2cUZR_con_e,(x1),(x2),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n"
, ByteString
"#define MK_TUP3(x1,x2,x3) (h$c3(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUZR_con_e,(x1),(x2),(x3),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n"
, ByteString
"#define MK_TUP4(x1,x2,x3,x4) (h$c4(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n"
, ByteString
"#define MK_TUP5(x1,x2,x3,x4,x5) (h$c5(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n"
, ByteString
"#define MK_TUP6(x1,x2,x3,x4,x5,x6) (h$c6(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n"
, ByteString
"#define MK_TUP7(x1,x2,x3,x4,x5,x6,x7) (h$c7(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n"
, ByteString
"#define MK_TUP8(x1,x2,x3,x4,x5,x6,x7,x8) (h$c8(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n"
, ByteString
"#define MK_TUP9(x1,x2,x3,x4,x5,x6,x7,x8,x9) (h$c9(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n"
, ByteString
"#define MK_TUP10(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) (h$c10(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9),(x10),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n"
]
else forall a. Monoid a => [a] -> a
mconcat
[ ByteString
"#define MK_TUP2(x1,x2) (h$c2(h$ghczmprimZCGHCziTupleziPrimziZLz2cUZR_con_e,(x1),(x2)))\n"
, ByteString
"#define MK_TUP3(x1,x2,x3) (h$c3(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUZR_con_e,(x1),(x2),(x3)))\n"
, ByteString
"#define MK_TUP4(x1,x2,x3,x4) (h$c4(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4)))\n"
, ByteString
"#define MK_TUP5(x1,x2,x3,x4,x5) (h$c5(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5)))\n"
, ByteString
"#define MK_TUP6(x1,x2,x3,x4,x5,x6) (h$c6(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6)))\n"
, ByteString
"#define MK_TUP7(x1,x2,x3,x4,x5,x6,x7) (h$c7(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7)))\n"
, ByteString
"#define MK_TUP8(x1,x2,x3,x4,x5,x6,x7,x8) (h$c8(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8)))\n"
, ByteString
"#define MK_TUP9(x1,x2,x3,x4,x5,x6,x7,x8,x9) (h$c9(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9)))\n"
, ByteString
"#define MK_TUP10(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) (h$c10(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9),(x10)))\n"
]
, ByteString
"#define TUP2_1(x) ((x).d1)\n"
, ByteString
"#define TUP2_2(x) ((x).d2)\n"
, if Bool
profiling
then ByteString
"#define MK_JSVAL(x) (h$c1(h$baseZCGHCziJSziPrimziJSVal_con_e, (x), h$CCS_SYSTEM))\n"
else ByteString
"#define MK_JSVAL(x) (h$c1(h$baseZCGHCziJSziPrimziJSVal_con_e, (x)))\n"
, ByteString
"#define JSVAL_VAL(x) ((x).d1)\n"
, if Bool
profiling
then ByteString
"#define MK_JSEXCEPTION(msg,hsMsg) (h$c2(h$baseZCGHCziJSziPrimziJSException_con_e,(msg),(hsMsg),h$CCS_SYSTEM))\n"
else ByteString
"#define MK_JSEXCEPTION(msg,hsMsg) (h$c2(h$baseZCGHCziJSziPrimziJSException_con_e,(msg),(hsMsg)))\n"
, ByteString
"#define HS_JSEXCEPTION_EXCEPTION h$baseZCGHCziJSziPrimzizdfExceptionJSException\n"
, if Bool
profiling
then ByteString
"#define MK_SOMEEXCEPTION(dict,except) (h$c2(h$baseZCGHCziExceptionziTypeziSomeException_con_e,(dict),(except),h$CCS_SYSTEM))\n"
else ByteString
"#define MK_SOMEEXCEPTION(dict,except) (h$c2(h$baseZCGHCziExceptionziTypeziSomeException_con_e,(dict),(except)))\n"
, if Bool
profiling
then ByteString
"#define MK_PTR(val,offset) (h$c2(h$baseZCGHCziPtrziPtr_con_e, (val), (offset), h$CCS_SYSTEM))\n"
else ByteString
"#define MK_PTR(val,offset) (h$c2(h$baseZCGHCziPtrziPtr_con_e, (val), (offset)))\n"
, ByteString
"#define HS_NOTHING h$baseZCGHCziMaybeziNothing\n"
, ByteString
"#define IS_NOTHING(cl) ((cl).f === h$baseZCGHCziMaybeziNothing_con_e)\n"
, ByteString
"#define IS_JUST(cl) ((cl).f === h$baseZCGHCziMaybeziJust_con_e)\n"
, ByteString
"#define JUST_VAL(jj) ((jj).d1)\n"
, if Bool
profiling
then ByteString
"#define MK_JUST(val) (h$c1(h$baseZCGHCziMaybeziJust_con_e, (val), h$CCS_SYSTEM))\n"
else ByteString
"#define MK_JUST(val) (h$c1(h$baseZCGHCziMaybeziJust_con_e, (val)))\n"
, ByteString
"#define HS_NIL h$ghczmprimZCGHCziTypesziZMZN\n"
, ByteString
"#define HS_NIL_CON h$ghczmprimZCGHCziTypesziZMZN_con_e\n"
, ByteString
"#define IS_CONS(cl) ((cl).f === h$ghczmprimZCGHCziTypesziZC_con_e)\n"
, ByteString
"#define IS_NIL(cl) ((cl).f === h$ghczmprimZCGHCziTypesziZMZN_con_e)\n"
, ByteString
"#define CONS_HEAD(cl) ((cl).d1)\n"
, ByteString
"#define CONS_TAIL(cl) ((cl).d2)\n"
, if Bool
profiling
then forall a. Monoid a => [a] -> a
mconcat
[ ByteString
"#define MK_CONS(head,tail) (h$c2(h$ghczmprimZCGHCziTypesziZC_con_e, (head), (tail), h$CCS_SYSTEM))\n"
, ByteString
"#define MK_CONS_CC(head,tail,cc) (h$c2(h$ghczmprimZCGHCziTypesziZC_con_e, (head), (tail), (cc)))\n"
]
else forall a. Monoid a => [a] -> a
mconcat
[ ByteString
"#define MK_CONS(head,tail) (h$c2(h$ghczmprimZCGHCziTypesziZC_con_e, (head), (tail)))\n"
, ByteString
"#define MK_CONS_CC(head,tail,cc) (h$c2(h$ghczmprimZCGHCziTypesziZC_con_e, (head), (tail)))\n"
]
, ByteString
"#define DATA_TEXT_ARRAY(x) ((x).d1)\n"
, ByteString
"#define DATA_TEXT_OFFSET(x) ((x).d2.d1)\n"
, ByteString
"#define DATA_TEXT_LENGTH(x) ((x).d2.d2)\n"
, ByteString
"#define LAZY_TEXT_IS_CHUNK(x) ((x).f.a === 2)\n"
, ByteString
"#define LAZY_TEXT_IS_NIL(x) ((x).f.a === 1)\n"
, ByteString
"#define LAZY_TEXT_CHUNK_HEAD(x) ((x))\n"
, ByteString
"#define LAZY_TEXT_CHUNK_TAIL(x) ((x).d2.d3)\n"
, ByteString
"#define IS_BLACKHOLE(x) (typeof (x) === 'object' && (x) && (x).f && (x).f.t === CLOSURE_TYPE_BLACKHOLE)\n"
, ByteString
"#define BLACKHOLE_TID(bh) ((bh).d1)\n"
, ByteString
"#define SET_BLACKHOLE_TID(bh,tid) ((bh).d1 = (tid))\n"
, ByteString
"#define BLACKHOLE_QUEUE(bh) ((bh).d2)\n"
, ByteString
"#define SET_BLACKHOLE_QUEUE(bh,val) ((bh).d2 = (val))\n"
, ByteString
"#define MAKE_RESUMABLE(closure,stack) { (closure).f = h$resume_e; (closure).d1 = (stack), (closure).d2 = null; }\n"
, ByteString
"#define IS_THUNK(x) ((x).f.t === CLOSURE_TYPE_THUNK)\n"
, ByteString
"#define CONSTR_TAG(x) ((x).f.a)\n"
, ByteString
"#define IS_WRAPPED_NUMBER(val) ((typeof(val)==='object')&&(val).f === h$unbox_e)\n"
, ByteString
"#define UNWRAP_NUMBER(val) ((typeof(val) === 'number')?(val):(val).d1)\n"
, if Bool
profiling
then forall a. Monoid a => [a] -> a
mconcat
[ ByteString
"#define MK_LAZY(fun) (h$c1(h$lazy_e, (fun), h$CCS_SYSTEM))\n"
, ByteString
"#define MK_LAZY_CC(fun,cc) (h$c1(h$lazy_e, (fun), (cc)))\n"
]
else forall a. Monoid a => [a] -> a
mconcat
[ ByteString
"#define MK_LAZY(fun) (h$c1(h$lazy_e, (fun)))\n"
, ByteString
"#define MK_LAZY_CC(fun,cc) (h$c1(h$lazy_e, (fun)))\n"
]
, if Bool
profiling
then forall a. Monoid a => [a] -> a
mconcat
[ ByteString
"#define MK_DATA1_1(val) (h$c1(h$data1_e, (val), h$CCS_SYSTEM))\n"
, ByteString
"#define MK_DATA1_2(val1,val2) (h$c2(h$data1_e, (val1), (val2), h$CCS_SYSTEM))\n"
, ByteString
"#define MK_DATA2_1(val) (h$c1(h$data2_e, (val), h$CCS_SYSTEM))\n"
, ByteString
"#define MK_DATA2_2(val1,val2) (h$c2(h$data1_e, (val1), (val2), h$CCS_SYSTEM))\n"
, ByteString
"#define MK_SELECT1(val) (h$c1(h$select1_e, (val), h$CCS_SYSTEM))\n"
, ByteString
"#define MK_SELECT2(val) (h$c1(h$select2_e, (val), h$CCS_SYSTEM))\n"
, ByteString
"#define MK_AP1(fun,val) (h$c2(h$ap1_e, (fun), (val), h$CCS_SYSTEM))\n"
, ByteString
"#define MK_AP2(fun,val1,val2) (h$c3(h$ap2_e, (fun), (val1), (val2), h$CCS_SYSTEM))\n"
, ByteString
"#define MK_AP3(fun,val1,val2,val3) (h$c4(h$ap3_e, (fun), (val1), (val2), (val3), h$CCS_SYSTEM))\n"
]
else forall a. Monoid a => [a] -> a
mconcat
[ ByteString
"#define MK_DATA1_1(val) (h$c1(h$data1_e, (val)))\n"
, ByteString
"#define MK_DATA1_2(val1,val2) (h$c2(h$data1_e, (val1), (val2)))\n"
, ByteString
"#define MK_DATA2_1(val) (h$c1(h$data2_e, (val)))\n"
, ByteString
"#define MK_DATA2_2(val1,val2) (h$c2(h$data2_e, (val1), (val2)))\n"
, ByteString
"#define MK_SELECT1(val) (h$c1(h$select1_e, (val)))\n"
, ByteString
"#define MK_SELECT2(val) (h$c1(h$select2_e, (val)))\n"
, ByteString
"#define MK_AP1(fun,val) (h$c2(h$ap1_e,(fun),(val)))\n"
, ByteString
"#define MK_AP2(fun,val1,val2) (h$c3(h$ap2_e,(fun),(val1),(val2)))\n"
, ByteString
"#define MK_AP3(fun,val1,val2,val3) (h$c4(h$ap3_e, (fun), (val1), (val2), (val3)))\n"
]
, ByteString
"#define RETURN_UBX_TUP2(x1,x2) { h$ret1 = (x2); return (x1); }\n"
, ByteString
"#define RETURN_UBX_TUP3(x1,x2,x3) { h$ret1 = (x2); h$ret2 = (x3); return (x1); }\n"
, ByteString
"#define RETURN_UBX_TUP4(x1,x2,x3,x4) { h$ret1 = (x2); h$ret2 = (x3); h$ret3 = (x4); return (x1); }\n"
, ByteString
"#define RETURN_UBX_TUP5(x1,x2,x3,x4,x5) { h$ret1 = (x2); h$ret2 = (x3); h$ret3 = (x4); h$ret4 = (x5); return (x1); }\n"
, ByteString
"#define RETURN_UBX_TUP6(x1,x2,x3,x4,x5,x6) { h$ret1 = (x2); h$ret2 = (x3); h$ret3 = (x4); h$ret4 = (x5); h$ret5 = (x6); return (x1); }\n"
, ByteString
"#define RETURN_UBX_TUP7(x1,x2,x3,x4,x5,x6,x7) { h$ret1 = (x2); h$ret2 = (x3); h$ret3 = (x4); h$ret4 = (x5); h$ret5 = (x6); h$ret6 = (x7); return (x1); }\n"
, ByteString
"#define RETURN_UBX_TUP8(x1,x2,x3,x4,x5,x6,x7,x8) { h$ret1 = (x2); h$ret2 = (x3); h$ret3 = (x4); h$ret4 = (x5); h$ret5 = (x6); h$ret6 = (x7); h$ret7 = (x8); return (x1); }\n"
, ByteString
"#define RETURN_UBX_TUP9(x1,x2,x3,x4,x5,x6,x7,x8,x9) { h$ret1 = (x2); h$ret2 = (x3); h$ret3 = (x4); h$ret4 = (x5); h$ret5 = (x6); h$ret6 = (x7); h$ret7 = (x8); h$ret8 = (x9); return (x1); }\n"
, ByteString
"#define RETURN_UBX_TUP10(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) { h$ret1 = (x2); h$ret2 = (x3); h$ret3 = (x4); h$ret4 = (x5); h$ret5 = (x6); h$ret6 = (x7); h$ret7 = (x8); h$ret8 = (x9); h$ret9 = (x10); return (x1); }\n"
, ByteString
"#define CALL_UBX_TUP2(r1,r2,c) { (r1) = (c); (r2) = h$ret1; }\n"
, ByteString
"#define CALL_UBX_TUP3(r1,r2,r3,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; }\n"
, ByteString
"#define CALL_UBX_TUP4(r1,r2,r3,r4,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; (r4) = h$ret3; }\n"
, ByteString
"#define CALL_UBX_TUP5(r1,r2,r3,r4,r5,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; (r4) = h$ret3; (r5) = h$ret4; }\n"
, ByteString
"#define CALL_UBX_TUP6(r1,r2,r3,r4,r5,r6,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; (r4) = h$ret3; (r5) = h$ret4; (r6) = h$ret5; }\n"
, ByteString
"#define CALL_UBX_TUP7(r1,r2,r3,r4,r5,r6,r7,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; (r4) = h$ret3; (r5) = h$ret4; (r6) = h$ret5; (r7) = h$ret6; }\n"
, ByteString
"#define CALL_UBX_TUP8(r1,r2,r3,r4,r5,r6,r7,r8,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; (r4) = h$ret3; (r5) = h$ret4; (r6) = h$ret5; (r7) = h$ret6; (r8) = h$ret7; }\n"
, ByteString
"#define CALL_UBX_TUP9(r1,r2,r3,r4,r5,r6,r7,r8,r9,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; (r4) = h$ret3; (r5) = h$ret4; (r6) = h$ret5; (r7) = h$ret6; (r8) = h$ret7; (r9) = h$ret8; }\n"
, ByteString
"#define CALL_UBX_TUP10(r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; (r4) = h$ret3; (r5) = h$ret4; (r6) = h$ret5; (r7) = h$ret6; (r8) = h$ret7; (r9) = h$ret8; (r10) = h$ret9; }\n"
]
jsExeFileName :: DynFlags -> FilePath
jsExeFileName :: DynFlags -> [Char]
jsExeFileName DynFlags
dflags
| Just [Char]
s <- DynFlags -> Maybe [Char]
outputFile_ DynFlags
dflags =
let s' :: [Char]
s' = forall {a}. Eq a => [a] -> [a] -> [a]
dropPrefix [Char]
"js_" (forall a. Int -> [a] -> [a]
drop Int
1 forall a b. (a -> b) -> a -> b
$ [Char] -> [Char]
takeExtension [Char]
s)
in if forall (t :: * -> *) a. Foldable t => t a -> Bool
Prelude.null [Char]
s'
then [Char] -> [Char]
dropExtension [Char]
s [Char] -> [Char] -> [Char]
<.> [Char]
jsexeExtension
else [Char] -> [Char]
dropExtension [Char]
s [Char] -> [Char] -> [Char]
<.> [Char]
s'
| Bool
otherwise =
if Platform -> OS
platformOS (DynFlags -> Platform
targetPlatform DynFlags
dflags) forall a. Eq a => a -> a -> Bool
== OS
OSMinGW32
then [Char]
"main.jsexe"
else [Char]
"a.jsexe"
where
dropPrefix :: [a] -> [a] -> [a]
dropPrefix [a]
prefix [a]
xs
| [a]
prefix forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` [a]
xs = forall a. Int -> [a] -> [a]
drop (forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
prefix) [a]
xs
| Bool
otherwise = [a]
xs
getOptionsFromJsFile :: FilePath
-> IO [JSOption]
getOptionsFromJsFile :: [Char] -> IO [JSOption]
getOptionsFromJsFile [Char]
filename
= forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
Exception.bracket
([Char] -> IOMode -> IO Handle
openBinaryFile [Char]
filename IOMode
ReadMode)
Handle -> IO ()
hClose
Handle -> IO [JSOption]
getJsOptions
data JSOption = CPP deriving (JSOption -> JSOption -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: JSOption -> JSOption -> Bool
$c/= :: JSOption -> JSOption -> Bool
== :: JSOption -> JSOption -> Bool
$c== :: JSOption -> JSOption -> Bool
Eq, Eq JSOption
JSOption -> JSOption -> Bool
JSOption -> JSOption -> Ordering
JSOption -> JSOption -> JSOption
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: JSOption -> JSOption -> JSOption
$cmin :: JSOption -> JSOption -> JSOption
max :: JSOption -> JSOption -> JSOption
$cmax :: JSOption -> JSOption -> JSOption
>= :: JSOption -> JSOption -> Bool
$c>= :: JSOption -> JSOption -> Bool
> :: JSOption -> JSOption -> Bool
$c> :: JSOption -> JSOption -> Bool
<= :: JSOption -> JSOption -> Bool
$c<= :: JSOption -> JSOption -> Bool
< :: JSOption -> JSOption -> Bool
$c< :: JSOption -> JSOption -> Bool
compare :: JSOption -> JSOption -> Ordering
$ccompare :: JSOption -> JSOption -> Ordering
Ord)
getJsOptions :: Handle -> IO [JSOption]
getJsOptions :: Handle -> IO [JSOption]
getJsOptions Handle
handle = do
Handle -> TextEncoding -> IO ()
hSetEncoding Handle
handle TextEncoding
utf8
ByteString
prefix' <- Handle -> Int -> IO ByteString
B.hGet Handle
handle Int
prefixLen
if ByteString
prefix forall a. Eq a => a -> a -> Bool
== ByteString
prefix'
then [Char] -> [JSOption]
parseJsOptions forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Handle -> IO [Char]
hGetLine Handle
handle
else forall (f :: * -> *) a. Applicative f => a -> f a
pure []
where
prefix :: B.ByteString
prefix :: ByteString
prefix = ByteString
"//#OPTIONS:"
prefixLen :: Int
prefixLen = ByteString -> Int
B.length ByteString
prefix
parseJsOptions :: String -> [JSOption]
parseJsOptions :: [Char] -> [JSOption]
parseJsOptions [Char]
xs = [Char] -> [JSOption]
go [Char]
xs
where
trim :: [Char] -> [Char]
trim = forall a. [a] -> [a]
reverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isSpace forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> [a]
reverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isSpace
go :: [Char] -> [JSOption]
go [] = []
go [Char]
xs = let ([Char]
tok, [Char]
rest) = forall a. (a -> Bool) -> [a] -> ([a], [a])
break (forall a. Eq a => a -> a -> Bool
== Char
',') [Char]
xs
tok' :: [Char]
tok' = [Char] -> [Char]
trim [Char]
tok
rest' :: [Char]
rest' = forall a. Int -> [a] -> [a]
drop Int
1 [Char]
rest
in if | [Char]
tok' forall a. Eq a => a -> a -> Bool
== [Char]
"CPP" -> JSOption
CPP forall a. a -> [a] -> [a]
: [Char] -> [JSOption]
go [Char]
rest'
| Bool
otherwise -> [Char] -> [JSOption]
go [Char]
rest'