0 | module System.Escape
 1 |
 2 | import Data.List
 3 |
 4 | import System.Info
 5 |
 6 | ||| Escape special characters in an Idris string, for use as a string literal
 7 | ||| in the shell
 8 | public export
 9 | escapeArg : String -> String
10 | escapeArg cmd = let escapedCmdChars = pack $ unpack cmd >>= escapeArgChar in
11 |     if isWindows
12 |        then escapedCmdChars
13 |        else "\"" ++ escapedCmdChars ++ "\""
14 |   where
15 |     escapeArgChar : Char -> List Char
16 |     escapeArgChar c =
17 |         if isWindows
18 |            then if c == '%'  || c == '^'  || c == '&'  || c == '<'  || c == '>' || c == '|' ||
19 |                    c == '\'' || c == '"'  || c == '`'  ||
20 |                    c == ' '  || c == '\t' || c == '\n' || c == ';' || c == ',' || c == '=' || c == '\x0B' || c == '\x0C' || c == '\xFF' ||
21 |                    c == '('  || c == ')'  || c == '!'
22 |                    then ['^', c]
23 |                    else [c]
24 |            else if c == '$' || c == '`' || c == '\\' || c == '"'
25 |                    then ['\\', c]
26 |                    else [c]
27 |
28 | ||| Escape special characters in a list of shell arguments, as a single command
29 | ||| for the shell.
30 | ||| eg. the list ["a", "b", "c d"] is interpreted as the command `a b "c d"`
31 | public export
32 | escapeCmd : List String -> String
33 | escapeCmd cmd = concat $ intersperse " " $ map escapeArg cmd
34 |