From fff9087ff75a7abe1fd33280f449fe4d9f154b33 Mon Sep 17 00:00:00 2001 From: Nikolay Yakimov Date: Sun, 27 Dec 2015 02:42:45 +0300 Subject: [PATCH] [Shell-Parse] Use \STX and \ETX for quoting Also drops escaping --- src/GHCMod/Options/ShellParse.hs | 34 +++++++++----------------------- test/ShellParseSpec.hs | 24 +++------------------- 2 files changed, 12 insertions(+), 46 deletions(-) diff --git a/src/GHCMod/Options/ShellParse.hs b/src/GHCMod/Options/ShellParse.hs index 5799906..4ad4efe 100644 --- a/src/GHCMod/Options/ShellParse.hs +++ b/src/GHCMod/Options/ShellParse.hs @@ -16,35 +16,19 @@ module GHCMod.Options.ShellParse (parseCmdLine) where import Data.Char -import Data.Maybe -isQuote :: Char -> Bool -isQuote = (==) '"' - -isEscapeChar :: Char -> Bool -isEscapeChar = (==) '\\' - -isEscapable :: Char -> Bool -isEscapable c = any ($ c) [isSpace, isQuote, isEscapeChar] - -go :: String -> String -> [String] -> Maybe Char -> [String] +go :: String -> String -> [String] -> Bool -> [String] -- result go [] curarg accargs _ = reverse $ reverse curarg : accargs --- escaped character -go (esc:c:cl) curarg accargs quote - | isEscapeChar esc - = if isEscapable c - then go cl (c:curarg) accargs quote - else go (c:cl) (esc:curarg) accargs quote go (c:cl) curarg accargs quotes - -- quote character -- opens quotes - | isQuote c, isNothing quotes - = go cl curarg accargs (Just c) + -- open quotes + | c == '\STX', not quotes + = go cl curarg accargs True -- close quotes - | quotes == Just c - = go cl curarg accargs Nothing - -- space separates argumetns outside quotes - | isSpace c, isNothing quotes + | c == '\ETX', quotes + = go cl curarg accargs False + -- space separates arguments outside quotes + | isSpace c, not quotes = if null curarg then go cl curarg accargs quotes else go cl [] (reverse curarg : accargs) quotes @@ -52,4 +36,4 @@ go (c:cl) curarg accargs quotes | otherwise = go cl (c:curarg) accargs quotes parseCmdLine :: String -> [String] -parseCmdLine comline = go comline [] [] Nothing +parseCmdLine comline = go comline [] [] False diff --git a/test/ShellParseSpec.hs b/test/ShellParseSpec.hs index 3d02f43..8817ec7 100644 --- a/test/ShellParseSpec.hs +++ b/test/ShellParseSpec.hs @@ -10,27 +10,9 @@ spec = describe "parseCmdLine" $ do it "splits arguments" $ parseCmdLine "test command line" `shouldBe` ["test", "command", "line"] - it "honors double quotes" $ - parseCmdLine "test command line \"with double quotes\"" - `shouldBe` ["test", "command", "line", "with double quotes"] - it "escapes spaces" $ do - parseCmdLine "with\\ spaces" - `shouldBe` ["with spaces"] - parseCmdLine "\"with\\ spaces\"" - `shouldBe` ["with spaces"] - it "escapes '\\'" $ do - parseCmdLine "\\\\" - `shouldBe` ["\\"] - parseCmdLine "\"\\\\\"" - `shouldBe` ["\\"] - it "escapes double quotes" $ do - parseCmdLine "\\\"" - `shouldBe` ["\""] - parseCmdLine "\"\\\"\"" - `shouldBe` ["\""] - it "doesn't escape random characters" $ - parseCmdLine "\\a\\b\\c" - `shouldBe` ["\\a\\b\\c"] + it "honors quoted segments" $ + parseCmdLine "test command line \STXwith quoted segment\ETX" + `shouldBe` ["test", "command", "line", "with quoted segment"] it "squashes multiple spaces" $ parseCmdLine "test command" `shouldBe` ["test", "command"]