module CmdLineParser (
processArgs, OptKind(..),
CmdLineP(..), getCmdLineState, putCmdLineState,
- Flag(..),
+ Flag(..), Deprecated(..),
+ errorsToGhcException
) where
#include "HsVersions.h"
import Util
+import Outputable
import Panic
+import SrcLoc
-data Flag m = Flag { flagName :: String, -- flag, without the leading -
- flagOptKind :: (OptKind m) -- What to do if we see it
- }
+data Flag m = Flag
+ {
+ flagName :: String, -- flag, without the leading -
+ flagOptKind :: (OptKind m), -- what to do if we see it
+ flagDeprecated :: Deprecated -- is the flag deprecated?
+ }
+
+data Deprecated = Supported | Deprecated String
data OptKind m -- Suppose the flag is -f
= NoArg (m ()) -- -f all by itself
processArgs :: Monad m
=> [Flag m] -- cmdline parser spec
- -> [String] -- args
+ -> [Located String] -- args
-> m (
- [String], -- spare args
- [String] -- errors
+ [Located String], -- spare args
+ [Located String], -- errors
+ [Located String] -- warnings
)
-processArgs spec args = process spec args [] []
+processArgs spec args = process spec args [] [] []
where
- process _spec [] spare errs =
- return (reverse spare, reverse errs)
+ process _spec [] spare errs warns =
+ return (reverse spare, reverse errs, reverse warns)
- process spec (dash_arg@('-':arg):args) spare errs =
+ process spec (locArg@(L loc dash_arg@('-' : arg)) : args) spare errs warns =
case findArg spec arg of
- Just (rest,action) ->
- case processOneArg action rest arg args of
- Left err -> process spec args spare (err:errs)
- Right (action,rest) -> action >> process spec rest spare errs
- Nothing -> process spec args (dash_arg:spare) errs
-
- process spec (arg:args) spare errs =
- process spec args (arg:spare) errs
-
-
-processOneArg :: OptKind m -> String -> String -> [String]
- -> Either String (m (), [String])
+ Just (rest, action, deprecated) ->
+ let warns' = case deprecated of
+ Deprecated warning ->
+ L loc ("Warning: " ++ dash_arg ++ " is deprecated: " ++ warning) : warns
+ Supported -> warns
+ in case processOneArg action rest arg args of
+ Left err -> process spec args spare (L loc err : errs) warns'
+ Right (action,rest) -> do action
+ process spec rest spare errs warns'
+ Nothing -> process spec args (locArg : spare) errs warns
+
+ process spec (arg : args) spare errs warns =
+ process spec args (arg : spare) errs warns
+
+
+processOneArg :: OptKind m -> String -> String -> [Located String]
+ -> Either String (m (), [Located String])
processOneArg action rest arg args
= let dash_arg = '-' : arg
rest_no_eq = dropEq rest
HasArg f | notNull rest_no_eq -> Right (f rest_no_eq, args)
| otherwise -> case args of
[] -> missingArgErr dash_arg
- (arg1:args1) -> Right (f arg1, args1)
+ (L _ arg1:args1) -> Right (f arg1, args1)
SepArg f -> case args of
[] -> unknownFlagErr dash_arg
- (arg1:args1) -> Right (f arg1, args1)
+ (L _ arg1:args1) -> Right (f arg1, args1)
Prefix f | notNull rest_no_eq -> Right (f rest_no_eq, args)
| otherwise -> unknownFlagErr dash_arg
AnySuffixPred _ f -> Right (f dash_arg, args)
-findArg :: [Flag m] -> String -> Maybe (String, OptKind m)
+findArg :: [Flag m] -> String -> Maybe (String, OptKind m, Deprecated)
findArg spec arg
- = case [ (removeSpaces rest, optKind)
+ = case [ (removeSpaces rest, optKind, flagDeprecated flag)
| flag <- spec,
let optKind = flagOptKind flag,
Just rest <- [maybePrefixMatch (flagName flag) arg],
getCmdLineState = CmdLineP $ \s -> (s,s)
putCmdLineState :: s -> CmdLineP s ()
putCmdLineState s = CmdLineP $ \_ -> ((),s)
+
+-- ---------------------------------------------------------------------
+-- Utils
+
+errorsToGhcException :: [Located String] -> GhcException
+errorsToGhcException errs =
+ let errors = vcat [ ppr l <> text ": " <> text e | L l e <- errs ]
+ in UsageError (showSDoc errors)
+