From d1cf9d734e1e44eba115778b480f3121fa302151 Mon Sep 17 00:00:00 2001 From: hallgren Date: Tue, 18 Aug 2015 13:13:31 +0000 Subject: [PATCH] GF shell: restore the eh command to working order and document it Also, when the command line parser fails, append the problematic command line to the error message "command not parsed". --- src/compiler/GF/Command/CommonCommands.hs | 5 +++++ src/compiler/GF/Command/Interpreter.hs | 2 +- src/compiler/GF/Interactive.hs | 26 +++++++++++++++-------- src/compiler/GF/Interactive2.hs | 24 ++++++++++++++------- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/src/compiler/GF/Command/CommonCommands.hs b/src/compiler/GF/Command/CommonCommands.hs index 8774c0a8d..63dba526d 100644 --- a/src/compiler/GF/Command/CommonCommands.hs +++ b/src/compiler/GF/Command/CommonCommands.hs @@ -71,6 +71,11 @@ commonCommands = fmap (mapCommandExec liftSIO) $ Map.fromList [ longname = "empty", synopsis = "empty the environment" }), + ("eh", emptyCommandInfo { + longname = "execute_history", + syntax = "eh FILE", + synopsis = "read commands from a file and execute them" + }), ("ph", emptyCommandInfo { longname = "print_history", synopsis = "print command history", diff --git a/src/compiler/GF/Command/Interpreter.hs b/src/compiler/GF/Command/Interpreter.hs index 92310048c..b01dc1fc5 100644 --- a/src/compiler/GF/Command/Interpreter.hs +++ b/src/compiler/GF/Command/Interpreter.hs @@ -27,7 +27,7 @@ interpretCommandLine env line = case readCommandLine line of Just [] -> return () Just pipes -> mapM_ (interpretPipe env) pipes - Nothing -> putStrLnE "command not parsed" + Nothing -> putStrLnE $ "command not parsed: "++line interpretPipe env cs = do Piped v@(_,s) <- intercs cs void diff --git a/src/compiler/GF/Interactive.hs b/src/compiler/GF/Interactive.hs index efbbcf341..59f7a6bce 100644 --- a/src/compiler/GF/Interactive.hs +++ b/src/compiler/GF/Interactive.hs @@ -13,7 +13,7 @@ import GF.Command.Help(helpCommand) import GF.Command.Abstract import GF.Command.Parse(readCommandLine,pCommand) import GF.Data.Operations (Err(..),done) -import GF.Data.Utilities(repeatM) +import GF.Data.Utilities(whenM,repeatM) import GF.Grammar hiding (Ident,isPrefixOf) import GF.Infra.UseIO(ioErrorText,putStrLnE) import GF.Infra.SIO @@ -113,17 +113,21 @@ type ShellM = StateT GFEnv SIO -- | Execute a given command line, returning 'True' to continue execution, -- | 'False' when it is time to quit -execute1 :: String -> ShellM Bool +execute1, execute1' :: String -> ShellM Bool execute1 s0 = do modify $ \ gfenv0 -> gfenv0 {history = s0 : history gfenv0} - opts <- gets startOpts + execute1' s0 + +-- | Execute a given command line, without adding it to the history +execute1' s0 = + do opts <- gets startOpts interruptible $ optionallyShowCPUTime opts $ case pwords s0 of -- cc, sd, so, ss and dg are now in GF.Commands.SourceCommands -- special commands "q" :_ -> quit "!" :ws -> system_command ws - "eh":ws -> eh ws + "eh":ws -> execute_history ws "i" :ws -> do import_ ws; continue -- other special commands, working on GFEnv "dc":ws -> define_command ws @@ -157,12 +161,16 @@ execute1 s0 = cs <- readFile w >>= return . map words . lines gfenv' <- foldM (flip (process False benv)) gfenv cs loopNewCPU gfenv' -} - eh [w] = -- Ehhh? Reads commands from a file, but does not execute them - do env <- gets commandenv - cs <- lift $ restricted (readFile w) >>= return . map (interpretCommandLine env) . lines + execute_history [w] = + do execute . lines =<< lift (restricted (readFile w)) continue - eh _ = do putStrLnE "eh command not parsed" - continue + where + execute [] = done + execute (line:lines) = whenM (execute1' line) (execute lines) + + execute_history _ = + do putStrLnE "eh command not parsed" + continue define_command (f:ws) = case readCommandLine (unwords ws) of diff --git a/src/compiler/GF/Interactive2.hs b/src/compiler/GF/Interactive2.hs index 70f7e567e..bfa7fd6b2 100644 --- a/src/compiler/GF/Interactive2.hs +++ b/src/compiler/GF/Interactive2.hs @@ -11,7 +11,7 @@ import GF.Command.Help(helpCommand) import GF.Command.Abstract import GF.Command.Parse(readCommandLine,pCommand) import GF.Data.Operations (Err(..),done) -import GF.Data.Utilities(repeatM) +import GF.Data.Utilities(whenM,repeatM) import GF.Infra.UseIO(ioErrorText,putStrLnE) import GF.Infra.SIO @@ -117,14 +117,18 @@ type ShellM = StateT GFEnv SIO execute1 :: String -> ShellM Bool execute1 s0 = do modify $ \ gfenv0 -> gfenv0 {history = s0 : history gfenv0} - opts <- gets startOpts + execute1' s0 + +-- | Execute a given command line, without adding it to the history +execute1' s0 = + do opts <- gets startOpts interruptible $ optionallyShowCPUTime opts $ case pwords s0 of -- cc, sd, so, ss and dg are now in GF.Commands.SourceCommands -- special commands "q" :_ -> quit "!" :ws -> system_command ws - "eh":ws -> eh ws + "eh":ws -> execute_history ws "i" :ws -> do import_ ws; continue -- other special commands, working on GFEnv "dc":ws -> define_command ws @@ -158,12 +162,16 @@ execute1 s0 = cs <- readFile w >>= return . map words . lines gfenv' <- foldM (flip (process False benv)) gfenv cs loopNewCPU gfenv' -} - eh [w] = -- Ehhh? Reads commands from a file, but does not execute them - do env <- gets commandenv - cs <- lift $ restricted (readFile w) >>= return . map (interpretCommandLine env) . lines + execute_history [w] = + do execute . lines =<< lift (restricted (readFile w)) continue - eh _ = do putStrLnE "eh command not parsed" - continue + where + execute [] = done + execute (line:lines) = whenM (execute1' line) (execute lines) + + execute_history _ = + do putStrLnE "eh command not parsed" + continue define_command (f:ws) = case readCommandLine (unwords ws) of