{-# LANGUAGE Safe #-}------------------------------------------------------------------------------- |-- Module : System.Console.GetOpt-- Copyright : (c) Sven Panne 2002-2005-- License : BSD-style (see the file libraries/base/LICENSE)---- Maintainer : libraries@haskell.org-- Stability : stable-- Portability : portable---- This module provides facilities for parsing the command-line options-- in a standalone program. It is essentially a Haskell port of the GNU-- @getopt@ library.-------------------------------------------------------------------------------{-
Sven Panne <Sven.Panne@informatik.uni-muenchen.de> Oct. 1996 (small
changes Dec. 1997)
Two rather obscure features are missing: The Bash 2.0 non-option hack
(if you don't already know it, you probably don't want to hear about
it...) and the recognition of long options with a single dash
(e.g. '-help' is recognised as '--help', as long as there is no short
option 'h').
Other differences between GNU's getopt and this implementation:
* To enforce a coherent description of options and arguments, there
 are explanation fields in the option/argument descriptor.
* Error messages are now more informative, but no longer POSIX
 compliant... :-(
And a final Haskell advertisement: The GNU C implementation uses well
over 1100 lines, we need only 195 here, including a 46 line example!
:-)
-}moduleSystem.Console.GetOpt (-- * GetOptgetOpt ,getOpt' ,usageInfo ,ArgOrder (..),OptDescr (..),ArgDescr (..),-- * Examples-- |To hopefully illuminate the role of the different data structures,-- here are the command-line options for a (very simple) compiler,-- done in two different ways.-- The difference arises because the type of 'getOpt' is-- parameterized by the type of values derived from flags.-- ** Interpreting flags as concrete values-- $example1-- ** Interpreting flags as transformations of an options record-- $example2)whereimportPrelude importGHC.Internal.Data.List (isPrefixOf ,find )-- |What to do with options following non-optionsdataArgOrder a =RequireOrder -- ^ no option processing after first non-option|Permute -- ^ freely intersperse options and non-options|ReturnInOrder (String ->a )-- ^ wrap non-options into options{-|
Each 'OptDescr' describes a single option.
The arguments to 'Option' are:
* list of short option characters
* list of long option strings (without \"--\")
* argument descriptor
* explanation of option for user
-}dataOptDescr a =-- description of a single options:Option [Char ]-- list of short option characters[String ]-- list of long option strings (without "--")(ArgDescr a )-- argument descriptorString -- explanation of option for user-- |Describes whether an option takes an argument or not, and if so-- how the argument is injected into a value of type @a@.dataArgDescr a =NoArg a -- ^ no argument expected|ReqArg (String ->a )String -- ^ option requires argument|OptArg (Maybe String ->a )String -- ^ optional argument-- | @since 4.7.0.0instanceFunctor ArgOrder wherefmap :: forall a b. (a -> b) -> ArgOrder a -> ArgOrder b
fmap a -> b
_ArgOrder a
RequireOrder =ArgOrder b
forall a. ArgOrder a
RequireOrder fmap a -> b
_ArgOrder a
Permute =ArgOrder b
forall a. ArgOrder a
Permute fmap a -> b
f (ReturnInOrder String -> a
g )=(String -> b) -> ArgOrder b
forall a. (String -> a) -> ArgOrder a
ReturnInOrder (a -> b
f (a -> b) -> (String -> a) -> String -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> a
g )-- | @since 4.7.0.0instanceFunctor OptDescr wherefmap :: forall a b. (a -> b) -> OptDescr a -> OptDescr b
fmap a -> b
f (Option String
a [String]
b ArgDescr a
argDescr String
c )=String -> [String] -> ArgDescr b -> String -> OptDescr b
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
a [String]
b ((a -> b) -> ArgDescr a -> ArgDescr b
forall a b. (a -> b) -> ArgDescr a -> ArgDescr b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f ArgDescr a
argDescr )String
c -- | @since 4.7.0.0instanceFunctor ArgDescr wherefmap :: forall a b. (a -> b) -> ArgDescr a -> ArgDescr b
fmap a -> b
f (NoArg a
a )=b -> ArgDescr b
forall a. a -> ArgDescr a
NoArg (a -> b
f a
a )fmap a -> b
f (ReqArg String -> a
g String
s )=(String -> b) -> String -> ArgDescr b
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (a -> b
f (a -> b) -> (String -> a) -> String -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> a
g )String
s fmap a -> b
f (OptArg Maybe String -> a
g String
s )=(Maybe String -> b) -> String -> ArgDescr b
forall a. (Maybe String -> a) -> String -> ArgDescr a
OptArg (a -> b
f (a -> b) -> (Maybe String -> a) -> Maybe String -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe String -> a
g )String
s dataOptKind a -- kind of cmd line arg (internal use only):=Opt a -- an option|UnreqOpt String -- an un-recognized option|NonOpt String -- a non-option|EndOfOpts -- end-of-options marker (i.e. "--")|OptErr String -- something went wrong...-- | Return a string describing the usage of a command, derived from-- the header (first argument) and the options described by the-- second argument.usageInfo ::String -- header->[OptDescr a ]-- option descriptors->String -- nicely formatted description of optionsusageInfo :: forall a. String -> [OptDescr a] -> String
usageInfo String
header [OptDescr a]
optDescr =[String] -> String
unlines (String
header String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
table )where([String]
ss ,[String]
ls ,[String]
ds )=([(String, String, String)] -> ([String], [String], [String])
forall a b c. [(a, b, c)] -> ([a], [b], [c])
unzip3 ([(String, String, String)] -> ([String], [String], [String]))
-> ([OptDescr a] -> [(String, String, String)])
-> [OptDescr a]
-> ([String], [String], [String])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (OptDescr a -> [(String, String, String)])
-> [OptDescr a] -> [(String, String, String)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap OptDescr a -> [(String, String, String)]
forall a. OptDescr a -> [(String, String, String)]
fmtOpt )[OptDescr a]
optDescr table :: [String]
table =(String -> String -> String -> String)
-> [String] -> [String] -> [String] -> [String]
forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3 String -> String -> String -> String
paste ([String] -> [String]
sameLen [String]
ss )([String] -> [String]
sameLen [String]
ls )[String]
ds paste :: String -> String -> String -> String
paste String
x String
y String
z =String
" "String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" "String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
y String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" "String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
z sameLen :: [String] -> [String]
sameLen [String]
xs =Int -> [String] -> [String]
flushLeft (([Int] -> Int
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([Int] -> Int) -> ([String] -> [Int]) -> [String] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> Int) -> [String] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length )[String]
xs )[String]
xs flushLeft :: Int -> [String] -> [String]
flushLeft Int
n [String]
xs =[Int -> String -> String
forall a. Int -> [a] -> [a]
take Int
n (String
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ Char -> String
forall a. a -> [a]
repeat Char
' ')|String
x <-[String]
xs ]fmtOpt ::OptDescr a ->[(String ,String ,String )]fmtOpt :: forall a. OptDescr a -> [(String, String, String)]
fmtOpt (Option String
sos [String]
los ArgDescr a
ad String
descr )=caseString -> [String]
lines String
descr of[]->[(String
sosFmt ,String
losFmt ,String
"")](String
d : [String]
ds )->(String
sosFmt ,String
losFmt ,String
d )(String, String, String)
-> [(String, String, String)] -> [(String, String, String)]
forall a. a -> [a] -> [a]
: [(String
"",String
"",String
d' )|String
d' <-[String]
ds ]wheresepBy :: Char -> [String] -> String
sepBy Char
_[]=String
""sepBy Char
_[String
x ]=String
x sepBy Char
ch (String
x : [String]
xs )=String
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ Char
ch Char -> String -> String
forall a. a -> [a] -> [a]
: Char
' 'Char -> String -> String
forall a. a -> [a] -> [a]
: Char -> [String] -> String
sepBy Char
ch [String]
xs sosFmt :: String
sosFmt =Char -> [String] -> String
sepBy Char
','((Char -> String) -> String -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (ArgDescr a -> Char -> String
forall a. ArgDescr a -> Char -> String
fmtShort ArgDescr a
ad )String
sos )losFmt :: String
losFmt =Char -> [String] -> String
sepBy Char
','((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (ArgDescr a -> String -> String
forall a. ArgDescr a -> String -> String
fmtLong ArgDescr a
ad )[String]
los )fmtShort ::ArgDescr a ->Char ->String fmtShort :: forall a. ArgDescr a -> Char -> String
fmtShort (NoArg a
_)Char
so =String
"-"String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Char
so ]fmtShort (ReqArg String -> a
_String
ad )Char
so =String
"-"String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Char
so ]String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" "String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
ad fmtShort (OptArg Maybe String -> a
_String
ad )Char
so =String
"-"String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Char
so ]String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"["String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
ad String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"]"fmtLong ::ArgDescr a ->String ->String fmtLong :: forall a. ArgDescr a -> String -> String
fmtLong (NoArg a
_)String
lo =String
"--"String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
lo fmtLong (ReqArg String -> a
_String
ad )String
lo =String
"--"String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
lo String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"="String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
ad fmtLong (OptArg Maybe String -> a
_String
ad )String
lo =String
"--"String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
lo String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"[="String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
ad String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"]"{-|
Process the command-line, and return the list of values that matched
(and those that didn\'t). The arguments are:
* The order requirements (see 'ArgOrder')
* The option descriptions (see 'OptDescr')
* The actual command line arguments (presumably got from
 'GHC.Internal.System.Environment.getArgs').
'getOpt' returns a triple consisting of the option arguments, a list
of non-options, and a list of error messages.
-}getOpt ::ArgOrder a -- non-option handling->[OptDescr a ]-- option descriptors->[String ]-- the command-line arguments->([a ],[String ],[String ])-- (options,non-options,error messages)getOpt :: forall a.
ArgOrder a -> [OptDescr a] -> [String] -> ([a], [String], [String])
getOpt ArgOrder a
ordering [OptDescr a]
optDescr [String]
args =([a]
os ,[String]
xs ,[String]
es [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
errUnrec [String]
us )where([a]
os ,[String]
xs ,[String]
us ,[String]
es )=ArgOrder a
-> [OptDescr a] -> [String] -> ([a], [String], [String], [String])
forall a.
ArgOrder a
-> [OptDescr a] -> [String] -> ([a], [String], [String], [String])
getOpt' ArgOrder a
ordering [OptDescr a]
optDescr [String]
args {-|
This is almost the same as 'getOpt', but returns a quadruple
consisting of the option arguments, a list of non-options, a list of
unrecognized options, and a list of error messages.
-}getOpt' ::ArgOrder a -- non-option handling->[OptDescr a ]-- option descriptors->[String ]-- the command-line arguments->([a ],[String ],[String ],[String ])-- (options,non-options,unrecognized,error messages)getOpt' :: forall a.
ArgOrder a
-> [OptDescr a] -> [String] -> ([a], [String], [String], [String])
getOpt' ArgOrder a
_[OptDescr a]
_[]=([],[],[],[])getOpt' ArgOrder a
ordering [OptDescr a]
optDescr (String
arg : [String]
args )=OptKind a -> ArgOrder a -> ([a], [String], [String], [String])
procNextOpt OptKind a
opt ArgOrder a
ordering whereprocNextOpt :: OptKind a -> ArgOrder a -> ([a], [String], [String], [String])
procNextOpt (Opt a
o )ArgOrder a
_=(a
o a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
os ,[String]
xs ,[String]
us ,[String]
es )procNextOpt (UnreqOpt String
u )ArgOrder a
_=([a]
os ,[String]
xs ,String
u String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
us ,[String]
es )procNextOpt (NonOpt String
x )ArgOrder a
RequireOrder =([],String
x String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
rest ,[],[])procNextOpt (NonOpt String
x )ArgOrder a
Permute =([a]
os ,String
x String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
xs ,[String]
us ,[String]
es )procNextOpt (NonOpt String
x )(ReturnInOrder String -> a
f )=(String -> a
f String
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
os ,[String]
xs ,[String]
us ,[String]
es )procNextOpt OptKind a
EndOfOpts ArgOrder a
RequireOrder =([],[String]
rest ,[],[])procNextOpt OptKind a
EndOfOpts ArgOrder a
Permute =([],[String]
rest ,[],[])procNextOpt OptKind a
EndOfOpts (ReturnInOrder String -> a
f )=((String -> a) -> [String] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map String -> a
f [String]
rest ,[],[],[])procNextOpt (OptErr String
e )ArgOrder a
_=([a]
os ,[String]
xs ,[String]
us ,String
e String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
es )(OptKind a
opt ,[String]
rest )=String -> [String] -> [OptDescr a] -> (OptKind a, [String])
forall a.
String -> [String] -> [OptDescr a] -> (OptKind a, [String])
getNext String
arg [String]
args [OptDescr a]
optDescr ([a]
os ,[String]
xs ,[String]
us ,[String]
es )=ArgOrder a
-> [OptDescr a] -> [String] -> ([a], [String], [String], [String])
forall a.
ArgOrder a
-> [OptDescr a] -> [String] -> ([a], [String], [String], [String])
getOpt' ArgOrder a
ordering [OptDescr a]
optDescr [String]
rest -- take a look at the next cmd line arg and decide what to do with itgetNext ::String ->[String ]->[OptDescr a ]->(OptKind a ,[String ])getNext :: forall a.
String -> [String] -> [OptDescr a] -> (OptKind a, [String])
getNext (Char
'-': Char
'-': [])[String]
rest [OptDescr a]
_=(OptKind a
forall a. OptKind a
EndOfOpts ,[String]
rest )getNext (Char
'-': Char
'-': String
xs )[String]
rest [OptDescr a]
optDescr =String -> [String] -> [OptDescr a] -> (OptKind a, [String])
forall a.
String -> [String] -> [OptDescr a] -> (OptKind a, [String])
longOpt String
xs [String]
rest [OptDescr a]
optDescr getNext (Char
'-': Char
x : String
xs )[String]
rest [OptDescr a]
optDescr =Char -> String -> [String] -> [OptDescr a] -> (OptKind a, [String])
forall a.
Char -> String -> [String] -> [OptDescr a] -> (OptKind a, [String])
shortOpt Char
x String
xs [String]
rest [OptDescr a]
optDescr getNext String
a [String]
rest [OptDescr a]
_=(String -> OptKind a
forall a. String -> OptKind a
NonOpt String
a ,[String]
rest )-- handle long optionlongOpt ::String ->[String ]->[OptDescr a ]->(OptKind a ,[String ])longOpt :: forall a.
String -> [String] -> [OptDescr a] -> (OptKind a, [String])
longOpt String
ls [String]
rs [OptDescr a]
optDescr =[ArgDescr a] -> String -> [String] -> (OptKind a, [String])
long [ArgDescr a]
ads String
arg [String]
rs where(String
opt ,String
arg )=(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
ls getWith :: (String -> String -> Bool) -> [OptDescr a]
getWith String -> String -> Bool
p =[OptDescr a
o |o :: OptDescr a
o @(Option String
_[String]
xs ArgDescr a
_String
_)<-[OptDescr a]
optDescr ,(String -> Bool) -> [String] -> Maybe String
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (String -> String -> Bool
p String
opt )[String]
xs Maybe String -> Maybe String -> Bool
forall a. Eq a => a -> a -> Bool
/= Maybe String
forall a. Maybe a
Nothing ]exact :: [OptDescr a]
exact =(String -> String -> Bool) -> [OptDescr a]
getWith String -> String -> Bool
forall a. Eq a => a -> a -> Bool
(==) options :: [OptDescr a]
options =if[OptDescr a] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [OptDescr a]
exact then(String -> String -> Bool) -> [OptDescr a]
getWith String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
isPrefixOf else[OptDescr a]
exact ads :: [ArgDescr a]
ads =[ArgDescr a
ad |Option String
_[String]
_ArgDescr a
ad String
_<-[OptDescr a]
options ]optStr :: String
optStr =(String
"--"String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
opt )long :: [ArgDescr a] -> String -> [String] -> (OptKind a, [String])
long (ArgDescr a
_: ArgDescr a
_: [ArgDescr a]
_)String
_[String]
rest =([OptDescr a] -> String -> OptKind a
forall a. [OptDescr a] -> String -> OptKind a
errAmbig [OptDescr a]
options String
optStr ,[String]
rest )long [NoArg a
a ][][String]
rest =(a -> OptKind a
forall a. a -> OptKind a
Opt a
a ,[String]
rest )long [NoArg a
_](Char
'=': String
_)[String]
rest =(String -> OptKind a
forall a. String -> OptKind a
errNoArg String
optStr ,[String]
rest )long [ReqArg String -> a
_String
d ][][]=(String -> String -> OptKind a
forall a. String -> String -> OptKind a
errReq String
d String
optStr ,[])long [ReqArg String -> a
f String
_][](String
r : [String]
rest )=(a -> OptKind a
forall a. a -> OptKind a
Opt (String -> a
f String
r ),[String]
rest )long [ReqArg String -> a
f String
_](Char
'=': String
xs )[String]
rest =(a -> OptKind a
forall a. a -> OptKind a
Opt (String -> a
f String
xs ),[String]
rest )long [OptArg Maybe String -> a
f String
_][][String]
rest =(a -> OptKind a
forall a. a -> OptKind a
Opt (Maybe String -> a
f Maybe String
forall a. Maybe a
Nothing ),[String]
rest )long [OptArg Maybe String -> a
f String
_](Char
'=': String
xs )[String]
rest =(a -> OptKind a
forall a. a -> OptKind a
Opt (Maybe String -> a
f (String -> Maybe String
forall a. a -> Maybe a
Just String
xs )),[String]
rest )long [ArgDescr a]
_String
_[String]
rest =(String -> OptKind a
forall a. String -> OptKind a
UnreqOpt (String
"--"String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
ls ),[String]
rest )-- handle short optionshortOpt ::Char ->String ->[String ]->[OptDescr a ]->(OptKind a ,[String ])shortOpt :: forall a.
Char -> String -> [String] -> [OptDescr a] -> (OptKind a, [String])
shortOpt Char
y String
ys [String]
rs [OptDescr a]
optDescr =[ArgDescr a] -> String -> [String] -> (OptKind a, [String])
short [ArgDescr a]
ads String
ys [String]
rs whereoptions :: [OptDescr a]
options =[OptDescr a
o |o :: OptDescr a
o @(Option String
ss [String]
_ArgDescr a
_String
_)<-[OptDescr a]
optDescr ,Char
s <-String
ss ,Char
y Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
s ]ads :: [ArgDescr a]
ads =[ArgDescr a
ad |Option String
_[String]
_ArgDescr a
ad String
_<-[OptDescr a]
options ]optStr :: String
optStr =Char
'-'Char -> String -> String
forall a. a -> [a] -> [a]
: [Char
y ]short :: [ArgDescr a] -> String -> [String] -> (OptKind a, [String])
short (ArgDescr a
_: ArgDescr a
_: [ArgDescr a]
_)String
_[String]
rest =([OptDescr a] -> String -> OptKind a
forall a. [OptDescr a] -> String -> OptKind a
errAmbig [OptDescr a]
options String
optStr ,[String]
rest )short (NoArg a
a : [ArgDescr a]
_)[][String]
rest =(a -> OptKind a
forall a. a -> OptKind a
Opt a
a ,[String]
rest )short (NoArg a
a : [ArgDescr a]
_)String
xs [String]
rest =(a -> OptKind a
forall a. a -> OptKind a
Opt a
a ,(Char
'-'Char -> String -> String
forall a. a -> [a] -> [a]
: String
xs )String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
rest )short (ReqArg String -> a
_String
d : [ArgDescr a]
_)[][]=(String -> String -> OptKind a
forall a. String -> String -> OptKind a
errReq String
d String
optStr ,[])short (ReqArg String -> a
f String
_: [ArgDescr a]
_)[](String
r : [String]
rest )=(a -> OptKind a
forall a. a -> OptKind a
Opt (String -> a
f String
r ),[String]
rest )short (ReqArg String -> a
f String
_: [ArgDescr a]
_)String
xs [String]
rest =(a -> OptKind a
forall a. a -> OptKind a
Opt (String -> a
f String
xs ),[String]
rest )short (OptArg Maybe String -> a
f String
_: [ArgDescr a]
_)[][String]
rest =(a -> OptKind a
forall a. a -> OptKind a
Opt (Maybe String -> a
f Maybe String
forall a. Maybe a
Nothing ),[String]
rest )short (OptArg Maybe String -> a
f String
_: [ArgDescr a]
_)String
xs [String]
rest =(a -> OptKind a
forall a. a -> OptKind a
Opt (Maybe String -> a
f (String -> Maybe String
forall a. a -> Maybe a
Just String
xs )),[String]
rest )short [][][String]
rest =(String -> OptKind a
forall a. String -> OptKind a
UnreqOpt String
optStr ,[String]
rest )short []String
xs [String]
rest =(String -> OptKind a
forall a. String -> OptKind a
UnreqOpt String
optStr ,(Char
'-'Char -> String -> String
forall a. a -> [a] -> [a]
: String
xs )String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
rest )-- miscellaneous error formattingerrAmbig ::[OptDescr a ]->String ->OptKind a errAmbig :: forall a. [OptDescr a] -> String -> OptKind a
errAmbig [OptDescr a]
ods String
optStr =String -> OptKind a
forall a. String -> OptKind a
OptErr (String -> [OptDescr a] -> String
forall a. String -> [OptDescr a] -> String
usageInfo String
header [OptDescr a]
ods )whereheader :: String
header =String
"option `"String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
optStr String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' is ambiguous; could be one of:"errReq ::String ->String ->OptKind a errReq :: forall a. String -> String -> OptKind a
errReq String
d String
optStr =String -> OptKind a
forall a. String -> OptKind a
OptErr (String
"option `"String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
optStr String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' requires an argument "String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
d String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n")errUnrec ::String ->String errUnrec :: String -> String
errUnrec String
optStr =String
"unrecognized option `"String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
optStr String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'\n"errNoArg ::String ->OptKind a errNoArg :: forall a. String -> OptKind a
errNoArg String
optStr =String -> OptKind a
forall a. String -> OptKind a
OptErr (String
"option `"String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
optStr String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' doesn't allow an argument\n"){-
-----------------------------------------------------------------------------------------
-- and here a small and hopefully enlightening example:
data Flag = Verbose | Version | Name String | Output String | Arg String deriving Show
options :: [OptDescr Flag]
options =
 [Option ['v'] ["verbose"] (NoArg Verbose) "verbosely list files",
 Option ['V','?'] ["version","release"] (NoArg Version) "show version info",
 Option ['o'] ["output"] (OptArg out "FILE") "use FILE for dump",
 Option ['n'] ["name"] (ReqArg Name "USER") "only dump USER's files"]
out :: Maybe String -> Flag
out Nothing = Output "stdout"
out (Just o) = Output o
test :: ArgOrder Flag -> [String] -> String
test order cmdline = case getOpt order options cmdline of
 (o,n,[] ) -> "options=" ++ show o ++ " args=" ++ show n ++ "\n"
 (_,_,errs) -> concat errs ++ usageInfo header options
 where header = "Usage: foobar [OPTION...] files..."
-- example runs:
-- putStr (test RequireOrder ["foo","-v"])
-- ==> options=[] args=["foo", "-v"]
-- putStr (test Permute ["foo","-v"])
-- ==> options=[Verbose] args=["foo"]
-- putStr (test (ReturnInOrder Arg) ["foo","-v"])
-- ==> options=[Arg "foo", Verbose] args=[]
-- putStr (test Permute ["foo","--","-v"])
-- ==> options=[] args=["foo", "-v"]
-- putStr (test Permute ["-?o","--name","bar","--na=baz"])
-- ==> options=[Version, Output "stdout", Name "bar", Name "baz"] args=[]
-- putStr (test Permute ["--ver","foo"])
-- ==> option `--ver' is ambiguous; could be one of:
-- -v --verbose verbosely list files
-- -V, -? --version, --release show version info
-- Usage: foobar [OPTION...] files...
-- -v --verbose verbosely list files
-- -V, -? --version, --release show version info
-- -o[FILE] --output[=FILE] use FILE for dump
-- -n USER --name=USER only dump USER's files
-----------------------------------------------------------------------------------------
-}{- $example1
A simple choice for the type associated with flags is to define a type
@Flag@ as an algebraic type representing the possible flags and their
arguments:
> module Opts1 where
>
> import System.Console.GetOpt
> import GHC.Internal.Data.Maybe ( fromMaybe )
>
> data Flag
> = Verbose | Version
> | Input String | Output String | LibDir String
> deriving Show
>
> options :: [OptDescr Flag]
> options =
> [ Option ['v'] ["verbose"] (NoArg Verbose) "chatty output on stderr"
> , Option ['V','?'] ["version"] (NoArg Version) "show version number"
> , Option ['o'] ["output"] (OptArg outp "FILE") "output FILE"
> , Option ['c'] [] (OptArg inp "FILE") "input FILE"
> , Option ['L'] ["libdir"] (ReqArg LibDir "DIR") "library directory"
> ]
>
> inp,outp :: Maybe String -> Flag
> outp = Output . fromMaybe "stdout"
> inp = Input . fromMaybe "stdin"
>
> compilerOpts :: [String] -> IO ([Flag], [String])
> compilerOpts argv =
> case getOpt Permute options argv of
> (o,n,[] ) -> return (o,n)
> (_,_,errs) -> ioError (userError (concat errs ++ usageInfo header options))
> where header = "Usage: ic [OPTION...] files..."
Then the rest of the program will use the constructed list of flags
to determine it\'s behaviour.
-}{- $example2
A different approach is to group the option values in a record of type
@Options@, and have each flag yield a function of type
@Options -> Options@ transforming this record.
> module Opts2 where
>
> import System.Console.GetOpt
> import GHC.Internal.Data.Maybe ( fromMaybe )
>
> data Options = Options
> { optVerbose :: Bool
> , optShowVersion :: Bool
> , optOutput :: Maybe FilePath
> , optInput :: Maybe FilePath
> , optLibDirs :: [FilePath]
> } deriving Show
>
> defaultOptions = Options
> { optVerbose = False
> , optShowVersion = False
> , optOutput = Nothing
> , optInput = Nothing
> , optLibDirs = []
> }
>
> options :: [OptDescr (Options -> Options)]
> options =
> [ Option ['v'] ["verbose"]
> (NoArg (\ opts -> opts { optVerbose = True }))
> "chatty output on stderr"
> , Option ['V','?'] ["version"]
> (NoArg (\ opts -> opts { optShowVersion = True }))
> "show version number"
> , Option ['o'] ["output"]
> (OptArg ((\ f opts -> opts { optOutput = Just f }) . fromMaybe "output")
> "FILE")
> "output FILE"
> , Option ['c'] []
> (OptArg ((\ f opts -> opts { optInput = Just f }) . fromMaybe "input")
> "FILE")
> "input FILE"
> , Option ['L'] ["libdir"]
> (ReqArg (\ d opts -> opts { optLibDirs = optLibDirs opts ++ [d] }) "DIR")
> "library directory"
> ]
>
> compilerOpts :: [String] -> IO (Options, [String])
> compilerOpts argv =
> case getOpt Permute options argv of
> (o,n,[] ) -> return (foldl (flip id) defaultOptions o, n)
> (_,_,errs) -> ioError (userError (concat errs ++ usageInfo header options))
> where header = "Usage: ic [OPTION...] files..."
Similarly, each flag could yield a monadic function transforming a record,
of type @Options -> IO Options@ (or any other monad), allowing option
processing to perform actions of the chosen monad, e.g. printing help or
version messages, checking that file arguments exist, etc.
-}

AltStyle によって変換されたページ (->オリジナル) /