ONC-RPC-0.1: tools/hsrpcgen.hs
{-# LANGUAGE RecordWildCards #-}
import Data.List (foldl', intercalate)
import Data.Maybe (fromMaybe)
import qualified System.Console.GetOpt as Opt
import System.Environment (getProgName, getArgs)
import System.Exit (exitFailure)
import System.FilePath (splitExtension, splitDirectories)
import System.IO (hPutStrLn, stderr)
import Network.ONCRPC.XDR.Generate
data Opts = Opts
{ optGenerate :: GenerateOptions
, optOutput :: FilePath
}
defModuleName :: String
defModuleName = "Prot"
defOpts :: Opts
defOpts = Opts
{ optGenerate = GenerateOptions
{ generateModuleName = defModuleName
, generateReidentOptions = defaultReidentOptions
}
, optOutput = "-"
}
setGenerate :: (GenerateOptions -> GenerateOptions) -> Opts -> Opts
setGenerate f o = o{ optGenerate = f (optGenerate o) }
setReident :: (ReidentOptions -> ReidentOptions) -> Opts -> Opts
setReident f = setGenerate $ \g -> g{ generateReidentOptions = f (generateReidentOptions g) }
setOutput :: FilePath -> Opts -> Opts
setOutput f o@Opts{ optGenerate = g } = o
{ optOutput = f
, optGenerate = if generateModuleName g == defModuleName && e == ".hs"
then g{ generateModuleName = m } else g
} where
(b, e) = splitExtension f
m = intercalate "." $ splitDirectories b
opts :: [Opt.OptDescr (Opts -> Opts)]
opts =
[ Opt.Option "o" ["output"]
(Opt.ReqArg setOutput "FILE")
"write the output to FILE [stdout]"
, Opt.Option "m" ["module"]
(Opt.ReqArg (\a -> setGenerate $ \g -> g{ generateModuleName = a }) "NAME")
("set the generated module name [" ++ defModuleName ++ " or from output filename]")
, Opt.Option "P" ["procedures-unique"]
(Opt.NoArg (setReident $ \r -> r{ reidentJoinProcedure = Nothing }))
"assume program version and procedure names are unique: don't add prefixes"
, Opt.Option "F" ["fields-unique"]
(Opt.NoArg (setReident $ \r -> r{ reidentJoinField = Nothing }))
"assume struct and union fields are unique: don't add type prefixes"
, Opt.Option "L" ["lowercase-prefix"]
(Opt.OptArg (\a -> setReident $ \r -> r{ reidentLowerPrefix = fromMaybe "_" a }) "PREFIX")
"make identifiers lower-case by prefixing them (with underscore)"
, Opt.Option "U" ["uppercase-prefix"]
(Opt.ReqArg (\a -> setReident $ \r -> r{ reidentLowerPrefix = a }) "PREFIX")
"make identifiers upper-case by prefixing them"
]
output :: FilePath -> String -> IO ()
output "-" = putStrLn
output f = writeFile f
main :: IO ()
main = do
prog <- getProgName
args <- getArgs
(Opts{..}, f) <- case Opt.getOpt Opt.Permute opts args of
(ol, [f], []) -> return (foldl' (flip ($)) defOpts ol, f)
(_, _, err) -> do
mapM_ (hPutStrLn stderr) err
hPutStrLn stderr $ Opt.usageInfo ("Usage: " ++ prog ++ " [OPTION...] FILE") opts
exitFailure
output optOutput =<< generateFromFile optGenerate f