module Cli.ParseCompileOptions (
optionHelpText,
parseCompileOptions,
validateCompileOptions,
) where
import Control.Monad (when)
import Lens.Micro
import Text.Regex.TDFA
import qualified Data.Set as Set
import Base.CompilerError
import Cli.CompileOptions
import Module.ProcessMetadata (isPrivateSource,isPublicSource,isTestSource)
import Types.TypeCategory (FunctionName(..))
import Types.TypeInstance (CategoryName(..))
optionHelpText :: [String]
optionHelpText :: [String]
optionHelpText = [
String
"",
String
"Compilation Modes:",
String
"",
String
" zeolite [options...] --fast [category(.function)] [.0rx source]",
String
" Create a binary without needing a config.",
String
"",
String
" zeolite [options...] -r [modules...]",
String
" Recompile using each module's .zeolite-module config.",
String
"",
String
" zeolite [options...] -R [modules...]",
String
" Recursively recompile using each module's .zeolite-module config.",
String
"",
String
" zeolite [options...] -t (--log-traces [filename]) [modules...] (tests...)",
String
" Only execute tests, without other compilation.",
String
"",
String
"Configuration Modes:",
String
"",
String
" zeolite [options...] -c [module]",
String
" Create a new .zeolite-module config for a libary module.",
String
"",
String
" zeolite [options...] -m [category(.function)] (-o [binary]) [module]",
String
" Create a new .zeolite-module config for a binary module.",
String
"",
String
"Special Modes:",
String
"",
String
" zeolite [options...] --templates [modules...]",
String
" Only create C++ templates for undefined categories in .0rp sources.",
String
"",
String
" zeolite (-p [path]) --clean [modules...]",
String
" Remove all cached data for the modules.",
String
"",
String
" zeolite (-p [path]) --missed-lines [filename] [modules...]",
String
" List all lines missed in a log file taken from --log-traces.",
String
"",
String
" zeolite (-p [path]) --show-deps [modules...]",
String
" Show category dependencies for the modules.",
String
"",
String
" zeolite (-p [path]) --show-traces [modules...]",
String
" Show the possible code traces for the modules.",
String
"",
String
"Compiler Info:",
String
"",
String
" zeolite --get-path",
String
" Show the data path and immediately exit.",
String
"",
String
" zeolite --version",
String
" Show the compiler version and immediately exit.",
String
"",
String
"Options:",
String
" -f: Force an operation that zeolite would otherwise reject.",
String
" -i [module]: A single source module to include as a public dependency.",
String
" -I [module]: A single source module to include as a private dependency.",
String
" -j [# parallel]: Parallel execution of compilation subprocesses.",
String
" -o [binary]: The name of the binary file to create with -m.",
String
" -p [path]: Set a path prefix for finding modules or files.",
String
" --log-traces [filename]: Log call traces to a file when running tests.",
String
"",
String
"Argument Types:",
String
" category: The name of a concrete category with no params.",
String
" function: The name of a @type function (defaults to \"run\") with no args or params.",
String
" module: Path to a directory containing an existing or to-be-created Zeolite module.",
String
" test: Name of a .0rt file to limit test execution to.",
String
"",
String
"Examples:",
String
"",
String
" # Create a config for a binary in myprogram that calls MyProgram.run() that uses lib/util.",
String
" zeolite -I lib/util -m MyProgram.run myprogram",
String
"",
String
" # Compile a binary that calls MyProgram.run() from myprogram.0rx without a config.",
String
" zeolite -I lib/util --fast MyProgram.run myprogram.0rx",
String
"",
String
" # Create a config for a library in mylibrary that uses lib/util.",
String
" zeolite -I lib/util -c mylibrary",
String
"",
String
" # Recompile myprogram, recursively recompiling its dependencies first.",
String
" zeolite -R myprogram",
String
"",
String
" # Execute the tests from .0rt files in mylibrary.",
String
" zeolite -t mylibrary",
String
"",
String
" # Display the contexts of all code lines missed by tests for mylibrary.",
String
" zeolite -t --log-traces traces.csv mylibrary",
String
" zeolite --missed-lines traces.csv mylibrary",
String
""
]
defaultMainFunc :: String
defaultMainFunc :: String
defaultMainFunc = String
"run"
optionsWithArgs :: Set.Set Char
optionsWithArgs :: Set Char
optionsWithArgs = forall a. Ord a => [a] -> Set a
Set.fromList String
"iIjmop"
splitOptionClusters :: [String] -> [String]
splitOptionClusters :: [String] -> [String]
splitOptionClusters (o :: String
o@(Char
'-':Char
c:String
rest):[String]
os)
| Char
c forall a. Eq a => a -> a -> Bool
== Char
'-' Bool -> Bool -> Bool
|| forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
rest = String
o forall a. a -> [a] -> [a]
: [String] -> [String]
splitOptionClusters [String]
os
| Char
c forall a. Ord a => a -> Set a -> Bool
`Set.member` Set Char
optionsWithArgs = (Char
'-'forall a. a -> [a] -> [a]
:Char
cforall a. a -> [a] -> [a]
:[]) forall a. a -> [a] -> [a]
: String
rest forall a. a -> [a] -> [a]
: [String] -> [String]
splitOptionClusters [String]
os
| Bool
otherwise = (Char
'-'forall a. a -> [a] -> [a]
:Char
cforall a. a -> [a] -> [a]
:[]) forall a. a -> [a] -> [a]
: [String] -> [String]
splitOptionClusters ((Char
'-'forall a. a -> [a] -> [a]
:String
rest)forall a. a -> [a] -> [a]
:[String]
os)
splitOptionClusters (String
o:[String]
os) = String
o forall a. a -> [a] -> [a]
: [String] -> [String]
splitOptionClusters [String]
os
splitOptionClusters [] = []
parseCompileOptions :: CollectErrorsM m => [String] -> m CompileOptions
parseCompileOptions :: forall (m :: * -> *).
CollectErrorsM m =>
[String] -> m CompileOptions
parseCompileOptions = forall {m :: * -> *} {a}.
(ErrorContextM m, Show a) =>
CompileOptions -> [(a, String)] -> m CompileOptions
parseAll CompileOptions
emptyCompileOptions forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. [a] -> [b] -> [(a, b)]
zip ([Int
1..] :: [Int]) forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
splitOptionClusters where
parseAll :: CompileOptions -> [(a, String)] -> m CompileOptions
parseAll CompileOptions
co [] = forall (m :: * -> *) a. Monad m => a -> m a
return CompileOptions
co
parseAll CompileOptions
co [(a, String)]
os = do
([(a, String)]
os',CompileOptions
co') <- forall {m :: * -> *} {a}.
(ErrorContextM m, Show a) =>
CompileOptions
-> [(a, String)] -> m ([(a, String)], CompileOptions)
parseSingle CompileOptions
co [(a, String)]
os
CompileOptions -> [(a, String)] -> m CompileOptions
parseAll CompileOptions
co' [(a, String)]
os'
argError :: a -> String -> String -> m a
argError a
n String
o String
m = forall (m :: * -> *) a. ErrorContextM m => String -> m a
compilerErrorM forall a b. (a -> b) -> a -> b
$ String
"Argument " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show a
n forall a. [a] -> [a] -> [a]
++ String
" (\"" forall a. [a] -> [a] -> [a]
++ String
o forall a. [a] -> [a] -> [a]
++ String
"\"): " forall a. [a] -> [a] -> [a]
++ String
m
checkPathName :: a -> String -> String -> m ()
checkPathName a
n String
f String
o
| String
f forall source source1 target.
(RegexMaker Regex CompOption ExecOption source,
RegexContext Regex source1 target) =>
source1 -> source -> target
=~ String
"^(/[^/]+|[^-/][^/]*)(/[^/]+)*$" = forall (m :: * -> *) a. Monad m => a -> m a
return ()
| forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
o = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
f String
"Invalid file path."
| Bool
otherwise = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
f forall a b. (a -> b) -> a -> b
$ String
"Invalid file path for " forall a. [a] -> [a] -> [a]
++ String
o forall a. [a] -> [a] -> [a]
++ String
"."
checkCategoryName :: a -> String -> String -> m ()
checkCategoryName a
n String
c String
o
| String
c forall source source1 target.
(RegexMaker Regex CompOption ExecOption source,
RegexContext Regex source1 target) =>
source1 -> source -> target
=~ String
"^[A-Z][A-Za-z0-9]+$" = forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
c forall a b. (a -> b) -> a -> b
$ String
"Invalid category name for " forall a. [a] -> [a] -> [a]
++ String
o forall a. [a] -> [a] -> [a]
++ String
"."
checkFunctionName :: a -> String -> String -> m ()
checkFunctionName a
n String
d String
o
| String
d forall source source1 target.
(RegexMaker Regex CompOption ExecOption source,
RegexContext Regex source1 target) =>
source1 -> source -> target
=~ String
"^[a-z][A-Za-z0-9]+$" = forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
d forall a b. (a -> b) -> a -> b
$ String
"Invalid function name for " forall a. [a] -> [a] -> [a]
++ String
o forall a. [a] -> [a] -> [a]
++ String
"."
parseSingle :: CompileOptions
-> [(a, String)] -> m ([(a, String)], CompileOptions)
parseSingle CompileOptions
_ [] = forall a. HasCallStack => a
undefined
parseSingle CompileOptions
opts ((a
_,String
"-h"):[(a, String)]
os) =
forall (m :: * -> *) a. Monad m => a -> m a
return ([(a, String)]
os,CompileOptions
opts forall a b. a -> (a -> b) -> b
& Lens' CompileOptions HelpMode
coHelp forall s t a b. ASetter s t a b -> b -> s -> t
.~ HelpMode
HelpNeeded)
parseSingle CompileOptions
opts ((a
_,String
"-f"):[(a, String)]
os) =
forall (m :: * -> *) a. Monad m => a -> m a
return ([(a, String)]
os,CompileOptions
opts forall a b. a -> (a -> b) -> b
& Lens' CompileOptions ForceMode
coForce forall s t a b. ASetter s t a b -> b -> s -> t
.~ ForceMode
ForceAll)
parseSingle CompileOptions
opts ((a
n,String
"-c"):[(a, String)]
os)
| (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions CompileMode
coMode) forall a. Eq a => a -> a -> Bool
/= CompileMode
CompileUnspecified = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
"-c" String
"Compiler mode already set."
| Bool
otherwise = forall (m :: * -> *) a. Monad m => a -> m a
return ([(a, String)]
os,CompileOptions
opts forall a b. a -> (a -> b) -> b
& Lens' CompileOptions HelpMode
coHelp forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ HelpMode -> HelpMode
maybeDisableHelp forall a b. a -> (a -> b) -> b
& Lens' CompileOptions CompileMode
coMode forall s t a b. ASetter s t a b -> b -> s -> t
.~ ([String] -> CompileMode
CompileIncremental []))
parseSingle CompileOptions
opts ((a
n,String
"-r"):[(a, String)]
os)
| (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions CompileMode
coMode) forall a. Eq a => a -> a -> Bool
/= CompileMode
CompileUnspecified = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
"-r" String
"Compiler mode already set."
| Bool
otherwise = forall (m :: * -> *) a. Monad m => a -> m a
return ([(a, String)]
os,CompileOptions
opts forall a b. a -> (a -> b) -> b
& Lens' CompileOptions HelpMode
coHelp forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ HelpMode -> HelpMode
maybeDisableHelp forall a b. a -> (a -> b) -> b
& Lens' CompileOptions CompileMode
coMode forall s t a b. ASetter s t a b -> b -> s -> t
.~ CompileMode
CompileRecompile)
parseSingle CompileOptions
opts ((a
n,String
"-R"):[(a, String)]
os)
| (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions CompileMode
coMode) forall a. Eq a => a -> a -> Bool
/= CompileMode
CompileUnspecified = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
"-R" String
"Compiler mode already set."
| Bool
otherwise = forall (m :: * -> *) a. Monad m => a -> m a
return ([(a, String)]
os,CompileOptions
opts forall a b. a -> (a -> b) -> b
& Lens' CompileOptions HelpMode
coHelp forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ HelpMode -> HelpMode
maybeDisableHelp forall a b. a -> (a -> b) -> b
& Lens' CompileOptions CompileMode
coMode forall s t a b. ASetter s t a b -> b -> s -> t
.~ CompileMode
CompileRecompileRecursive)
parseSingle CompileOptions
opts ((a
n,String
"-t"):[(a, String)]
os)
| (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions CompileMode
coMode) forall a. Eq a => a -> a -> Bool
/= CompileMode
CompileUnspecified = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
"-t" String
"Compiler mode already set."
| Bool
otherwise = forall (m :: * -> *) a. Monad m => a -> m a
return ([(a, String)]
os,CompileOptions
opts forall a b. a -> (a -> b) -> b
& Lens' CompileOptions HelpMode
coHelp forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ HelpMode -> HelpMode
maybeDisableHelp forall a b. a -> (a -> b) -> b
& Lens' CompileOptions CompileMode
coMode forall s t a b. ASetter s t a b -> b -> s -> t
.~ ([String] -> Maybe String -> CompileMode
ExecuteTests [] forall a. Maybe a
Nothing))
parseSingle CompileOptions
opts ((a
n,String
"--templates"):[(a, String)]
os)
| (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions CompileMode
coMode) forall a. Eq a => a -> a -> Bool
/= CompileMode
CompileUnspecified = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
"--templates" String
"Compiler mode already set."
| Bool
otherwise = forall (m :: * -> *) a. Monad m => a -> m a
return ([(a, String)]
os,CompileOptions
opts forall a b. a -> (a -> b) -> b
& Lens' CompileOptions HelpMode
coHelp forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ HelpMode -> HelpMode
maybeDisableHelp forall a b. a -> (a -> b) -> b
& Lens' CompileOptions CompileMode
coMode forall s t a b. ASetter s t a b -> b -> s -> t
.~ CompileMode
CreateTemplates)
parseSingle CompileOptions
opts ((a
n,String
"-m"):[(a, String)]
os)
| (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions CompileMode
coMode) forall a. Eq a => a -> a -> Bool
/= CompileMode
CompileUnspecified = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
"-m" String
"Compiler mode already set."
| Bool
otherwise = forall {m :: * -> *} {a}.
(ErrorContextM m, Show a) =>
[(a, String)] -> m ([(a, String)], CompileOptions)
update [(a, String)]
os where
update :: [(a, String)] -> m ([(a, String)], CompileOptions)
update ((a
n2,String
c):[(a, String)]
os2) = do
(String
t,String
fn) <- forall {m :: * -> *} {a}.
ErrorContextM m =>
(a, String) -> m (a, String)
check forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> ([a], [a])
break (forall a. Eq a => a -> a -> Bool
== Char
'.') String
c
forall {m :: * -> *} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m ()
checkCategoryName a
n2 String
t String
"-m"
forall {m :: * -> *} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m ()
checkFunctionName a
n2 String
fn String
"-m"
let m2 :: CompileMode
m2 = CategoryName
-> FunctionName -> LinkerMode -> String -> [String] -> CompileMode
CompileBinary (String -> CategoryName
CategoryName String
t) (String -> FunctionName
FunctionName String
fn) LinkerMode
LinkDynamic String
"" []
forall (m :: * -> *) a. Monad m => a -> m a
return ([(a, String)]
os2,CompileOptions
opts forall a b. a -> (a -> b) -> b
& Lens' CompileOptions HelpMode
coHelp forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ HelpMode -> HelpMode
maybeDisableHelp forall a b. a -> (a -> b) -> b
& Lens' CompileOptions CompileMode
coMode forall s t a b. ASetter s t a b -> b -> s -> t
.~ CompileMode
m2) where
check :: (a, String) -> m (a, String)
check (a
t,String
"") = forall (m :: * -> *) a. Monad m => a -> m a
return (a
t,String
defaultMainFunc)
check (a
t,Char
'.':String
fn) = forall (m :: * -> *) a. Monad m => a -> m a
return (a
t,String
fn)
check (a, String)
_ = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n2 String
c forall a b. (a -> b) -> a -> b
$ String
"Invalid entry point."
update [(a, String)]
_ = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
"-m" String
"Requires a category name."
parseSingle CompileOptions
opts ((a
n,String
"--fast"):[(a, String)]
os)
| (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions CompileMode
coMode) forall a. Eq a => a -> a -> Bool
/= CompileMode
CompileUnspecified = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
"--fast" String
"Compiler mode already set."
| Bool
otherwise = forall {m :: * -> *} {a}.
(ErrorContextM m, Show a) =>
[(a, String)] -> m ([(a, String)], CompileOptions)
update [(a, String)]
os where
update :: [(a, String)] -> m ([(a, String)], CompileOptions)
update ((a
n2,String
c):(a
n3,String
f2):[(a, String)]
os2) = do
(String
t,String
fn) <- forall {m :: * -> *} {a}.
ErrorContextM m =>
(a, String) -> m (a, String)
check forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> ([a], [a])
break (forall a. Eq a => a -> a -> Bool
== Char
'.') String
c
forall {m :: * -> *} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m ()
checkCategoryName a
n2 String
t String
"--fast"
forall {m :: * -> *} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m ()
checkFunctionName a
n2 String
fn String
"--fast"
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ String -> Bool
isPrivateSource String
f2) forall a b. (a -> b) -> a -> b
$ forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n3 String
f2 forall a b. (a -> b) -> a -> b
$ String
"Must specify a .0rx source file."
let m2 :: CompileMode
m2 = CategoryName -> FunctionName -> String -> CompileMode
CompileFast (String -> CategoryName
CategoryName String
t) (String -> FunctionName
FunctionName String
fn) String
f2
forall (m :: * -> *) a. Monad m => a -> m a
return ([(a, String)]
os2,CompileOptions
opts forall a b. a -> (a -> b) -> b
& Lens' CompileOptions HelpMode
coHelp forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ HelpMode -> HelpMode
maybeDisableHelp forall a b. a -> (a -> b) -> b
& Lens' CompileOptions CompileMode
coMode forall s t a b. ASetter s t a b -> b -> s -> t
.~ CompileMode
m2) where
check :: (a, String) -> m (a, String)
check (a
t,String
"") = forall (m :: * -> *) a. Monad m => a -> m a
return (a
t,String
defaultMainFunc)
check (a
t,Char
'.':String
fn) = forall (m :: * -> *) a. Monad m => a -> m a
return (a
t,String
fn)
check (a, String)
_ = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n2 String
c forall a b. (a -> b) -> a -> b
$ String
"Invalid entry point."
update [(a, String)]
_ = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
"--fast" String
"Requires a category name and a .0rx file."
parseSingle CompileOptions
opts ((a
n,String
"--log-traces"):[(a, String)]
os) = forall {m :: * -> *} {a}.
ErrorContextM m =>
CompileMode -> [(a, String)] -> m ([(a, String)], CompileOptions)
update (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions CompileMode
coMode) [(a, String)]
os where
update :: CompileMode -> [(a, String)] -> m ([(a, String)], CompileOptions)
update (ExecuteTests [String]
tp Maybe String
cl) ((a
_,String
cl2):[(a, String)]
os2)
| Maybe String
cl forall a. Eq a => a -> a -> Bool
/= forall a. Maybe a
Nothing = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
"--log-traces" String
"Trace-log filename already set."
| Bool
otherwise = forall (m :: * -> *) a. Monad m => a -> m a
return ([(a, String)]
os2,CompileOptions
opts forall a b. a -> (a -> b) -> b
& Lens' CompileOptions HelpMode
coHelp forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ HelpMode -> HelpMode
maybeDisableHelp forall a b. a -> (a -> b) -> b
& Lens' CompileOptions CompileMode
coMode forall s t a b. ASetter s t a b -> b -> s -> t
.~ ([String] -> Maybe String -> CompileMode
ExecuteTests [String]
tp (forall a. a -> Maybe a
Just String
cl2)))
update CompileMode
_ [] = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
"--log-traces" String
"Requires an output filename."
update CompileMode
_ [(a, String)]
_ = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
"--log-traces" String
"Set mode to test (-t) first."
parseSingle CompileOptions
opts ((a
n,String
"-o"):[(a, String)]
os) = forall {m :: * -> *} {a}.
(ErrorContextM m, Show a) =>
CompileMode -> [(a, String)] -> m ([(a, String)], CompileOptions)
update (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions CompileMode
coMode) [(a, String)]
os where
update :: CompileMode -> [(a, String)] -> m ([(a, String)], CompileOptions)
update (CompileBinary CategoryName
t FunctionName
fn LinkerMode
lm String
o [String]
lf) ((a
n2,String
o2):[(a, String)]
os2)
| Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
o = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
"-o" String
"Output name already set."
| Bool
otherwise = do
forall {m :: * -> *} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m ()
checkPathName a
n2 String
o2 String
"-o"
forall (m :: * -> *) a. Monad m => a -> m a
return ([(a, String)]
os2,CompileOptions
opts forall a b. a -> (a -> b) -> b
& Lens' CompileOptions HelpMode
coHelp forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ HelpMode -> HelpMode
maybeDisableHelp forall a b. a -> (a -> b) -> b
& Lens' CompileOptions CompileMode
coMode forall s t a b. ASetter s t a b -> b -> s -> t
.~ (CategoryName
-> FunctionName -> LinkerMode -> String -> [String] -> CompileMode
CompileBinary CategoryName
t FunctionName
fn LinkerMode
lm String
o2 [String]
lf))
update CompileMode
_ [] = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
"-o" String
"Requires an output name."
update CompileMode
_ [(a, String)]
_ = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
"-o" String
"Set mode to binary (-m) first."
parseSingle CompileOptions
opts ((a
n,String
"-i"):[(a, String)]
os) = forall {m :: * -> *} {a}.
(ErrorContextM m, Show a) =>
[(a, String)] -> m ([(a, String)], CompileOptions)
update [(a, String)]
os where
update :: [(a, String)] -> m ([(a, String)], CompileOptions)
update ((a
n2,String
d):[(a, String)]
os2)
| String -> Bool
isPublicSource String
d = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n2 String
d String
"Cannot directly include .0rp source files."
| String -> Bool
isPrivateSource String
d = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n2 String
d String
"Cannot directly include .0rx source files."
| String -> Bool
isTestSource String
d = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n2 String
d String
"Cannot directly include .0rt test files."
| Bool
otherwise = do
forall {m :: * -> *} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m ()
checkPathName a
n2 String
d String
"-i"
forall (m :: * -> *) a. Monad m => a -> m a
return ([(a, String)]
os2,CompileOptions
opts forall a b. a -> (a -> b) -> b
& Lens' CompileOptions HelpMode
coHelp forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ HelpMode -> HelpMode
maybeDisableHelp forall a b. a -> (a -> b) -> b
& Lens' CompileOptions [String]
coPublicDeps forall a s t. Monoid a => ASetter s t a a -> a -> s -> t
<>~ [String
d])
update [(a, String)]
_ = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
"-i" String
"Requires a source path."
parseSingle CompileOptions
opts ((a
n,String
"-I"):[(a, String)]
os) = forall {m :: * -> *} {a}.
(ErrorContextM m, Show a) =>
[(a, String)] -> m ([(a, String)], CompileOptions)
update [(a, String)]
os where
update :: [(a, String)] -> m ([(a, String)], CompileOptions)
update ((a
n2,String
d):[(a, String)]
os2)
| String -> Bool
isPublicSource String
d = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n2 String
d String
"Cannot directly include .0rp source files."
| String -> Bool
isPrivateSource String
d = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n2 String
d String
"Cannot directly include .0rx source files."
| String -> Bool
isTestSource String
d = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n2 String
d String
"Cannot directly include .0rt test files."
| Bool
otherwise = do
forall {m :: * -> *} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m ()
checkPathName a
n2 String
d String
"-i"
forall (m :: * -> *) a. Monad m => a -> m a
return ([(a, String)]
os2,CompileOptions
opts forall a b. a -> (a -> b) -> b
& Lens' CompileOptions HelpMode
coHelp forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ HelpMode -> HelpMode
maybeDisableHelp forall a b. a -> (a -> b) -> b
& Lens' CompileOptions [String]
coPrivateDeps forall a s t. Monoid a => ASetter s t a a -> a -> s -> t
<>~ [String
d])
update [(a, String)]
_ = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
"-I" String
"Requires a source path."
parseSingle CompileOptions
opts ((a
n,String
"-p"):[(a, String)]
os)
| Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Bool
null (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions String
coSourcePrefix) = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
"-p" String
"Path prefix already set."
| Bool
otherwise = forall {m :: * -> *} {a}.
(ErrorContextM m, Show a) =>
[(a, String)] -> m ([(a, String)], CompileOptions)
update [(a, String)]
os where
update :: [(a, String)] -> m ([(a, String)], CompileOptions)
update ((a
n2,String
p2):[(a, String)]
os2) = do
forall {m :: * -> *} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m ()
checkPathName a
n2 String
p2 String
"-p"
forall (m :: * -> *) a. Monad m => a -> m a
return ([(a, String)]
os2,CompileOptions
opts forall a b. a -> (a -> b) -> b
& Lens' CompileOptions HelpMode
coHelp forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ HelpMode -> HelpMode
maybeDisableHelp forall a b. a -> (a -> b) -> b
& Lens' CompileOptions String
coSourcePrefix forall s t a b. ASetter s t a b -> b -> s -> t
.~ String
p2)
update [(a, String)]
_ = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
"-p" String
"Requires a path prefix."
parseSingle CompileOptions
opts ((a
n,String
"-j"):[(a, String)]
os) = forall {m :: * -> *} {a}.
(ErrorContextM m, Show a) =>
[(a, String)] -> m ([(a, String)], CompileOptions)
update [(a, String)]
os where
update :: [(a, String)] -> m ([(a, String)], CompileOptions)
update ((a
n2,String
k):[(a, String)]
os2) = do
case forall a. Read a => ReadS a
reads String
k of
[(Int
pn,[])] -> if Int
pn forall a. Ord a => a -> a -> Bool
> Int
0
then forall (m :: * -> *) a. Monad m => a -> m a
return ([(a, String)]
os2,CompileOptions
opts forall a b. a -> (a -> b) -> b
& Lens' CompileOptions HelpMode
coHelp forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ HelpMode -> HelpMode
maybeDisableHelp forall a b. a -> (a -> b) -> b
& Lens' CompileOptions Int
coParallel forall s t a b. ASetter s t a b -> b -> s -> t
.~ Int
pn)
else forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n2 String
k String
"Must be > 0."
[(Int, String)]
_ -> forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n2 String
k String
"Not a valid integer."
update [(a, String)]
_ = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
"-j" String
"Requires an integer > 0."
parseSingle CompileOptions
_ ((a
n,o :: String
o@(Char
'-':String
_)):[(a, String)]
_) = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
o String
"Unknown option."
parseSingle CompileOptions
opts ((a
n,String
d):[(a, String)]
os)
| String -> Bool
isPublicSource String
d = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
d String
"Cannot directly include .0rp source files."
| String -> Bool
isPrivateSource String
d = forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
d String
"Cannot directly include .0rx source files."
| String -> Bool
isTestSource String
d = do
case CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions CompileMode
coMode of
ExecuteTests [String]
tp Maybe String
cl -> do
forall {m :: * -> *} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m ()
checkPathName a
n String
d String
""
forall (m :: * -> *) a. Monad m => a -> m a
return ([(a, String)]
os,CompileOptions
opts forall a b. a -> (a -> b) -> b
& Lens' CompileOptions HelpMode
coHelp forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ HelpMode -> HelpMode
maybeDisableHelp forall a b. a -> (a -> b) -> b
& Lens' CompileOptions CompileMode
coMode forall s t a b. ASetter s t a b -> b -> s -> t
.~ ([String] -> Maybe String -> CompileMode
ExecuteTests ([String]
tp forall a. [a] -> [a] -> [a]
++ [String
d]) Maybe String
cl))
CompileMode
_ -> forall {m :: * -> *} {a} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m a
argError a
n String
d String
"Test mode (-t) must be enabled before listing any .0rt test files."
| Bool
otherwise = do
forall {m :: * -> *} {a}.
(ErrorContextM m, Show a) =>
a -> String -> String -> m ()
checkPathName a
n String
d String
""
forall (m :: * -> *) a. Monad m => a -> m a
return ([(a, String)]
os,CompileOptions
opts forall a b. a -> (a -> b) -> b
& Lens' CompileOptions HelpMode
coHelp forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ HelpMode -> HelpMode
maybeDisableHelp forall a b. a -> (a -> b) -> b
& Lens' CompileOptions [String]
coPaths forall a s t. Monoid a => ASetter s t a a -> a -> s -> t
<>~ [String
d])
validateCompileOptions :: CollectErrorsM m => CompileOptions -> m CompileOptions
validateCompileOptions :: forall (m :: * -> *).
CollectErrorsM m =>
CompileOptions -> m CompileOptions
validateCompileOptions CompileOptions
opts
| (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions HelpMode
coHelp) forall a. Eq a => a -> a -> Bool
/= HelpMode
HelpNotNeeded = forall (m :: * -> *) a. Monad m => a -> m a
return CompileOptions
opts
| CompileMode -> Bool
isCompileUnspecified (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions CompileMode
coMode) =
forall (m :: * -> *) a. ErrorContextM m => String -> m a
compilerErrorM String
"Compiler mode must be specified explicitly."
| (Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Bool
null forall a b. (a -> b) -> a -> b
$ (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions [String]
coPublicDeps) forall a. [a] -> [a] -> [a]
++ (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions [String]
coPrivateDeps)) Bool -> Bool -> Bool
&& (CompileMode -> Bool
isExecuteTests (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions CompileMode
coMode)) =
forall (m :: * -> *) a. ErrorContextM m => String -> m a
compilerErrorM String
"Include paths (-i/-I) are not allowed in test mode (-t)."
| (Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Bool
null forall a b. (a -> b) -> a -> b
$ (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions [String]
coPublicDeps) forall a. [a] -> [a] -> [a]
++ (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions [String]
coPrivateDeps)) Bool -> Bool -> Bool
&& (CompileMode -> Bool
isCompileRecompile (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions CompileMode
coMode)) =
forall (m :: * -> *) a. ErrorContextM m => String -> m a
compilerErrorM String
"Include paths (-i/-I) are not allowed in recompile mode (-r/-R)."
| (forall (t :: * -> *) a. Foldable t => t a -> Int
length (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions [String]
coPaths) forall a. Eq a => a -> a -> Bool
/= Int
0) Bool -> Bool -> Bool
&& (CompileMode -> Bool
isCompileFast (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions CompileMode
coMode)) =
forall (m :: * -> *) a. ErrorContextM m => String -> m a
compilerErrorM String
"Input path is not allowed with fast mode (--fast)."
| forall (t :: * -> *) a. Foldable t => t a -> Bool
null (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions [String]
coPaths) Bool -> Bool -> Bool
&& (Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ CompileMode -> Bool
isCompileFast (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions CompileMode
coMode)) =
forall (m :: * -> *) a. ErrorContextM m => String -> m a
compilerErrorM String
"Please specify at least one input path."
| (forall (t :: * -> *) a. Foldable t => t a -> Int
length (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions [String]
coPaths) forall a. Ord a => a -> a -> Bool
> Int
1) Bool -> Bool -> Bool
&& (Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ CompileMode -> Bool
isCompileRecompile (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions CompileMode
coMode)) Bool -> Bool -> Bool
&& (Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ CompileMode -> Bool
isExecuteTests (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions CompileMode
coMode)) =
forall (m :: * -> *) a. ErrorContextM m => String -> m a
compilerErrorM String
"Multiple input paths are only allowed with recompile mode (-r/-R) and test mode (-t)."
| Bool
otherwise = do
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ((CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions Int
coParallel) forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
&& Bool -> Bool
not (CompileMode -> Bool
isCompileRecompile (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions CompileMode
coMode)) Bool -> Bool -> Bool
&& Bool -> Bool
not (CompileMode -> Bool
isCompileFast (CompileOptions
opts forall s a. s -> Getting a s a -> a
^. Lens' CompileOptions CompileMode
coMode))) forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *). ErrorContextM m => String -> m ()
compilerWarningM String
"Parallel processing (-j) has no effect outside of recompile mode (-r/-R) and fast mode (--fast)."
forall (m :: * -> *) a. Monad m => a -> m a
return CompileOptions
opts