From 75e102ed7d91b040e1989c7a08d6b4a070771933 Mon Sep 17 00:00:00 2001 From: Joscha Date: Tue, 19 Nov 2019 11:45:24 +0000 Subject: [PATCH] Improve command-line option parsing --- app/MimaRun/Main.hs | 9 +++-- src/Mima/Format/State.hs | 16 -------- src/Mima/Options.hs | 79 +++++++++++++++++++++++----------------- 3 files changed, 51 insertions(+), 53 deletions(-) diff --git a/app/MimaRun/Main.hs b/app/MimaRun/Main.hs index 9bf2665..692d09c 100644 --- a/app/MimaRun/Main.hs +++ b/app/MimaRun/Main.hs @@ -46,7 +46,7 @@ settingsParser = Settings <> metavar "OUTFILE" <> help "If specified, write the memory dump to this file after execution is finished") <*> switchWithNo "discover" True - (help "Disable the automatic loading of the .mima-flags and .mima-symbols files") + "Try to load .mima-flags and .mima-symbols corresponding to the .mima input file" <*> (optional . strOption) (long "flag-file" <> short 'f' @@ -59,11 +59,12 @@ settingsParser = Settings <> help "A file containing label names and addresses, specified in the .mima-symbols format") <*> (optional . option auto) (long "steps" + <> short 'n' <> metavar "N" <> help "How many instructions to execute (if not specified, runs until HALT or execution exception)") <*> flag False True - (long "norun" - <> help "Don't run the MiMa. Use the initial state for all further actions. Roughly equivalent to -n 0") + (long "no-run" + <> help "Don't run the MiMa. Use the initial state for all further actions. Roughly equivalent to --steps 0") <*> flag False True (long "quiet" <> short 'q' @@ -71,7 +72,7 @@ settingsParser = Settings <*> formatConfigParser opts :: ParserInfo Settings -opts = info (helper <*> settingsParser) $ fullDesc <> failureCode 1 <> footer formatConfigHelp +opts = info (helper <*> settingsParser) $ fullDesc <> failureCode 1 <> footer flagFooter {- Loading the flag file -} diff --git a/src/Mima/Format/State.hs b/src/Mima/Format/State.hs index fcc47b9..c4d1f7b 100644 --- a/src/Mima/Format/State.hs +++ b/src/Mima/Format/State.hs @@ -2,7 +2,6 @@ module Mima.Format.State ( FormatConfig(..) - , defaultFormatConfig , FormatEnv(..) , FormatReader , Formatter @@ -43,21 +42,6 @@ data FormatConfig = FormatConfig , fcShowLabels :: Bool -- Currently unused } deriving (Show) -defaultFormatConfig :: FormatConfig -defaultFormatConfig = FormatConfig - { fcSparse = True - , fcShowRegisterFlags = True - , fcShowMemoryFlags = True - , fcShowAddressDec = True - , fcShowAddressHex = True - , fcShowAddressBin = False - , fcShowWordDec = True - , fcShowWordHex = True - , fcShowWordBin = False - , fcShowInstructions = True - , fcShowLabels = False - } - data FormatEnv = FormatEnv { feState :: MimaState , feFlags :: Flags (MimaAddress -> Bool) diff --git a/src/Mima/Options.hs b/src/Mima/Options.hs index 3aa2b72..ae41c20 100644 --- a/src/Mima/Options.hs +++ b/src/Mima/Options.hs @@ -1,6 +1,7 @@ module Mima.Options - ( switchWithNo - , formatConfigHelp + ( flagFooter + , switchWithNo + , hiddenSwitchWithNo , formatConfigParser ) where @@ -8,38 +9,50 @@ import Options.Applicative import Mima.Format.State -switchWithNo :: String -> Bool -> Mod FlagFields Bool -> Parser Bool -switchWithNo name defaultValue fields - | defaultValue = flag' False noMod <|> flag True True yesMod - | otherwise = flag' True yesMod <|> flag False False noMod - where - yesMod = long name <> hidden <> fields - noMod = long ("no-" ++ name) <> hidden +flagFooter :: String +flagFooter = "To disable an option, prepend 'no-' to its name (e. g. to disable" + ++ " '--discover', use '--no-discover'). This only applies to options" + ++ " with a default of 'enabled' or 'disabled'." -formatConfigHelp :: String -formatConfigHelp = "All options labeled with 'Formatting:' can be negated by prepending 'no-' to their name (e. g. '--sparse' becomes '--no-sparse')." +enabledOrDisabled :: Bool -> String +enabledOrDisabled False = "disabled" +enabledOrDisabled True = "enabled" + +switchWithNo :: String -> Bool -> String -> Parser Bool +switchWithNo name defaultValue helpText = + flag' False noMod <|> flag defaultValue True yesMod + where + noMod = long ("no-" ++ name) <> hidden + yesMod = long name <> help (helpText ++ " (default: " ++ enabledOrDisabled defaultValue ++ ")") + +hiddenSwitchWithNo :: String -> Bool -> String -> Parser Bool +hiddenSwitchWithNo name defaultValue helpText = + flag' False noMod <|> flag defaultValue True yesMod + where + noMod = long ("no-" ++ name) <> hidden + yesMod = long name <> hidden <> help (helpText ++ " (default: " ++ enabledOrDisabled defaultValue ++ ")") formatConfigParser :: Parser FormatConfig formatConfigParser = FormatConfig - <$> switchWithNo "sparse" False - (help "Formatting: Omit uninteresting addresses") - <*> switchWithNo "register-flags" True - (help "Formatting: For each address, show all the memory flags that are active for that address") - <*> switchWithNo "memory-flags" True - (help "Formatting: For each address, show all registers currently pointing to that address") - <*> switchWithNo "address-dec" True - (help "Formatting: Display addresses in decimal") - <*> switchWithNo "address-hex" True - (help "Formatting: Display addresses in hexadecimal") - <*> switchWithNo "address-bin" False - (help "Formatting: Display addresses in binary") - <*> switchWithNo "word-dec" True - (help "Formatting: Display words in decimal") - <*> switchWithNo "word-hex" True - (help "Formatting: Display words in hexadecimal") - <*> switchWithNo "word-bin" False - (help "Formatting: Display words in binary") - <*> switchWithNo "instructions" True - (help "Formatting: Show instructions") - <*> switchWithNo "labels" True - (help "Formatting: Show labels from the symbol file") + <$> hiddenSwitchWithNo "sparse" True + "Omit uninteresting addresses" + <*> hiddenSwitchWithNo "register-flags" True + "For each address, show all the memory flags that are active for that address" + <*> hiddenSwitchWithNo "memory-flags" True + "For each address, show all registers currently pointing to that address" + <*> hiddenSwitchWithNo "address-dec" True + "Display addresses in decimal" + <*> hiddenSwitchWithNo "address-hex" True + "Display addresses in hexadecimal" + <*> hiddenSwitchWithNo "address-bin" False + "Display addresses in binary" + <*> hiddenSwitchWithNo "word-dec" True + "Display words in decimal" + <*> hiddenSwitchWithNo "word-hex" True + "Display words in hexadecimal" + <*> hiddenSwitchWithNo "word-bin" False + "Display words in binary" + <*> hiddenSwitchWithNo "instructions" True + "Show instructions" + <*> hiddenSwitchWithNo "labels" True + "Show labels from the symbol file"