packages feed

dedukti-1.1.3: System/Console/Option.hs

-- |
-- Copyright : © 2009 CNRS - École Polytechnique - INRIA
-- License   : GPL
--
-- Parse command-line options (or flags).
--
-- Flag descriptions obey the following conventions:
--
-- * double hyphen flags don't have arguments.
--
-- * Everything after the first letter of a hyphen flag is part of the
-- argument.

module System.Console.Option where

import Text.PrettyPrint.Leijen
import Data.Either (partitionEithers)
import Data.List (partition, isPrefixOf)
import System.IO


data FlagArity f = Nullary String f
                 | Unary String (String -> f)

type Description f = [([FlagArity f], String)]

parseCmdline :: Description f -> [String] -> ([f], [String], [String])
parseCmdline desc args =
  let (hyphened, rest) = partition (\arg -> "-" `isPrefixOf` arg) args
      (errors, flags) = partitionEithers $ map toFlag hyphened
  in (flags, rest, errors)
    where flagmap = concatMap fst desc
          unpack ('-':'-':name) = (name, "")
          unpack ('-':name:arg) = ([name], arg)
          unpack x = error $ "Malformed argument: " ++ x
          lookupFlag name arg (Nullary n f : desc)
              | fst (unpack n) == name =
                  if null arg
                  then Right f
                  else Left $ "No argument expected for flag " ++ n
          lookupFlag name arg (Unary n f : desc)
              | fst (unpack n) == name = Right (f arg)
          lookupFlag name _ [] = Left $ "Flag not found: " ++ name
          lookupFlag name arg (_:desc) = lookupFlag name arg desc
          toFlag x | (name, arg) <- unpack x = lookupFlag name arg flagmap

printUsage :: Doc -> IO ()
printUsage = hPutStrLn stderr . show

printHelp :: Doc -> Description f -> IO ()
printHelp usage desc = do
  let flags = vsep (map pflag desc)
  putStrLn $ show $ usage <$> text "Options:" <$> indent 4 flags
    where pflag (flags, desc) = fillBreak 14 (hcat $ punctuate (text ", ") $
                                   map (text . name) flags) <+> text desc
          name (Nullary n _) = n
          name (Unary n _) = n