1
0
forked from GitHub/gf-core
Files
gf-core/src/GF/Infra/Option.hs
2004-04-01 09:51:32 +00:00

234 lines
5.8 KiB
Haskell

module Option where
import List (partition)
import Char (isDigit)
-- all kinds of options, to be kept abstract
newtype Option = Opt (String,[String]) deriving (Eq,Show,Read)
newtype Options = Opts [Option] deriving (Eq,Show,Read)
noOptions :: Options
noOptions = Opts []
iOpt o = Opt (o,[]) -- simple option -o
aOpt o a = Opt (o,[a]) -- option with argument -o=a
iOpts = Opts
oArg s = s -- value of option argument
oElem :: Option -> Options -> Bool
oElem o (Opts os) = elem o os
eqOpt :: String -> Option -> Bool
eqOpt s (Opt (o, [])) = s == o
eqOpt s _ = False
type OptFun = String -> Option
getOptVal :: Options -> OptFun -> Maybe String
getOptVal (Opts os) fopt =
case [a | opt@(Opt (o,[a])) <- os, opt == fopt a] of
a:_ -> Just a
_ -> Nothing
getOptInt :: Options -> OptFun -> Maybe Int
getOptInt opts f = do
s <- getOptVal opts f
if (not (null s) && all isDigit s) then return (read s) else Nothing
optIntOrAll :: Options -> OptFun -> [a] -> [a]
optIntOrAll opts f = case getOptInt opts f of
Just i -> take i
_ -> id
optIntOrN :: Options -> OptFun -> Int -> Int
optIntOrN opts f n = case getOptInt opts f of
Just i -> i
_ -> n
optIntOrOne :: Options -> OptFun -> Int
optIntOrOne opts f = optIntOrN opts f 1
changeOptVal :: Options -> OptFun -> String -> Options
changeOptVal os f x =
addOption (f x) $ maybe os (\y -> removeOption (f y) os) $ getOptVal os f
addOption :: Option -> Options -> Options
addOption o (Opts os) = iOpts (o:os)
addOptions (Opts os) os0 = foldr addOption os0 os
concatOptions :: [Options] -> Options
concatOptions = foldr addOptions noOptions
removeOption :: Option -> Options -> Options
removeOption o (Opts os) = iOpts (filter (/=o) os)
removeOptions (Opts os) os0 = foldr removeOption os0 os
options = foldr addOption noOptions
unionOptions :: Options -> Options -> Options
unionOptions (Opts os) (Opts os') = Opts (os ++ os')
-- parsing options, with prefix pre (e.g. "-")
getOptions :: String -> [String] -> (Options, [String])
getOptions pre inp = let
(os,rest) = span (isOption pre) inp -- options before args
in
(Opts (map (pOption pre) os), rest)
pOption :: String -> String -> Option
pOption pre s = case span (/= '=') (drop (length pre) s) of
(f,_:a) -> aOpt f a
(o,[]) -> iOpt o
isOption :: String -> String -> Bool
isOption pre = (==pre) . take (length pre)
-- printing options, without prefix
prOpt (Opt (s,[])) = s
prOpt (Opt (s,xs)) = s ++ "=" ++ concat xs
prOpts (Opts os) = unwords $ map prOpt os
-- a suggestion for option names
-- parsing
strictParse = iOpt "strict"
forgiveParse = iOpt "n"
ignoreParse = iOpt "ign"
literalParse = iOpt "lit"
rawParse = iOpt "raw"
firstParse = iOpt "1"
dontParse = iOpt "read" -- parse as term instead of string
-- grammar formats
showAbstr = iOpt "abs"
showXML = iOpt "xml"
showOld = iOpt "old"
showLatex = iOpt "latex"
showFullForm = iOpt "fullform"
showEBNF = iOpt "ebnf"
showCF = iOpt "cf"
showWords = iOpt "ws"
showOpts = iOpt "opts"
-- showOptim = iOpt "opt"
isCompiled = iOpt "gfc"
isHaskell = iOpt "gfhs"
noCompOpers = iOpt "nocomp"
retainOpers = iOpt "retain"
defaultGrOpts = []
newParser = iOpt "new"
noCF = iOpt "nocf"
checkCirc = iOpt "nocirc"
noCheckCirc = iOpt "nocheckcirc"
lexerByNeed = iOpt "cflexer"
-- linearization
allLin = iOpt "all"
firstLin = iOpt "one"
distinctLin = iOpt "nub"
dontLin = iOpt "show"
showRecord = iOpt "record"
showStruct = iOpt "structured"
xmlLin = showXML
latexLin = showLatex
tableLin = iOpt "table"
defaultLinOpts = [firstLin]
useUTF8 = iOpt "utf8"
showLang = iOpt "lang"
-- other
beVerbose = iOpt "v"
showInfo = iOpt "i"
beSilent = iOpt "s"
emitCode = iOpt "o"
notEmitCode = iOpt "noemit"
makeMulti = iOpt "multi"
beShort = iOpt "short"
wholeGrammar = iOpt "w"
makeFudget = iOpt "f"
byLines = iOpt "lines"
byWords = iOpt "words"
analMorpho = iOpt "morpho"
doTrace = iOpt "tr"
noCPU = iOpt "nocpu"
doCompute = iOpt "c"
optimizeCanon = iOpt "opt"
stripQualif = iOpt "strip"
nostripQualif = iOpt "nostrip"
showAll = iOpt "all"
fromSource = iOpt "src"
-- mainly for stand-alone
useUnicode = iOpt "unicode"
optCompute = iOpt "compute"
optCheck = iOpt "typecheck"
optParaphrase = iOpt "paraphrase"
forJava = iOpt "java"
-- for edit session
allLangs = iOpt "All"
absView = iOpt "Abs"
-- options that take arguments
useTokenizer = aOpt "lexer"
useUntokenizer = aOpt "unlexer"
useParser = aOpt "parser"
withFun = aOpt "fun"
firstCat = aOpt "cat" -- used on command line
gStartCat = aOpt "startcat" -- used in grammar, to avoid clash w res word
useLanguage = aOpt "lang"
useResource = aOpt "res"
speechLanguage = aOpt "language"
useFont = aOpt "font"
grammarFormat = aOpt "format"
grammarPrinter = aOpt "printer"
filterString = aOpt "filter"
termCommand = aOpt "transform"
transferFun = aOpt "transfer"
forForms = aOpt "forms"
menuDisplay = aOpt "menu"
sizeDisplay = aOpt "size"
typeDisplay = aOpt "types"
noDepTypes = aOpt "nodeptypes"
extractGr = aOpt "extract"
pathList = aOpt "path"
uniCoding = aOpt "coding"
useName = aOpt "name"
useAbsName = aOpt "abs"
useCncName = aOpt "cnc"
useResName = aOpt "res"
markLin = aOpt "mark"
markOptXML = oArg "xml"
markOptJava = oArg "java"
markOptStruct = oArg "struct"
markOptFocus = oArg "focus"
-- refinement order
nextRefine = aOpt "nextrefine"
firstRefine = oArg "first"
lastRefine = oArg "last"
-- Boolean flags
flagYes = oArg "yes"
flagNo = oArg "no"
-- integer flags
flagDepth = aOpt "depth"
flagLength = aOpt "length"
flagNumber = aOpt "number"
caseYesNo :: Options -> OptFun -> Maybe Bool
caseYesNo opts f = do
v <- getOptVal opts f
if v == flagYes then return True
else if v == flagNo then return False
else Nothing