{-
    Copyright 2012-2022 Vidar Holen

    This file is part of ShellCheck.
    https://www.shellcheck.net

    ShellCheck is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    ShellCheck is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiWayIf #-}
module ShellCheck.Parser (parseScript, runTests) where

import ShellCheck.AST
import ShellCheck.ASTLib hiding (runTests)
import ShellCheck.Data
import ShellCheck.Interface
import ShellCheck.Prelude

import Control.Applicative ((<*), (*>))
import Control.Monad
import Control.Monad.Identity
import Control.Monad.Trans
import Data.Char
import Data.Functor
import Data.List (isPrefixOf, isInfixOf, isSuffixOf, partition, sortBy, intercalate, nub, find)
import Data.Maybe
import Data.Monoid
import GHC.Exts (sortWith)
import Prelude hiding (readList)
import System.IO
import Text.Parsec hiding (runParser, (<?>))
import Text.Parsec.Error
import Text.Parsec.Pos
import qualified Control.Monad.Reader as Mr
import qualified Control.Monad.State as Ms
import qualified Data.Map.Strict as Map

import Test.QuickCheck.All (quickCheckAll)

type SCBase m = Mr.ReaderT (Environment m) (Ms.StateT SystemState m)
type SCParser m v = ParsecT String UserState (SCBase m) v

backslash :: Monad m => SCParser m Char
backslash :: forall (m :: * -> *). Monad m => SCParser m Char
backslash = forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\\'
linefeed :: Monad m => SCParser m Char
linefeed :: forall (m :: * -> *). Monad m => SCParser m Char
linefeed = do
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall {m :: * -> *} {s} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m Char
carriageReturn
    Char
c <- forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\n'
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readPendingHereDocs
    forall (m :: * -> *) a. Monad m => a -> m a
return Char
c
singleQuote :: ParsecT s u m Char
singleQuote = forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\''
doubleQuote :: ParsecT s u m Char
doubleQuote = forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'"'
variableStart :: ParsecT s u m Char
variableStart = forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
upper forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
lower forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"_"
variableChars :: ParsecT s u m Char
variableChars = forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
upper forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
lower forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"_"
-- Chars to allow in function names
functionChars :: ParsecT s u m Char
functionChars = forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
variableChars forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
":+?-./^@,"
-- Chars to allow in functions using the 'function' keyword
extendedFunctionChars :: ParsecT s u m Char
extendedFunctionChars = forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
functionChars forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"[]*=!"
specialVariable :: ParsecT s u m Char
specialVariable = forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf (forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
specialVariables)
paramSubSpecialChars :: ParsecT s u m Char
paramSubSpecialChars = forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"/:+-=%"
quotableChars :: String
quotableChars = String
"|&;<>()\\ '\t\n\r\xA0" forall a. [a] -> [a] -> [a]
++ String
doubleQuotableChars
quotable :: ParsecT s UserState m Char
quotable = forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m Char
almostSpace forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
quotableChars
bracedQuotable :: ParsecT s u m Char
bracedQuotable = forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"}\"$`'"
doubleQuotableChars :: String
doubleQuotableChars = String
"\\\"$`"
doubleQuotable :: ParsecT s u m Char
doubleQuotable = forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
doubleQuotableChars
whitespace :: ParsecT String UserState (SCBase m) Char
whitespace = forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
" \t" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *} {s} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m Char
carriageReturn forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m Char
almostSpace forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *). Monad m => SCParser m Char
linefeed
linewhitespace :: ParsecT s UserState m Char
linewhitespace = forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
" \t" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m Char
almostSpace

suspectCharAfterQuotes :: ParsecT s u m Char
suspectCharAfterQuotes = forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
variableChars forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'%'

extglobStartChars :: String
extglobStartChars = String
"?*@!+"
extglobStart :: ParsecT s u m Char
extglobStart = forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
extglobStartChars

unicodeDoubleQuotes :: String
unicodeDoubleQuotes = String
"\x201C\x201D\x2033\x2036"
unicodeSingleQuotes :: String
unicodeSingleQuotes = String
"\x2018\x2019"

prop_spacing1 :: Bool
prop_spacing1 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing String
"  \\\n # Comment"
prop_spacing2 :: Bool
prop_spacing2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing String
"# We can continue lines with \\"
prop_spacing3 :: Bool
prop_spacing3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing String
"   \\\n #  --verbose=true \\"
spacing :: ParsecT s UserState m String
spacing = do
    [String]
x <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Char
linewhitespace forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, Stream s m Char,
 MonadState SystemState m) =>
ParsecT s UserState m String
continuation)
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m String
readComment
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
x
  where
    continuation :: ParsecT s UserState m String
continuation = do
        forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"\\\n")
        -- The line was continued. Warn if this next line is a comment with a trailing \
        String
whitespace <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Char
linewhitespace
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ do
            String
x <- forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m String
readComment
            forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String
"\\" forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` String
x) forall a b. (a -> b) -> a -> b
$
                forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1143 String
"This backslash is part of a comment and does not continue the line."
        forall (m :: * -> *) a. Monad m => a -> m a
return String
whitespace

spacing1 :: ParsecT s UserState m String
spacing1 = do
    String
spacing <- forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
spacing) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected whitespace"
    forall (m :: * -> *) a. Monad m => a -> m a
return String
spacing

prop_allspacing :: Bool
prop_allspacing = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing String
"#foo"
prop_allspacing2 :: Bool
prop_allspacing2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing String
" #foo\n # bar\n#baz\n"
prop_allspacing3 :: Bool
prop_allspacing3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing String
"#foo\n#bar\n#baz\n"
allspacing :: ParsecT String UserState (SCBase m) String
allspacing = do
    String
s <- forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
    Bool
more <- forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option Bool
False (forall (m :: * -> *). Monad m => SCParser m Char
linefeed forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True)
    if Bool
more then do
        String
rest <- ParsecT String UserState (SCBase m) String
allspacing
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ String
s forall a. [a] -> [a] -> [a]
++ String
"\n" forall a. [a] -> [a] -> [a]
++ String
rest
      else
        forall (m :: * -> *) a. Monad m => a -> m a
return String
s

allspacingOrFail :: ParsecT String UserState (SCBase m) String
allspacingOrFail = do
    String
s <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
s) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected whitespace"
    forall (m :: * -> *) a. Monad m => a -> m a
return String
s

readUnicodeQuote :: ParsecT String UserState (SCBase m) Token
readUnicodeQuote = do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    Char
c <- forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf (String
unicodeSingleQuotes forall a. [a] -> [a] -> [a]
++ String
unicodeDoubleQuotes)
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId Id
id Severity
WarningC Integer
1110 String
"This is a unicode quote. Delete and retype it (or quote to make literal)."
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id [Char
c]

carriageReturn :: ParsecT s u m Char
carriageReturn = do
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\r'
    forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1017 String
"Literal carriage return. Run script through tr -d '\\r' ."
    forall (m :: * -> *) a. Monad m => a -> m a
return Char
'\r'

almostSpace :: ParsecT s UserState m Char
almostSpace =
    forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [
        forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m,
 Stream s m Char) =>
Char -> String -> ParsecT s UserState m Char
check Char
'\xA0' String
"unicode non-breaking space",
        forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m,
 Stream s m Char) =>
Char -> String -> ParsecT s UserState m Char
check Char
'\x200B' String
"unicode zerowidth space"
    ]
  where
    check :: Char -> String -> ParsecT s UserState m Char
check Char
c String
name = do
        forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s UserState m ()
parseNote Severity
ErrorC Integer
1018 forall a b. (a -> b) -> a -> b
$ String
"This is a " forall a. [a] -> [a] -> [a]
++ String
name forall a. [a] -> [a] -> [a]
++ String
". Delete and retype it."
        forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
c
        forall (m :: * -> *) a. Monad m => a -> m a
return Char
' '

--------- Message/position annotation on top of user state
data ParseNote = ParseNote SourcePos SourcePos Severity Code String deriving (Line -> ParseNote -> ShowS
[ParseNote] -> ShowS
ParseNote -> String
forall a.
(Line -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ParseNote] -> ShowS
$cshowList :: [ParseNote] -> ShowS
show :: ParseNote -> String
$cshow :: ParseNote -> String
showsPrec :: Line -> ParseNote -> ShowS
$cshowsPrec :: Line -> ParseNote -> ShowS
Show, ParseNote -> ParseNote -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ParseNote -> ParseNote -> Bool
$c/= :: ParseNote -> ParseNote -> Bool
== :: ParseNote -> ParseNote -> Bool
$c== :: ParseNote -> ParseNote -> Bool
Eq)
data Context =
        ContextName SourcePos String
        | ContextAnnotation [Annotation]
        | ContextSource String
    deriving (Line -> Context -> ShowS
[Context] -> ShowS
Context -> String
forall a.
(Line -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Context] -> ShowS
$cshowList :: [Context] -> ShowS
show :: Context -> String
$cshow :: Context -> String
showsPrec :: Line -> Context -> ShowS
$cshowsPrec :: Line -> Context -> ShowS
Show)

data HereDocContext =
        HereDocPending Token [Context] -- on linefeed, read this T_HereDoc
    deriving (Line -> HereDocContext -> ShowS
[HereDocContext] -> ShowS
HereDocContext -> String
forall a.
(Line -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [HereDocContext] -> ShowS
$cshowList :: [HereDocContext] -> ShowS
show :: HereDocContext -> String
$cshow :: HereDocContext -> String
showsPrec :: Line -> HereDocContext -> ShowS
$cshowsPrec :: Line -> HereDocContext -> ShowS
Show)

data UserState = UserState {
    UserState -> Id
lastId :: Id,
    UserState -> Map Id (SourcePos, SourcePos)
positionMap :: Map.Map Id (SourcePos, SourcePos),
    UserState -> [ParseNote]
parseNotes :: [ParseNote],
    UserState -> Map Id [Token]
hereDocMap :: Map.Map Id [Token],
    UserState -> [HereDocContext]
pendingHereDocs :: [HereDocContext]
}
initialUserState :: UserState
initialUserState = UserState {
    lastId :: Id
lastId = Line -> Id
Id forall a b. (a -> b) -> a -> b
$ -Line
1,
    positionMap :: Map Id (SourcePos, SourcePos)
positionMap = forall k a. Map k a
Map.empty,
    parseNotes :: [ParseNote]
parseNotes = [],
    hereDocMap :: Map Id [Token]
hereDocMap = forall k a. Map k a
Map.empty,
    pendingHereDocs :: [HereDocContext]
pendingHereDocs = []
}

codeForParseNote :: ParseNote -> Integer
codeForParseNote (ParseNote SourcePos
_ SourcePos
_ Severity
_ Integer
code String
_) = Integer
code

getLastId :: ParsecT s UserState m Id
getLastId = UserState -> Id
lastId forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState

getNextIdBetween :: SourcePos -> SourcePos -> ParsecT s UserState m Id
getNextIdBetween SourcePos
startPos SourcePos
endPos = do
    UserState
state <- forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
    let newId :: Id
newId = Id -> Id
incId (UserState -> Id
lastId UserState
state)
    let newMap :: Map Id (SourcePos, SourcePos)
newMap = forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert Id
newId (SourcePos
startPos, SourcePos
endPos) (UserState -> Map Id (SourcePos, SourcePos)
positionMap UserState
state)
    forall (m :: * -> *) u s. Monad m => u -> ParsecT s u m ()
putState forall a b. (a -> b) -> a -> b
$ UserState
state {
        lastId :: Id
lastId = Id
newId,
        positionMap :: Map Id (SourcePos, SourcePos)
positionMap = Map Id (SourcePos, SourcePos)
newMap
    }
    forall (m :: * -> *) a. Monad m => a -> m a
return Id
newId
  where incId :: Id -> Id
incId (Id Line
n) = Line -> Id
Id forall a b. (a -> b) -> a -> b
$ Line
nforall a. Num a => a -> a -> a
+Line
1

getNextIdSpanningTokens :: Token -> Token -> ParsecT String UserState (SCBase m) Id
getNextIdSpanningTokens Token
startTok Token
endTok = do
    (SourcePos
start, SourcePos
_) <- forall (m :: * -> *).
Monad m =>
Id -> SCParser m (SourcePos, SourcePos)
getSpanForId (Token -> Id
getId Token
startTok)
    (SourcePos
_, SourcePos
end)   <- forall (m :: * -> *).
Monad m =>
Id -> SCParser m (SourcePos, SourcePos)
getSpanForId (Token -> Id
getId Token
endTok)
    forall {m :: * -> *} {s}.
Monad m =>
SourcePos -> SourcePos -> ParsecT s UserState m Id
getNextIdBetween SourcePos
start SourcePos
end

-- Get an ID starting from the first token of the list, and ending after the last
getNextIdSpanningTokenList :: [Token] -> ParsecT String UserState (SCBase m) Id
getNextIdSpanningTokenList [Token]
list =
    case [Token]
list of
    [] -> do
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        forall {m :: * -> *} {s}.
Monad m =>
SourcePos -> SourcePos -> ParsecT s UserState m Id
getNextIdBetween SourcePos
pos SourcePos
pos
    (Token
h:[Token]
_) ->
        forall {m :: * -> *}.
Monad m =>
Token -> Token -> ParsecT String UserState (SCBase m) Id
getNextIdSpanningTokens Token
h (forall a. [a] -> a
last [Token]
list)

-- Get the span covered by an id
getSpanForId :: Monad m => Id -> SCParser m (SourcePos, SourcePos)
getSpanForId :: forall (m :: * -> *).
Monad m =>
Id -> SCParser m (SourcePos, SourcePos)
getSpanForId Id
id =
    forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault (forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ ShowS
pleaseReport String
"no parser span for id") Id
id forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
        forall {m :: * -> *} {s}.
Monad m =>
ParsecT s UserState m (Map Id (SourcePos, SourcePos))
getMap

-- Create a new id with the same span as an existing one
getNewIdFor :: Monad m => Id -> SCParser m Id
getNewIdFor :: forall (m :: * -> *). Monad m => Id -> SCParser m Id
getNewIdFor Id
id = forall (m :: * -> *).
Monad m =>
Id -> SCParser m (SourcePos, SourcePos)
getSpanForId Id
id forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall {m :: * -> *} {s}.
Monad m =>
SourcePos -> SourcePos -> ParsecT s UserState m Id
getNextIdBetween

data IncompleteInterval = IncompleteInterval SourcePos

startSpan :: ParsecT s u m IncompleteInterval
startSpan = SourcePos -> IncompleteInterval
IncompleteInterval forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition

endSpan :: IncompleteInterval -> ParsecT s UserState m Id
endSpan (IncompleteInterval SourcePos
start) = do
    SourcePos
endPos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    forall {m :: * -> *} {s}.
Monad m =>
SourcePos -> SourcePos -> ParsecT s UserState m Id
getNextIdBetween SourcePos
start SourcePos
endPos

getSpanPositionsFor :: ParsecT s u m a -> ParsecT s u m (SourcePos, SourcePos)
getSpanPositionsFor ParsecT s u m a
m = do
    SourcePos
start <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    ParsecT s u m a
m
    SourcePos
end <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    forall (m :: * -> *) a. Monad m => a -> m a
return (SourcePos
start, SourcePos
end)

addToHereDocMap :: Id -> [Token] -> ParsecT s UserState m ()
addToHereDocMap Id
id [Token]
list = do
    UserState
state <- forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
    let map :: Map Id [Token]
map = UserState -> Map Id [Token]
hereDocMap UserState
state
    forall (m :: * -> *) u s. Monad m => u -> ParsecT s u m ()
putState forall a b. (a -> b) -> a -> b
$ UserState
state {
        hereDocMap :: Map Id [Token]
hereDocMap = forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert Id
id [Token]
list Map Id [Token]
map
    }

addPendingHereDoc :: Token -> ParsecT s UserState m ()
addPendingHereDoc Token
t = do
    UserState
state <- forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
    [Context]
context <- forall {m :: * -> *}. MonadState SystemState m => m [Context]
getCurrentContexts
    let docs :: [HereDocContext]
docs = UserState -> [HereDocContext]
pendingHereDocs UserState
state
    forall (m :: * -> *) u s. Monad m => u -> ParsecT s u m ()
putState forall a b. (a -> b) -> a -> b
$ UserState
state {
        pendingHereDocs :: [HereDocContext]
pendingHereDocs = Token -> [Context] -> HereDocContext
HereDocPending Token
t [Context]
context forall a. a -> [a] -> [a]
: [HereDocContext]
docs
    }

popPendingHereDocs :: ParsecT s UserState m [HereDocContext]
popPendingHereDocs = do
    UserState
state <- forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
    let pending :: [HereDocContext]
pending = UserState -> [HereDocContext]
pendingHereDocs UserState
state
    forall (m :: * -> *) u s. Monad m => u -> ParsecT s u m ()
putState forall a b. (a -> b) -> a -> b
$ UserState
state {
        pendingHereDocs :: [HereDocContext]
pendingHereDocs = []
    }
    forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> [a]
reverse forall a b. (a -> b) -> a -> b
$ UserState -> [HereDocContext]
pendingHereDocs UserState
state

getMap :: ParsecT s UserState m (Map Id (SourcePos, SourcePos))
getMap = UserState -> Map Id (SourcePos, SourcePos)
positionMap forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
getParseNotes :: ParsecT s UserState m [ParseNote]
getParseNotes = UserState -> [ParseNote]
parseNotes forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState

addParseNote :: ParseNote -> ParsecT s UserState m ()
addParseNote ParseNote
n = do
    Bool
irrelevant <- forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Integer -> m Bool
shouldIgnoreCode (ParseNote -> Integer
codeForParseNote ParseNote
n)
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
irrelevant forall a b. (a -> b) -> a -> b
$ do
        UserState
state <- forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
        forall (m :: * -> *) u s. Monad m => u -> ParsecT s u m ()
putState forall a b. (a -> b) -> a -> b
$ UserState
state {
            parseNotes :: [ParseNote]
parseNotes = ParseNote
n forall a. a -> [a] -> [a]
: UserState -> [ParseNote]
parseNotes UserState
state
        }

ignoreProblemsOf :: t (t m) b -> t (t m) b
ignoreProblemsOf t (t m) b
p = do
    a
systemState <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *). MonadState s m => m s
Ms.get
    t (t m) b
p forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* (forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *). MonadState s m => s -> m ()
Ms.put forall a b. (a -> b) -> a -> b
$ a
systemState)

shouldIgnoreCode :: Integer -> m Bool
shouldIgnoreCode Integer
code = do
    [Context]
context <- forall {m :: * -> *}. MonadState SystemState m => m [Context]
getCurrentContexts
    Bool
checkSourced <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
Mr.asks forall (m :: * -> *). Environment m -> Bool
checkSourced
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Bool -> Integer -> Context -> Bool
contextItemDisablesCode Bool
checkSourced Integer
code) [Context]
context

-- Does this item on the context stack disable warnings for 'code'?
contextItemDisablesCode :: Bool -> Integer -> Context -> Bool
contextItemDisablesCode :: Bool -> Integer -> Context -> Bool
contextItemDisablesCode Bool
alsoCheckSourced Integer
code = Bool -> Context -> Bool
disabling Bool
alsoCheckSourced
  where
    disabling :: Bool -> Context -> Bool
disabling Bool
checkSourced Context
item =
        case Context
item of
            ContextAnnotation [Annotation]
list -> forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Annotation -> Bool
disabling' [Annotation]
list
            ContextSource String
_ -> Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ Bool
checkSourced
            Context
_ -> Bool
False
    disabling' :: Annotation -> Bool
disabling' (DisableComment Integer
n Integer
m) = Integer
code forall a. Ord a => a -> a -> Bool
>= Integer
n Bool -> Bool -> Bool
&& Integer
code forall a. Ord a => a -> a -> Bool
< Integer
m
    disabling' Annotation
_ = Bool
False



getCurrentAnnotations :: Bool -> f [Annotation]
getCurrentAnnotations Bool
includeSource =
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Context -> [Annotation]
get forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Context -> Bool
isBoundary) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {m :: * -> *}. MonadState SystemState m => m [Context]
getCurrentContexts
  where
    get :: Context -> [Annotation]
get (ContextAnnotation [Annotation]
list) = [Annotation]
list
    get Context
_ = []
    isBoundary :: Context -> Bool
isBoundary (ContextSource String
_) = Bool -> Bool
not Bool
includeSource
    isBoundary Context
_ = Bool
False


shouldFollow :: String -> ParsecT s u m Bool
shouldFollow String
file = do
    [Context]
context <- forall {m :: * -> *}. MonadState SystemState m => m [Context]
getCurrentContexts
    if forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Context -> Bool
isThisFile [Context]
context
      then forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
      else
        if forall (t :: * -> *) a. Foldable t => t a -> Line
length (forall a. (a -> Bool) -> [a] -> [a]
filter Context -> Bool
isSource [Context]
context) forall a. Ord a => a -> a -> Bool
>= Line
100
          then do
            forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1092 String
"Stopping at 100 'source' frames :O"
            forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
          else
            forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
  where
    isSource :: Context -> Bool
isSource (ContextSource String
_) = Bool
True
    isSource Context
_ = Bool
False
    isThisFile :: Context -> Bool
isThisFile (ContextSource String
name) | String
name forall a. Eq a => a -> a -> Bool
== String
file = Bool
True
    isThisFile Context
_= Bool
False

getSourceOverride :: m (Maybe String)
getSourceOverride = do
    [Context]
context <- forall {m :: * -> *}. MonadState SystemState m => m [Context]
getCurrentContexts
    forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map Context -> Maybe String
findFile forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> [a]
takeWhile Context -> Bool
isSameFile [Context]
context
  where
    isSameFile :: Context -> Bool
isSameFile (ContextSource String
_) = Bool
False
    isSameFile Context
_ = Bool
True

    findFile :: Context -> Maybe String
findFile (ContextAnnotation [Annotation]
list) = forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map Annotation -> Maybe String
getFile [Annotation]
list
    findFile Context
_ = forall a. Maybe a
Nothing
    getFile :: Annotation -> Maybe String
getFile (SourceOverride String
str) = forall a. a -> Maybe a
Just String
str
    getFile Annotation
_ = forall a. Maybe a
Nothing

-- Store potential parse problems outside of parsec

data SystemState = SystemState {
    SystemState -> [Context]
contextStack :: [Context],
    SystemState -> [ParseNote]
parseProblems :: [ParseNote]
}
initialSystemState :: SystemState
initialSystemState = SystemState {
    contextStack :: [Context]
contextStack = [],
    parseProblems :: [ParseNote]
parseProblems = []
}

data Environment m = Environment {
    forall (m :: * -> *). Environment m -> SystemInterface m
systemInterface :: SystemInterface m,
    forall (m :: * -> *). Environment m -> Bool
checkSourced :: Bool,
    forall (m :: * -> *). Environment m -> Bool
ignoreRC :: Bool,
    forall (m :: * -> *). Environment m -> String
currentFilename :: String,
    forall (m :: * -> *). Environment m -> Maybe Shell
shellTypeOverride :: Maybe Shell
}

parseProblem :: Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
level Integer
code String
msg = do
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
level Integer
code String
msg

setCurrentContexts :: [Context] -> m ()
setCurrentContexts [Context]
c = forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
Ms.modify (\SystemState
state -> SystemState
state { contextStack :: [Context]
contextStack = [Context]
c })
getCurrentContexts :: m [Context]
getCurrentContexts = forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
Ms.gets SystemState -> [Context]
contextStack

popContext :: m (Maybe Context)
popContext = do
    [Context]
v <- forall {m :: * -> *}. MonadState SystemState m => m [Context]
getCurrentContexts
    case [Context]
v of
        (Context
a:[Context]
r) -> do
            forall {m :: * -> *}. MonadState SystemState m => [Context] -> m ()
setCurrentContexts [Context]
r
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just Context
a
        [] ->
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing

pushContext :: Context -> m ()
pushContext Context
c = do
    [Context]
v <- forall {m :: * -> *}. MonadState SystemState m => m [Context]
getCurrentContexts
    forall {m :: * -> *}. MonadState SystemState m => [Context] -> m ()
setCurrentContexts (Context
cforall a. a -> [a] -> [a]
:[Context]
v)

parseProblemAtWithEnd :: SourcePos -> SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAtWithEnd SourcePos
start SourcePos
end Severity
level Integer
code String
msg = do
    Bool
irrelevant <- forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Integer -> m Bool
shouldIgnoreCode Integer
code
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
irrelevant forall a b. (a -> b) -> a -> b
$
        forall {m :: * -> *}. MonadState SystemState m => ParseNote -> m ()
addParseProblem ParseNote
note
  where
    note :: ParseNote
note = SourcePos
-> SourcePos -> Severity -> Integer -> String -> ParseNote
ParseNote SourcePos
start SourcePos
end Severity
level Integer
code String
msg

addParseProblem :: ParseNote -> m ()
addParseProblem ParseNote
note =
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
Ms.modify (\SystemState
state -> SystemState
state {
        parseProblems :: [ParseNote]
parseProblems = ParseNote
noteforall a. a -> [a] -> [a]
:SystemState -> [ParseNote]
parseProblems SystemState
state
    })

parseProblemAt :: SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos = forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAtWithEnd SourcePos
pos SourcePos
pos

parseProblemAtId :: Monad m => Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId :: forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId Id
id Severity
level Integer
code String
msg = do
    (SourcePos
start, SourcePos
end) <- forall (m :: * -> *).
Monad m =>
Id -> SCParser m (SourcePos, SourcePos)
getSpanForId Id
id
    forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAtWithEnd SourcePos
start SourcePos
end Severity
level Integer
code String
msg

-- Store non-parse problems inside

parseNote :: Severity -> Integer -> String -> ParsecT s UserState m ()
parseNote Severity
c Integer
l String
a = do
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
pos Severity
c Integer
l String
a

parseNoteAt :: SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
pos Severity
c Integer
l String
a = forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
ParseNote -> ParsecT s UserState m ()
addParseNote forall a b. (a -> b) -> a -> b
$ SourcePos
-> SourcePos -> Severity -> Integer -> String -> ParseNote
ParseNote SourcePos
pos SourcePos
pos Severity
c Integer
l String
a
parseNoteAtId :: Id
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
parseNoteAtId Id
id Severity
c Integer
l String
a = do
    (SourcePos
start, SourcePos
end) <- forall (m :: * -> *).
Monad m =>
Id -> SCParser m (SourcePos, SourcePos)
getSpanForId Id
id
    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
ParseNote -> ParsecT s UserState m ()
addParseNote forall a b. (a -> b) -> a -> b
$ SourcePos
-> SourcePos -> Severity -> Integer -> String -> ParseNote
ParseNote SourcePos
start SourcePos
end Severity
c Integer
l String
a

parseNoteAtWithEnd :: SourcePos
-> SourcePos
-> Severity
-> Integer
-> String
-> ParsecT s UserState m ()
parseNoteAtWithEnd SourcePos
start SourcePos
end Severity
c Integer
l String
a = forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
ParseNote -> ParsecT s UserState m ()
addParseNote forall a b. (a -> b) -> a -> b
$ SourcePos
-> SourcePos -> Severity -> Integer -> String -> ParseNote
ParseNote SourcePos
start SourcePos
end Severity
c Integer
l String
a

--------- Convenient combinators
thenSkip :: ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
thenSkip ParsecT s u m a
main ParsecT s u m a
follow = ParsecT s u m a
main forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional ParsecT s u m a
follow

unexpecting :: String -> ParsecT s u m a -> ParsecT s u m ()
unexpecting String
s ParsecT s u m a
p = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$
    (forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT s u m a
p forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"Unexpected " forall a. [a] -> [a] -> [a]
++ String
s)) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return ()

notFollowedBy2 :: ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 = forall {s} {u} {m :: * -> *} {a}.
String -> ParsecT s u m a -> ParsecT s u m ()
unexpecting String
""

isFollowedBy :: ParsecT s u m a -> ParsecT s u m Bool
isFollowedBy ParsecT s u m a
p = (forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ ParsecT s u m a
p forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Bool
True) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False

reluctantlyTill :: ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m [a]
reluctantlyTill ParsecT s u m a
p ParsecT s u m a
end =
    (forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT s u m a
end) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return []) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do
        a
x <- ParsecT s u m a
p
        [a]
more <- ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m [a]
reluctantlyTill ParsecT s u m a
p ParsecT s u m a
end
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ a
xforall a. a -> [a] -> [a]
:[a]
more
      forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return []

reluctantlyTill1 :: ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m [a]
reluctantlyTill1 ParsecT s u m a
p ParsecT s u m a
end = do
    forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 ParsecT s u m a
end
    a
x <- ParsecT s u m a
p
    [a]
more <- forall {s} {m :: * -> *} {t} {u} {a} {a}.
(Stream s m t, Show t) =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m [a]
reluctantlyTill ParsecT s u m a
p ParsecT s u m a
end
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ a
xforall a. a -> [a] -> [a]
:[a]
more

attempting :: ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
attempting ParsecT s u m a
rest ParsecT s u m a
branch =
    (forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT s u m a
branch forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT s u m a
rest) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m a
rest

orFail :: ParsecT s u m a -> ParsecT s u m String -> ParsecT s u m a
orFail ParsecT s u m a
parser ParsecT s u m String
errorAction =
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT s u m a
parser forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (ParsecT s u m String
errorAction forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) a. MonadFail m => String -> m a
fail)

-- Construct a node with a parser, e.g. T_Literal `withParser` (readGenericLiteral ",")
withParser :: (Id -> t -> b)
-> ParsecT s UserState m t -> ParsecT s UserState m b
withParser Id -> t -> b
node ParsecT s UserState m t
parser = do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    t
contents <- ParsecT s UserState m t
parser
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> t -> b
node Id
id t
contents

wasIncluded :: ParsecT s u m a -> ParsecT s u m Bool
wasIncluded ParsecT s u m a
p = forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option Bool
False (ParsecT s u m a
p forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True)

acceptButWarn :: ParsecT s u m a
-> Severity -> Integer -> String -> ParsecT s u m ()
acceptButWarn ParsecT s u m a
parser Severity
level Integer
code String
note =
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (do
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        ParsecT s u m a
parser
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
level Integer
code String
note
      )

parsecBracket :: ParsecT s u m t
-> (t -> ParsecT s u m a)
-> (t -> ParsecT s u m b)
-> ParsecT s u m b
parsecBracket ParsecT s u m t
before t -> ParsecT s u m a
after t -> ParsecT s u m b
op = do
    t
val <- ParsecT s u m t
before
    t -> ParsecT s u m b
op t
val forall {s} {m :: * -> *} {t} {u} {a} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`thenSkip` t -> ParsecT s u m a
after t
val forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (t -> ParsecT s u m a
after t
val forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"")

swapContext :: [Context] -> ParsecT s u m b -> ParsecT s u m b
swapContext [Context]
contexts ParsecT s u m b
p =
    forall {s} {m :: * -> *} {t} {u} {t} {a} {b}.
Stream s m t =>
ParsecT s u m t
-> (t -> ParsecT s u m a)
-> (t -> ParsecT s u m b)
-> ParsecT s u m b
parsecBracket (forall {m :: * -> *}. MonadState SystemState m => m [Context]
getCurrentContexts forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall {m :: * -> *}. MonadState SystemState m => [Context] -> m ()
setCurrentContexts [Context]
contexts)
                  forall {m :: * -> *}. MonadState SystemState m => [Context] -> m ()
setCurrentContexts
                  (forall a b. a -> b -> a
const ParsecT s u m b
p)

withContext :: Context -> ParsecT s u m b -> ParsecT s u m b
withContext Context
entry ParsecT s u m b
p = forall {s} {m :: * -> *} {t} {u} {t} {a} {b}.
Stream s m t =>
ParsecT s u m t
-> (t -> ParsecT s u m a)
-> (t -> ParsecT s u m b)
-> ParsecT s u m b
parsecBracket (forall {m :: * -> *}. MonadState SystemState m => Context -> m ()
pushContext Context
entry) (forall a b. a -> b -> a
const forall {m :: * -> *}. MonadState SystemState m => m (Maybe Context)
popContext) (forall a b. a -> b -> a
const ParsecT s u m b
p)

called :: String -> ParsecT s u m b -> ParsecT s u m b
called String
s ParsecT s u m b
p = do
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    forall {s} {m :: * -> *} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
Context -> ParsecT s u m b -> ParsecT s u m b
withContext (SourcePos -> String -> Context
ContextName SourcePos
pos String
s) ParsecT s u m b
p

withAnnotations :: [Annotation] -> ParsecT s u m b -> ParsecT s u m b
withAnnotations [Annotation]
anns ParsecT s u m b
p =
    if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Annotation]
anns then ParsecT s u m b
p else forall {s} {m :: * -> *} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
Context -> ParsecT s u m b -> ParsecT s u m b
withContext ([Annotation] -> Context
ContextAnnotation [Annotation]
anns) ParsecT s u m b
p

readConditionContents :: Bool -> ParsecT String UserState (SCBase m) Token
readConditionContents Bool
single =
    ParsecT String UserState (SCBase m) Token
readCondContents forall {s} {u} {m :: * -> *} {a} {a}.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`attempting` forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (do
                                SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                                String
s <- forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readVariableName
                                forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing1
                                forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String
s forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
commonCommands) forall a b. (a -> b) -> a -> b
$
                                    forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
WarningC Integer
1014 String
"Use 'if cmd; then ..' to check exit code, or 'if [[ $(cmd) == .. ]]' to check output.")

  where
    spacingOrLf :: ParsecT String UserState (SCBase m) String
spacingOrLf = forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) String
condSpacing Bool
True
    condSpacing :: Bool -> ParsecT String UserState (SCBase m) String
condSpacing Bool
required = do
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        String
space <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
required Bool -> Bool -> Bool
&& forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
space) forall a b. (a -> b) -> a -> b
$
            forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1035 String
"You are missing a required space here."
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
single Bool -> Bool -> Bool
&& Char
'\n' forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
space) forall a b. (a -> b) -> a -> b
$
            forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1080 String
"When breaking lines in [ ], you need \\ before the linefeed."
        forall (m :: * -> *) a. Monad m => a -> m a
return String
space

    typ :: ConditionType
typ = if Bool
single then ConditionType
SingleBracket else ConditionType
DoubleBracket
    readCondBinaryOp :: ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readCondBinaryOp = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall {s} {m :: * -> *} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m ()
guardArithmetic
        Token -> Token -> Token
op <- forall {m :: * -> *} {s} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m (Token -> Token -> Token)
getOp
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacingOrLf
        forall (m :: * -> *) a. Monad m => a -> m a
return Token -> Token -> Token
op
      where
        flaglessOps :: [String]
flaglessOps = [ String
"==", String
"!=", String
"<=", String
">=", String
"=~", String
">", String
"<", String
"=" ]

        getOp :: ParsecT s UserState m (Token -> Token -> Token)
getOp = do
            IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
            String
op <- forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String -> ParsecT s u m String
readRegularOrEscaped forall {s} {m :: * -> *} {m :: * -> *} {u}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s u m String
anyOp
            Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> ConditionType -> String -> Token -> Token -> Token
TC_Binary Id
id ConditionType
typ String
op

        anyOp :: ParsecT s u m String
anyOp = forall {s} {m :: * -> *} {m :: * -> *} {u}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s u m String
flagOp forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
flaglessOp forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. MonadFail m => String -> m a
fail
                    String
"Expected comparison operator (don't wrap commands in []/[[]])"
        flagOp :: ParsecT s u m String
flagOp = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
            String
s <- forall {s} {m :: * -> *} {m :: * -> *} {u}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s u m String
readOp
            forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String
s forall a. Eq a => a -> a -> Bool
== String
"-a" Bool -> Bool -> Bool
|| String
s forall a. Eq a => a -> a -> Bool
== String
"-o") forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Unexpected operator"
            forall (m :: * -> *) a. Monad m => a -> m a
return String
s
        flaglessOp :: ParsecT s u m String
flaglessOp =
            forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string) [String]
flaglessOps

        -- hacks to read quoted operators without having to read a shell word
    readEscaped :: ParsecT s u m String -> ParsecT s u m String
readEscaped ParsecT s u m String
p = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ ParsecT s u m String
withEscape forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m String
withQuotes
      where
        withEscape :: ParsecT s u m String
withEscape = do
            forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\\'
            ShowS
escaped forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m String
p
        withQuotes :: ParsecT s u m String
withQuotes = do
            Char
c <- forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"'\""
            String
s <- ParsecT s u m String
p
            forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
c
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ ShowS
escaped String
s
        escaped :: ShowS
escaped String
s = if forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
s) String
"<>()" then Char
'\\'forall a. a -> [a] -> [a]
:String
s else String
s

    readRegularOrEscaped :: ParsecT s u m String -> ParsecT s u m String
readRegularOrEscaped ParsecT s u m String
p = forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String -> ParsecT s u m String
readEscaped ParsecT s u m String
p forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m String
p


    guardArithmetic :: ParsecT s u m ()
guardArithmetic = do
        forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"+*/%") forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"- ")
        forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1076 forall a b. (a -> b) -> a -> b
$
            if Bool
single
            then String
"Trying to do math? Use e.g. [ $((i/2+7)) -ge 18 ]."
            else String
"Trying to do math? Use e.g. [[ $((i/2+7)) -ge 18 ]]."

    readCondUnaryExp :: ParsecT String UserState (SCBase m) Token
readCondUnaryExp = do
      Token -> Token
op <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) (Token -> Token)
readCondUnaryOp
      SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
      forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM Token -> Token
op ParsecT String UserState (SCBase m) Token
readCondWord forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m String -> ParsecT s u m a
`orFail` do
          forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1019 String
"Expected this to be an argument to the unary condition."
          forall (m :: * -> *) a. Monad m => a -> m a
return String
"Expected an argument for the unary operator"

    readCondUnaryOp :: ParsecT String UserState (SCBase m) (Token -> Token)
readCondUnaryOp = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        String
s <- forall {s} {m :: * -> *} {m :: * -> *} {u}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s u m String
readOp
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacingOrLf
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> ConditionType -> String -> Token -> Token
TC_Unary Id
id ConditionType
typ String
s

    readOp :: ParsecT s u m String
readOp = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
        forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'-' forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *} {s} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m Char
weirdDash
        String
s <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
letter forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected a test operator"
        forall (m :: * -> *) a. Monad m => a -> m a
return (Char
'-'forall a. a -> [a] -> [a]
:String
s)

    weirdDash :: ParsecT s u m Char
weirdDash = do
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"\x058A\x05BE\x2010\x2011\x2012\x2013\x2014\x2015\xFE63\xFF0D"
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1100
            String
"This is a unicode dash. Delete and retype as ASCII minus."
        forall (m :: * -> *) a. Monad m => a -> m a
return Char
'-'

    readCondWord :: ParsecT String UserState (SCBase m) Token
readCondWord = do
        forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 (forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"]"))
        Token
x <- ParsecT String UserState (SCBase m) Token
readNormalWord
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Token -> Bool
notArrayIndex Token
x Bool -> Bool -> Bool
&& String -> Token -> Bool
endedWith String
"]" Token
x Bool -> Bool -> Bool
&& Bool -> Bool
not (Token
x Token -> String -> Bool
`containsLiteral` String
"[")) forall a b. (a -> b) -> a -> b
$ do
            forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1020 forall a b. (a -> b) -> a -> b
$
                String
"You need a space before the " forall a. [a] -> [a] -> [a]
++ (if Bool
single then String
"]" else String
"]]") forall a. [a] -> [a] -> [a]
++ String
"."
            forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Missing space before ]"
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
single Bool -> Bool -> Bool
&& String -> Token -> Bool
endedWith String
")" Token
x) forall a b. (a -> b) -> a -> b
$ do
            forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1021
                String
"You need a space before the \\)"
            forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Missing space before )"
        forall (f :: * -> *) a. Functor f => f a -> f ()
void forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
        forall (m :: * -> *) a. Monad m => a -> m a
return Token
x
      where endedWith :: String -> Token -> Bool
endedWith String
str (T_NormalWord Id
id s :: [Token]
s@(Token
_:[Token]
_)) =
                case forall a. [a] -> a
last [Token]
s of T_Literal Id
id String
s -> String
str forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` String
s
                               Token
_ -> Bool
False
            endedWith String
_ Token
_ = Bool
False
            notArrayIndex :: Token -> Bool
notArrayIndex (T_NormalWord Id
id s :: [Token]
s@(Token
_:T_Literal Id
_ String
t:[Token]
_)) = String
t forall a. Eq a => a -> a -> Bool
/= String
"["
            notArrayIndex Token
_ = Bool
True
            containsLiteral :: Token -> String -> Bool
containsLiteral Token
x String
s = String
s forall a. Eq a => [a] -> [a] -> Bool
`isInfixOf` Token -> String
onlyLiteralString Token
x

    readCondAndOp :: ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readCondAndOp = forall {m :: * -> *} {b}.
Monad m =>
(Id -> ConditionType -> String -> b)
-> String -> Bool -> ParsecT String UserState (SCBase m) b
readAndOrOp Id -> ConditionType -> String -> Token -> Token -> Token
TC_And String
"&&" Bool
False forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *} {b}.
Monad m =>
(Id -> ConditionType -> String -> b)
-> String -> Bool -> ParsecT String UserState (SCBase m) b
readAndOrOp Id -> ConditionType -> String -> Token -> Token -> Token
TC_And String
"-a" Bool
True

    readCondOrOp :: ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readCondOrOp = do
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall {s} {m :: * -> *} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m ()
guardArithmetic
        forall {m :: * -> *} {b}.
Monad m =>
(Id -> ConditionType -> String -> b)
-> String -> Bool -> ParsecT String UserState (SCBase m) b
readAndOrOp Id -> ConditionType -> String -> Token -> Token -> Token
TC_Or String
"||" Bool
False forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *} {b}.
Monad m =>
(Id -> ConditionType -> String -> b)
-> String -> Bool -> ParsecT String UserState (SCBase m) b
readAndOrOp Id -> ConditionType -> String -> Token -> Token -> Token
TC_Or String
"-o" Bool
True

    readAndOrOp :: (Id -> ConditionType -> String -> b)
-> String -> Bool -> ParsecT String UserState (SCBase m) b
readAndOrOp Id -> ConditionType -> String -> b
node String
op Bool
requiresSpacing = do
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall {m :: * -> *} {s} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m Char
weirdDash
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        String
x <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
op
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) String
condSpacing Bool
requiresSpacing
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> ConditionType -> String -> b
node Id
id ConditionType
typ String
x

    readCondNullaryOrBinary :: ParsecT String UserState (SCBase m) Token
readCondNullaryOrBinary = do
      IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
      Token
x <- ParsecT String UserState (SCBase m) Token
readCondWord forall {s} {u} {m :: * -> *} {a} {a}.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`attempting` (do
              SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
              forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'[')
              forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1026 forall a b. (a -> b) -> a -> b
$ if Bool
single
                  then String
"If grouping expressions inside [..], use \\( ..\\)."
                  else String
"If grouping expressions inside [[..]], use ( .. )."
            )
      Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
      (do
            SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
            Bool
isRegex <- forall {s} {m :: * -> *} {u}. Stream s m Char => ParsecT s u m Bool
regexOperatorAhead
            Token -> Token -> Token
op <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readCondBinaryOp
            Token
y <- if Bool
isRegex
                    then ParsecT String UserState (SCBase m) Token
readRegex
                    else  ParsecT String UserState (SCBase m) Token
readCondWord forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1027 String
"Expected another argument for this operator." forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. MonadPlus m => m a
mzero)
            forall (m :: * -> *) a. Monad m => a -> m a
return (Token
x Token -> Token -> Token
`op` Token
y)
          ) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ( do
            forall {m :: * -> *}.
Monad m =>
Token -> ParsecT String UserState (SCBase m) ()
checkTrailingOp Token
x
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> ConditionType -> Token -> Token
TC_Nullary Id
id ConditionType
typ Token
x
          )

    checkTrailingOp :: Token -> ParsecT String UserState (SCBase m) ()
checkTrailingOp Token
x = forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_ forall a b. (a -> b) -> a -> b
$ do
        (T_Literal Id
id String
str) <- Token -> Maybe Token
getTrailingUnquotedLiteral Token
x
        String
trailingOp <- forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` String
str) [String]
binaryTestOps
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId Id
id Severity
ErrorC Integer
1108 forall a b. (a -> b) -> a -> b
$
            String
"You need a space before and after the " forall a. [a] -> [a] -> [a]
++ String
trailingOp forall a. [a] -> [a] -> [a]
++ String
" ."

    readCondGroup :: ParsecT String UserState (SCBase m) Token
readCondGroup = do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        String
lparen <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String -> ParsecT s u m String
readRegularOrEscaped (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"(")
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
single Bool -> Bool -> Bool
&& String
lparen forall a. Eq a => a -> a -> Bool
== String
"(") forall a b. (a -> b) -> a -> b
$
            forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> m ()
singleWarning SourcePos
pos
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not Bool
single Bool -> Bool -> Bool
&& String
lparen forall a. Eq a => a -> a -> Bool
== String
"\\(") forall a b. (a -> b) -> a -> b
$
            forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> m ()
doubleWarning SourcePos
pos
        forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) String
condSpacing Bool
single
        Token
x <- ParsecT String UserState (SCBase m) Token
readCondContents
        SourcePos
cpos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        String
rparen <- forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String -> ParsecT s u m String
readRegularOrEscaped (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
")")
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) String
condSpacing Bool
single
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
single Bool -> Bool -> Bool
&& String
rparen forall a. Eq a => a -> a -> Bool
== String
")") forall a b. (a -> b) -> a -> b
$
            forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> m ()
singleWarning SourcePos
cpos
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not Bool
single Bool -> Bool -> Bool
&& String
rparen forall a. Eq a => a -> a -> Bool
== String
"\\)") forall a b. (a -> b) -> a -> b
$
            forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> m ()
doubleWarning SourcePos
cpos
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> ConditionType -> Token -> Token
TC_Group Id
id ConditionType
typ Token
x

      where
        singleWarning :: SourcePos -> m ()
singleWarning SourcePos
pos =
            forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1028 String
"In [..] you have to escape \\( \\) or preferably combine [..] expressions."
        doubleWarning :: SourcePos -> m ()
doubleWarning SourcePos
pos =
            forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1029 String
"In [[..]] you shouldn't escape ( or )."


    -- Currently a bit of a hack since parsing rules are obscure
    regexOperatorAhead :: ParsecT s u m Bool
regexOperatorAhead = forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (do
        forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"=~") forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"~=")
        forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True)
          forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
    readRegex :: ParsecT String UserState (SCBase m) Token
readRegex = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"regex" forall a b. (a -> b) -> a -> b
$ do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        [Token]
parts <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String UserState (SCBase m) Token
readPart
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall (f :: * -> *) a. Functor f => f a -> f ()
void forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_NormalWord Id
id [Token]
parts
      where
        readPart :: ParsecT String UserState (SCBase m) Token
readPart = forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [
            ParsecT String UserState (SCBase m) Token
readGroup,
            forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSingleQuoted,
            ParsecT String UserState (SCBase m) Token
readDoubleQuoted,
            forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarExpression,
            forall {m :: * -> *} {s} {s} {a}.
(Stream s m Char, MonadState s m) =>
ParsecT s UserState m a -> ParsecT s UserState m Token
readLiteralForParser forall a b. (a -> b) -> a -> b
$ forall {m :: * -> *}.
Monad m =>
String -> ParsecT String UserState (SCBase m) Token
readNormalLiteral String
"( ",
            forall {m :: * -> *} {s}.
Stream s m Char =>
String -> ParsecT s UserState m Token
readLiteralString String
"|",
            forall {m :: * -> *} {s}.
Stream s m Char =>
ParsecT s UserState m Token
readGlobLiteral
            ]
        readGlobLiteral :: ParsecT s UserState m Token
readGlobLiteral = do
            IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
            Char
s <- forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
extglobStart forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"{}[]$"
            Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id [Char
s]
        readGroup :: ParsecT String UserState (SCBase m) Token
readGroup = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"regex grouping" forall a b. (a -> b) -> a -> b
$ do
            IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
            Token
p1 <- forall {m :: * -> *} {s}.
Stream s m Char =>
String -> ParsecT s UserState m Token
readLiteralString String
"("
            [Token]
parts <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (ParsecT String UserState (SCBase m) Token
readPart forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readRegexLiteral)
            Token
p2 <- forall {m :: * -> *} {s}.
Stream s m Char =>
String -> ParsecT s UserState m Token
readLiteralString String
")"
            Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_NormalWord Id
id (Token
p1forall a. a -> [a] -> [a]
:([Token]
parts forall a. [a] -> [a] -> [a]
++ [Token
p2]))
        readRegexLiteral :: ParsecT String UserState (SCBase m) Token
readRegexLiteral = do
            IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
            String
str <- forall {m :: * -> *} {a}.
Monad m =>
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) String
readGenericLiteral1 (forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
singleQuote forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
doubleQuotable forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"()")
            Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
str
        readLiteralString :: String -> ParsecT s UserState m Token
readLiteralString String
s = do
            IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
            String
str <- forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
s
            Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
str

    readCondTerm :: ParsecT String UserState (SCBase m) Token
readCondTerm = do
        Token
term <- ParsecT String UserState (SCBase m) Token
readCondNot forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readCondExpr
        forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) String
condSpacing Bool
False
        forall (m :: * -> *) a. Monad m => a -> m a
return Token
term

    readCondNot :: ParsecT String UserState (SCBase m) Token
readCondNot = do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'!'
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacingOrLf
        Token
expr <- ParsecT String UserState (SCBase m) Token
readCondExpr
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> ConditionType -> String -> Token -> Token
TC_Unary Id
id ConditionType
typ String
"!" Token
expr

    readCondExpr :: ParsecT String UserState (SCBase m) Token
readCondExpr =
      ParsecT String UserState (SCBase m) Token
readCondGroup forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readCondUnaryExp forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readCondNullaryOrBinary

    readCondOr :: ParsecT String UserState (SCBase m) Token
readCondOr = forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (a -> a -> a) -> ParsecT s u m a
chainl1 ParsecT String UserState (SCBase m) Token
readCondAnd forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readCondAndOp
    readCondAnd :: ParsecT String UserState (SCBase m) Token
readCondAnd = forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (a -> a -> a) -> ParsecT s u m a
chainl1 ParsecT String UserState (SCBase m) Token
readCondTerm forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readCondOrOp
    readCondContents :: ParsecT String UserState (SCBase m) Token
readCondContents = ParsecT String UserState (SCBase m) Token
readCondOr


prop_a1 :: Bool
prop_a1 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
" n++ + ++c"
prop_a2 :: Bool
prop_a2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"$N*4-(3,2)"
prop_a3 :: Bool
prop_a3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"n|=2<<1"
prop_a4 :: Bool
prop_a4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"n &= 2 **3"
prop_a5 :: Bool
prop_a5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"1 |= 4 && n >>= 4"
prop_a6 :: Bool
prop_a6 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
" 1 | 2 ||3|4"
prop_a7 :: Bool
prop_a7 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"3*2**10"
prop_a8 :: Bool
prop_a8 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"3"
prop_a9 :: Bool
prop_a9 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"a^!-b"
prop_a10 :: Bool
prop_a10 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"! $?"
prop_a11 :: Bool
prop_a11 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"10#08 * 16#f"
prop_a12 :: Bool
prop_a12 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"\"$((3+2))\" + '37'"
prop_a13 :: Bool
prop_a13 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"foo[9*y+x]++"
prop_a14 :: Bool
prop_a14 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"1+`echo 2`"
prop_a15 :: Bool
prop_a15 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"foo[`echo foo | sed s/foo/4/g` * 3] + 4"
prop_a16 :: Bool
prop_a16 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"$foo$bar"
prop_a17 :: Bool
prop_a17 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"i<(0+(1+1))"
prop_a18 :: Bool
prop_a18 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"a?b:c"
prop_a19 :: Bool
prop_a19 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"\\\n3 +\\\n  2"
prop_a20 :: Bool
prop_a20 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"a ? b ? c : d : e"
prop_a21 :: Bool
prop_a21 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"a ? b : c ? d : e"
prop_a22 :: Bool
prop_a22 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"!!a"
prop_a23 :: Bool
prop_a23 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"~0"
readArithmeticContents :: Monad m => SCParser m Token
readArithmeticContents :: forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents =
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSequence
  where
    spacing :: ParsecT String UserState (SCBase m) String
spacing =
        let lf :: ParsecT s u m Char
lf = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"\\\n") forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Char
'\n'
        in forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (forall (m :: * -> *). Monad m => SCParser m Char
whitespace forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
lf)

    splitBy :: ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
splitBy ParsecT String UserState (SCBase m) Token
x [String]
ops = forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (a -> a -> a) -> ParsecT s u m a
chainl1 ParsecT String UserState (SCBase m) Token
x (forall {m :: * -> *}.
Monad m =>
[String]
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readBinary [String]
ops)
    readBinary :: [String]
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readBinary [String]
ops = forall {m :: * -> *} {b}.
Monad m =>
[String]
-> (Id -> String -> b) -> ParsecT String UserState (SCBase m) b
readComboOp [String]
ops Id -> String -> Token -> Token -> Token
TA_Binary
    readComboOp :: [String]
-> (Id -> String -> b) -> ParsecT String UserState (SCBase m) b
readComboOp [String]
op Id -> String -> b
token = do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        String
op <- forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice (forall a b. (a -> b) -> [a] -> [b]
map (\String
x -> forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
                                        String
s <- forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
x
                                        forall {s} {m :: * -> *} {u}. Stream s m Char => ParsecT s u m ()
failIfIncompleteOp
                                        forall (m :: * -> *) a. Monad m => a -> m a
return String
s
                            ) [String]
op)
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> b
token Id
id String
op

    failIfIncompleteOp :: ParsecT s u m ()
failIfIncompleteOp = forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"&|<>="

    -- Read binary minus, but also check for -lt, -gt and friends:
    readMinusOp :: ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readMinusOp = do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
            forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'-'
            forall {s} {m :: * -> *} {u}. Stream s m Char => ParsecT s u m ()
failIfIncompleteOp
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ do
            (String
str, String
alt) <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall {s} {m :: * -> *} {m :: * -> *} {b}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
(String, b) -> ParsecT s UserState m (String, b)
tryOp [
                (String
"lt", String
"<"),
                (String
"gt", String
">"),
                (String
"le", String
"<="),
                (String
"ge", String
">="),
                (String
"eq", String
"=="),
                (String
"ne", String
"!=")
              ]
            forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1106 forall a b. (a -> b) -> a -> b
$ String
"In arithmetic contexts, use " forall a. [a] -> [a] -> [a]
++ String
alt forall a. [a] -> [a] -> [a]
++ String
" instead of -" forall a. [a] -> [a] -> [a]
++ String
str
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token -> Token -> Token
TA_Binary Id
id String
"-"
      where
        tryOp :: (String, b) -> ParsecT s UserState m (String, b)
tryOp (String
str, b
alt) = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
            forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
str
            forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing1
            forall (m :: * -> *) a. Monad m => a -> m a
return (String
str, b
alt)

    readArrayIndex :: ParsecT String UserState (SCBase m) Token
readArrayIndex = do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'['
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        String
middle <- forall {s} {m :: * -> *} {s} {u} {a}.
(Stream s m Char, MonadState s m) =>
ParsecT s u m a -> ParsecT s u m String
readStringForParser forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents
        forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
']'
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> SourcePos -> String -> Token
T_UnparsedIndex Id
id SourcePos
pos String
middle

    literal :: String -> ParsecT s UserState m Token
literal String
s = do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
s
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
s

    readVariable :: ParsecT String UserState (SCBase m) Token
readVariable = do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        String
name <- forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readVariableName
        [Token]
indices <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArrayIndex
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> [Token] -> Token
TA_Variable Id
id String
name [Token]
indices

    readExpansion :: ParsecT String UserState (SCBase m) Token
readExpansion = do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        [Token]
pieces <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [
            forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSingleQuoted,
            forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDoubleQuoted,
            forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalDollar,
            forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraced,
            forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readUnquotedBackTicked,
            forall {m :: * -> *} {s}.
Stream s m Char =>
String -> ParsecT s UserState m Token
literal String
"#",
            forall {m :: * -> *}.
Monad m =>
String -> ParsecT String UserState (SCBase m) Token
readNormalLiteral String
"+-*/=%^,]?:"
            ]
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
TA_Expansion Id
id [Token]
pieces

    readGroup :: ParsecT String UserState (SCBase m) Token
readGroup = do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'('
        Token
s <- ParsecT String UserState (SCBase m) Token
readSequence
        forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')'
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> Token -> Token
TA_Parentesis Id
id Token
s

    readArithTerm :: ParsecT String UserState (SCBase m) Token
readArithTerm = ParsecT String UserState (SCBase m) Token
readGroup forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readVariable forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readExpansion

    readSequence :: ParsecT String UserState (SCBase m) Token
readSequence = do
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        [Token]
l <- ParsecT String UserState (SCBase m) Token
readAssignment forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
`sepBy` (forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
',' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing)
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
TA_Sequence Id
id [Token]
l

    readAssignment :: ParsecT String UserState (SCBase m) Token
readAssignment = forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (a -> a -> a) -> ParsecT s u m a
chainr1 ParsecT String UserState (SCBase m) Token
readTrinary forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readAssignmentOp
    readAssignmentOp :: ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readAssignmentOp = forall {m :: * -> *} {b}.
Monad m =>
[String]
-> (Id -> String -> b) -> ParsecT String UserState (SCBase m) b
readComboOp [String
"=", String
"*=", String
"/=", String
"%=", String
"+=", String
"-=", String
"<<=", String
">>=", String
"&=", String
"^=", String
"|="] Id -> String -> Token -> Token -> Token
TA_Assignment

    readTrinary :: ParsecT String UserState (SCBase m) Token
readTrinary = do
        Token
x <- ParsecT String UserState (SCBase m) Token
readLogicalOr
        do
            IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
            forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"?"
            forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
            Token
y <- ParsecT String UserState (SCBase m) Token
readTrinary
            forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
":"
            forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
            Token
z <- ParsecT String UserState (SCBase m) Token
readTrinary
            Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> Token -> Token -> Token -> Token
TA_Trinary Id
id Token
x Token
y Token
z
         forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
          forall (m :: * -> *) a. Monad m => a -> m a
return Token
x

    readLogicalOr :: ParsecT String UserState (SCBase m) Token
readLogicalOr  = ParsecT String UserState (SCBase m) Token
readLogicalAnd forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
`splitBy` [String
"||"]
    readLogicalAnd :: ParsecT String UserState (SCBase m) Token
readLogicalAnd = ParsecT String UserState (SCBase m) Token
readBitOr forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
`splitBy` [String
"&&"]
    readBitOr :: ParsecT String UserState (SCBase m) Token
readBitOr  = ParsecT String UserState (SCBase m) Token
readBitXor forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
`splitBy` [String
"|"]
    readBitXor :: ParsecT String UserState (SCBase m) Token
readBitXor = ParsecT String UserState (SCBase m) Token
readBitAnd forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
`splitBy` [String
"^"]
    readBitAnd :: ParsecT String UserState (SCBase m) Token
readBitAnd = ParsecT String UserState (SCBase m) Token
readEquated forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
`splitBy` [String
"&"]
    readEquated :: ParsecT String UserState (SCBase m) Token
readEquated = ParsecT String UserState (SCBase m) Token
readCompared forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
`splitBy` [String
"==", String
"!="]
    readCompared :: ParsecT String UserState (SCBase m) Token
readCompared = ParsecT String UserState (SCBase m) Token
readShift forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
`splitBy` [String
"<=", String
">=", String
"<", String
">"]
    readShift :: ParsecT String UserState (SCBase m) Token
readShift = ParsecT String UserState (SCBase m) Token
readAddition forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
`splitBy` [String
"<<", String
">>"]
    readAddition :: ParsecT String UserState (SCBase m) Token
readAddition = forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (a -> a -> a) -> ParsecT s u m a
chainl1 ParsecT String UserState (SCBase m) Token
readMultiplication (forall {m :: * -> *}.
Monad m =>
[String]
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readBinary [String
"+"] forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readMinusOp)
    readMultiplication :: ParsecT String UserState (SCBase m) Token
readMultiplication = ParsecT String UserState (SCBase m) Token
readExponential forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
`splitBy` [String
"*", String
"/", String
"%"]
    readExponential :: ParsecT String UserState (SCBase m) Token
readExponential = ParsecT String UserState (SCBase m) Token
readAnyNegated forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
`splitBy` [String
"**"]

    readAnyNegated :: ParsecT String UserState (SCBase m) Token
readAnyNegated = ParsecT String UserState (SCBase m) Token
readNegated forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readAnySigned
    readNegated :: ParsecT String UserState (SCBase m) Token
readNegated = do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        Char
op <- forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"!~"
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
        Token
x <- ParsecT String UserState (SCBase m) Token
readAnyNegated
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token -> Token
TA_Unary Id
id [Char
op] Token
x

    readAnySigned :: ParsecT String UserState (SCBase m) Token
readAnySigned = ParsecT String UserState (SCBase m) Token
readSigned forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readAnycremented
    readSigned :: ParsecT String UserState (SCBase m) Token
readSigned = do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        Char
op <- forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice (forall a b. (a -> b) -> [a] -> [b]
map forall {m :: * -> *}.
Monad m =>
Char -> ParsecT String UserState (SCBase m) Char
readSignOp String
"+-")
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
        Token
x <- ParsecT String UserState (SCBase m) Token
readAnycremented
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token -> Token
TA_Unary Id
id [Char
op] Token
x
     where
        readSignOp :: Char -> ParsecT String UserState (SCBase m) Char
readSignOp Char
c = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
            forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
c
            forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
c
            forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
            forall (m :: * -> *) a. Monad m => a -> m a
return Char
c

    readAnycremented :: ParsecT String UserState (SCBase m) Token
readAnycremented = ParsecT String UserState (SCBase m) Token
readNormalOrPostfixIncremented forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readPrefixIncremented
    readPrefixIncremented :: ParsecT String UserState (SCBase m) Token
readPrefixIncremented = do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        String
op <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"++" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"--"
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
        Token
x <- ParsecT String UserState (SCBase m) Token
readArithTerm
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token -> Token
TA_Unary Id
id (String
op forall a. [a] -> [a] -> [a]
++ String
"|") Token
x

    readNormalOrPostfixIncremented :: ParsecT String UserState (SCBase m) Token
readNormalOrPostfixIncremented = do
        Token
x <- ParsecT String UserState (SCBase m) Token
readArithTerm
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
        do
            IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
            String
op <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"++" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"--"
            Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
            forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token -> Token
TA_Unary Id
id (Char
'|'forall a. a -> [a] -> [a]
:String
op) Token
x
         forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
            forall (m :: * -> *) a. Monad m => a -> m a
return Token
x



prop_readCondition :: Bool
prop_readCondition   = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[ \\( a = b \\) -a \\( c = d \\) ]"
prop_readCondition2 :: Bool
prop_readCondition2  = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ (a = b) || (c = d) ]]"
prop_readCondition3 :: Bool
prop_readCondition3  = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ $c = [[:alpha:].~-] ]]"
prop_readCondition4 :: Bool
prop_readCondition4  = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ $c =~ *foo* ]]"
prop_readCondition5 :: Bool
prop_readCondition5  = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ $c =~ f( ]] )* ]]"
prop_readCondition5a :: Bool
prop_readCondition5a = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ $c =~ a(b) ]]"
prop_readCondition5b :: Bool
prop_readCondition5b = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ $c =~ f( ($var ]]) )* ]]"
prop_readCondition6 :: Bool
prop_readCondition6  = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ $c =~ ^[yY]$ ]]"
prop_readCondition7 :: Bool
prop_readCondition7  = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ ${line} =~ ^[[:space:]]*# ]]"
prop_readCondition8 :: Bool
prop_readCondition8  = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ $l =~ ogg|flac ]]"
prop_readCondition9 :: Bool
prop_readCondition9  = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[ foo -a -f bar ]"
prop_readCondition10 :: Bool
prop_readCondition10 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[\na == b\n||\nc == d ]]"
prop_readCondition10a :: Bool
prop_readCondition10a = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[\na == b  ||\nc == d ]]"
prop_readCondition10b :: Bool
prop_readCondition10b = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ a == b\n||\nc == d ]]"
prop_readCondition11 :: Bool
prop_readCondition11 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ a == b ||\n c == d ]]"
prop_readCondition12 :: Bool
prop_readCondition12 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[ a == b \n -o c == d ]"
prop_readCondition13 :: Bool
prop_readCondition13 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ foo =~ ^fo{1,3}$ ]]"
prop_readCondition14 :: Bool
prop_readCondition14 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[ foo '>' bar ]"
prop_readCondition15 :: Bool
prop_readCondition15 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[ foo \">=\" bar ]"
prop_readCondition16 :: Bool
prop_readCondition16 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[ foo \\< bar ]"
prop_readCondition17 :: Bool
prop_readCondition17 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ ${file::1} = [-.\\|/\\\\] ]]"
prop_readCondition18 :: Bool
prop_readCondition18 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[ ]"
prop_readCondition19 :: Bool
prop_readCondition19 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[ '(' x \")\" ]"
prop_readCondition20 :: Bool
prop_readCondition20 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ echo_rc -eq 0 ]]"
prop_readCondition21 :: Bool
prop_readCondition21 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ $1 =~ ^(a\\ b)$ ]]"
prop_readCondition22 :: Bool
prop_readCondition22 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ $1 =~ \\.a\\.(\\.b\\.)\\.c\\. ]]"
prop_readCondition23 :: Bool
prop_readCondition23 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ -v arr[$var] ]]"
prop_readCondition25 :: Bool
prop_readCondition25 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ lex.yy.c -ot program.l ]]"
prop_readCondition26 :: Bool
prop_readCondition26 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"[[ foo ]]\\\n && bar"
prop_readCondition27 :: Bool
prop_readCondition27 = Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readConditionCommand String
"[[ x ]] foo"
prop_readCondition28 :: Bool
prop_readCondition28 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ x = [\"$1\"] ]]"
prop_readCondition29 :: Bool
prop_readCondition29 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ x = [*] ]]"

readCondition :: ParsecT String UserState (SCBase m) Token
readCondition = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"test expression" forall a b. (a -> b) -> a -> b
$ do
    SourcePos
opos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    String
open <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"[[") forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"["
    let single :: Bool
single = String
open forall a. Eq a => a -> a -> Bool
== String
"["
    let typ :: ConditionType
typ = if Bool
single then ConditionType
SingleBracket else ConditionType
DoubleBracket

    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    String
space <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
space) forall a b. (a -> b) -> a -> b
$
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAtWithEnd SourcePos
opos SourcePos
pos Severity
ErrorC Integer
1035 forall a b. (a -> b) -> a -> b
$ String
"You need a space after the " forall a. [a] -> [a] -> [a]
++
            if Bool
single
                then String
"[ and before the ]."
                else String
"[[ and before the ]]."
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
single Bool -> Bool -> Bool
&& Char
'\n' forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
space) forall a b. (a -> b) -> a -> b
$
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1080 String
"You need \\ before line feeds to break lines in [ ]."

    Token
condition <- Bool -> ParsecT String UserState (SCBase m) Token
readConditionContents Bool
single forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do
        forall (f :: * -> *). Alternative f => Bool -> f ()
guard forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> Bool
null forall a b. (a -> b) -> a -> b
$ String
space
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"]"
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> ConditionType -> Token
TC_Empty Id
id ConditionType
typ

    SourcePos
cpos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    String
close <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"]]") forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"]" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected test to end here (don't wrap commands in []/[[]])"
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String
open forall a. Eq a => a -> a -> Bool
== String
"[[" Bool -> Bool -> Bool
&& String
close forall a. Eq a => a -> a -> Bool
/= String
"]]") forall a b. (a -> b) -> a -> b
$ forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
cpos Severity
ErrorC Integer
1033 String
"Test expression was opened with double [[ but closed with single ]. Make sure they match."
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String
open forall a. Eq a => a -> a -> Bool
== String
"[" Bool -> Bool -> Bool
&& String
close forall a. Eq a => a -> a -> Bool
/= String
"]" ) forall a b. (a -> b) -> a -> b
$ forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
opos Severity
ErrorC Integer
1034 String
"Test expression was opened with single [ but closed with double ]]. Make sure they match."
    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> ConditionType -> Token -> Token
T_Condition Id
id ConditionType
typ Token
condition

readAnnotationPrefix :: ParsecT s UserState m String
readAnnotationPrefix = do
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'#'
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Char
linewhitespace
    forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"shellcheck"

prop_readAnnotation1 :: Bool
prop_readAnnotation1 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotation String
"# shellcheck disable=1234,5678\n"
prop_readAnnotation2 :: Bool
prop_readAnnotation2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotation String
"# shellcheck disable=SC1234 disable=SC5678\n"
prop_readAnnotation3 :: Bool
prop_readAnnotation3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotation String
"# shellcheck disable=SC1234 source=/dev/null disable=SC5678\n"
prop_readAnnotation4 :: Bool
prop_readAnnotation4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotation String
"# shellcheck cats=dogs disable=SC1234\n"
prop_readAnnotation5 :: Bool
prop_readAnnotation5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotation String
"# shellcheck disable=SC2002 # All cats are precious\n"
prop_readAnnotation6 :: Bool
prop_readAnnotation6 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotation String
"# shellcheck disable=SC1234 # shellcheck foo=bar\n"
prop_readAnnotation7 :: Bool
prop_readAnnotation7 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotation String
"# shellcheck disable=SC1000,SC2000-SC3000,SC1001\n"
prop_readAnnotation8 :: Bool
prop_readAnnotation8 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotation String
"# shellcheck disable=all\n"
prop_readAnnotation9 :: Bool
prop_readAnnotation9 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotation String
"# shellcheck source='foo bar' source-path=\"baz etc\"\n"
prop_readAnnotation10 :: Bool
prop_readAnnotation10 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotation String
"# shellcheck disable='SC1234,SC2345' enable=\"foo\" shell='bash'\n"
prop_readAnnotation11 :: Bool
prop_readAnnotation11 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk (forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) [Annotation]
readAnnotationWithoutPrefix Bool
False) String
"external-sources='true'"

readAnnotation :: ParsecT String UserState (SCBase m) [Annotation]
readAnnotation = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"shellcheck directive" forall a b. (a -> b) -> a -> b
$ do
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m String
readAnnotationPrefix
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Char
linewhitespace
    forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) [Annotation]
readAnnotationWithoutPrefix Bool
True

readAnnotationWithoutPrefix :: Bool -> ParsecT String UserState (SCBase m) [Annotation]
readAnnotationWithoutPrefix Bool
sandboxed = do
    [[Annotation]]
values <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readKey
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readAnyComment
    forall (f :: * -> *) a. Functor f => f a -> f ()
void forall (m :: * -> *). Monad m => SCParser m Char
linefeed forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do
        forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s UserState m ()
parseNote Severity
ErrorC Integer
1125 String
"Invalid key=value pair? Ignoring the rest of this directive starting here."
        forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
"\n")
        forall (f :: * -> *) a. Functor f => f a -> f ()
void forall (m :: * -> *). Monad m => SCParser m Char
linefeed forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Char
linewhitespace
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Annotation]]
values
  where
    plainOrQuoted :: ParsecT String u m a -> ParsecT String u m a
plainOrQuoted ParsecT String u m a
p = forall {m :: * -> *} {u} {b}.
Monad m =>
ParsecT String u m b -> ParsecT String u m b
quoted ParsecT String u m a
p forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String u m a
p
    quoted :: ParsecT String u m b -> ParsecT String u m b
quoted ParsecT String u m b
p = do
        Char
c <- forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"'\""
        SourcePos
start <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        String
str <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf (Char
cforall a. a -> [a] -> [a]
:String
"\n")
        forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
c forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Missing terminating quote for directive."
        forall {m :: * -> *} {a} {u} {b}.
Monad m =>
SourcePos -> ParsecT a u m b -> a -> ParsecT a u m b
subParse SourcePos
start ParsecT String u m b
p String
str
    readKey :: ParsecT String UserState (SCBase m) [Annotation]
readKey = do
        SourcePos
keyPos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        String
key <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
letter forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'-')
        forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'=' forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected '=' after directive key"
        [Annotation]
annotations <- case String
key of
            String
"disable" -> forall {m :: * -> *} {u} {b}.
Monad m =>
ParsecT String u m b -> ParsecT String u m b
plainOrQuoted forall a b. (a -> b) -> a -> b
$ forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m Annotation
readElement forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
`sepBy` forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
','
              where
                readElement :: ParsecT s u m Annotation
readElement = forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m Annotation
readRange forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m Annotation
readAll
                readAll :: ParsecT s u m Annotation
readAll = do
                    forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"all"
                    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Annotation
DisableComment Integer
0 Integer
1000000
                readRange :: ParsecT s u m Annotation
readRange = do
                    Integer
from <- forall {s} {m :: * -> *} {b} {u}.
(Stream s m Char, Read b) =>
ParsecT s u m b
readCode
                    Integer
to <- forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [ forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'-' forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall {s} {m :: * -> *} {b} {u}.
(Stream s m Char, Read b) =>
ParsecT s u m b
readCode, forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Integer
fromforall a. Num a => a -> a -> a
+Integer
1 ]
                    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Annotation
DisableComment Integer
from Integer
to
                readCode :: ParsecT s u m b
readCode = do
                    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"SC"
                    String
int <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit
                    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Read a => String -> a
read String
int

            String
"enable" -> forall {m :: * -> *} {u} {b}.
Monad m =>
ParsecT String u m b -> ParsecT String u m b
plainOrQuoted forall a b. (a -> b) -> a -> b
$ forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m Annotation
readName forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
`sepBy` forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
','
              where
                readName :: ParsecT s u m Annotation
readName = String -> Annotation
EnableComment forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
letter forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'-')

            String
"source" -> do
                String
filename <- forall {m :: * -> *} {u} {b}.
Monad m =>
ParsecT String u m b -> ParsecT String u m b
quoted (forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
" \n")
                forall (m :: * -> *) a. Monad m => a -> m a
return [String -> Annotation
SourceOverride String
filename]

            String
"source-path" -> do
                String
dirname <- forall {m :: * -> *} {u} {b}.
Monad m =>
ParsecT String u m b -> ParsecT String u m b
quoted (forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
" \n")
                forall (m :: * -> *) a. Monad m => a -> m a
return [String -> Annotation
SourcePath String
dirname]

            String
"shell" -> do
                SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                String
shell <- forall {m :: * -> *} {u} {b}.
Monad m =>
ParsecT String u m b -> ParsecT String u m b
quoted (forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
" \n")
                forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (forall a. Maybe a -> Bool
isNothing forall a b. (a -> b) -> a -> b
$ String -> Maybe Shell
shellForExecutable String
shell) forall a b. (a -> b) -> a -> b
$
                    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
pos Severity
ErrorC Integer
1103
                        String
"This shell type is unknown. Use e.g. sh or bash."
                forall (m :: * -> *) a. Monad m => a -> m a
return [String -> Annotation
ShellOverride String
shell]

            String
"external-sources" -> do
                SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                String
value <- forall {m :: * -> *} {u} {b}.
Monad m =>
ParsecT String u m b -> ParsecT String u m b
plainOrQuoted forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
letter
                case String
value of
                    String
"true" ->
                        if Bool
sandboxed
                        then do
                            forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
pos Severity
ErrorC Integer
1144 String
"external-sources can only be enabled in .shellcheckrc, not in individual files."
                            forall (m :: * -> *) a. Monad m => a -> m a
return []
                        else forall (m :: * -> *) a. Monad m => a -> m a
return [Bool -> Annotation
ExternalSources Bool
True]
                    String
"false" -> forall (m :: * -> *) a. Monad m => a -> m a
return [Bool -> Annotation
ExternalSources Bool
False]
                    String
_ -> do
                        forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
pos Severity
ErrorC Integer
1145 String
"Unknown external-sources value. Expected true/false."
                        forall (m :: * -> *) a. Monad m => a -> m a
return []

            String
_ -> do
                forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
keyPos Severity
WarningC Integer
1107 String
"This directive is unknown. It will be ignored."
                forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar forall {s} {m :: * -> *} {t} {u} {a} {a}.
(Stream s m t, Show t) =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m [a]
`reluctantlyTill` forall (m :: * -> *). Monad m => SCParser m Char
whitespace
                forall (m :: * -> *) a. Monad m => a -> m a
return []

        forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Char
linewhitespace
        forall (m :: * -> *) a. Monad m => a -> m a
return [Annotation]
annotations

readAnnotations :: ParsecT String UserState (SCBase m) [Annotation]
readAnnotations = do
    [[Annotation]]
annotations <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotation forall {s} {m :: * -> *} {t} {u} {a} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`thenSkip` forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing)
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Annotation]]
annotations

readComment :: ParsecT s UserState m String
readComment = do
    forall {s} {u} {m :: * -> *} {a}.
String -> ParsecT s u m a -> ParsecT s u m ()
unexpecting String
"shellcheck annotation" forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m String
readAnnotationPrefix
    forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readAnyComment

prop_readAnyComment :: Bool
prop_readAnyComment = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readAnyComment String
"# Comment"
readAnyComment :: ParsecT s u m String
readAnyComment = do
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'#'
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
"\r\n"

prop_readNormalWord :: Bool
prop_readNormalWord = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"'foo'\"bar\"{1..3}baz$(lol)"
prop_readNormalWord2 :: Bool
prop_readNormalWord2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"foo**(foo)!!!(@@(bar))"
prop_readNormalWord3 :: Bool
prop_readNormalWord3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"foo#"
prop_readNormalWord4 :: Bool
prop_readNormalWord4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"$\"foo\"$'foo\nbar'"
prop_readNormalWord5 :: Bool
prop_readNormalWord5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"${foo}}"
prop_readNormalWord6 :: Bool
prop_readNormalWord6 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"foo/{}"
prop_readNormalWord7 :: Bool
prop_readNormalWord7 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"foo\\\nbar"
prop_readNormalWord8 :: Bool
prop_readNormalWord8 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSubshell String
"(foo\\ \nbar)"
prop_readNormalWord9 :: Bool
prop_readNormalWord9 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSubshell String
"(foo\\ ;\nbar)"
prop_readNormalWord10 :: Bool
prop_readNormalWord10 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"\x201Chello\x201D"
prop_readNormalWord11 :: Bool
prop_readNormalWord11 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"\x2018hello\x2019"
prop_readNormalWord12 :: Bool
prop_readNormalWord12 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"hello\x2018"
readNormalWord :: ParsecT String UserState (SCBase m) Token
readNormalWord = String -> [String] -> ParsecT String UserState (SCBase m) Token
readNormalishWord String
"" [String
"do", String
"done", String
"then", String
"fi", String
"esac"]

readPatternWord :: ParsecT String UserState (SCBase m) Token
readPatternWord = String -> [String] -> ParsecT String UserState (SCBase m) Token
readNormalishWord String
"" [String
"esac"]

readNormalishWord :: String -> [String] -> ParsecT String UserState (SCBase m) Token
readNormalishWord String
end [String]
terms = do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    [Token]
x <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (String -> ParsecT String UserState (SCBase m) Token
readNormalWordPart String
end)
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall {f :: * -> *} {t :: * -> *} {m :: * -> *}.
(Foldable t, MonadState SystemState f,
 MonadReader (Environment m) f) =>
SourcePos -> [Token] -> t String -> f ()
checkPossibleTermination SourcePos
pos [Token]
x [String]
terms
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_NormalWord Id
id [Token]
x

readIndexSpan :: ParsecT String UserState (SCBase m) Token
readIndexSpan = do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    [Token]
x <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (String -> ParsecT String UserState (SCBase m) Token
readNormalWordPart String
"]" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m Token
someSpace forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s} {m :: * -> *}.
Stream s m Char =>
ParsecT s UserState m Token
otherLiteral)
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_NormalWord Id
id [Token]
x
  where
    someSpace :: ParsecT s UserState m Token
someSpace = do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        String
str <- forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing1
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
str
    otherLiteral :: ParsecT s UserState m Token
otherLiteral = do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        String
str <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
quotableChars
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
str

checkPossibleTermination :: SourcePos -> [Token] -> t String -> f ()
checkPossibleTermination SourcePos
pos [T_Literal Id
_ String
x] t String
terminators =
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String
x forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` t String
terminators) forall a b. (a -> b) -> a -> b
$
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
WarningC Integer
1010 forall a b. (a -> b) -> a -> b
$ String
"Use semicolon or linefeed before '" forall a. [a] -> [a] -> [a]
++ String
x forall a. [a] -> [a] -> [a]
++ String
"' (or quote to make it literal)."
checkPossibleTermination SourcePos
_ [Token]
_ t String
_ = forall (m :: * -> *) a. Monad m => a -> m a
return ()

readNormalWordPart :: String -> ParsecT String UserState (SCBase m) Token
readNormalWordPart String
end = do
    forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
end
    forall {s} {m :: * -> *} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m ()
checkForParenthesis
    forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSingleQuoted,
        ParsecT String UserState (SCBase m) Token
readDoubleQuoted,
        ParsecT String UserState (SCBase m) Token
readGlob,
        ParsecT String UserState (SCBase m) Token
readNormalDollar,
        ParsecT String UserState (SCBase m) Token
readBraced,
        ParsecT String UserState (SCBase m) Token
readUnquotedBackTicked,
        ParsecT String UserState (SCBase m) Token
readProcSub,
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readUnicodeQuote,
        forall {m :: * -> *}.
Monad m =>
String -> ParsecT String UserState (SCBase m) Token
readNormalLiteral String
end,
        forall {m :: * -> *} {s} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
readLiteralCurlyBraces
      ]
  where
    checkForParenthesis :: ParsecT s u m ()
checkForParenthesis =
        forall (m :: * -> *) a. Monad m => a -> m a
return () forall {s} {u} {m :: * -> *} {a} {a}.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`attempting` do
            SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
            forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'('
            forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1036 String
"'(' is invalid here. Did you forget to escape it?"

    readLiteralCurlyBraces :: ParsecT s UserState m Token
readLiteralCurlyBraces = do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        String
str <- forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
findParam forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *} {s} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m String
literalBraces
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
str

    findParam :: ParsecT s u m String
findParam = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"{}"
    literalBraces :: ParsecT s u m String
literalBraces = do
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        Char
c <- forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"{}"
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
WarningC Integer
1083 forall a b. (a -> b) -> a -> b
$
            String
"This " forall a. [a] -> [a] -> [a]
++ [Char
c] forall a. [a] -> [a] -> [a]
++ String
" is literal. Check expression (missing ;/\\n?) or quote it."
        forall (m :: * -> *) a. Monad m => a -> m a
return [Char
c]


readSpacePart :: ParsecT String UserState (SCBase m) Token
readSpacePart = do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    String
x <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall (m :: * -> *). Monad m => SCParser m Char
whitespace
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
x

readDollarBracedWord :: ParsecT String UserState (SCBase m) Token
readDollarBracedWord = do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    [Token]
list <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String UserState (SCBase m) Token
readDollarBracedPart
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_NormalWord Id
id [Token]
list

readDollarBracedPart :: ParsecT String UserState (SCBase m) Token
readDollarBracedPart = forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSingleQuoted forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readDoubleQuoted forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
                       forall {s} {m :: * -> *}.
Stream s m Char =>
ParsecT s UserState m Token
readParamSubSpecialChar forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readExtglob forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readNormalDollar forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
                       ParsecT String UserState (SCBase m) Token
readUnquotedBackTicked forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarBracedLiteral

readDollarBracedLiteral :: ParsecT String UserState (SCBase m) Token
readDollarBracedLiteral = do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    [String]
vars <- (forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readBraceEscaped forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Char
x -> forall (m :: * -> *) a. Monad m => a -> m a
return [Char
x])) forall {s} {m :: * -> *} {t} {u} {a} {a}.
(Stream s m t, Show t) =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m [a]
`reluctantlyTill1` forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
bracedQuotable
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
vars

readParamSubSpecialChar :: ParsecT s UserState m Token
readParamSubSpecialChar = do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    String
x <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
paramSubSpecialChars
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_ParamSubSpecialChar Id
id String
x

prop_readProcSub1 :: Bool
prop_readProcSub1 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readProcSub String
"<(echo test | wc -l)"
prop_readProcSub2 :: Bool
prop_readProcSub2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readProcSub String
"<(  if true; then true; fi )"
prop_readProcSub3 :: Bool
prop_readProcSub3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readProcSub String
"<( # nothing here \n)"
readProcSub :: ParsecT String UserState (SCBase m) Token
readProcSub = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"process substitution" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    String
dir <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
                    Char
x <- forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"<>"
                    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'('
                    forall (m :: * -> *) a. Monad m => a -> m a
return [Char
x]
    [Token]
list <- ParsecT String UserState (SCBase m) [Token]
readCompoundListOrEmpty
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')'
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> [Token] -> Token
T_ProcSub Id
id String
dir [Token]
list

prop_readSingleQuoted :: Bool
prop_readSingleQuoted = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSingleQuoted String
"'foo bar'"
prop_readSingleQuoted2 :: Bool
prop_readSingleQuoted2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSingleQuoted String
"'foo bar\\'"
prop_readSingleQuoted4 :: Bool
prop_readSingleQuoted4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"'it's"
prop_readSingleQuoted5 :: Bool
prop_readSingleQuoted5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"foo='bar\ncow 'arg"
prop_readSingleQuoted6 :: Bool
prop_readSingleQuoted6 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"foo='bar cow 'arg"
prop_readSingleQuoted7 :: Bool
prop_readSingleQuoted7 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSingleQuoted String
"'foo\x201C\&bar'"
prop_readSingleQuoted8 :: Bool
prop_readSingleQuoted8 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSingleQuoted String
"'foo\x2018\&bar'"
readSingleQuoted :: ParsecT String UserState (SCBase m) Token
readSingleQuoted = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"single quoted string" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    SourcePos
startPos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
singleQuote
    [String]
s <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readSingleQuotedPart
    let string :: String
string = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
s
    SourcePos
endPos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
singleQuote forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected end of single quoted string"

    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ do
        Char
c <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
suspectCharAfterQuotes forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"'"
        if Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
string) Bool -> Bool -> Bool
&& Char -> Bool
isAlpha Char
c Bool -> Bool -> Bool
&& Char -> Bool
isAlpha (forall a. [a] -> a
last String
string)
          then
            forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
endPos Severity
WarningC Integer
1011
                String
"This apostrophe terminated the single quoted string!"
          else
            forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Char
'\n' forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
string Bool -> Bool -> Bool
&& Bool -> Bool
not (String
"\n" forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
string)) forall a b. (a -> b) -> a -> b
$
                forall {m :: * -> *} {m :: * -> *}.
(MonadReader (Environment m) m, MonadState SystemState m) =>
SourcePos -> SourcePos -> String -> m ()
suggestForgotClosingQuote SourcePos
startPos SourcePos
endPos String
"single quoted string"

    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return (Id -> String -> Token
T_SingleQuoted Id
id String
string)

readSingleQuotedLiteral :: ParsecT String UserState (SCBase m) String
readSingleQuotedLiteral = do
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
singleQuote
    [String]
strs <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readSingleQuotedPart
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
singleQuote
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
strs

readSingleQuotedPart :: ParsecT String UserState (SCBase m) String
readSingleQuotedPart =
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readSingleEscaped
    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf forall a b. (a -> b) -> a -> b
$ String
"'\\" forall a. [a] -> [a] -> [a]
++ String
unicodeSingleQuotes)
    forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *} {s} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m String
readUnicodeQuote
   where
    readUnicodeQuote :: ParsecT s u m String
readUnicodeQuote = do
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        Char
x <- forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
unicodeSingleQuotes
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
WarningC Integer
1112
            String
"This is a unicode quote. Delete and retype it (or ignore/doublequote for literal)."
        forall (m :: * -> *) a. Monad m => a -> m a
return [Char
x]


prop_readBackTicked :: Bool
prop_readBackTicked = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk (forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) Token
readBackTicked Bool
False) String
"`ls *.mp3`"
prop_readBackTicked2 :: Bool
prop_readBackTicked2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk (forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) Token
readBackTicked Bool
False) String
"`grep \"\\\"\"`"
prop_readBackTicked3 :: Bool
prop_readBackTicked3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning (forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) Token
readBackTicked Bool
False) String
"´grep \"\\\"\"´"
prop_readBackTicked4 :: Bool
prop_readBackTicked4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"`echo foo\necho bar`"
prop_readBackTicked5 :: Bool
prop_readBackTicked5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"echo `foo`bar"
prop_readBackTicked6 :: Bool
prop_readBackTicked6 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"echo `foo\necho `bar"
prop_readBackTicked7 :: Bool
prop_readBackTicked7 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"`#inline comment`"
prop_readBackTicked8 :: Bool
prop_readBackTicked8 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"echo `#comment` \\\nbar baz"
readQuotedBackTicked :: ParsecT String UserState (SCBase m) Token
readQuotedBackTicked = Bool -> ParsecT String UserState (SCBase m) Token
readBackTicked Bool
True
readUnquotedBackTicked :: ParsecT String UserState (SCBase m) Token
readUnquotedBackTicked = Bool -> ParsecT String UserState (SCBase m) Token
readBackTicked Bool
False
readBackTicked :: Bool -> ParsecT String UserState (SCBase m) Token
readBackTicked Bool
quoted = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"backtick expansion" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    SourcePos
startPos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    forall {s} {m :: * -> *} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m ()
backtick
    SourcePos
subStart <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    String
subString <- forall {m :: * -> *}.
Monad m =>
String -> ParsecT String UserState (SCBase m) String
readGenericLiteral String
"`´"
    SourcePos
endPos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    forall {s} {m :: * -> *} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m ()
backtick
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start

    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ do
        Char
c <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
suspectCharAfterQuotes
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Char
'\n' forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
subString Bool -> Bool -> Bool
&& Bool -> Bool
not (String
"\n" forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
subString)) forall a b. (a -> b) -> a -> b
$
            forall {m :: * -> *} {m :: * -> *}.
(MonadReader (Environment m) m, MonadState SystemState m) =>
SourcePos -> SourcePos -> String -> m ()
suggestForgotClosingQuote SourcePos
startPos SourcePos
endPos String
"backtick expansion"

    -- Result positions may be off due to escapes
    [Token]
result <- forall {m :: * -> *} {a} {u} {b}.
Monad m =>
SourcePos -> ParsecT a u m b -> a -> ParsecT a u m b
subParse SourcePos
subStart (forall (m :: * -> *) v. Monad m => SCParser m v -> SCParser m v
tryWithErrors ParsecT String UserState (SCBase m) [Token]
subParser forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return []) (ShowS
unEscape String
subString)
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_Backticked Id
id [Token]
result
  where
    unEscape :: ShowS
unEscape [] = []
    unEscape (Char
'\\':Char
'"':String
rest) | Bool
quoted = Char
'"' forall a. a -> [a] -> [a]
: ShowS
unEscape String
rest
    unEscape (Char
'\\':Char
x:String
rest) | Char
x forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
"$`\\" = Char
x forall a. a -> [a] -> [a]
: ShowS
unEscape String
rest
    unEscape (Char
'\\':Char
'\n':String
rest) = ShowS
unEscape String
rest
    unEscape (Char
c:String
rest) = Char
c forall a. a -> [a] -> [a]
: ShowS
unEscape String
rest
    subParser :: ParsecT String UserState (SCBase m) [Token]
subParser = do
        [Token]
cmds <- ParsecT String UserState (SCBase m) [Token]
readCompoundListOrEmpty
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
verifyEof
        forall (m :: * -> *) a. Monad m => a -> m a
return [Token]
cmds
    backtick :: ParsecT s u m ()
backtick =
      forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'`') forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do
         SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
         forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'´'
         forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1077
            String
"For command expansion, the tick should slant left (` vs ´). Use $(..) instead."

-- Run a parser on a new input, such as for `..` or here documents.
subParse :: SourcePos -> ParsecT a u m b -> a -> ParsecT a u m b
subParse SourcePos
pos ParsecT a u m b
parser a
input = do
    SourcePos
lastPosition <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    a
lastInput <- forall (m :: * -> *) s u. Monad m => ParsecT s u m s
getInput
    forall (m :: * -> *) s u. Monad m => SourcePos -> ParsecT s u m ()
setPosition SourcePos
pos
    forall (m :: * -> *) s u. Monad m => s -> ParsecT s u m ()
setInput a
input
    b
result <- ParsecT a u m b
parser
    forall (m :: * -> *) s u. Monad m => s -> ParsecT s u m ()
setInput a
lastInput
    forall (m :: * -> *) s u. Monad m => SourcePos -> ParsecT s u m ()
setPosition SourcePos
lastPosition
    forall (m :: * -> *) a. Monad m => a -> m a
return b
result

-- Parse something, but forget all parseProblems
inSeparateContext :: ParsecT s u m b -> ParsecT s u m b
inSeparateContext = forall {s} {m :: * -> *} {s} {u} {b}.
MonadState s m =>
Bool -> ParsecT s u m b -> ParsecT s u m b
parseForgettingContext Bool
True
-- Parse something, but forget all parseProblems on failure
forgetOnFailure :: ParsecT s u m b -> ParsecT s u m b
forgetOnFailure = forall {s} {m :: * -> *} {s} {u} {b}.
MonadState s m =>
Bool -> ParsecT s u m b -> ParsecT s u m b
parseForgettingContext Bool
False

parseForgettingContext :: Bool -> ParsecT s u m b -> ParsecT s u m b
parseForgettingContext Bool
alsoOnSuccess ParsecT s u m b
parser = do
    s
context <- forall s (m :: * -> *). MonadState s m => m s
Ms.get
    forall {s}. MonadState s m => s -> ParsecT s u m b
success s
context forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *} {s} {b}.
(MonadState s m, MonadFail m) =>
s -> m b
failure s
context
  where
    success :: s -> ParsecT s u m b
success s
c = do
        b
res <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT s u m b
parser
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
alsoOnSuccess forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *). MonadState s m => s -> m ()
Ms.put s
c
        forall (m :: * -> *) a. Monad m => a -> m a
return b
res
    failure :: s -> m b
failure s
c = do
        forall s (m :: * -> *). MonadState s m => s -> m ()
Ms.put s
c
        forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
""

prop_readDoubleQuoted :: Bool
prop_readDoubleQuoted = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDoubleQuoted String
"\"Hello $FOO\""
prop_readDoubleQuoted2 :: Bool
prop_readDoubleQuoted2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDoubleQuoted String
"\"$'\""
prop_readDoubleQuoted3 :: Bool
prop_readDoubleQuoted3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDoubleQuoted String
"\"\x2018hello\x2019\""
prop_readDoubleQuoted4 :: Bool
prop_readDoubleQuoted4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"\"foo\nbar\"foo"
prop_readDoubleQuoted5 :: Bool
prop_readDoubleQuoted5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"lol \"foo\nbar\" etc"
prop_readDoubleQuoted6 :: Bool
prop_readDoubleQuoted6 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"echo \"${ ls; }\""
prop_readDoubleQuoted7 :: Bool
prop_readDoubleQuoted7 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"echo \"${ ls;}bar\""
prop_readDoubleQuoted8 :: Bool
prop_readDoubleQuoted8 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDoubleQuoted String
"\"\x201Chello\x201D\""
prop_readDoubleQuoted10 :: Bool
prop_readDoubleQuoted10 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDoubleQuoted String
"\"foo\\\\n\""
readDoubleQuoted :: ParsecT String UserState (SCBase m) Token
readDoubleQuoted = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"double quoted string" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    SourcePos
startPos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
doubleQuote
    [Token]
x <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String UserState (SCBase m) Token
doubleQuotedPart
    SourcePos
endPos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
doubleQuote forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected end of double quoted string"
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ do
        forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
suspectCharAfterQuotes forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"$\""
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Token -> Bool
hasLineFeed [Token]
x Bool -> Bool -> Bool
&& Bool -> Bool
not ([Token] -> Bool
startsWithLineFeed [Token]
x)) forall a b. (a -> b) -> a -> b
$
            forall {m :: * -> *} {m :: * -> *}.
(MonadReader (Environment m) m, MonadState SystemState m) =>
SourcePos -> SourcePos -> String -> m ()
suggestForgotClosingQuote SourcePos
startPos SourcePos
endPos String
"double quoted string"
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_DoubleQuoted Id
id [Token]
x
  where
    startsWithLineFeed :: [Token] -> Bool
startsWithLineFeed (T_Literal Id
_ (Char
'\n':String
_):[Token]
_) = Bool
True
    startsWithLineFeed [Token]
_ = Bool
False
    hasLineFeed :: Token -> Bool
hasLineFeed (T_Literal Id
_ String
str) | Char
'\n' forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
str = Bool
True
    hasLineFeed Token
_ = Bool
False

suggestForgotClosingQuote :: SourcePos -> SourcePos -> String -> m ()
suggestForgotClosingQuote SourcePos
startPos SourcePos
endPos String
name = do
    forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
startPos Severity
WarningC Integer
1078 forall a b. (a -> b) -> a -> b
$
        String
"Did you forget to close this " forall a. [a] -> [a] -> [a]
++ String
name forall a. [a] -> [a] -> [a]
++ String
"?"
    forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
endPos Severity
InfoC Integer
1079
        String
"This is actually an end quote, but due to next char it looks suspect."

doubleQuotedPart :: ParsecT String UserState (SCBase m) Token
doubleQuotedPart = forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDoubleLiteral forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readDoubleQuotedDollar forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readQuotedBackTicked forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *} {s} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
readUnicodeQuote
  where
    readUnicodeQuote :: ParsecT s UserState m Token
readUnicodeQuote = do
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        Char
c <- forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
unicodeDoubleQuotes
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
WarningC Integer
1111
            String
"This is a unicode quote. Delete and retype it (or ignore/singlequote for literal)."
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id [Char
c]

readDoubleLiteral :: ParsecT String UserState (SCBase m) Token
readDoubleLiteral = do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    [String]
s <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readDoubleLiteralPart
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id (forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
s)

readDoubleLiteralPart :: ParsecT String UserState (SCBase m) String
readDoubleLiteralPart = do
    [String]
x <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readDoubleEscaped forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf (String
doubleQuotableChars forall a. [a] -> [a] -> [a]
++ String
unicodeDoubleQuotes)))
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
x

readNormalLiteral :: String -> ParsecT String UserState (SCBase m) Token
readNormalLiteral String
end = do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    [String]
s <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (forall {m :: * -> *}.
Monad m =>
String -> ParsecT String UserState (SCBase m) String
readNormalLiteralPart String
end)
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id (forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
s)

prop_readGlob1 :: Bool
prop_readGlob1 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readGlob String
"*"
prop_readGlob2 :: Bool
prop_readGlob2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readGlob String
"[^0-9]"
prop_readGlob3 :: Bool
prop_readGlob3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readGlob String
"[a[:alpha:]]"
prop_readGlob4 :: Bool
prop_readGlob4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readGlob String
"[[:alnum:]]"
prop_readGlob5 :: Bool
prop_readGlob5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readGlob String
"[^[:alpha:]1-9]"
prop_readGlob6 :: Bool
prop_readGlob6 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readGlob String
"[\\|]"
prop_readGlob7 :: Bool
prop_readGlob7 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readGlob String
"[^[]"
prop_readGlob8 :: Bool
prop_readGlob8 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readGlob String
"[*?]"
prop_readGlob9 :: Bool
prop_readGlob9 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readGlob String
"[!]^]"
prop_readGlob10 :: Bool
prop_readGlob10 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readGlob String
"[]]"
readGlob :: ParsecT String UserState (SCBase m) Token
readGlob = ParsecT String UserState (SCBase m) Token
readExtglob forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *} {s}.
Stream s m Char =>
ParsecT s UserState m Token
readSimple forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readClass forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *} {s}.
Stream s m Char =>
ParsecT s UserState m Token
readGlobbyLiteral
    where
        readSimple :: ParsecT s UserState m Token
readSimple = do
            IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
            Char
c <- forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"*?"
            Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Glob Id
id [Char
c]
        readClass :: ParsecT String UserState (SCBase m) Token
readClass = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
            IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
            forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'['
            String
negation <- forall {m :: * -> *} {f :: * -> *} {a}.
(Monad m, Functor f) =>
f a -> f (m a)
charToString (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"!^") forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return String
""
            String
leadingBracket <- forall {m :: * -> *} {f :: * -> *} {a}.
(Monad m, Functor f) =>
f a -> f (m a)
charToString (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"]") forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return String
""
            [String]
s <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
predefined forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
String -> ParsecT String UserState (SCBase m) String
readNormalLiteralPart String
"]" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s} {m :: * -> *} {m :: * -> *} {u}.
(Stream s m Char, Monad m) =>
ParsecT s u m (m Char)
globchars)
            forall (f :: * -> *). Alternative f => Bool -> f ()
guard forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
leadingBracket) Bool -> Bool -> Bool
|| Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
s)
            forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
']'
            Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Glob Id
id forall a b. (a -> b) -> a -> b
$ String
"[" forall a. [a] -> [a] -> [a]
++ forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (String
negationforall a. a -> [a] -> [a]
:String
leadingBracketforall a. a -> [a] -> [a]
:[String]
s) forall a. [a] -> [a] -> [a]
++ String
"]"
          where
           globchars :: ParsecT s u m (m Char)
globchars = forall {m :: * -> *} {f :: * -> *} {a}.
(Monad m, Functor f) =>
f a -> f (m a)
charToString forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf forall a b. (a -> b) -> a -> b
$ String
"![" forall a. [a] -> [a] -> [a]
++ String
extglobStartChars
           predefined :: ParsecT s u m String
predefined = do
              forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"[:"
              String
s <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
letter
              forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
":]"
              forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ String
"[:" forall a. [a] -> [a] -> [a]
++ String
s forall a. [a] -> [a] -> [a]
++ String
":]"

        charToString :: f a -> f (m a)
charToString = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (m :: * -> *) a. Monad m => a -> m a
return
        readGlobbyLiteral :: ParsecT s UserState m Token
readGlobbyLiteral = do
            IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
            Char
c <- forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
extglobStart forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'['
            Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id [Char
c]

readNormalLiteralPart :: String -> ParsecT String UserState (SCBase m) String
readNormalLiteralPart String
customEnd =
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readNormalEscaped forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf (String
customEnd forall a. [a] -> [a] -> [a]
++ String
standardEnd))
  where
    standardEnd :: String
standardEnd = String
"[{}"
        forall a. [a] -> [a] -> [a]
++ String
quotableChars
        forall a. [a] -> [a] -> [a]
++ String
extglobStartChars
        forall a. [a] -> [a] -> [a]
++ String
unicodeDoubleQuotes
        forall a. [a] -> [a] -> [a]
++ String
unicodeSingleQuotes

readNormalEscaped :: ParsecT String UserState (SCBase m) String
readNormalEscaped = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"escaped char" forall a b. (a -> b) -> a -> b
$ do
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    forall (m :: * -> *). Monad m => SCParser m Char
backslash
    do
        Char
next <- forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m Char
quotable forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"?*@!+[]{}.,~#"
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Char
next forall a. Eq a => a -> a -> Bool
== Char
' ') forall a b. (a -> b) -> a -> b
$ forall {m :: * -> *}.
Monad m =>
SourcePos -> ParsecT String UserState (SCBase m) ()
checkTrailingSpaces SourcePos
pos forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return ()
        -- Check if this line is followed by a commented line with a trailing backslash
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Char
next forall a. Eq a => a -> a -> Bool
== Char
'\n') forall a b. (a -> b) -> a -> b
$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Functor f => f a -> f ()
void forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ if Char
next forall a. Eq a => a -> a -> Bool
== Char
'\n' then String
"" else [Char
next]
      forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
        do
            Char
next <- forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar
            case Char -> Maybe String
escapedChar Char
next of
                Just String
name -> forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
pos Severity
WarningC Integer
1012 forall a b. (a -> b) -> a -> b
$ String
"\\" forall a. [a] -> [a] -> [a]
++ [Char
next] forall a. [a] -> [a] -> [a]
++ String
" is just literal '" forall a. [a] -> [a] -> [a]
++ [Char
next] forall a. [a] -> [a] -> [a]
++ String
"' here. For " forall a. [a] -> [a] -> [a]
++ String
name forall a. [a] -> [a] -> [a]
++ String
", use " forall a. [a] -> [a] -> [a]
++ Char -> String
alternative Char
next forall a. [a] -> [a] -> [a]
++ String
" instead."
                Maybe String
Nothing -> forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
pos Severity
InfoC Integer
1001 forall a b. (a -> b) -> a -> b
$ String
"This \\" forall a. [a] -> [a] -> [a]
++ [Char
next] forall a. [a] -> [a] -> [a]
++ String
" will be a regular '" forall a. [a] -> [a] -> [a]
++ [Char
next] forall a. [a] -> [a] -> [a]
++ String
"' in this context."
            forall (m :: * -> *) a. Monad m => a -> m a
return [Char
next]
  where
    alternative :: Char -> String
alternative Char
'n' = String
"a quoted, literal line feed"
    alternative Char
t = String
"\"$(printf '\\" forall a. [a] -> [a] -> [a]
++ [Char
t] forall a. [a] -> [a] -> [a]
++ String
"')\""
    escapedChar :: Char -> Maybe String
escapedChar Char
'n' = forall a. a -> Maybe a
Just String
"line feed"
    escapedChar Char
't' = forall a. a -> Maybe a
Just String
"tab"
    escapedChar Char
'r' = forall a. a -> Maybe a
Just String
"carriage return"
    escapedChar Char
_ = forall a. Maybe a
Nothing

    checkTrailingSpaces :: SourcePos -> ParsecT String UserState (SCBase m) ()
checkTrailingSpaces SourcePos
pos = forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
        forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Char
linewhitespace
        forall (f :: * -> *) a. Functor f => f a -> f ()
void forall (m :: * -> *). Monad m => SCParser m Char
linefeed forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1101 String
"Delete trailing spaces after \\ to break line (or use quotes for literal space)."


prop_readExtglob1 :: Bool
prop_readExtglob1 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readExtglob String
"!(*.mp3)"
prop_readExtglob2 :: Bool
prop_readExtglob2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readExtglob String
"!(*.mp3|*.wmv)"
prop_readExtglob4 :: Bool
prop_readExtglob4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readExtglob String
"+(foo \\) bar)"
prop_readExtglob5 :: Bool
prop_readExtglob5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readExtglob String
"+(!(foo *(bar)))"
prop_readExtglob6 :: Bool
prop_readExtglob6 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readExtglob String
"*(((||))|())"
prop_readExtglob7 :: Bool
prop_readExtglob7 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readExtglob String
"*(<>)"
prop_readExtglob8 :: Bool
prop_readExtglob8 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readExtglob String
"@(|*())"
readExtglob :: ParsecT String UserState (SCBase m) Token
readExtglob = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"extglob" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    Char
c <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
            Char
f <- forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
extglobStart
            forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'('
            forall (m :: * -> *) a. Monad m => a -> m a
return Char
f
    [Token]
contents <- ParsecT String UserState (SCBase m) Token
readExtglobPart forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
`sepBy` forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'|'
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')'
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> [Token] -> Token
T_Extglob Id
id [Char
c] [Token]
contents

readExtglobPart :: ParsecT String UserState (SCBase m) Token
readExtglobPart = do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    [Token]
x <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (ParsecT String UserState (SCBase m) Token
readExtglobGroup forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) Token
readNormalWordPart String
"" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSpacePart forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s} {m :: * -> *}.
Stream s m Char =>
ParsecT s UserState m Token
readExtglobLiteral)
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_NormalWord Id
id [Token]
x
  where
    readExtglobGroup :: ParsecT String UserState (SCBase m) Token
readExtglobGroup = do
        forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'('
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        [Token]
contents <- ParsecT String UserState (SCBase m) Token
readExtglobPart forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
`sepBy` forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'|'
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')'
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> [Token] -> Token
T_Extglob Id
id String
"" [Token]
contents
    readExtglobLiteral :: ParsecT s UserState m Token
readExtglobLiteral = do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        String
str <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"<>#;&")
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
str


readSingleEscaped :: ParsecT String UserState (SCBase m) String
readSingleEscaped = do
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    Char
s <- forall (m :: * -> *). Monad m => SCParser m Char
backslash
    Char
x <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar

    case Char
x of
        Char
'\'' -> forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
InfoC Integer
1003 String
"Want to escape a single quote? echo 'This is how it'\\''s done'.";
        Char
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return ()

    forall (m :: * -> *) a. Monad m => a -> m a
return [Char
s]

readDoubleEscaped :: ParsecT String UserState (SCBase m) String
readDoubleEscaped = do
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    Char
bs <- forall (m :: * -> *). Monad m => SCParser m Char
backslash
    (forall (m :: * -> *). Monad m => SCParser m Char
linefeed forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return String
"")
        forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (m :: * -> *) a. Monad m => a -> m a
return forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
doubleQuotable
        forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do
            Char
c <- forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar
            -- This is an invalid escape sequence where the \ is literal.
            -- Previously this caused a SC1117, which may be re-enabled as
            -- as a pedantic warning.
            forall (m :: * -> *) a. Monad m => a -> m a
return [Char
bs, Char
c]

readBraceEscaped :: ParsecT String UserState (SCBase m) String
readBraceEscaped = do
    Char
bs <- forall (m :: * -> *). Monad m => SCParser m Char
backslash
    (forall (m :: * -> *). Monad m => SCParser m Char
linefeed forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return String
"")
        forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (m :: * -> *) a. Monad m => a -> m a
return forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
bracedQuotable
        forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\ Char
x -> [Char
bs, Char
x]) forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar


readGenericLiteral :: String -> ParsecT String UserState (SCBase m) String
readGenericLiteral String
endChars = do
    [String]
strings <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readGenericEscaped forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf (Char
'\\'forall a. a -> [a] -> [a]
:String
endChars)))
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
strings

readGenericLiteral1 :: ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) String
readGenericLiteral1 ParsecT String UserState (SCBase m) a
endExp = do
    [String]
strings <- (forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readGenericEscaped forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Char
x -> forall (m :: * -> *) a. Monad m => a -> m a
return [Char
x])) forall {s} {m :: * -> *} {t} {u} {a} {a}.
(Stream s m t, Show t) =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m [a]
`reluctantlyTill1` ParsecT String UserState (SCBase m) a
endExp
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
strings

readGenericEscaped :: ParsecT String UserState (SCBase m) String
readGenericEscaped = do
    forall (m :: * -> *). Monad m => SCParser m Char
backslash
    Char
x <- forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ if Char
x forall a. Eq a => a -> a -> Bool
== Char
'\n' then [] else [Char
'\\', Char
x]

prop_readBraced :: Bool
prop_readBraced = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraced String
"{1..4}"
prop_readBraced2 :: Bool
prop_readBraced2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraced String
"{foo,bar,\"baz lol\"}"
prop_readBraced3 :: Bool
prop_readBraced3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraced String
"{1,\\},2}"
prop_readBraced4 :: Bool
prop_readBraced4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraced String
"{1,{2,3}}"
prop_readBraced5 :: Bool
prop_readBraced5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraced String
"{JP{,E}G,jp{,e}g}"
prop_readBraced6 :: Bool
prop_readBraced6 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraced String
"{foo,bar,$((${var}))}"
prop_readBraced7 :: Bool
prop_readBraced7 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isNotOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraced String
"{}"
prop_readBraced8 :: Bool
prop_readBraced8 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isNotOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraced String
"{foo}"
readBraced :: ParsecT String UserState (SCBase m) Token
readBraced = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT String UserState (SCBase m) Token
braceExpansion
  where
    braceExpansion :: ParsecT String UserState (SCBase m) Token
braceExpansion =
        Id -> [Token] -> Token
T_BraceExpansion forall {m :: * -> *} {t} {b} {s}.
Monad m =>
(Id -> t -> b)
-> ParsecT s UserState m t -> ParsecT s UserState m b
`withParser` do
            forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'{'
            [Token]
elements <- ParsecT String UserState (SCBase m) Token
bracedElement forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
`sepBy1` forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
','
            forall (f :: * -> *). Alternative f => Bool -> f ()
guard forall a b. (a -> b) -> a -> b
$
                case [Token]
elements of
                    (Token
_:Token
_:[Token]
_) -> Bool
True
                    [Token
t] -> String
".." forall a. Eq a => [a] -> [a] -> Bool
`isInfixOf` Token -> String
onlyLiteralString Token
t
                    [] -> Bool
False
            forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'}'
            forall (m :: * -> *) a. Monad m => a -> m a
return [Token]
elements
    bracedElement :: ParsecT String UserState (SCBase m) Token
bracedElement =
        Id -> [Token] -> Token
T_NormalWord forall {m :: * -> *} {t} {b} {s}.
Monad m =>
(Id -> t -> b)
-> ParsecT s UserState m t -> ParsecT s UserState m b
`withParser` do
            forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [
                ParsecT String UserState (SCBase m) Token
braceExpansion,
                forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarExpression,
                forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSingleQuoted,
                ParsecT String UserState (SCBase m) Token
readDoubleQuoted,
                forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
braceLiteral
                ]
    braceLiteral :: ParsecT String UserState (SCBase m) Token
braceLiteral =
        Id -> String -> Token
T_Literal forall {m :: * -> *} {t} {b} {s}.
Monad m =>
(Id -> t -> b)
-> ParsecT s UserState m t -> ParsecT s UserState m b
`withParser` forall {m :: * -> *} {a}.
Monad m =>
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) String
readGenericLiteral1 (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"{}\"$'," forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *). Monad m => SCParser m Char
whitespace)

ensureDollar :: ParsecT s u m Char
ensureDollar =
    -- The grammar should have been designed along the lines of readDollarExpr = char '$' >> stuff, but
    -- instead, each subunit parses its own $. This results in ~7 1-3 char lookaheads instead of one 1-char.
    -- Instead of optimizing the grammar, here's a green cut that decreases shellcheck runtime by 10%:
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'$'

readNormalDollar :: ParsecT String UserState (SCBase m) Token
readNormalDollar = do
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
ensureDollar
    ParsecT String UserState (SCBase m) Token
readDollarExp forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readDollarDoubleQuote forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarSingleQuote forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) Token
readDollarLonely Bool
False
readDoubleQuotedDollar :: ParsecT String UserState (SCBase m) Token
readDoubleQuotedDollar = do
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
ensureDollar
    ParsecT String UserState (SCBase m) Token
readDollarExp forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) Token
readDollarLonely Bool
True


prop_readDollarExpression1 :: Bool
prop_readDollarExpression1 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarExpression String
"$(((1) && 3))"
prop_readDollarExpression2 :: Bool
prop_readDollarExpression2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarExpression String
"$(((1)) && 3)"
prop_readDollarExpression3 :: Bool
prop_readDollarExpression3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarExpression String
"$((\"$@\" &); foo;)"
readDollarExpression :: Monad m => SCParser m Token
readDollarExpression :: forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarExpression = do
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
ensureDollar
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarExp

readDollarExp :: ParsecT String UserState (SCBase m) Token
readDollarExp = ParsecT String UserState (SCBase m) Token
arithmetic forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readDollarExpansion forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarBracket forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readDollarBraceCommandExpansion forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readDollarBraced forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarVariable
  where
    arithmetic :: ParsecT String UserState (SCBase m) Token
arithmetic = forall (m :: * -> *) p.
Monad m =>
String
-> SCParser m p
-> SCParser m p
-> (SourcePos -> SCParser m ())
-> SCParser m p
readAmbiguous String
"$((" forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarArithmetic ParsecT String UserState (SCBase m) Token
readDollarExpansion (\SourcePos
pos ->
        forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
pos Severity
ErrorC Integer
1102 String
"Shells disambiguate $(( differently or not at all. For $(command substitution), add space after $( . For $((arithmetics)), fix parsing errors.")

prop_readDollarSingleQuote :: Bool
prop_readDollarSingleQuote = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarSingleQuote String
"$'foo\\\'lol'"
readDollarSingleQuote :: ParsecT String UserState (SCBase m) Token
readDollarSingleQuote = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"$'..' expression" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"$'"
    String
str <- forall {m :: * -> *}.
Monad m =>
String -> ParsecT String UserState (SCBase m) String
readGenericLiteral String
"'"
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\''
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_DollarSingleQuoted Id
id String
str

prop_readDollarDoubleQuote :: Bool
prop_readDollarDoubleQuote = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarDoubleQuote String
"$\"hello\""
readDollarDoubleQuote :: ParsecT String UserState (SCBase m) Token
readDollarDoubleQuote = do
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"$\""
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'$'
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
doubleQuote
    [Token]
x <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String UserState (SCBase m) Token
doubleQuotedPart
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
doubleQuote forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected end of translated double quoted string"
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_DollarDoubleQuoted Id
id [Token]
x

prop_readDollarArithmetic :: Bool
prop_readDollarArithmetic = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarArithmetic String
"$(( 3 * 4 +5))"
prop_readDollarArithmetic2 :: Bool
prop_readDollarArithmetic2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarArithmetic String
"$(((3*4)+(1*2+(3-1))))"
readDollarArithmetic :: ParsecT String UserState (SCBase m) Token
readDollarArithmetic = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"$((..)) expression" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"$((")
    Token
c <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')'
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')' forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected a double )) to end the $((..))"
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return (Id -> Token -> Token
T_DollarArithmetic Id
id Token
c)

readDollarBracket :: ParsecT String UserState (SCBase m) Token
readDollarBracket = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"$[..] expression" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"$[")
    Token
c <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents
    forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"]"
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return (Id -> Token -> Token
T_DollarBracket Id
id Token
c)

prop_readArithmeticExpression :: Bool
prop_readArithmeticExpression = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticExpression String
"((a?b:c))"
readArithmeticExpression :: ParsecT String UserState (SCBase m) Token
readArithmeticExpression = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"((..)) command" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"((")
    Token
c <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents
    forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"))"
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
    forall (m :: * -> *) a. Monad m => a -> m a
return (Id -> Token -> Token
T_Arithmetic Id
id Token
c)

-- If the next characters match prefix, try two different parsers and warn if the alternate parser had to be used
readAmbiguous :: Monad m => String -> SCParser m p -> SCParser m p -> (SourcePos -> SCParser m ()) -> SCParser m p
readAmbiguous :: forall (m :: * -> *) p.
Monad m =>
String
-> SCParser m p
-> SCParser m p
-> (SourcePos -> SCParser m ())
-> SCParser m p
readAmbiguous String
prefix SCParser m p
expected SCParser m p
alternative SourcePos -> SCParser m ()
warner = do
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
prefix
    -- If the expected parser fails, try the alt.
    -- If the alt fails, run the expected one again for the errors.
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try SCParser m p
expected forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (SourcePos -> SCParser m p
withAlt SourcePos
pos) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> SCParser m p
expected
  where
    withAlt :: SourcePos -> SCParser m p
withAlt SourcePos
pos = do
        p
t <- forall {s} {m :: * -> *} {s} {u} {b}.
MonadState s m =>
ParsecT s u m b -> ParsecT s u m b
forgetOnFailure SCParser m p
alternative
        SourcePos -> SCParser m ()
warner SourcePos
pos
        forall (m :: * -> *) a. Monad m => a -> m a
return p
t

prop_readDollarBraceCommandExpansion1 :: Bool
prop_readDollarBraceCommandExpansion1 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarBraceCommandExpansion String
"${ ls; }"
prop_readDollarBraceCommandExpansion2 :: Bool
prop_readDollarBraceCommandExpansion2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarBraceCommandExpansion String
"${\nls\n}"
readDollarBraceCommandExpansion :: ParsecT String UserState (SCBase m) Token
readDollarBraceCommandExpansion = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"ksh ${ ..; } command expansion" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
        forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"${"
        forall (m :: * -> *). Monad m => SCParser m Char
whitespace
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    [Token]
term <- ParsecT String UserState (SCBase m) [Token]
readTerm
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'}' forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected } to end the ksh ${ ..; } command expansion"
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_DollarBraceCommandExpansion Id
id [Token]
term

prop_readDollarBraced1 :: Bool
prop_readDollarBraced1 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarBraced String
"${foo//bar/baz}"
prop_readDollarBraced2 :: Bool
prop_readDollarBraced2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarBraced String
"${foo/'{cow}'}"
prop_readDollarBraced3 :: Bool
prop_readDollarBraced3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarBraced String
"${foo%%$(echo cow\\})}"
prop_readDollarBraced4 :: Bool
prop_readDollarBraced4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarBraced String
"${foo#\\}}"
readDollarBraced :: ParsecT String UserState (SCBase m) Token
readDollarBraced = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"parameter expansion" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"${")
    Token
word <- ParsecT String UserState (SCBase m) Token
readDollarBracedWord
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'}'
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> Bool -> Token -> Token
T_DollarBraced Id
id Bool
True Token
word

prop_readDollarExpansion1 :: Bool
prop_readDollarExpansion1 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarExpansion String
"$(echo foo; ls\n)"
prop_readDollarExpansion2 :: Bool
prop_readDollarExpansion2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarExpansion String
"$(  )"
prop_readDollarExpansion3 :: Bool
prop_readDollarExpansion3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarExpansion String
"$( command \n#comment \n)"
readDollarExpansion :: ParsecT String UserState (SCBase m) Token
readDollarExpansion = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"command expansion" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"$(")
    [Token]
cmds <- ParsecT String UserState (SCBase m) [Token]
readCompoundListOrEmpty
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')' forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected end of $(..) expression"
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_DollarExpansion Id
id [Token]
cmds

prop_readDollarVariable :: Bool
prop_readDollarVariable = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarVariable String
"$@"
prop_readDollarVariable2 :: Bool
prop_readDollarVariable2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk (forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarVariable forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar) String
"$?!"
prop_readDollarVariable3 :: Bool
prop_readDollarVariable3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning (forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarVariable forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar) String
"$10"
prop_readDollarVariable4 :: Bool
prop_readDollarVariable4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning (forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarVariable forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"[@]") String
"$arr[@]"
prop_readDollarVariable5 :: Bool
prop_readDollarVariable5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning (forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarVariable forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"[f") String
"$arr[f"

readDollarVariable :: Monad m => SCParser m Token
readDollarVariable :: forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarVariable = do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition

    let singleCharred :: ParsecT s UserState m Char -> ParsecT s UserState m Token
singleCharred ParsecT s UserState m Char
p = do
        Token
value <- forall {m :: * -> *} {s}.
Monad m =>
ParsecT s UserState m String -> ParsecT s UserState m Token
wrapString ((forall a. a -> [a] -> [a]
:[]) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s UserState m Char
p)
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ (Id -> Bool -> Token -> Token
T_DollarBraced Id
id Bool
False Token
value)

    let positional :: ParsecT s UserState m Token
positional = do
        Token
value <- forall {m :: * -> *} {s}.
Monad m =>
ParsecT s UserState m Char -> ParsecT s UserState m Token
singleCharred forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit
        forall (m :: * -> *) a. Monad m => a -> m a
return Token
value forall {s} {u} {m :: * -> *} {a} {a}.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`attempting` do
            forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit
            forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
pos Severity
ErrorC Integer
1037 String
"Braces are required for positionals over 9, e.g. ${10}."

    let special :: ParsecT s UserState m Token
special = forall {m :: * -> *} {s}.
Monad m =>
ParsecT s UserState m Char -> ParsecT s UserState m Token
singleCharred forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
specialVariable

    let regular :: ParsecT s UserState m Token
regular = do
        Token
value <- forall {m :: * -> *} {s}.
Monad m =>
ParsecT s UserState m String -> ParsecT s UserState m Token
wrapString forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readVariableName
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall (m :: * -> *) a. Monad m => a -> m a
return (Id -> Bool -> Token -> Token
T_DollarBraced Id
id Bool
False Token
value) forall {s} {u} {m :: * -> *} {a} {a}.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`attempting` do
            forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'['
            forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
pos Severity
ErrorC Integer
1087 String
"Use braces when expanding arrays, e.g. ${array[idx]} (or ${var}[.. to quiet)."

    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'$' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
positional forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *} {s}.
Stream s m Char =>
ParsecT s UserState m Token
special forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
regular)

  where
    wrapString :: ParsecT s UserState m String -> ParsecT s UserState m Token
wrapString ParsecT s UserState m String
p = do
        SourcePos
start <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        String
s <- ParsecT s UserState m String
p
        SourcePos
end <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        Id
id1 <- forall {m :: * -> *} {s}.
Monad m =>
SourcePos -> SourcePos -> ParsecT s UserState m Id
getNextIdBetween SourcePos
start SourcePos
end
        Id
id2 <- forall {m :: * -> *} {s}.
Monad m =>
SourcePos -> SourcePos -> ParsecT s UserState m Id
getNextIdBetween SourcePos
start SourcePos
end
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_NormalWord Id
id1 [Id -> String -> Token
T_Literal Id
id2 String
s]

readVariableName :: ParsecT s u m String
readVariableName = do
    Char
f <- forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
variableStart
    String
rest <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
variableChars
    forall (m :: * -> *) a. Monad m => a -> m a
return (Char
fforall a. a -> [a] -> [a]
:String
rest)


prop_readDollarLonely1 :: Bool
prop_readDollarLonely1 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"\"$\"var"
prop_readDollarLonely2 :: Bool
prop_readDollarLonely2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"\"$\"\"var\""
prop_readDollarLonely3 :: Bool
prop_readDollarLonely3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"\"$\"$var"
prop_readDollarLonely4 :: Bool
prop_readDollarLonely4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"\"$\"*"
prop_readDollarLonely5 :: Bool
prop_readDollarLonely5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"$\"str\""
readDollarLonely :: Bool -> ParsecT String UserState (SCBase m) Token
readDollarLonely Bool
quoted = do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'$'
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
quoted forall a b. (a -> b) -> a -> b
$ do
        Bool
isHack <- forall {s} {m :: * -> *} {u}. Stream s m Char => ParsecT s u m Bool
quoteForEscape
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
isHack forall a b. (a -> b) -> a -> b
$
            forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId Id
id Severity
StyleC Integer
1135
                String
"Prefer escape over ending quote to make $ literal. Instead of \"It costs $\"5, use \"It costs \\$5\"."
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
"$"
  where
    quoteForEscape :: ParsecT s u m Bool
quoteForEscape = forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option Bool
False forall a b. (a -> b) -> a -> b
$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ do
        forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'"'
        -- Check for "foo $""bar"
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'"'
        Char
c <- forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyVar
        -- Don't trigger on [[ x == "$"* ]] or "$"$pattern
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Char
c forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` String
"*$"
    anyVar :: ParsecT s u m Char
anyVar = forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
variableStart forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
specialVariable


prop_readHereDoc :: Bool
prop_readHereDoc = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat << foo\nlol\ncow\nfoo"
prop_readHereDoc2 :: Bool
prop_readHereDoc2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isNotOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat <<- EOF\n  cow\n  EOF"
prop_readHereDoc3 :: Bool
prop_readHereDoc3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat << foo\n$\"\nfoo"
prop_readHereDoc4 :: Bool
prop_readHereDoc4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isNotOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat << foo\n`\nfoo"
prop_readHereDoc5 :: Bool
prop_readHereDoc5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat <<- !foo\nbar\n!foo"
prop_readHereDoc6 :: Bool
prop_readHereDoc6 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat << foo\\ bar\ncow\nfoo bar"
prop_readHereDoc7 :: Bool
prop_readHereDoc7 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat << foo\n\\$(f ())\nfoo"
prop_readHereDoc8 :: Bool
prop_readHereDoc8 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat <<foo>>bar\netc\nfoo"
prop_readHereDoc9 :: Bool
prop_readHereDoc9 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"if true; then cat << foo; fi\nbar\nfoo\n"
prop_readHereDoc10 :: Bool
prop_readHereDoc10 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"if true; then cat << foo << bar; fi\nfoo\nbar\n"
prop_readHereDoc11 :: Bool
prop_readHereDoc11 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat << foo $(\nfoo\n)lol\nfoo\n"
prop_readHereDoc12 :: Bool
prop_readHereDoc12 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat << foo|cat\nbar\nfoo"
prop_readHereDoc13 :: Bool
prop_readHereDoc13 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat <<'#!'\nHello World\n#!\necho Done"
prop_readHereDoc14 :: Bool
prop_readHereDoc14 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat << foo\nbar\nfoo \n"
prop_readHereDoc15 :: Bool
prop_readHereDoc15 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat <<foo\nbar\nfoo bar\nfoo"
prop_readHereDoc16 :: Bool
prop_readHereDoc16 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat <<- ' foo'\nbar\n foo\n"
prop_readHereDoc17 :: Bool
prop_readHereDoc17 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat <<- ' foo'\nbar\n  foo\n foo\n"
prop_readHereDoc18 :: Bool
prop_readHereDoc18 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat <<'\"foo'\nbar\n\"foo\n"
prop_readHereDoc20 :: Bool
prop_readHereDoc20 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat << foo\n  foo\n()\nfoo\n"
prop_readHereDoc21 :: Bool
prop_readHereDoc21 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"# shellcheck disable=SC1039\ncat << foo\n  foo\n()\nfoo\n"
prop_readHereDoc22 :: Bool
prop_readHereDoc22 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat << foo\r\ncow\r\nfoo\r\n"
prop_readHereDoc23 :: Bool
prop_readHereDoc23 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isNotOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat << foo \r\ncow\r\nfoo\r\n"
readHereDoc :: ParsecT String UserState (SCBase m) Token
readHereDoc = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"here document" forall a b. (a -> b) -> a -> b
$ do
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"<<"
    Dashed
dashed <- (forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'-' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Dashed
Dashed) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return Dashed
Undashed
    String
sp <- forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ do
        forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'('
        let message :: String
message = String
"Shells are space sensitive. Use '< <(cmd)', not '<<" forall a. [a] -> [a] -> [a]
++ String
sp forall a. [a] -> [a] -> [a]
++ String
"(cmd)'."
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1038 String
message
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    (Quoted
quoted, String
endToken) <- ParsecT String UserState (SCBase m) (Quoted, String)
readToken
    Id
hid <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start

    -- add empty tokens for now, read the rest in readPendingHereDocs
    let doc :: Token
doc = Id -> Dashed -> Quoted -> String -> [Token] -> Token
T_HereDoc Id
hid Dashed
dashed Quoted
quoted String
endToken []
    forall {m :: * -> *} {s}.
MonadState SystemState m =>
Token -> ParsecT s UserState m ()
addPendingHereDoc Token
doc
    forall (m :: * -> *) a. Monad m => a -> m a
return Token
doc
  where
    unquote :: String -> (Quoted, String)
    unquote :: String -> (Quoted, String)
unquote String
"" = (Quoted
Unquoted, String
"")
    unquote [Char
c] = (Quoted
Unquoted, [Char
c])
    unquote s :: String
s@(Char
cl:String
tl) =
      case forall a. [a] -> [a]
reverse String
tl of
        (Char
cr:String
tr) | Char
cr forall a. Eq a => a -> a -> Bool
== Char
cl Bool -> Bool -> Bool
&& Char
cl forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
"\"'" -> (Quoted
Quoted, forall a. [a] -> [a]
reverse String
tr)
        String
_ -> (if Char
'\\' forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
s then (Quoted
Quoted, forall a. (a -> Bool) -> [a] -> [a]
filter (forall a. Eq a => a -> a -> Bool
(/=) Char
'\\') String
s) else (Quoted
Unquoted, String
s))
    -- Fun fact: bash considers << foo"" quoted, but not << <("foo").
    readToken :: ParsecT String UserState (SCBase m) (Quoted, String)
readToken = do
        String
str <- forall {s} {m :: * -> *} {s} {u} {a}.
(Stream s m Char, MonadState s m) =>
ParsecT s u m a -> ParsecT s u m String
readStringForParser ParsecT String UserState (SCBase m) Token
readNormalWord
        -- A here doc actually works with \r\n because the \r becomes part of the token
        String
crstr <- (forall {m :: * -> *} {s} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m Char
carriageReturn forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ String
str forall a. [a] -> [a] -> [a]
++ String
"\r")) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return String
str
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ String -> (Quoted, String)
unquote String
crstr

readPendingHereDocs :: ParsecT String UserState (SCBase m) ()
readPendingHereDocs = do
    [HereDocContext]
docs <- forall {m :: * -> *} {s}.
Monad m =>
ParsecT s UserState m [HereDocContext]
popPendingHereDocs
    forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall {m :: * -> *}.
Monad m =>
HereDocContext -> ParsecT String UserState (SCBase m) ()
readDoc [HereDocContext]
docs
  where
    readDoc :: HereDocContext -> ParsecT String UserState (SCBase m) ()
readDoc (HereDocPending (T_HereDoc Id
id Dashed
dashed Quoted
quoted String
endToken [Token]
_) [Context]
ctx) =
      forall {s} {m :: * -> *} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
[Context] -> ParsecT s u m b -> ParsecT s u m b
swapContext [Context]
ctx forall a b. (a -> b) -> a -> b
$
      do
        SourcePos
docStartPos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        (Bool
terminated, Bool
wasWarned, [String]
lines) <- forall (m :: * -> *).
Monad m =>
Dashed -> String -> SCParser m (Bool, Bool, [String])
readDocLines Dashed
dashed String
endToken
        SourcePos
docEndPos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        let hereData :: String
hereData = [String] -> String
unlines [String]
lines
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
terminated forall a b. (a -> b) -> a -> b
$ do
            forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
wasWarned forall a b. (a -> b) -> a -> b
$
                forall {m :: * -> *}.
Monad m =>
Id -> String -> String -> ParsecT String UserState (SCBase m) ()
debugHereDoc Id
id String
endToken String
hereData
            forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Here document was not correctly terminated"
        [Token]
list <- forall {m :: * -> *}.
Monad m =>
Quoted
-> (SourcePos, SourcePos)
-> String
-> ParsecT String UserState (SCBase m) [Token]
parseHereData Quoted
quoted (SourcePos
docStartPos, SourcePos
docEndPos) String
hereData
        forall {m :: * -> *} {s}.
Monad m =>
Id -> [Token] -> ParsecT s UserState m ()
addToHereDocMap Id
id [Token]
list

    -- Read the lines making up the here doc. Returns (IsTerminated, Lines)
    readDocLines :: Monad m => Dashed -> String -> SCParser m (Bool, Bool, [String])
    readDocLines :: forall (m :: * -> *).
Monad m =>
Dashed -> String -> SCParser m (Bool, Bool, [String])
readDocLines Dashed
dashed String
endToken = do
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        String
str <- forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
rawLine
        Bool
isEof <- forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option Bool
False (forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True)
        (Bool
isEnd, Bool
wasWarned) <- forall {m :: * -> *} {a} {u} {b}.
Monad m =>
SourcePos -> ParsecT a u m b -> a -> ParsecT a u m b
subParse SourcePos
pos forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, Stream s m Char,
 MonadState SystemState m) =>
ParsecT s UserState m (Bool, Bool)
checkEnd String
str
        if
            | Bool
isEnd -> forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
True, Bool
wasWarned, [])
            | Bool
isEof -> forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
False, Bool
wasWarned, [String
str])
            | Bool
True -> do
                (Bool
ok, Bool
previousWarning, [String]
rest) <- forall (m :: * -> *).
Monad m =>
Dashed -> String -> SCParser m (Bool, Bool, [String])
readDocLines Dashed
dashed String
endToken
                forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
ok, Bool
wasWarned Bool -> Bool -> Bool
|| Bool
previousWarning, String
strforall a. a -> [a] -> [a]
:[String]
rest)
      where
        -- Check if this is the actual end, or a plausible false end
        checkEnd :: ParsecT s UserState m (Bool, Bool)
checkEnd = forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option (Bool
False, Bool
False) forall a b. (a -> b) -> a -> b
$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
            -- Match what's basically '^( *)token( *)(.*)$'
            SourcePos
leadingSpacePos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
            String
leadingSpace <- forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Char
linewhitespace forall {s} {m :: * -> *} {t} {u} {a} {a}.
(Stream s m t, Show t) =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m [a]
`reluctantlyTill` forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
endToken
            forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
endToken
            SourcePos
trailingSpacePos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
            String
trailingSpace <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Char
linewhitespace
            SourcePos
trailerPos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
            String
trailer <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar

            let leadingSpacesAreTabs :: Bool
leadingSpacesAreTabs = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (forall a. Eq a => a -> a -> Bool
== Char
'\t') String
leadingSpace
            let thereIsNoTrailer :: Bool
thereIsNoTrailer = forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
trailingSpace Bool -> Bool -> Bool
&& forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
trailer
            let leaderIsOk :: Bool
leaderIsOk = forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
leadingSpace
                    Bool -> Bool -> Bool
|| Dashed
dashed forall a. Eq a => a -> a -> Bool
== Dashed
Dashed Bool -> Bool -> Bool
&& Bool
leadingSpacesAreTabs
            let trailerStart :: Char
trailerStart = case String
trailer of [] -> Char
'\0'; (Char
h:String
_) -> Char
h
            let hasTrailingSpace :: Bool
hasTrailingSpace = Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
trailingSpace
            let hasTrailer :: Bool
hasTrailer = Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
trailer
            let ppt :: Integer -> String -> m ()
ppt = forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
trailerPos Severity
ErrorC

            if Bool
leaderIsOk Bool -> Bool -> Bool
&& Bool
thereIsNoTrailer
              then forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
True, Bool
False)
              else do
                let foundCause :: m (Bool, Bool)
foundCause = forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
False, Bool
True)
                let skipLine :: m (Bool, Bool)
skipLine = forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
False, Bool
False)
                -- This may be intended as an end token. Debug why it isn't.
                if
                    | Char
trailerStart forall a. Eq a => a -> a -> Bool
== Char
')' -> do
                        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Integer -> String -> m ()
ppt Integer
1119 forall a b. (a -> b) -> a -> b
$ String
"Add a linefeed between end token and terminating ')'."
                        forall {m :: * -> *}. Monad m => m (Bool, Bool)
foundCause
                    | Char
trailerStart forall a. Eq a => a -> a -> Bool
== Char
'#' -> do
                        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Integer -> String -> m ()
ppt Integer
1120 String
"No comments allowed after here-doc token. Comment the next line instead."
                        forall {m :: * -> *}. Monad m => m (Bool, Bool)
foundCause
                    | Char
trailerStart forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
";>|&" -> do
                        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Integer -> String -> m ()
ppt Integer
1121 String
"Add ;/& terminators (and other syntax) on the line with the <<, not here."
                        forall {m :: * -> *}. Monad m => m (Bool, Bool)
foundCause
                    | Bool
hasTrailingSpace Bool -> Bool -> Bool
&& Bool
hasTrailer -> do
                        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Integer -> String -> m ()
ppt Integer
1122 String
"Nothing allowed after end token. To continue a command, put it on the line with the <<."
                        forall {m :: * -> *}. Monad m => m (Bool, Bool)
foundCause
                    | Bool
leaderIsOk Bool -> Bool -> Bool
&& Bool
hasTrailingSpace Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
hasTrailer -> do
                        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
trailingSpacePos Severity
ErrorC Integer
1118 String
"Delete whitespace after the here-doc end token."
                        -- Parse as if it's the actual end token. Will koala_man regret this once again?
                        forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
True, Bool
True)
                    | Bool -> Bool
not Bool
hasTrailingSpace Bool -> Bool -> Bool
&& Bool
hasTrailer ->
                        -- The end token is just a prefix
                        forall {m :: * -> *}. Monad m => m (Bool, Bool)
skipLine
                    | Bool
hasTrailer ->
                        forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ ShowS
pleaseReport String
"unexpected heredoc trailer"

                    -- The following cases assume no trailing text:
                    | Dashed
dashed forall a. Eq a => a -> a -> Bool
== Dashed
Undashed Bool -> Bool -> Bool
&& (Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
leadingSpace) -> do
                        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
leadingSpacePos Severity
ErrorC Integer
1039 String
"Remove indentation before end token (or use <<- and indent with tabs)."
                        forall {m :: * -> *}. Monad m => m (Bool, Bool)
foundCause
                    | Dashed
dashed forall a. Eq a => a -> a -> Bool
== Dashed
Dashed Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
leadingSpacesAreTabs -> do
                        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
leadingSpacePos Severity
ErrorC Integer
1040 String
"When using <<-, you can only indent with tabs."
                        forall {m :: * -> *}. Monad m => m (Bool, Bool)
foundCause
                    | Bool
True -> forall {m :: * -> *}. Monad m => m (Bool, Bool)
skipLine

    rawLine :: ParsecT s u m String
rawLine = do
        String
c <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
"\n"
        forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\n') forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof
        forall (m :: * -> *) a. Monad m => a -> m a
return String
c

    parseHereData :: Quoted
-> (SourcePos, SourcePos)
-> String
-> ParsecT String UserState (SCBase m) [Token]
parseHereData Quoted
Quoted (SourcePos
start,SourcePos
end) String
hereData = do
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
SourcePos -> SourcePos -> ParsecT s UserState m Id
getNextIdBetween SourcePos
start SourcePos
end
        forall (m :: * -> *) a. Monad m => a -> m a
return [Id -> String -> Token
T_Literal Id
id String
hereData]

    parseHereData Quoted
Unquoted (SourcePos
startPos, SourcePos
_) String
hereData =
        forall {m :: * -> *} {a} {u} {b}.
Monad m =>
SourcePos -> ParsecT a u m b -> a -> ParsecT a u m b
subParse SourcePos
startPos forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Token]
readHereData String
hereData

    readHereData :: ParsecT String UserState (SCBase m) [Token]
readHereData = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall a b. (a -> b) -> a -> b
$ forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
doubleQuotedPart forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s} {m :: * -> *}.
Stream s m Char =>
ParsecT s UserState m Token
readHereLiteral

    readHereLiteral :: ParsecT s UserState m Token
readHereLiteral = do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        String
chars <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
"`$\\"
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
chars

    debugHereDoc :: Id -> String -> String -> ParsecT String UserState (SCBase m) ()
debugHereDoc Id
tokenId String
endToken String
doc
        | String
endToken forall a. Eq a => [a] -> [a] -> Bool
`isInfixOf` String
doc =
            let lookAt :: String -> ParsecT String UserState (SCBase m) ()
lookAt String
line = forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String
endToken forall a. Eq a => [a] -> [a] -> Bool
`isInfixOf` String
line) forall a b. (a -> b) -> a -> b
$
                      forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId Id
tokenId Severity
ErrorC Integer
1042 (String
"Close matches include '" forall a. [a] -> [a] -> [a]
++ (ShowS
e4m String
line) forall a. [a] -> [a] -> [a]
++ String
"' (!= '" forall a. [a] -> [a] -> [a]
++ (ShowS
e4m String
endToken) forall a. [a] -> [a] -> [a]
++ String
"').")
            in do
                  forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId Id
tokenId Severity
ErrorC Integer
1041 (String
"Found '" forall a. [a] -> [a] -> [a]
++ (ShowS
e4m String
endToken) forall a. [a] -> [a] -> [a]
++ String
"' further down, but not on a separate line.")
                  forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall {m :: * -> *}.
Monad m =>
String -> ParsecT String UserState (SCBase m) ()
lookAt (String -> [String]
lines String
doc)
        | forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
endToken forall a. Eq a => [a] -> [a] -> Bool
`isInfixOf` forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
doc =
            forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId Id
tokenId Severity
ErrorC Integer
1043 (String
"Found " forall a. [a] -> [a] -> [a]
++ (ShowS
e4m String
endToken) forall a. [a] -> [a] -> [a]
++ String
" further down, but with wrong casing.")
        | Bool
otherwise =
            forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId Id
tokenId Severity
ErrorC Integer
1044 (String
"Couldn't find end token `" forall a. [a] -> [a] -> [a]
++ (ShowS
e4m String
endToken) forall a. [a] -> [a] -> [a]
++ String
"' in the here document.")


readFilename :: ParsecT String UserState (SCBase m) Token
readFilename = ParsecT String UserState (SCBase m) Token
readNormalWord
readIoFileOp :: ParsecT s UserState m Token
readIoFileOp = forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_DGREAT, forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_LESSGREAT, forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_GREATAND, forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_LESSAND, forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_CLOBBER, forall {m :: * -> *} {s} {a}.
Stream s m Char =>
Char -> (Id -> a) -> ParsecT s UserState m a
redirToken Char
'<' Id -> Token
T_Less, forall {m :: * -> *} {s} {a}.
Stream s m Char =>
Char -> (Id -> a) -> ParsecT s UserState m a
redirToken Char
'>' Id -> Token
T_Greater ]

readIoDuplicate :: ParsecT s UserState m Token
readIoDuplicate = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    Token
op <- forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_GREATAND forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_LESSAND
    String
target <- forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readIoVariable forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
digitsAndOrDash
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> Token -> String -> Token
T_IoDuplicate Id
id Token
op String
target
  where
    -- either digits with optional dash, or a required dash
    digitsAndOrDash :: ParsecT s u m String
digitsAndOrDash = do
        String
str <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit
        String
dash <- (if forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
str then forall a. a -> a
id else forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option String
"") forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"-"
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ String
str forall a. [a] -> [a] -> [a]
++ String
dash


prop_readIoFile :: Bool
prop_readIoFile = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIoFile String
">> \"$(date +%YYmmDD)\""
readIoFile :: ParsecT String UserState (SCBase m) Token
readIoFile = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"redirection" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    Token
op <- forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, Stream s m Char,
 MonadState SystemState m) =>
ParsecT s UserState m Token
readIoFileOp
    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
    Token
file <- ParsecT String UserState (SCBase m) Token
readFilename
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> Token -> Token -> Token
T_IoFile Id
id Token
op Token
file

readIoVariable :: ParsecT s u m String
readIoVariable = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'{'
    String
x <- forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readVariableName
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'}'
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ String
"{" forall a. [a] -> [a] -> [a]
++ String
x forall a. [a] -> [a] -> [a]
++ String
"}"

readIoSource :: ParsecT s UserState m String
readIoSource = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
    String
x <- forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"&" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readIoVariable forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Functor f => f a -> f ()
void forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, Stream s m Char,
 MonadState SystemState m) =>
ParsecT s UserState m Token
readIoFileOp forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"<<")
    forall (m :: * -> *) a. Monad m => a -> m a
return String
x

prop_readIoRedirect :: Bool
prop_readIoRedirect = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIoRedirect String
"3>&2"
prop_readIoRedirect2 :: Bool
prop_readIoRedirect2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIoRedirect String
"2> lol"
prop_readIoRedirect3 :: Bool
prop_readIoRedirect3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIoRedirect String
"4>&-"
prop_readIoRedirect4 :: Bool
prop_readIoRedirect4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIoRedirect String
"&> lol"
prop_readIoRedirect5 :: Bool
prop_readIoRedirect5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIoRedirect String
"{foo}>&2"
prop_readIoRedirect6 :: Bool
prop_readIoRedirect6 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIoRedirect String
"{foo}<&-"
prop_readIoRedirect7 :: Bool
prop_readIoRedirect7 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIoRedirect String
"{foo}>&1-"
readIoRedirect :: ParsecT String UserState (SCBase m) Token
readIoRedirect = do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    String
n <- forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m String
readIoSource
    Token
redir <- ParsecT String UserState (SCBase m) Token
readHereString forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readHereDoc forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m Token
readIoDuplicate forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readIoFile
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m ()
skipAnnotationAndWarn
    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token -> Token
T_FdRedirect Id
id String
n Token
redir

prop_readHereString :: Bool
prop_readHereString = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readHereString String
"<<< \"Hello $world\""
readHereString :: ParsecT String UserState (SCBase m) Token
readHereString = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"here string" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"<<<"
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
    Token
word <- ParsecT String UserState (SCBase m) Token
readNormalWord
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> Token -> Token
T_HereString Id
id Token
word

prop_readNewlineList1 :: Bool
prop_readNewlineList1 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"&> /dev/null echo foo"
readNewlineList :: ParsecT String UserState (SCBase m) String
readNewlineList =
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 ((forall (m :: * -> *). Monad m => SCParser m Char
linefeed forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *} {s} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m Char
carriageReturn) forall {s} {m :: * -> *} {t} {u} {a} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`thenSkip` forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall {s} {m :: * -> *} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m ()
checkBadBreak
  where
    checkBadBreak :: ParsecT s u m ()
checkBadBreak = forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ do
                SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"|&") --  See if the next thing could be |, || or &&
                forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"&>") --  Except &> or &>> which is valid
                forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1133
                    String
"Unexpected start of line. If breaking lines, |/||/&& should be at the end of the previous one."
readLineBreak :: ParsecT String UserState (SCBase m) ()
readLineBreak = forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readNewlineList

prop_readSeparator1 :: Bool
prop_readSeparator1 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"a &; b"
prop_readSeparator2 :: Bool
prop_readSeparator2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"a & b"
prop_readSeparator3 :: Bool
prop_readSeparator3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"a &amp; b"
prop_readSeparator4 :: Bool
prop_readSeparator4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"a &gt; file; b"
prop_readSeparator5 :: Bool
prop_readSeparator5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"curl https://example.com/?foo=moo&bar=cow"
readSeparatorOp :: ParsecT String UserState (SCBase m) (Char, (SourcePos, SourcePos))
readSeparatorOp = do
    forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 (forall (f :: * -> *) a. Functor f => f a -> f ()
void forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_AND_IF forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (f :: * -> *) a. Functor f => f a -> f ()
void forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) CaseType
readCaseSeparator)
    forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"&>")
    SourcePos
start <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    Char
f <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (do
                    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'&'
                    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [
                        do
                            String
s <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string) forall a b. (a -> b) -> a -> b
$
                                [String
"amp;", String
"gt;", String
"lt;"]
                            forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1109 String
"This is an unquoted HTML entity. Replace with corresponding character.",

                        do
                            forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
variableStart
                            forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
WarningC Integer
1132 String
"This & terminates the command. Escape it or add space after & to silence."
                      ]

                    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
                    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
';'
                    -- In case statements we might have foo & ;;
                    forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
';'
                    forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1045 String
"It's not 'foo &; bar', just 'foo & bar'."
                    forall (m :: * -> *) a. Monad m => a -> m a
return Char
'&'
            ) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
';' forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'&'
    SourcePos
end <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
    forall (m :: * -> *) a. Monad m => a -> m a
return (Char
f, (SourcePos
start, SourcePos
end))

readSequentialSep :: ParsecT String UserState (SCBase m) ()
readSequentialSep = forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m Token
g_Semi forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readLineBreak) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (f :: * -> *) a. Functor f => f a -> f ()
void forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readNewlineList
readSeparator :: ParsecT String UserState (SCBase m) (Char, (SourcePos, SourcePos))
readSeparator =
    do
        (Char, (SourcePos, SourcePos))
separator <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) (Char, (SourcePos, SourcePos))
readSeparatorOp
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readLineBreak
        forall (m :: * -> *) a. Monad m => a -> m a
return (Char, (SourcePos, SourcePos))
separator
     forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
        do
            SourcePos
start <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
            forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readNewlineList
            SourcePos
end <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
            forall (m :: * -> *) a. Monad m => a -> m a
return (Char
'\n', (SourcePos
start, SourcePos
end))

prop_readSimpleCommand :: Bool
prop_readSimpleCommand = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"echo test > file"
prop_readSimpleCommand2 :: Bool
prop_readSimpleCommand2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"cmd &> file"
prop_readSimpleCommand3 :: Bool
prop_readSimpleCommand3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"export foo=(bar baz)"
prop_readSimpleCommand4 :: Bool
prop_readSimpleCommand4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"typeset -a foo=(lol)"
prop_readSimpleCommand5 :: Bool
prop_readSimpleCommand5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"time if true; then echo foo; fi"
prop_readSimpleCommand6 :: Bool
prop_readSimpleCommand6 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"time -p ( ls -l; )"
prop_readSimpleCommand7 :: Bool
prop_readSimpleCommand7 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"\\ls"
prop_readSimpleCommand7b :: Bool
prop_readSimpleCommand7b = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"\\:"
prop_readSimpleCommand8 :: Bool
prop_readSimpleCommand8 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"// Lol"
prop_readSimpleCommand9 :: Bool
prop_readSimpleCommand9 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"/* Lolbert */"
prop_readSimpleCommand10 :: Bool
prop_readSimpleCommand10 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"/**** Lolbert */"
prop_readSimpleCommand11 :: Bool
prop_readSimpleCommand11 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"/\\* foo"
prop_readSimpleCommand12 :: Bool
prop_readSimpleCommand12 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"elsif foo"
prop_readSimpleCommand13 :: Bool
prop_readSimpleCommand13 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"ElseIf foo"
prop_readSimpleCommand14 :: Bool
prop_readSimpleCommand14 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"elseif[$i==2]"
prop_readSimpleCommand15 :: Bool
prop_readSimpleCommand15 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"trap 'foo\"bar' INT"
readSimpleCommand :: ParsecT String UserState (SCBase m) Token
readSimpleCommand = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"simple command" forall a b. (a -> b) -> a -> b
$ do
    [Token]
prefix <- forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option [] ParsecT String UserState (SCBase m) [Token]
readCmdPrefix
    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m ()
skipAnnotationAndWarn
    Maybe Token
cmd <- forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option forall a. Maybe a
Nothing forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String UserState (SCBase m) Token
readCmdName
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Token]
prefix Bool -> Bool -> Bool
&& forall a. Maybe a -> Bool
isNothing Maybe Token
cmd) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected a command"

    case Maybe Token
cmd of
      Maybe Token
Nothing -> do
        Id
id1 <- forall {m :: * -> *}.
Monad m =>
[Token] -> ParsecT String UserState (SCBase m) Id
getNextIdSpanningTokenList [Token]
prefix
        Id
id2 <- forall (m :: * -> *). Monad m => Id -> SCParser m Id
getNewIdFor Id
id1
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> Id -> [Token] -> [Token] -> [Token] -> Token
makeSimpleCommand Id
id1 Id
id2 [Token]
prefix [] []

      Just Token
cmd -> do
            forall {m :: * -> *}.
Monad m =>
Token -> ParsecT String UserState (SCBase m) ()
validateCommand Token
cmd
            -- We have to ignore possible parsing problems from the lookAhead parser
            Maybe Token
firstArgument <- forall {t :: (* -> *) -> * -> *} {t :: (* -> *) -> * -> *}
       {m :: * -> *} {a} {b}.
(MonadTrans t, MonadTrans t, Monad (t (t m)), Monad (t m),
 MonadState a m) =>
t (t m) b -> t (t m) b
ignoreProblemsOf forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
optionMaybe forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) Token
readCmdWord
            [Token]
suffix <- forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option [] forall a b. (a -> b) -> a -> b
$ forall {t :: * -> *} {t}.
Foldable t =>
t -> Token -> [(t String, t)] -> t
getParser ParsecT String UserState (SCBase m) [Token]
readCmdSuffix
                    -- If `export` or other modifier commands are called with `builtin` we have to look at the first argument
                    (if forall {t :: * -> *}. Foldable t => t String -> Token -> Bool
isCommand [String
"builtin"] Token
cmd then forall a. a -> Maybe a -> a
fromMaybe Token
cmd Maybe Token
firstArgument else Token
cmd) [
                        ([String
"declare", String
"export", String
"local", String
"readonly", String
"typeset"], ParsecT String UserState (SCBase m) [Token]
readModifierSuffix),
                        ([String
"time"], ParsecT String UserState (SCBase m) [Token]
readTimeSuffix),
                        ([String
"let"], forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Token]
readLetSuffix),
                        ([String
"eval"], ParsecT String UserState (SCBase m) [Token]
readEvalSuffix)
                    ]

            Id
id1 <- forall {m :: * -> *}.
Monad m =>
[Token] -> ParsecT String UserState (SCBase m) Id
getNextIdSpanningTokenList ([Token]
prefix forall a. [a] -> [a] -> [a]
++ (Token
cmdforall a. a -> [a] -> [a]
:[Token]
suffix))
            Id
id2 <- forall (m :: * -> *). Monad m => Id -> SCParser m Id
getNewIdFor Id
id1

            let result :: Token
result = Id -> Id -> [Token] -> [Token] -> [Token] -> Token
makeSimpleCommand Id
id1 Id
id2 [Token]
prefix [Token
cmd] [Token]
suffix
            case () of
                ()
_ | forall {t :: * -> *}. Foldable t => t String -> Token -> Bool
isCommand [String
"source", String
"."] Token
cmd -> forall (m :: * -> *). Monad m => Token -> SCParser m Token
readSource Token
result
                ()
_ | forall {t :: * -> *}. Foldable t => t String -> Token -> Bool
isCommand [String
"trap"] Token
cmd -> do
                        Token -> ParsecT String UserState (SCBase m) ()
syntaxCheckTrap Token
result
                        forall (m :: * -> *) a. Monad m => a -> m a
return Token
result
                ()
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return Token
result
  where
    isCommand :: t String -> Token -> Bool
isCommand t String
strings (T_NormalWord Id
_ [T_Literal Id
_ String
s]) = String
s forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` t String
strings
    isCommand t String
_ Token
_ = Bool
False
    getParser :: t -> Token -> [(t String, t)] -> t
getParser t
def Token
cmd [] = t
def
    getParser t
def Token
cmd ((t String
list, t
action):[(t String, t)]
rest) =
        if forall {t :: * -> *}. Foldable t => t String -> Token -> Bool
isCommand t String
list Token
cmd
        then t
action
        else t -> Token -> [(t String, t)] -> t
getParser t
def Token
cmd [(t String, t)]
rest

    validateCommand :: Token -> SCParser m ()
validateCommand Token
cmd =
        case Token
cmd of
            (T_NormalWord Id
_ [T_Literal Id
_ String
"//"]) -> forall {m :: * -> *}. Monad m => Id -> SCParser m ()
commentWarning (Token -> Id
getId Token
cmd)
            (T_NormalWord Id
_ (T_Literal Id
_ String
"/" : T_Glob Id
_ String
"*" :[Token]
_)) -> forall {m :: * -> *}. Monad m => Id -> SCParser m ()
commentWarning (Token -> Id
getId Token
cmd)
            (T_NormalWord Id
_ (T_Literal Id
_ String
str:[Token]
_)) -> do
                let cmdString :: String
cmdString = forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> [a]
takeWhile Char -> Bool
isAlpha String
str
                forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String
cmdString forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String
"elsif", String
"elseif"]) forall a b. (a -> b) -> a -> b
$
                    forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId (Token -> Id
getId Token
cmd) Severity
ErrorC Integer
1131 String
"Use 'elif' to start another branch."
            Token
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return ()

    syntaxCheckTrap :: Token -> ParsecT String UserState (SCBase m) ()
syntaxCheckTrap Token
cmd =
        case Token
cmd of
            (T_Redirecting Id
_ [Token]
_ (T_SimpleCommand Id
_ [Token]
_ (Token
cmd:Token
arg:[Token]
_))) -> Token -> Maybe String -> ParsecT String UserState (SCBase m) ()
checkArg Token
arg (Token -> Maybe String
getLiteralString Token
arg)
            Token
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
      where
        checkArg :: Token -> Maybe String -> ParsecT String UserState (SCBase m) ()
checkArg Token
_ Maybe String
Nothing = forall (m :: * -> *) a. Monad m => a -> m a
return ()
        checkArg Token
arg (Just (Char
'-':String
_)) = forall (m :: * -> *) a. Monad m => a -> m a
return ()
        checkArg Token
arg (Just String
str) = do
            (SourcePos
start,SourcePos
end) <- forall (m :: * -> *).
Monad m =>
Id -> SCParser m (SourcePos, SourcePos)
getSpanForId (Token -> Id
getId Token
arg)
            forall {m :: * -> *} {a} {u} {b}.
Monad m =>
SourcePos -> ParsecT a u m b -> a -> ParsecT a u m b
subParse SourcePos
start (forall (m :: * -> *) v. Monad m => SCParser m v -> SCParser m v
tryWithErrors (ParsecT String UserState (SCBase m) [Token]
readCompoundListOrEmpty forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
verifyEof) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return ()) String
str

    commentWarning :: Id -> SCParser m ()
commentWarning Id
id =
        forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId Id
id Severity
ErrorC Integer
1127 String
"Was this intended as a comment? Use # in sh."

    makeSimpleCommand :: Id -> Id -> [Token] -> [Token] -> [Token] -> Token
makeSimpleCommand Id
id1 Id
id2 [Token]
prefix [Token]
cmd [Token]
suffix =
        let
            ([Token]
preAssigned, [Token]
preRest) = forall a. (a -> Bool) -> [a] -> ([a], [a])
partition Token -> Bool
assignment [Token]
prefix
            ([Token]
preRedirected, [Token]
preRest2) = forall a. (a -> Bool) -> [a] -> ([a], [a])
partition Token -> Bool
redirection [Token]
preRest
            ([Token]
postRedirected, [Token]
postRest) = forall a. (a -> Bool) -> [a] -> ([a], [a])
partition Token -> Bool
redirection [Token]
suffix

            redirs :: [Token]
redirs = [Token]
preRedirected forall a. [a] -> [a] -> [a]
++ [Token]
postRedirected
            assigns :: [Token]
assigns = [Token]
preAssigned
            args :: [Token]
args = [Token]
cmd forall a. [a] -> [a] -> [a]
++ [Token]
preRest2 forall a. [a] -> [a] -> [a]
++ [Token]
postRest
        in
            Id -> [Token] -> Token -> Token
T_Redirecting Id
id1 [Token]
redirs forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> [Token] -> Token
T_SimpleCommand Id
id2 [Token]
assigns [Token]
args
      where
        assignment :: Token -> Bool
assignment (T_Assignment {}) = Bool
True
        assignment Token
_ = Bool
False
        redirection :: Token -> Bool
redirection (T_FdRedirect {}) = Bool
True
        redirection Token
_ = Bool
False


readSource :: Monad m => Token -> SCParser m Token
readSource :: forall (m :: * -> *). Monad m => Token -> SCParser m Token
readSource t :: Token
t@(T_Redirecting Id
_ [Token]
_ (T_SimpleCommand Id
cmdId [Token]
_ (Token
cmd:Token
file':[Token]
rest'))) = do
    let file :: Token
file = Token -> [Token] -> Token
getFile Token
file' [Token]
rest'
    Maybe String
override <- forall {m :: * -> *}. MonadState SystemState m => m (Maybe String)
getSourceOverride
    let literalFile :: Maybe String
literalFile = do
        String
name <- Maybe String
override forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` Token -> Maybe String
getLiteralString Token
file forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` Token -> Maybe String
stripDynamicPrefix Token
file
        -- Hack to avoid 'source ~/foo' trying to read from literal tilde
        forall (f :: * -> *). Alternative f => Bool -> f ()
guard forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ String
"~/" forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
name
        forall (m :: * -> *) a. Monad m => a -> m a
return String
name
    case Maybe String
literalFile of
        Maybe String
Nothing -> do
            forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseNoteAtId (Token -> Id
getId Token
file) Severity
WarningC Integer
1090
                String
"ShellCheck can't follow non-constant source. Use a directive to specify location."
            forall (m :: * -> *) a. Monad m => a -> m a
return Token
t
        Just String
filename -> do
            Bool
proceed <- forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
String -> ParsecT s u m Bool
shouldFollow String
filename
            if Bool -> Bool
not Bool
proceed
              then do
                -- FIXME: This actually gets squashed without -a
                forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseNoteAtId (Token -> Id
getId Token
file) Severity
InfoC Integer
1093
                    String
"This file appears to be recursively sourced. Ignoring."
                forall (m :: * -> *) a. Monad m => a -> m a
return Token
t
              else do
                SystemInterface m
sys <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
Mr.asks forall (m :: * -> *). Environment m -> SystemInterface m
systemInterface
                (Either String String
input, String
resolvedFile) <-
                    if String
filename forall a. Eq a => a -> a -> Bool
== String
"/dev/null" -- always allow /dev/null
                    then forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. b -> Either a b
Right String
"", String
filename)
                    else do
                        [Annotation]
allAnnotations <- forall {f :: * -> *}.
MonadState SystemState f =>
Bool -> f [Annotation]
getCurrentAnnotations Bool
True
                        String
currentScript <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
Mr.asks forall (m :: * -> *). Environment m -> String
currentFilename
                        let paths :: [String]
paths = forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Annotation -> Maybe String
getSourcePath [Annotation]
allAnnotations
                        let externalSources :: Maybe Bool
externalSources = forall a. [a] -> Maybe a
listToMaybe forall a b. (a -> b) -> a -> b
$ forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Annotation -> Maybe Bool
getExternalSources [Annotation]
allAnnotations
                        String
resolved <- forall {t :: (* -> *) -> * -> *} {t :: (* -> *) -> * -> *}
       {t :: (* -> *) -> * -> *} {m :: * -> *} {a}.
(MonadTrans t, MonadTrans t, MonadTrans t, Monad m,
 Monad (t (t m)), Monad (t m)) =>
m a -> t (t (t m)) a
system forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
SystemInterface m
-> String -> Maybe Bool -> [String] -> String -> m String
siFindSource SystemInterface m
sys String
currentScript Maybe Bool
externalSources [String]
paths String
filename
                        Either String String
contents <- forall {t :: (* -> *) -> * -> *} {t :: (* -> *) -> * -> *}
       {t :: (* -> *) -> * -> *} {m :: * -> *} {a}.
(MonadTrans t, MonadTrans t, MonadTrans t, Monad m,
 Monad (t (t m)), Monad (t m)) =>
m a -> t (t (t m)) a
system forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
SystemInterface m
-> Maybe Bool -> String -> m (Either String String)
siReadFile SystemInterface m
sys Maybe Bool
externalSources String
resolved
                        forall (m :: * -> *) a. Monad m => a -> m a
return (Either String String
contents, String
resolved)
                case Either String String
input of
                    Left String
err -> do
                        forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseNoteAtId (Token -> Id
getId Token
file) Severity
InfoC Integer
1091 forall a b. (a -> b) -> a -> b
$
                            String
"Not following: " forall a. [a] -> [a] -> [a]
++ String
err
                        forall (m :: * -> *) a. Monad m => a -> m a
return Token
t
                    Right String
script -> do
                        Id
id1 <- forall (m :: * -> *). Monad m => Id -> SCParser m Id
getNewIdFor Id
cmdId
                        Id
id2 <- forall (m :: * -> *). Monad m => Id -> SCParser m Id
getNewIdFor Id
cmdId

                        let included :: ParsecT String UserState (SCBase m) Token
included = do
                            Token
src <- forall {m :: * -> *}.
Monad m =>
String -> String -> ParsecT String UserState (SCBase m) Token
subRead String
resolvedFile String
script
                            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> Token -> Token -> Token
T_SourceCommand Id
id1 Token
t (Id -> Token -> Token
T_Include Id
id2 Token
src)

                        let failed :: ParsecT String UserState (SCBase m) Token
failed = do
                            forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseNoteAtId (Token -> Id
getId Token
file) Severity
WarningC Integer
1094
                                String
"Parsing of sourced file failed. Ignoring it."
                            forall (m :: * -> *) a. Monad m => a -> m a
return Token
t

                        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
included forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
failed
  where
    getFile :: Token -> [Token] -> Token
    getFile :: Token -> [Token] -> Token
getFile Token
file (Token
next:[Token]
rest) =
        case Token -> Maybe String
getLiteralString Token
file of
            Just String
"--" -> Token
next
            Maybe String
x -> Token
file
    getFile Token
file [Token]
_ = Token
file

    getSourcePath :: Annotation -> Maybe String
getSourcePath Annotation
t =
        case Annotation
t of
            SourcePath String
x -> forall a. a -> Maybe a
Just String
x
            Annotation
_ -> forall a. Maybe a
Nothing

    getExternalSources :: Annotation -> Maybe Bool
getExternalSources Annotation
t =
        case Annotation
t of
            ExternalSources Bool
b -> forall a. a -> Maybe a
Just Bool
b
            Annotation
_ -> forall a. Maybe a
Nothing

    -- If the word has a single expansion as the directory, try stripping it
    -- This affects `$foo/bar` but not `${foo}-dir/bar` or `/foo/$file`
    stripDynamicPrefix :: Token -> Maybe String
stripDynamicPrefix Token
word =
        case Token -> [Token]
getWordParts Token
word of
            Token
exp : [Token]
rest | Token -> Bool
isStringExpansion Token
exp -> do
                String
str <- Token -> Maybe String
getLiteralString (Id -> [Token] -> Token
T_NormalWord (Line -> Id
Id Line
0) [Token]
rest)
                forall (f :: * -> *). Alternative f => Bool -> f ()
guard forall a b. (a -> b) -> a -> b
$ String
"/" forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
str
                forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ String
"." forall a. [a] -> [a] -> [a]
++ String
str
            [Token]
_ -> forall a. Maybe a
Nothing

    subRead :: String -> String -> ParsecT String UserState (SCBase m) Token
subRead String
name String
script =
        forall {s} {m :: * -> *} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
Context -> ParsecT s u m b -> ParsecT s u m b
withContext (String -> Context
ContextSource String
name) forall a b. (a -> b) -> a -> b
$
            forall {s} {m :: * -> *} {s} {u} {b}.
MonadState s m =>
ParsecT s u m b -> ParsecT s u m b
inSeparateContext forall a b. (a -> b) -> a -> b
$
                forall {m :: * -> *} {a} {u} {b}.
Monad m =>
SourcePos -> ParsecT a u m b -> a -> ParsecT a u m b
subParse (String -> SourcePos
initialPos String
name) (forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) Token
readScriptFile Bool
True) String
script
readSource Token
t = forall (m :: * -> *) a. Monad m => a -> m a
return Token
t


prop_readPipeline :: Bool
prop_readPipeline = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readPipeline String
"! cat /etc/issue | grep -i ubuntu"
prop_readPipeline2 :: Bool
prop_readPipeline2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readPipeline String
"!cat /etc/issue | grep -i ubuntu"
prop_readPipeline3 :: Bool
prop_readPipeline3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readPipeline String
"for f; do :; done|cat"
readPipeline :: ParsecT String UserState (SCBase m) Token
readPipeline = do
    forall {s} {u} {m :: * -> *} {a}.
String -> ParsecT s u m a -> ParsecT s u m ()
unexpecting String
"keyword/token" forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readKeyword
    do
        (T_Bang Id
id) <- forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m Token
g_Bang
        Token
pipe <- ParsecT String UserState (SCBase m) Token
readPipeSequence
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> Token -> Token
T_Banged Id
id Token
pipe
      forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
        ParsecT String UserState (SCBase m) Token
readPipeSequence

prop_readAndOr :: Bool
prop_readAndOr = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readAndOr String
"grep -i lol foo || exit 1"
prop_readAndOr1 :: Bool
prop_readAndOr1 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readAndOr String
"# shellcheck disable=1\nfoo"
prop_readAndOr2 :: Bool
prop_readAndOr2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readAndOr String
"# shellcheck disable=1\n# lol\n# shellcheck disable=3\nfoo"
readAndOr :: ParsecT String UserState (SCBase m) Token
readAndOr = do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    SourcePos
apos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    [Annotation]
annotations <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotations
    Id
aid <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start

    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Annotation]
annotations) forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ do
        forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readKeyword
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
apos Severity
ErrorC Integer
1123 String
"ShellCheck directives are only valid in front of complete compound commands, like 'if', not e.g. individual 'elif' branches."

    Token
andOr <- forall {s} {m :: * -> *} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
[Annotation] -> ParsecT s u m b -> ParsecT s u m b
withAnnotations [Annotation]
annotations forall a b. (a -> b) -> a -> b
$
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (a -> a -> a) -> ParsecT s u m a
chainl1 ParsecT String UserState (SCBase m) Token
readPipeline forall a b. (a -> b) -> a -> b
$ do
            Token
op <- forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_AND_IF forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_OR_IF
            forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readLineBreak
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ case Token
op of T_AND_IF Id
id -> Id -> Token -> Token -> Token
T_AndIf Id
id
                                T_OR_IF  Id
id -> Id -> Token -> Token -> Token
T_OrIf Id
id

    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Annotation]
annotations
                then Token
andOr
                else Id -> [Annotation] -> Token -> Token
T_Annotation Id
aid [Annotation]
annotations Token
andOr

readTermOrNone :: ParsecT String UserState (SCBase m) [Token]
readTermOrNone = do
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Token]
readTerm forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do
        forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof
        forall (m :: * -> *) a. Monad m => a -> m a
return []

prop_readTerm :: Bool
prop_readTerm = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Token]
readTerm String
"time ( foo; bar; )"
readTerm :: ParsecT String UserState (SCBase m) [Token]
readTerm = do
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    Token
m <- ParsecT String UserState (SCBase m) Token
readAndOr
    Token -> ParsecT String UserState (SCBase m) [Token]
readTerm' Token
m
  where
    readTerm' :: Token -> ParsecT String UserState (SCBase m) [Token]
readTerm' Token
current =
        do
            (Char
sep, (SourcePos
start, SourcePos
end)) <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) (Char, (SourcePos, SourcePos))
readSeparator
            Id
id <- forall {m :: * -> *} {s}.
Monad m =>
SourcePos -> SourcePos -> ParsecT s UserState m Id
getNextIdBetween SourcePos
start SourcePos
end
            Token
more <- forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option (Id -> Token
T_EOF Id
id) ParsecT String UserState (SCBase m) Token
readAndOr
            case Token
more of (T_EOF Id
_) -> forall (m :: * -> *) a. Monad m => a -> m a
return [Id -> Char -> Token -> Token
transformWithSeparator Id
id Char
sep Token
current]
                         Token
_         -> do
                                    [Token]
list <- Token -> ParsecT String UserState (SCBase m) [Token]
readTerm' Token
more
                                    forall (m :: * -> *) a. Monad m => a -> m a
return (Id -> Char -> Token -> Token
transformWithSeparator Id
id Char
sep Token
current forall a. a -> [a] -> [a]
: [Token]
list)
          forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
            forall (m :: * -> *) a. Monad m => a -> m a
return [Token
current]
      where
        transformWithSeparator :: Id -> Char -> Token -> Token
transformWithSeparator Id
i Char
'&' = Id -> Token -> Token
T_Backgrounded Id
i
        transformWithSeparator Id
i Char
_  = forall a. a -> a
id


readPipeSequence :: ParsecT String UserState (SCBase m) Token
readPipeSequence = do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    ([Token]
cmds, [Token]
pipes) <- forall {s} {m :: * -> *} {t} {u} {a} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m ([a], [a])
sepBy1WithSeparators ParsecT String UserState (SCBase m) Token
readCommand
                        (forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m Token
readPipe forall {s} {m :: * -> *} {t} {u} {a} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`thenSkip` (forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readLineBreak))
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> [Token] -> Token
T_Pipeline Id
id [Token]
pipes [Token]
cmds
  where
    sepBy1WithSeparators :: ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m ([a], [a])
sepBy1WithSeparators ParsecT s u m a
p ParsecT s u m a
s = do
        let elems :: ParsecT s u m ([a], [a])
elems = ParsecT s u m a
p forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
x -> forall (m :: * -> *) a. Monad m => a -> m a
return ([a
x], [])
        let seps :: ParsecT s u m (([a], [a]) -> ([a], [a]) -> ([a], [a]))
seps = do
            a
separator <- ParsecT s u m a
s
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ \([a]
a,[a]
b) ([a]
c,[a]
d) -> ([a]
aforall a. [a] -> [a] -> [a]
++[a]
c, [a]
b forall a. [a] -> [a] -> [a]
++ [a]
d forall a. [a] -> [a] -> [a]
++ [a
separator])
        forall {a}. ParsecT s u m ([a], [a])
elems forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (a -> a -> a) -> ParsecT s u m a
`chainl1` forall {a}. ParsecT s u m (([a], [a]) -> ([a], [a]) -> ([a], [a]))
seps

readPipe :: ParsecT s UserState m Token
readPipe = do
    forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_OR_IF
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'|'
    String
qualifier <- forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"&" forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return String
""
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Pipe Id
id (Char
'|'forall a. a -> [a] -> [a]
:String
qualifier)

readCommand :: ParsecT String UserState (SCBase m) Token
readCommand = forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [
    ParsecT String UserState (SCBase m) Token
readCompoundCommand,
    ParsecT String UserState (SCBase m) Token
readConditionCommand,
    ParsecT String UserState (SCBase m) Token
readCoProc,
    ParsecT String UserState (SCBase m) Token
readSimpleCommand
    ]

readCmdName :: ParsecT String UserState (SCBase m) Token
readCmdName = do
    -- Ignore alias suppression
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
        forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\\'
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
variableChars forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
":."
    ParsecT String UserState (SCBase m) Token
readCmdWord

readCmdWord :: ParsecT String UserState (SCBase m) Token
readCmdWord = do
    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m ()
skipAnnotationAndWarn
    ParsecT String UserState (SCBase m) Token
readNormalWord forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing

-- Due to poor planning, annotations after commands isn't handled well.
-- At the time this function is used, it's usually too late to skip
-- comments, so you end up with a parse failure instead.
skipAnnotationAndWarn :: ParsecT s UserState m ()
skipAnnotationAndWarn = forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ do
        forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m String
readAnnotationPrefix
        forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1126 String
"Place shellcheck directives before commands, not after."
        forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readAnyComment

prop_readIfClause :: Bool
prop_readIfClause = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIfClause String
"if false; then foo; elif true; then stuff; more stuff; else cows; fi"
prop_readIfClause2 :: Bool
prop_readIfClause2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIfClause String
"if false; then; echo oo; fi"
prop_readIfClause3 :: Bool
prop_readIfClause3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIfClause String
"if false; then true; else; echo lol; fi"
prop_readIfClause4 :: Bool
prop_readIfClause4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIfClause String
"if false; then true; else if true; then echo lol; fi; fi"
prop_readIfClause5 :: Bool
prop_readIfClause5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIfClause String
"if false; then true; else\nif true; then echo lol; fi; fi"
prop_readIfClause6 :: Bool
prop_readIfClause6 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIfClause String
"if true\nthen\nDo the thing\nfi"
readIfClause :: ParsecT String UserState (SCBase m) Token
readIfClause = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"if expression" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    ([Token]
condition, [Token]
action) <- ParsecT String UserState (SCBase m) ([Token], [Token])
readIfPart
    [([Token], [Token])]
elifs <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String UserState (SCBase m) ([Token], [Token])
readElifPart
    [Token]
elses <- forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option [] ParsecT String UserState (SCBase m) [Token]
readElsePart

    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Fi forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m String -> ParsecT s u m a
`orFail` do
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1046 String
"Couldn't find 'fi' for this 'if'."
        forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1047 String
"Expected 'fi' matching previously mentioned 'if'."
        forall (m :: * -> *) a. Monad m => a -> m a
return String
"Expected 'fi'"
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start

    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [([Token], [Token])] -> [Token] -> Token
T_IfExpression Id
id (([Token]
condition, [Token]
action)forall a. a -> [a] -> [a]
:[([Token], [Token])]
elifs) [Token]
elses


verifyNotEmptyIf :: String -> ParsecT String UserState (SCBase m) ()
verifyNotEmptyIf String
s =
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (do
                SourcePos
emptyPos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ (forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Fi forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Elif forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Else)
                forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
emptyPos Severity
ErrorC Integer
1048 forall a b. (a -> b) -> a -> b
$ String
"Can't have empty " forall a. [a] -> [a] -> [a]
++ String
s forall a. [a] -> [a] -> [a]
++ String
" clauses (use 'true' as a no-op).")
readIfPart :: ParsecT String UserState (SCBase m) ([Token], [Token])
readIfPart = do
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_If
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    [Token]
condition <- ParsecT String UserState (SCBase m) [Token]
readTerm

    forall {s} {m :: * -> *} {t} {u} {a} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m ()
ifNextToken (forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Fi forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Elif forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Else) forall a b. (a -> b) -> a -> b
$
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1049 String
"Did you forget the 'then' for this 'if'?"

    forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"then clause" forall a b. (a -> b) -> a -> b
$ do
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Then forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m String -> ParsecT s u m a
`orFail` do
            forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1050 String
"Expected 'then'."
            forall (m :: * -> *) a. Monad m => a -> m a
return String
"Expected 'then'"

        forall {s} {m :: * -> *} {t} {m :: * -> *} {u} {a}.
(Stream s m t, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m a
-> Severity -> Integer -> String -> ParsecT s u m ()
acceptButWarn forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m Token
g_Semi Severity
ErrorC Integer
1051 String
"Semicolons directly after 'then' are not allowed. Just remove it."
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
        forall {m :: * -> *}.
Monad m =>
String -> ParsecT String UserState (SCBase m) ()
verifyNotEmptyIf String
"then"

        [Token]
action <- ParsecT String UserState (SCBase m) [Token]
readTerm
        forall (m :: * -> *) a. Monad m => a -> m a
return ([Token]
condition, [Token]
action)

readElifPart :: ParsecT String UserState (SCBase m) ([Token], [Token])
readElifPart = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"elif clause" forall a b. (a -> b) -> a -> b
$ do
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Elif
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    [Token]
condition <- ParsecT String UserState (SCBase m) [Token]
readTerm
    forall {s} {m :: * -> *} {t} {u} {a} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m ()
ifNextToken (forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Fi forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Elif forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Else) forall a b. (a -> b) -> a -> b
$
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1049 String
"Did you forget the 'then' for this 'elif'?"

    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Then
    forall {s} {m :: * -> *} {t} {m :: * -> *} {u} {a}.
(Stream s m t, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m a
-> Severity -> Integer -> String -> ParsecT s u m ()
acceptButWarn forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m Token
g_Semi Severity
ErrorC Integer
1052 String
"Semicolons directly after 'then' are not allowed. Just remove it."
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    forall {m :: * -> *}.
Monad m =>
String -> ParsecT String UserState (SCBase m) ()
verifyNotEmptyIf String
"then"
    [Token]
action <- ParsecT String UserState (SCBase m) [Token]
readTerm
    forall (m :: * -> *) a. Monad m => a -> m a
return ([Token]
condition, [Token]
action)

readElsePart :: ParsecT String UserState (SCBase m) [Token]
readElsePart = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"else clause" forall a b. (a -> b) -> a -> b
$ do
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Else
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ do
        forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_If
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1075 String
"Use 'elif' instead of 'else if' (or put 'if' on new line if nesting)."

    forall {s} {m :: * -> *} {t} {m :: * -> *} {u} {a}.
(Stream s m t, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m a
-> Severity -> Integer -> String -> ParsecT s u m ()
acceptButWarn forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m Token
g_Semi Severity
ErrorC Integer
1053 String
"Semicolons directly after 'else' are not allowed. Just remove it."
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    forall {m :: * -> *}.
Monad m =>
String -> ParsecT String UserState (SCBase m) ()
verifyNotEmptyIf String
"else"
    ParsecT String UserState (SCBase m) [Token]
readTerm

ifNextToken :: ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m ()
ifNextToken ParsecT s u m a
parser ParsecT s u m a
action =
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ do
        forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ ParsecT s u m a
parser
        ParsecT s u m a
action

prop_readSubshell :: Bool
prop_readSubshell = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSubshell String
"( cd /foo; tar cf stuff.tar * )"
readSubshell :: ParsecT String UserState (SCBase m) Token
readSubshell = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"explicit subshell" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'('
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    [Token]
list <- ParsecT String UserState (SCBase m) [Token]
readCompoundList
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')' forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected ) closing the subshell"
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_Subshell Id
id [Token]
list

prop_readBraceGroup :: Bool
prop_readBraceGroup = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraceGroup String
"{ a; b | c | d; e; }"
prop_readBraceGroup2 :: Bool
prop_readBraceGroup2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraceGroup String
"{foo;}"
prop_readBraceGroup3 :: Bool
prop_readBraceGroup3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraceGroup String
"{(foo)}"
readBraceGroup :: ParsecT String UserState (SCBase m) Token
readBraceGroup = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"brace group" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'{'
    forall (f :: * -> *) a. Functor f => f a -> f ()
void forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacingOrFail forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (do
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
"(" -- {( is legal
        forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1054 String
"You need a space after the '{'.")
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ do
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'}'
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1055 String
"You need at least one command here. Use 'true;' as a no-op."
    [Token]
list <- ParsecT String UserState (SCBase m) [Token]
readTerm
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'}' forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do
        forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1056 String
"Expected a '}'. If you have one, try a ; or \\n in front of it."
        forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Missing '}'"
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_BraceGroup Id
id [Token]
list

prop_readBatsTest1 :: Bool
prop_readBatsTest1 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBatsTest String
"@test 'can parse' {\n  true\n}"
prop_readBatsTest2 :: Bool
prop_readBatsTest2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBatsTest String
"@test random text !(@*$Y&! {\n  true\n}"
prop_readBatsTest3 :: Bool
prop_readBatsTest3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBatsTest String
"@test foo { bar { baz {\n  true\n}"
prop_readBatsTest4 :: Bool
prop_readBatsTest4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isNotOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBatsTest String
"@test foo \n{\n true\n}"
readBatsTest :: ParsecT String UserState (SCBase m) Token
readBatsTest = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"bats @test" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"@test "
    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
    String
name <- forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readBatsName
    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
    Token
test <- ParsecT String UserState (SCBase m) Token
readBraceGroup
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token -> Token
T_BatsTest Id
id String
name Token
test
  where
    readBatsName :: ParsecT s u m String
readBatsName = do
        String
line <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
"\n"
        let name :: String
name = forall a. [a] -> [a]
reverse forall a b. (a -> b) -> a -> b
$ ShowS
f forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [a]
reverse String
line
        forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
name

    -- We want everything before the last " {" in a string, so we find everything after "{ " in its reverse
    f :: ShowS
f (Char
'{':Char
' ':String
rest) = forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isSpace String
rest
    f (Char
a:String
rest) = ShowS
f String
rest
    f [] = String
""

prop_readWhileClause :: Bool
prop_readWhileClause = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readWhileClause String
"while [[ -e foo ]]; do sleep 1; done"
readWhileClause :: ParsecT String UserState (SCBase m) Token
readWhileClause = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"while loop" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    Id
kwId <- Token -> Id
getId forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_While
    [Token]
condition <- ParsecT String UserState (SCBase m) [Token]
readTerm
    [Token]
statements <- Id -> ParsecT String UserState (SCBase m) [Token]
readDoGroup Id
kwId
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> [Token] -> Token
T_WhileExpression Id
id [Token]
condition [Token]
statements

prop_readUntilClause :: Bool
prop_readUntilClause = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readUntilClause String
"until kill -0 $PID; do sleep 1; done"
readUntilClause :: ParsecT String UserState (SCBase m) Token
readUntilClause = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"until loop" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    Id
kwId <- Token -> Id
getId forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Until
    [Token]
condition <- ParsecT String UserState (SCBase m) [Token]
readTerm
    [Token]
statements <- Id -> ParsecT String UserState (SCBase m) [Token]
readDoGroup Id
kwId
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> [Token] -> Token
T_UntilExpression Id
id [Token]
condition [Token]
statements

readDoGroup :: Id -> ParsecT String UserState (SCBase m) [Token]
readDoGroup Id
kwId = do
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (do
                forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Done
                forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId Id
kwId Severity
ErrorC Integer
1057 String
"Did you forget the 'do' for this loop?")

    Token
doKw <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Do forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m String -> ParsecT s u m a
`orFail` do
        forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1058 String
"Expected 'do'."
        forall (m :: * -> *) a. Monad m => a -> m a
return String
"Expected 'do'"

    forall {s} {m :: * -> *} {t} {m :: * -> *} {u} {a}.
(Stream s m t, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m a
-> Severity -> Integer -> String -> ParsecT s u m ()
acceptButWarn forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m Token
g_Semi Severity
ErrorC Integer
1059 String
"Semicolon is not allowed directly after 'do'. You can just delete it."
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing

    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (do
                forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Done
                forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId (Token -> Id
getId Token
doKw) Severity
ErrorC Integer
1060 String
"Can't have empty do clauses (use 'true' as a no-op).")

    [Token]
commands <- ParsecT String UserState (SCBase m) [Token]
readCompoundList
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Done forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m String -> ParsecT s u m a
`orFail` do
            forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId (Token -> Id
getId Token
doKw) Severity
ErrorC Integer
1061 String
"Couldn't find 'done' for this 'do'."
            forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1062 String
"Expected 'done' matching previously mentioned 'do'."
            forall (m :: * -> *) a. Monad m => a -> m a
return String
"Expected 'done'"

    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ do
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"<("
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1142 String
"Use 'done < <(cmd)' to redirect from process substitution (currently missing one '<')."
    forall (m :: * -> *) a. Monad m => a -> m a
return [Token]
commands


prop_readForClause :: Bool
prop_readForClause = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for f in *; do rm \"$f\"; done"
prop_readForClause1 :: Bool
prop_readForClause1 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for f in *; { rm \"$f\"; }"
prop_readForClause3 :: Bool
prop_readForClause3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for f; do foo; done"
prop_readForClause4 :: Bool
prop_readForClause4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for((i=0; i<10; i++)); do echo $i; done"
prop_readForClause5 :: Bool
prop_readForClause5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for ((i=0;i<10 && n>x;i++,--n))\ndo \necho $i\ndone"
prop_readForClause6 :: Bool
prop_readForClause6 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for ((;;))\ndo echo $i\ndone"
prop_readForClause7 :: Bool
prop_readForClause7 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for ((;;)) do echo $i\ndone"
prop_readForClause8 :: Bool
prop_readForClause8 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for ((;;)) ; do echo $i\ndone"
prop_readForClause9 :: Bool
prop_readForClause9 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for i do true; done"
prop_readForClause10 :: Bool
prop_readForClause10 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for ((;;)) { true; }"
prop_readForClause12 :: Bool
prop_readForClause12 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for $a in *; do echo \"$a\"; done"
prop_readForClause13 :: Bool
prop_readForClause13 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for foo\nin\\\n  bar\\\n  baz\ndo true; done"
readForClause :: ParsecT String UserState (SCBase m) Token
readForClause = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"for loop" forall a b. (a -> b) -> a -> b
$ do
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    (T_For Id
id) <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_For
    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
    Id -> ParsecT String UserState (SCBase m) Token
readArithmetic Id
id forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Id -> ParsecT String UserState (SCBase m) Token
readRegular Id
id
  where
    readArithmetic :: Id -> ParsecT String UserState (SCBase m) Token
readArithmetic Id
id = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"arithmetic for condition" forall a b. (a -> b) -> a -> b
$ do
        forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, Stream s m Char,
 MonadState SystemState m) =>
Char -> String -> ParsecT s UserState m ()
readArithmeticDelimiter Char
'(' String
"Missing second '(' to start arithmetic for ((;;)) loop"
        Token
x <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents
        forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
';' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
        Token
y <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents
        forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
';' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
        Token
z <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents
        forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
        forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, Stream s m Char,
 MonadState SystemState m) =>
Char -> String -> ParsecT s UserState m ()
readArithmeticDelimiter Char
')' String
"Missing second ')' to terminate 'for ((;;))' loop condition"
        forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readSequentialSep forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
        [Token]
group <- ParsecT String UserState (SCBase m) [Token]
readBraced forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Id -> ParsecT String UserState (SCBase m) [Token]
readDoGroup Id
id
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> Token -> Token -> Token -> [Token] -> Token
T_ForArithmetic Id
id Token
x Token
y Token
z [Token]
group

    -- For c='(' read "((" and be lenient about spaces
    readArithmeticDelimiter :: Char -> String -> ParsecT s UserState m ()
readArithmeticDelimiter Char
c String
msg = do
        forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
c
        SourcePos
startPos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        String
sp <- forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
        SourcePos
endPos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
c forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do
            forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
startPos Severity
ErrorC Integer
1137 String
msg
            forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
""
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
sp) forall a b. (a -> b) -> a -> b
$
            forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAtWithEnd SourcePos
startPos SourcePos
endPos Severity
ErrorC Integer
1138 forall a b. (a -> b) -> a -> b
$ String
"Remove spaces between " forall a. [a] -> [a] -> [a]
++ [Char
c,Char
c] forall a. [a] -> [a] -> [a]
++ String
" in arithmetic for loop."

    readBraced :: ParsecT String UserState (SCBase m) [Token]
readBraced = do
        (T_BraceGroup Id
_ [Token]
list) <- ParsecT String UserState (SCBase m) Token
readBraceGroup
        forall (m :: * -> *) a. Monad m => a -> m a
return [Token]
list

    readRegular :: Id -> ParsecT String UserState (SCBase m) Token
readRegular Id
id = do
        forall {s} {m :: * -> *} {t} {m :: * -> *} {u} {a}.
(Stream s m t, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m a
-> Severity -> Integer -> String -> ParsecT s u m ()
acceptButWarn (forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'$') Severity
ErrorC Integer
1086
            String
"Don't use $ on the iterator name in for loops."
        String
name <- forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readVariableName forall {s} {m :: * -> *} {t} {u} {a} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`thenSkip` forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
        [Token]
values <- ParsecT String UserState (SCBase m) [Token]
readInClause forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readSequentialSep forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return [])
        [Token]
group <- ParsecT String UserState (SCBase m) [Token]
readBraced forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Id -> ParsecT String UserState (SCBase m) [Token]
readDoGroup Id
id
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> [Token] -> [Token] -> Token
T_ForIn Id
id String
name [Token]
values [Token]
group

prop_readSelectClause1 :: Bool
prop_readSelectClause1 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSelectClause String
"select foo in *; do echo $foo; done"
prop_readSelectClause2 :: Bool
prop_readSelectClause2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSelectClause String
"select foo; do echo $foo; done"
readSelectClause :: ParsecT String UserState (SCBase m) Token
readSelectClause = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"select loop" forall a b. (a -> b) -> a -> b
$ do
    (T_Select Id
id) <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Select
    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
    Id -> [Token] -> ParsecT String UserState (SCBase m) Token
typ <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) (Id -> [Token] -> m Token)
readRegular
    [Token]
group <- Id -> ParsecT String UserState (SCBase m) [Token]
readDoGroup Id
id
    Id -> [Token] -> ParsecT String UserState (SCBase m) Token
typ Id
id [Token]
group
  where
    readRegular :: ParsecT String UserState (SCBase m) (Id -> [Token] -> m Token)
readRegular = do
        String
name <- forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readVariableName
        forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
        [Token]
values <- ParsecT String UserState (SCBase m) [Token]
readInClause forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readSequentialSep forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return [])
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ \Id
id [Token]
group -> (forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> [Token] -> [Token] -> Token
T_SelectIn Id
id String
name [Token]
values [Token]
group)

readInClause :: ParsecT String UserState (SCBase m) [Token]
readInClause = do
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_In
    [Token]
things <- ParsecT String UserState (SCBase m) Token
readCmdWord forall {s} {m :: * -> *} {t} {u} {a} {a}.
(Stream s m t, Show t) =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m [a]
`reluctantlyTill`
                (forall (f :: * -> *) a. Functor f => f a -> f ()
void forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m Token
g_Semi forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (f :: * -> *) a. Functor f => f a -> f ()
void forall (m :: * -> *). Monad m => SCParser m Char
linefeed forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (f :: * -> *) a. Functor f => f a -> f ()
void forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Do)

    do {
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Do;
        forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s UserState m ()
parseNote Severity
ErrorC Integer
1063 String
"You need a line feed or semicolon before the 'do'.";
    } forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do {
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m Token
g_Semi;
        forall (f :: * -> *) a. Functor f => f a -> f ()
void forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing;
    }

    forall (m :: * -> *) a. Monad m => a -> m a
return [Token]
things

prop_readCaseClause :: Bool
prop_readCaseClause = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCaseClause String
"case foo in a ) lol; cow;; b|d) fooo; esac"
prop_readCaseClause2 :: Bool
prop_readCaseClause2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCaseClause String
"case foo\n in * ) echo bar;; esac"
prop_readCaseClause3 :: Bool
prop_readCaseClause3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCaseClause String
"case foo\n in * ) echo bar & ;; esac"
prop_readCaseClause4 :: Bool
prop_readCaseClause4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCaseClause String
"case foo\n in *) echo bar ;& bar) foo; esac"
prop_readCaseClause5 :: Bool
prop_readCaseClause5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCaseClause String
"case foo\n in *) echo bar;;& foo) baz;; esac"
prop_readCaseClause6 :: Bool
prop_readCaseClause6 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCaseClause String
"case foo\n in if) :;; done) :;; esac"
readCaseClause :: ParsecT String UserState (SCBase m) Token
readCaseClause = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"case expression" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Case
    Token
word <- ParsecT String UserState (SCBase m) Token
readNormalWord
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_In forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected 'in'"
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readLineBreak
    [(CaseType, [Token], [Token])]
list <- ParsecT String UserState (SCBase m) [(CaseType, [Token], [Token])]
readCaseList
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Esac forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected 'esac' to close the case statement"
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> Token -> [(CaseType, [Token], [Token])] -> Token
T_CaseExpression Id
id Token
word [(CaseType, [Token], [Token])]
list

readCaseList :: ParsecT String UserState (SCBase m) [(CaseType, [Token], [Token])]
readCaseList = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String UserState (SCBase m) (CaseType, [Token], [Token])
readCaseItem

readCaseItem :: ParsecT String UserState (SCBase m) (CaseType, [Token], [Token])
readCaseItem = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"case item" forall a b. (a -> b) -> a -> b
$ do
    forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Esac
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ do
        forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m String
readAnnotationPrefix
        forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1124 String
"ShellCheck directives are only valid in front of complete commands like 'case' statements, not individual case branches."
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_Lparen
    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
    [Token]
pattern' <- ParsecT String UserState (SCBase m) [Token]
readPattern
    forall (f :: * -> *) a. Functor f => f a -> f ()
void forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_Rparen forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do
        forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1085
            String
"Did you forget to move the ;; after extending this case item?"
        forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected ) to open a new case item"
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readLineBreak
    [Token]
list <- (forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) CaseType
readCaseSeparator forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return []) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) [Token]
readCompoundList
    CaseType
separator <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) CaseType
readCaseSeparator forall {s} {u} {m :: * -> *} {a} {a}.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`attempting` do
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_Rparen
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1074
            String
"Did you forget the ;; after the previous case item?"
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readLineBreak
    forall (m :: * -> *) a. Monad m => a -> m a
return (CaseType
separator, [Token]
pattern', [Token]
list)

readCaseSeparator :: ParsecT String UserState (SCBase m) CaseType
readCaseSeparator = forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [
    forall {m :: * -> *} {s} {m :: * -> *} {a}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
String -> (Id -> a) -> ParsecT s UserState m a
tryToken String
";;&" (forall a b. a -> b -> a
const ()) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return CaseType
CaseContinue,
    forall {m :: * -> *} {s} {m :: * -> *} {a}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
String -> (Id -> a) -> ParsecT s UserState m a
tryToken String
";&" (forall a b. a -> b -> a
const ()) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return CaseType
CaseFallThrough,
    forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_DSEMI forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return CaseType
CaseBreak,
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readLineBreak forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Esac) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return CaseType
CaseBreak
    ]

prop_readFunctionDefinition :: Bool
prop_readFunctionDefinition = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readFunctionDefinition String
"foo() { command foo --lol \"$@\"; }"
prop_readFunctionDefinition1 :: Bool
prop_readFunctionDefinition1 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readFunctionDefinition String
"foo   (){ command foo --lol \"$@\"; }"
prop_readFunctionDefinition4 :: Bool
prop_readFunctionDefinition4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readFunctionDefinition String
"foo(a, b) { true; }"
prop_readFunctionDefinition5 :: Bool
prop_readFunctionDefinition5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readFunctionDefinition String
":(){ :|:;}"
prop_readFunctionDefinition6 :: Bool
prop_readFunctionDefinition6 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readFunctionDefinition String
"?(){ foo; }"
prop_readFunctionDefinition7 :: Bool
prop_readFunctionDefinition7 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readFunctionDefinition String
"..(){ cd ..; }"
prop_readFunctionDefinition8 :: Bool
prop_readFunctionDefinition8 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readFunctionDefinition String
"foo() (ls)"
prop_readFunctionDefinition9 :: Bool
prop_readFunctionDefinition9 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readFunctionDefinition String
"function foo { true; }"
prop_readFunctionDefinition10 :: Bool
prop_readFunctionDefinition10 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readFunctionDefinition String
"function foo () { true; }"
prop_readFunctionDefinition11 :: Bool
prop_readFunctionDefinition11 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readFunctionDefinition String
"function foo{\ntrue\n}"
prop_readFunctionDefinition12 :: Bool
prop_readFunctionDefinition12 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readFunctionDefinition String
"function []!() { true; }"
prop_readFunctionDefinition13 :: Bool
prop_readFunctionDefinition13 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readFunctionDefinition String
"@require(){ true; }"
readFunctionDefinition :: ParsecT String UserState (SCBase m) Token
readFunctionDefinition = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"function" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    Id -> Token -> Token
functionSignature <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) (Id -> Token -> Token)
readFunctionSignature
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"{(") forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1064 String
"Expected a { to open the function definition."
    Token
group <- ParsecT String UserState (SCBase m) Token
readBraceGroup forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readSubshell
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> Token -> Token
functionSignature Id
id Token
group
  where
    readFunctionSignature :: ParsecT String UserState (SCBase m) (Id -> Token -> Token)
readFunctionSignature =
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) (Id -> Token -> Token)
readWithFunction forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m (Id -> Token -> Token)
readWithoutFunction
      where
        readWithFunction :: ParsecT String UserState (SCBase m) (Id -> Token -> Token)
readWithFunction = do
            forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
                forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"function"
                forall (m :: * -> *). Monad m => SCParser m Char
whitespace
            forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
            String
name <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
extendedFunctionChars
            String
spaces <- forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
            Bool
hasParens <- forall {s} {m :: * -> *} {t} {u} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m Bool
wasIncluded forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, Stream s m Char,
 MonadState SystemState m) =>
ParsecT s UserState m ()
readParens
            forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not Bool
hasParens Bool -> Bool -> Bool
&& forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
spaces) forall a b. (a -> b) -> a -> b
$
                forall {s} {m :: * -> *} {t} {m :: * -> *} {u} {a}.
(Stream s m t, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m a
-> Severity -> Integer -> String -> ParsecT s u m ()
acceptButWarn (forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"{("))
                    Severity
ErrorC Integer
1095 String
"You need a space or linefeed between the function name and body."
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ \Id
id -> Id
-> FunctionKeyword
-> FunctionParentheses
-> String
-> Token
-> Token
T_Function Id
id (Bool -> FunctionKeyword
FunctionKeyword Bool
True) (Bool -> FunctionParentheses
FunctionParentheses Bool
hasParens) String
name

        readWithoutFunction :: ParsecT s UserState m (Id -> Token -> Token)
readWithoutFunction = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
            String
name <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
functionChars
            forall (f :: * -> *). Alternative f => Bool -> f ()
guard forall a b. (a -> b) -> a -> b
$ String
name forall a. Eq a => a -> a -> Bool
/= String
"time"  -- Interferes with time ( foo )
            forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
            forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, Stream s m Char,
 MonadState SystemState m) =>
ParsecT s UserState m ()
readParens
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ \Id
id -> Id
-> FunctionKeyword
-> FunctionParentheses
-> String
-> Token
-> Token
T_Function Id
id (Bool -> FunctionKeyword
FunctionKeyword Bool
False) (Bool -> FunctionParentheses
FunctionParentheses Bool
True) String
name

        readParens :: ParsecT s UserState m ()
readParens = do
            forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_Lparen
            forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
            forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_Rparen forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do
                forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1065 String
"Trying to declare parameters? Don't. Use () and refer to params as $1, $2.."
                forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
"\n){"
                forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_Rparen
            forall (m :: * -> *) a. Monad m => a -> m a
return ()

prop_readCoProc1 :: Bool
prop_readCoProc1 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCoProc String
"coproc foo { echo bar; }"
prop_readCoProc2 :: Bool
prop_readCoProc2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCoProc String
"coproc { echo bar; }"
prop_readCoProc3 :: Bool
prop_readCoProc3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCoProc String
"coproc echo bar"
readCoProc :: ParsecT String UserState (SCBase m) Token
readCoProc = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"coproc" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
        forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"coproc"
        forall (m :: * -> *). Monad m => SCParser m Char
whitespace
    forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ IncompleteInterval -> ParsecT String UserState (SCBase m) Token
readCompoundCoProc IncompleteInterval
start, IncompleteInterval -> ParsecT String UserState (SCBase m) Token
readSimpleCoProc IncompleteInterval
start ]
  where
    readCompoundCoProc :: IncompleteInterval -> ParsecT String UserState (SCBase m) Token
readCompoundCoProc IncompleteInterval
start = do
        Maybe String
var <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
optionMaybe forall a b. (a -> b) -> a -> b
$
            forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readVariableName forall {s} {m :: * -> *} {t} {u} {a} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`thenSkip` forall (m :: * -> *). Monad m => SCParser m Char
whitespace
        Token
body <- forall {m :: * -> *} {s}.
Monad m =>
ParsecT s UserState m Token -> ParsecT s UserState m Token
readBody ParsecT String UserState (SCBase m) Token
readCompoundCommand
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> Maybe String -> Token -> Token
T_CoProc Id
id Maybe String
var Token
body
    readSimpleCoProc :: IncompleteInterval -> ParsecT String UserState (SCBase m) Token
readSimpleCoProc IncompleteInterval
start = do
        Token
body <- forall {m :: * -> *} {s}.
Monad m =>
ParsecT s UserState m Token -> ParsecT s UserState m Token
readBody ParsecT String UserState (SCBase m) Token
readSimpleCommand
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> Maybe String -> Token -> Token
T_CoProc Id
id forall a. Maybe a
Nothing Token
body
    readBody :: ParsecT s UserState m Token -> ParsecT s UserState m Token
readBody ParsecT s UserState m Token
parser = do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        Token
body <- ParsecT s UserState m Token
parser
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> Token -> Token
T_CoProcBody Id
id Token
body

readPattern :: ParsecT String UserState (SCBase m) [Token]
readPattern = (ParsecT String UserState (SCBase m) Token
readPatternWord forall {s} {m :: * -> *} {t} {u} {a} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`thenSkip` forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing) forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
`sepBy1` (forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'|' forall {s} {m :: * -> *} {t} {u} {a} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`thenSkip` forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing)

prop_readConditionCommand :: Bool
prop_readConditionCommand = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readConditionCommand String
"[[ x ]] > foo 2>&1"
readConditionCommand :: ParsecT String UserState (SCBase m) Token
readConditionCommand = do
    Token
cmd <- ParsecT String UserState (SCBase m) Token
readCondition
    [Token]
redirs <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String UserState (SCBase m) Token
readIoRedirect
    Id
id <- forall {m :: * -> *}.
Monad m =>
[Token] -> ParsecT String UserState (SCBase m) Id
getNextIdSpanningTokenList (Token
cmdforall a. a -> [a] -> [a]
:[Token]
redirs)

    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    Bool
hasDashAo <- forall {s} {m :: * -> *} {t} {u} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m Bool
isFollowedBy forall a b. (a -> b) -> a -> b
$ do
        String
c <- forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice forall a b. (a -> b) -> a -> b
$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [String
"-o", String
"-a", String
"or", String
"and"]
        SourcePos
posEnd <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAtWithEnd SourcePos
pos SourcePos
posEnd Severity
ErrorC Integer
1139 forall a b. (a -> b) -> a -> b
$
            String
"Use " forall a. [a] -> [a] -> [a]
++ ShowS
alt String
c forall a. [a] -> [a] -> [a]
++ String
" instead of '" forall a. [a] -> [a] -> [a]
++ String
c forall a. [a] -> [a] -> [a]
++ String
"' between test commands."

    -- If the next word is a keyword, readNormalWord will trigger a warning
    Bool
hasKeyword <- forall {s} {m :: * -> *} {t} {u} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m Bool
isFollowedBy forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readKeyword
    Bool
hasWord <- forall {s} {m :: * -> *} {t} {u} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m Bool
isFollowedBy ParsecT String UserState (SCBase m) Token
readNormalWord

    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
hasWord Bool -> Bool -> Bool
&& Bool -> Bool
not (Bool
hasKeyword Bool -> Bool -> Bool
|| Bool
hasDashAo)) forall a b. (a -> b) -> a -> b
$ do
        -- We have other words following, and no error has been emitted.
        SourcePos
posEnd <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAtWithEnd SourcePos
pos SourcePos
posEnd Severity
ErrorC Integer
1140 String
"Unexpected parameters after condition. Missing &&/||, or bad expression?"

    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token -> Token
T_Redirecting Id
id [Token]
redirs Token
cmd
  where
    alt :: ShowS
alt String
"or" = String
"||"
    alt String
"-o" = String
"||"
    alt String
"and" = String
"&&"
    alt String
"-a" = String
"&&"
    alt String
_ = String
"|| or &&"

prop_readCompoundCommand :: Bool
prop_readCompoundCommand = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCompoundCommand String
"{ echo foo; }>/dev/null"
readCompoundCommand :: ParsecT String UserState (SCBase m) Token
readCompoundCommand = do
    Token
cmd <- forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [
        ParsecT String UserState (SCBase m) Token
readBraceGroup,
        forall (m :: * -> *) p.
Monad m =>
String
-> SCParser m p
-> SCParser m p
-> (SourcePos -> SCParser m ())
-> SCParser m p
readAmbiguous String
"((" forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticExpression ParsecT String UserState (SCBase m) Token
readSubshell (\SourcePos
pos ->
            forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
pos Severity
ErrorC Integer
1105 String
"Shells disambiguate (( differently or not at all. For subshell, add spaces around ( . For ((, fix parsing errors."),
        ParsecT String UserState (SCBase m) Token
readSubshell,
        ParsecT String UserState (SCBase m) Token
readWhileClause,
        ParsecT String UserState (SCBase m) Token
readUntilClause,
        ParsecT String UserState (SCBase m) Token
readIfClause,
        ParsecT String UserState (SCBase m) Token
readForClause,
        ParsecT String UserState (SCBase m) Token
readSelectClause,
        ParsecT String UserState (SCBase m) Token
readCaseClause,
        ParsecT String UserState (SCBase m) Token
readBatsTest,
        ParsecT String UserState (SCBase m) Token
readFunctionDefinition
        ]
    [Token]
redirs <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String UserState (SCBase m) Token
readIoRedirect
    Id
id <- forall {m :: * -> *}.
Monad m =>
[Token] -> ParsecT String UserState (SCBase m) Id
getNextIdSpanningTokenList (Token
cmdforall a. a -> [a] -> [a]
:[Token]
redirs)
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ do
        forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readKeyword, forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Lbrace]
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String UserState (SCBase m) Token
readNormalWord
        SourcePos
posEnd <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAtWithEnd SourcePos
pos SourcePos
posEnd Severity
ErrorC Integer
1141 String
"Unexpected tokens after compound command. Bad redirection or missing ;/&&/||/|?"
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token -> Token
T_Redirecting Id
id [Token]
redirs Token
cmd


readCompoundList :: ParsecT String UserState (SCBase m) [Token]
readCompoundList = ParsecT String UserState (SCBase m) [Token]
readTerm
readCompoundListOrEmpty :: ParsecT String UserState (SCBase m) [Token]
readCompoundListOrEmpty = do
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    ParsecT String UserState (SCBase m) [Token]
readTerm forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return []

readCmdPrefix :: ParsecT String UserState (SCBase m) [Token]
readCmdPrefix = forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (ParsecT String UserState (SCBase m) Token
readIoRedirect forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readAssignmentWord)
readCmdSuffix :: ParsecT String UserState (SCBase m) [Token]
readCmdSuffix = forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (ParsecT String UserState (SCBase m) Token
readIoRedirect forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readCmdWord)
readModifierSuffix :: ParsecT String UserState (SCBase m) [Token]
readModifierSuffix = forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (ParsecT String UserState (SCBase m) Token
readIoRedirect forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readWellFormedAssignment forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readCmdWord)
readTimeSuffix :: ParsecT String UserState (SCBase m) [Token]
readTimeSuffix = do
    [Token]
flags <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String UserState (SCBase m) Token
readFlag
    Token
pipeline <- ParsecT String UserState (SCBase m) Token
readPipeline
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [Token]
flags forall a. [a] -> [a] -> [a]
++ [Token
pipeline]
  where
    -- This fails for quoted variables and such. Fixme?
    readFlag :: ParsecT String UserState (SCBase m) Token
readFlag = do
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'-'
        ParsecT String UserState (SCBase m) Token
readCmdWord

-- Fixme: this is a hack that doesn't handle let c='4'"5" or let a\>b
readLetSuffix :: Monad m => SCParser m [Token]
readLetSuffix :: forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Token]
readLetSuffix = forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIoRedirect forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readLetExpression forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCmdWord)
  where
    readLetExpression :: Monad m => SCParser m Token
    readLetExpression :: forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readLetExpression = do
        SourcePos
startPos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        String
expression <- forall {s} {m :: * -> *} {s} {u} {a}.
(Stream s m Char, MonadState s m) =>
ParsecT s u m a -> ParsecT s u m String
readStringForParser forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCmdWord
        let (String
unQuoted, SourcePos
newPos) = String -> SourcePos -> (String, SourcePos)
kludgeAwayQuotes String
expression SourcePos
startPos
        forall {m :: * -> *} {a} {u} {b}.
Monad m =>
SourcePos -> ParsecT a u m b -> a -> ParsecT a u m b
subParse SourcePos
newPos (forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof) String
unQuoted

    kludgeAwayQuotes :: String -> SourcePos -> (String, SourcePos)
    kludgeAwayQuotes :: String -> SourcePos -> (String, SourcePos)
kludgeAwayQuotes String
s SourcePos
p =
        case String
s of
            Char
first:rest :: String
rest@(Char
_:String
_) ->
                let (Char
last:String
backwards) = forall a. [a] -> [a]
reverse String
rest
                    middle :: String
middle = forall a. [a] -> [a]
reverse String
backwards
                in
                    if Char
first forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
"'\"" Bool -> Bool -> Bool
&& Char
first forall a. Eq a => a -> a -> Bool
== Char
last
                    then (String
middle, SourcePos -> Char -> SourcePos
updatePosChar SourcePos
p Char
first)
                    else (String
s, SourcePos
p)
            String
x -> (String
s, SourcePos
p)


-- bash allows a=(b), ksh allows $a=(b). dash allows neither. Let's warn.
readEvalSuffix :: ParsecT String UserState (SCBase m) [Token]
readEvalSuffix = forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (ParsecT String UserState (SCBase m) Token
readIoRedirect forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readCmdWord forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s} {m :: * -> *} {m :: * -> *} {u} {b}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m b
evalFallback)
  where
    evalFallback :: ParsecT s u m b
evalFallback = do
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'('
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
WarningC Integer
1098 String
"Quote/escape special characters when using eval, e.g. eval \"a=(b)\"."
        forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Unexpected parentheses. Make sure to quote when eval'ing as shell parsers differ."

-- Get whatever a parser would parse as a string
readStringForParser :: ParsecT s u m a -> ParsecT s u m String
readStringForParser ParsecT s u m a
parser = do
    SourcePos
pos <- forall {s} {m :: * -> *} {s} {u} {b}.
MonadState s m =>
ParsecT s u m b -> ParsecT s u m b
inSeparateContext forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT s u m a
parser forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition)
    forall {s} {m :: * -> *} {u}.
Stream s m Char =>
SourcePos -> ParsecT s u m String
readUntil SourcePos
pos
  where
    readUntil :: SourcePos -> ParsecT s u m String
readUntil SourcePos
endPos = forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar forall {s} {m :: * -> *} {t} {u} {a} {a}.
(Stream s m t, Show t) =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m [a]
`reluctantlyTill` (forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (f :: * -> *). Alternative f => Bool -> f ()
guard forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Eq a => a -> a -> Bool
== SourcePos
endPos))

-- Like readStringForParser, returning the span as a T_Literal
readLiteralForParser :: ParsecT s UserState m a -> ParsecT s UserState m Token
readLiteralForParser ParsecT s UserState m a
parser = do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    String
str <- forall {s} {m :: * -> *} {s} {u} {a}.
(Stream s m Char, MonadState s m) =>
ParsecT s u m a -> ParsecT s u m String
readStringForParser ParsecT s UserState m a
parser
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
str

prop_readAssignmentWord :: Bool
prop_readAssignmentWord = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readAssignmentWord String
"a=42"
prop_readAssignmentWord2 :: Bool
prop_readAssignmentWord2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readAssignmentWord String
"b=(1 2 3)"
prop_readAssignmentWord5 :: Bool
prop_readAssignmentWord5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readAssignmentWord String
"b+=lol"
prop_readAssignmentWord7 :: Bool
prop_readAssignmentWord7 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readAssignmentWord String
"a[3$n'']=42"
prop_readAssignmentWord8 :: Bool
prop_readAssignmentWord8 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readAssignmentWord String
"a[4''$(cat foo)]=42"
prop_readAssignmentWord9 :: Bool
prop_readAssignmentWord9 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readAssignmentWord String
"IFS= "
prop_readAssignmentWord9a :: Bool
prop_readAssignmentWord9a = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readAssignmentWord String
"foo="
prop_readAssignmentWord9b :: Bool
prop_readAssignmentWord9b = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readAssignmentWord String
"foo=  "
prop_readAssignmentWord9c :: Bool
prop_readAssignmentWord9c = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readAssignmentWord String
"foo=  #bar"
prop_readAssignmentWord11 :: Bool
prop_readAssignmentWord11 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readAssignmentWord String
"foo=([a]=b [c] [d]= [e f )"
prop_readAssignmentWord12 :: Bool
prop_readAssignmentWord12 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readAssignmentWord String
"a[b <<= 3 + c]='thing'"
prop_readAssignmentWord13 :: Bool
prop_readAssignmentWord13 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readAssignmentWord String
"var=( (1 2) (3 4) )"
prop_readAssignmentWord14 :: Bool
prop_readAssignmentWord14 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readAssignmentWord String
"var=( 1 [2]=(3 4) )"
prop_readAssignmentWord15 :: Bool
prop_readAssignmentWord15 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readAssignmentWord String
"var=(1 [2]=(3 4))"
readAssignmentWord :: ParsecT String UserState (SCBase m) Token
readAssignmentWord = Bool -> ParsecT String UserState (SCBase m) Token
readAssignmentWordExt Bool
True
readWellFormedAssignment :: ParsecT String UserState (SCBase m) Token
readWellFormedAssignment = Bool -> ParsecT String UserState (SCBase m) Token
readAssignmentWordExt Bool
False
readAssignmentWordExt :: Bool -> ParsecT String UserState (SCBase m) Token
readAssignmentWordExt Bool
lenient = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"variable assignment" forall a b. (a -> b) -> a -> b
$ do
    -- Parse up to and including the = in a 'try'
    (Id
id, String
variable, AssignmentMode
op, [Token]
indices) <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        -- Check for a leading $ at parse time, to warn for $foo=(bar) which
        -- would otherwise cause a parse failure so it can't be checked later.
        Maybe (SourcePos, SourcePos)
leadingDollarPos <-
            if Bool
lenient
            then forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
optionMaybe forall a b. (a -> b) -> a -> b
$ forall {m :: * -> *} {s} {u} {a}.
Monad m =>
ParsecT s u m a -> ParsecT s u m (SourcePos, SourcePos)
getSpanPositionsFor (forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'$')
            else forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
        String
variable <- forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readVariableName
        [Token]
indices <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String UserState (SCBase m) Token
readArrayIndex
        Bool
hasLeftSpace <- forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> Bool
null) forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
        SourcePos
opStart <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        AssignmentMode
op <- forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m AssignmentMode
readAssignmentOp
        SourcePos
opEnd <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition

        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (forall a. Maybe a -> Bool
isJust Maybe (SourcePos, SourcePos)
leadingDollarPos Bool -> Bool -> Bool
|| Bool
hasLeftSpace) forall a b. (a -> b) -> a -> b
$ do
            Bool
hasParen <- forall {s} {m :: * -> *} {t} {u} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m Bool
isFollowedBy (forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'(')
            forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
hasParen forall a b. (a -> b) -> a -> b
$
                forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_ forall a b. (a -> b) -> a -> b
$ do
                    (SourcePos
l, SourcePos
r) <- Maybe (SourcePos, SourcePos)
leadingDollarPos
                    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAtWithEnd SourcePos
l SourcePos
r Severity
ErrorC Integer
1066 String
"Don't use $ on the left side of assignments."

            -- Fail so that this is not parsed as an assignment.
            forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
""
        -- At this point we know for sure.
        forall (m :: * -> *) a. Monad m => a -> m a
return (Id
id, String
variable, AssignmentMode
op, [Token]
indices)

    SourcePos
rightPosStart <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    Bool
hasRightSpace <- forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> Bool
null) forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
    SourcePos
rightPosEnd <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    Bool
isEndOfCommand <- forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Maybe a -> Bool
isJust forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
optionMaybe (forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ (forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"\r\n;&|)") forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof))

    if Bool
hasRightSpace Bool -> Bool -> Bool
|| Bool
isEndOfCommand
      then do
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String
variable forall a. Eq a => a -> a -> Bool
/= String
"IFS" Bool -> Bool -> Bool
&& Bool
hasRightSpace Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
isEndOfCommand) forall a b. (a -> b) -> a -> b
$ do
            forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAtWithEnd SourcePos
rightPosStart SourcePos
rightPosEnd Severity
WarningC Integer
1007
                String
"Remove space after = if trying to assign a value (for empty string, use var='' ... )."
        Token
value <- forall {m :: * -> *} {s}. Monad m => ParsecT s UserState m Token
readEmptyLiteral
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> AssignmentMode -> String -> [Token] -> Token -> Token
T_Assignment Id
id AssignmentMode
op String
variable [Token]
indices Token
value
      else do
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ do
            forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'='
            forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1097 String
"Unexpected ==. For assignment, use =. For comparison, use [/[[. Or quote for literal string."

        Token
value <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArray forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readNormalWord
        forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> AssignmentMode -> String -> [Token] -> Token -> Token
T_Assignment Id
id AssignmentMode
op String
variable [Token]
indices Token
value
  where
    readAssignmentOp :: ParsecT s u m AssignmentMode
readAssignmentOp = do
        -- This is probably some kind of ascii art border
        forall {s} {u} {m :: * -> *} {a}.
String -> ParsecT s u m a -> ParsecT s u m ()
unexpecting String
"===" (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"===")
        forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [
            forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"+=" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return AssignmentMode
Append,
            forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"=" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return AssignmentMode
Assign
            ]

readEmptyLiteral :: ParsecT s UserState m Token
readEmptyLiteral = do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
""

readArrayIndex :: ParsecT String UserState (SCBase m) Token
readArrayIndex = do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'['
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    String
str <- forall {s} {m :: * -> *} {s} {u} {a}.
(Stream s m Char, MonadState s m) =>
ParsecT s u m a -> ParsecT s u m String
readStringForParser ParsecT String UserState (SCBase m) Token
readIndexSpan
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
']'
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> SourcePos -> String -> Token
T_UnparsedIndex Id
id SourcePos
pos String
str

readArray :: Monad m => SCParser m Token
readArray :: forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArray = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"array assignment" forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    SourcePos
opening <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'('
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ do
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'('
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
opening Severity
ErrorC Integer
1116 String
"Missing $ on a $((..)) expression? (or use ( ( for arrays)."
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    [Token]
words <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readElement forall {s} {m :: * -> *} {t} {u} {a} {a}.
(Stream s m t, Show t) =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m [a]
`reluctantlyTill` forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')'
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')' forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected ) to close array assignment"
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_Array Id
id [Token]
words
  where
    readElement :: ParsecT String UserState (SCBase m) Token
readElement = (forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIndexed forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readRegular) forall {s} {m :: * -> *} {t} {u} {a} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`thenSkip` forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    readIndexed :: ParsecT String UserState (SCBase m) Token
readIndexed = do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        [Token]
index <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
            [Token]
x <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArrayIndex
            forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'='
            forall (m :: * -> *) a. Monad m => a -> m a
return [Token]
x
        Token
value <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readRegular forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *} {s}. Monad m => ParsecT s UserState m Token
nothing
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token -> Token
T_IndexedElement Id
id [Token]
index Token
value
    readRegular :: ParsecT String UserState (SCBase m) Token
readRegular = forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArray forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord

    nothing :: ParsecT s UserState m Token
nothing = do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
""

tryToken :: String -> (Id -> a) -> ParsecT s UserState m a
tryToken String
s Id -> a
t = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
s
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> a
t Id
id

redirToken :: Char -> (Id -> a) -> ParsecT s UserState m a
redirToken Char
c Id -> a
t = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
c
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'('
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> a
t Id
id

tryWordToken :: String -> (Id -> a) -> ParsecT String UserState (SCBase m) a
tryWordToken String
s Id -> a
t = forall {m :: * -> *} {a}.
Monad m =>
String -> (Id -> a) -> ParsecT String UserState (SCBase m) a
tryParseWordToken String
s Id -> a
t forall {s} {m :: * -> *} {t} {u} {a} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`thenSkip` forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing
tryParseWordToken :: String -> (Id -> a) -> ParsecT String UserState (SCBase m) a
tryParseWordToken String
keyword Id -> a
t = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    String
str <- forall {t :: * -> *} {s} {m :: * -> *} {u}.
(Traversable t, Stream s m Char) =>
t Char -> ParsecT s u m (t Char)
anycaseString String
keyword
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start

    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall a b. (a -> b) -> a -> b
$ do
        Char
c <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar
        let warning :: Integer -> ParsecT s u m ()
warning Integer
code = forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
code forall a b. (a -> b) -> a -> b
$ String
"You need a space before the " forall a. [a] -> [a] -> [a]
++ [Char
c] forall a. [a] -> [a] -> [a]
++ String
"."
        case Char
c of
            Char
'[' -> forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Integer -> ParsecT s u m ()
warning Integer
1069
            Char
'#' -> forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Integer -> ParsecT s u m ()
warning Integer
1099
            Char
'!' -> forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Integer -> ParsecT s u m ()
warning Integer
1129
            Char
':' -> forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Integer -> ParsecT s u m ()
warning Integer
1130
            Char
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return ()

    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
keywordSeparator
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String
str forall a. Eq a => a -> a -> Bool
/= String
keyword) forall a b. (a -> b) -> a -> b
$ do
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1081 forall a b. (a -> b) -> a -> b
$
            String
"Scripts are case sensitive. Use '" forall a. [a] -> [a] -> [a]
++ String
keyword forall a. [a] -> [a] -> [a]
++ String
"', not '" forall a. [a] -> [a] -> [a]
++ String
str forall a. [a] -> [a] -> [a]
++ String
"' (or quote if literal)."
        forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
""
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> a
t Id
id

anycaseString :: t Char -> ParsecT s u m (t Char)
anycaseString =
    forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
anycaseChar
  where
    anycaseChar :: Char -> ParsecT s u m Char
anycaseChar Char
c = forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char (Char -> Char
toLower Char
c) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char (Char -> Char
toUpper Char
c)

g_AND_IF :: ParsecT s UserState m Token
g_AND_IF = forall {m :: * -> *} {s} {m :: * -> *} {a}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
String -> (Id -> a) -> ParsecT s UserState m a
tryToken String
"&&" Id -> Token
T_AND_IF
g_OR_IF :: ParsecT s UserState m Token
g_OR_IF = forall {m :: * -> *} {s} {m :: * -> *} {a}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
String -> (Id -> a) -> ParsecT s UserState m a
tryToken String
"||" Id -> Token
T_OR_IF
g_DSEMI :: ParsecT s UserState m Token
g_DSEMI = forall {m :: * -> *} {s} {m :: * -> *} {a}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
String -> (Id -> a) -> ParsecT s UserState m a
tryToken String
";;" Id -> Token
T_DSEMI
g_DLESS :: ParsecT s UserState m Token
g_DLESS = forall {m :: * -> *} {s} {m :: * -> *} {a}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
String -> (Id -> a) -> ParsecT s UserState m a
tryToken String
"<<" Id -> Token
T_DLESS
g_DGREAT :: ParsecT s UserState m Token
g_DGREAT = forall {m :: * -> *} {s} {m :: * -> *} {a}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
String -> (Id -> a) -> ParsecT s UserState m a
tryToken String
">>" Id -> Token
T_DGREAT
g_LESSAND :: ParsecT s UserState m Token
g_LESSAND = forall {m :: * -> *} {s} {m :: * -> *} {a}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
String -> (Id -> a) -> ParsecT s UserState m a
tryToken String
"<&" Id -> Token
T_LESSAND
g_GREATAND :: ParsecT s UserState m Token
g_GREATAND = forall {m :: * -> *} {s} {m :: * -> *} {a}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
String -> (Id -> a) -> ParsecT s UserState m a
tryToken String
">&" Id -> Token
T_GREATAND
g_LESSGREAT :: ParsecT s UserState m Token
g_LESSGREAT = forall {m :: * -> *} {s} {m :: * -> *} {a}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
String -> (Id -> a) -> ParsecT s UserState m a
tryToken String
"<>" Id -> Token
T_LESSGREAT
g_DLESSDASH :: ParsecT s UserState m Token
g_DLESSDASH = forall {m :: * -> *} {s} {m :: * -> *} {a}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
String -> (Id -> a) -> ParsecT s UserState m a
tryToken String
"<<-" Id -> Token
T_DLESSDASH
g_CLOBBER :: ParsecT s UserState m Token
g_CLOBBER = forall {m :: * -> *} {s} {m :: * -> *} {a}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
String -> (Id -> a) -> ParsecT s UserState m a
tryToken String
">|" Id -> Token
T_CLOBBER
g_OPERATOR :: ParsecT s UserState m Token
g_OPERATOR = forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_AND_IF forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_OR_IF forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_DSEMI forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_DLESSDASH forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_DLESS forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_DGREAT forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_LESSAND forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_GREATAND forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_LESSGREAT

g_If :: ParsecT String UserState (SCBase m) Token
g_If = forall {m :: * -> *} {a}.
Monad m =>
String -> (Id -> a) -> ParsecT String UserState (SCBase m) a
tryWordToken String
"if" Id -> Token
T_If
g_Then :: ParsecT String UserState (SCBase m) Token
g_Then = forall {m :: * -> *} {a}.
Monad m =>
String -> (Id -> a) -> ParsecT String UserState (SCBase m) a
tryWordToken String
"then" Id -> Token
T_Then
g_Else :: ParsecT String UserState (SCBase m) Token
g_Else = forall {m :: * -> *} {a}.
Monad m =>
String -> (Id -> a) -> ParsecT String UserState (SCBase m) a
tryWordToken String
"else" Id -> Token
T_Else
g_Elif :: ParsecT String UserState (SCBase m) Token
g_Elif = forall {m :: * -> *} {a}.
Monad m =>
String -> (Id -> a) -> ParsecT String UserState (SCBase m) a
tryWordToken String
"elif" Id -> Token
T_Elif
g_Fi :: ParsecT String UserState (SCBase m) Token
g_Fi = forall {m :: * -> *} {a}.
Monad m =>
String -> (Id -> a) -> ParsecT String UserState (SCBase m) a
tryWordToken String
"fi" Id -> Token
T_Fi
g_Do :: ParsecT String UserState (SCBase m) Token
g_Do = forall {m :: * -> *} {a}.
Monad m =>
String -> (Id -> a) -> ParsecT String UserState (SCBase m) a
tryWordToken String
"do" Id -> Token
T_Do
g_Done :: ParsecT String UserState (SCBase m) Token
g_Done = forall {m :: * -> *} {a}.
Monad m =>
String -> (Id -> a) -> ParsecT String UserState (SCBase m) a
tryWordToken String
"done" Id -> Token
T_Done
g_Case :: ParsecT String UserState (SCBase m) Token
g_Case = forall {m :: * -> *} {a}.
Monad m =>
String -> (Id -> a) -> ParsecT String UserState (SCBase m) a
tryWordToken String
"case" Id -> Token
T_Case
g_Esac :: ParsecT String UserState (SCBase m) Token
g_Esac = forall {m :: * -> *} {a}.
Monad m =>
String -> (Id -> a) -> ParsecT String UserState (SCBase m) a
tryWordToken String
"esac" Id -> Token
T_Esac
g_While :: ParsecT String UserState (SCBase m) Token
g_While = forall {m :: * -> *} {a}.
Monad m =>
String -> (Id -> a) -> ParsecT String UserState (SCBase m) a
tryWordToken String
"while" Id -> Token
T_While
g_Until :: ParsecT String UserState (SCBase m) Token
g_Until = forall {m :: * -> *} {a}.
Monad m =>
String -> (Id -> a) -> ParsecT String UserState (SCBase m) a
tryWordToken String
"until" Id -> Token
T_Until
g_For :: ParsecT String UserState (SCBase m) Token
g_For = forall {m :: * -> *} {a}.
Monad m =>
String -> (Id -> a) -> ParsecT String UserState (SCBase m) a
tryWordToken String
"for" Id -> Token
T_For
g_Select :: ParsecT String UserState (SCBase m) Token
g_Select = forall {m :: * -> *} {a}.
Monad m =>
String -> (Id -> a) -> ParsecT String UserState (SCBase m) a
tryWordToken String
"select" Id -> Token
T_Select
g_In :: ParsecT String UserState (SCBase m) Token
g_In = forall {m :: * -> *} {a}.
Monad m =>
String -> (Id -> a) -> ParsecT String UserState (SCBase m) a
tryWordToken String
"in" Id -> Token
T_In forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m ()
skipAnnotationAndWarn
g_Lbrace :: ParsecT String UserState (SCBase m) Token
g_Lbrace = forall {m :: * -> *} {a}.
Monad m =>
String -> (Id -> a) -> ParsecT String UserState (SCBase m) a
tryWordToken String
"{" Id -> Token
T_Lbrace
g_Rbrace :: ParsecT s UserState m Token
g_Rbrace = do -- handled specially due to ksh echo "${ foo; }bar"
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'}'
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> Token
T_Rbrace Id
id

g_Lparen :: ParsecT s UserState m Token
g_Lparen = forall {m :: * -> *} {s} {m :: * -> *} {a}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
String -> (Id -> a) -> ParsecT s UserState m a
tryToken String
"(" Id -> Token
T_Lparen
g_Rparen :: ParsecT s UserState m Token
g_Rparen = forall {m :: * -> *} {s} {m :: * -> *} {a}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
String -> (Id -> a) -> ParsecT s UserState m a
tryToken String
")" Id -> Token
T_Rparen
g_Bang :: ParsecT s UserState m Token
g_Bang = do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'!'
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall (f :: * -> *) a. Functor f => f a -> f ()
void forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m String
spacing1 forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1035
            String
"You are missing a required space after the !."
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> Token
T_Bang Id
id

g_Semi :: ParsecT s UserState m Token
g_Semi = do
    forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_DSEMI
    forall {m :: * -> *} {s} {m :: * -> *} {a}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
String -> (Id -> a) -> ParsecT s UserState m a
tryToken String
";" Id -> Token
T_Semi

keywordSeparator :: ParsecT String UserState (SCBase m) ()
keywordSeparator =
    forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacingOrFail) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
";()[<>&|")

readKeyword :: ParsecT String UserState (SCBase m) Token
readKeyword = forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [ forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Then, forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Else, forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Elif, forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Fi, forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Do, forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Done, forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Esac, forall {m :: * -> *} {s}.
Stream s m Char =>
ParsecT s UserState m Token
g_Rbrace, forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_Rparen, forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_DSEMI ]

ifParse :: ParsecT s u m a
-> ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
ifParse ParsecT s u m a
p ParsecT s u m a
t ParsecT s u m a
f =
    (forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT s u m a
p) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT s u m a
t) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m a
f

prop_readShebang1 :: Bool
prop_readShebang1 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readShebang String
"#!/bin/sh\n"
prop_readShebang2 :: Bool
prop_readShebang2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readShebang String
"!# /bin/sh\n"
prop_readShebang3 :: Bool
prop_readShebang3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isNotOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readShebang String
"#shellcheck shell=/bin/sh\n"
prop_readShebang4 :: Bool
prop_readShebang4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readShebang String
"! /bin/sh"
prop_readShebang5 :: Bool
prop_readShebang5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readShebang String
"\n#!/bin/sh"
prop_readShebang6 :: Bool
prop_readShebang6 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readShebang String
" # Copyright \n!#/bin/bash"
prop_readShebang7 :: Bool
prop_readShebang7 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isNotOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readShebang String
"# Copyright \nfoo\n#!/bin/bash"
readShebang :: ParsecT String UserState (SCBase m) Token
readShebang = do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
anyShebang forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m ()
readMissingBang forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
withHeader
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Char
linewhitespace
    String
str <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
"\r\n"
    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall {m :: * -> *} {s} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m Char
carriageReturn
    forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall (m :: * -> *). Monad m => SCParser m Char
linefeed
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
str
  where
    anyShebang :: ParsecT String UserState (SCBase m) ()
anyShebang = forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try [
        forall {s} {m :: * -> *} {u}. Stream s m Char => ParsecT s u m ()
readCorrect,
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readSwapped,
        forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m ()
readTooManySpaces,
        forall {m :: * -> *} {m :: * -> *} {s}.
(MonadReader (Environment m) m, MonadState SystemState m,
 Stream s m Char) =>
ParsecT s UserState m ()
readMissingHash
        ]
    readCorrect :: ParsecT s u m ()
readCorrect = forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"#!"

    readSwapped :: ParsecT String UserState (SCBase m) ()
readSwapped = do
        IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"!#"
        Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId Id
id Severity
ErrorC Integer
1084
            String
"Use #!, not !#, for the shebang."

    skipSpaces :: ParsecT s UserState m Bool
skipSpaces = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> Bool
null) forall a b. (a -> b) -> a -> b
$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Char
linewhitespace
    readTooManySpaces :: ParsecT s UserState m ()
readTooManySpaces = do
        SourcePos
startPos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        Bool
startSpaces <- forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Bool
skipSpaces
        forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'#'
        SourcePos
middlePos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        Bool
middleSpaces <- forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Bool
skipSpaces
        forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'!'
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
startSpaces forall a b. (a -> b) -> a -> b
$
            forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
startPos Severity
ErrorC Integer
1114
                String
"Remove leading spaces before the shebang."
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
middleSpaces forall a b. (a -> b) -> a -> b
$
            forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
middlePos Severity
ErrorC Integer
1115
                String
"Remove spaces between # and ! in the shebang."

    readMissingHash :: ParsecT s UserState m ()
readMissingHash = do
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'!'
        forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Char
ensurePathAhead
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1104
            String
"Use #!, not just !, for the shebang."

    readMissingBang :: ParsecT s UserState m ()
readMissingBang = do
        forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'#'
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Char
ensurePathAhead
        forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1113
            String
"Use #!, not just #, for the shebang."

    ensurePathAhead :: ParsecT s UserState m Char
ensurePathAhead = forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead forall a b. (a -> b) -> a -> b
$ do
        forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Char
linewhitespace
        forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'/'

    withHeader :: ParsecT String UserState (SCBase m) ()
withHeader = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 forall (m :: * -> *). Monad m => SCParser m Char
headerLine
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
anyShebang forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<*
            forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1128 String
"The shebang must be on the first line. Delete blanks and move comments."

    headerLine :: ParsecT String UserState (SCBase m) Char
headerLine = do
        forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
anyShebang
        forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Char
linewhitespace
        forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readAnyComment
        forall (m :: * -> *). Monad m => SCParser m Char
linefeed

verifyEof :: ParsecT String UserState (SCBase m) ()
verifyEof = forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [
        forall {s} {m :: * -> *} {t} {u} {a} {b}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
ifParsable forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadReader (Environment m) m,
 MonadState SystemState m) =>
ParsecT s UserState m Token
g_Lparen forall a b. (a -> b) -> a -> b
$
            forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1088 String
"Parsing stopped here. Invalid use of parentheses?",

        forall {s} {m :: * -> *} {t} {u} {a} {b}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
ifParsable forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readKeyword forall a b. (a -> b) -> a -> b
$
            forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1089 String
"Parsing stopped here. Is this keyword correctly matched up?",

        forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1070 String
"Parsing stopped here. Mismatched keywords or invalid parentheses?"
    ]
  where
    ifParsable :: ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
ifParsable ParsecT s u m a
p ParsecT s u m b
action = do
        forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead ParsecT s u m a
p)
        ParsecT s u m b
action


readConfigFile :: Monad m => FilePath -> SCParser m [Annotation]
readConfigFile :: forall (m :: * -> *). Monad m => String -> SCParser m [Annotation]
readConfigFile String
filename = do
    Bool
shouldIgnore <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
Mr.asks forall (m :: * -> *). Environment m -> Bool
ignoreRC
    if Bool
shouldIgnore then forall (m :: * -> *) a. Monad m => a -> m a
return [] else forall {m :: * -> *} {s} {u}.
Monad m =>
String
-> ParsecT
     s u (ReaderT (Environment m) (StateT SystemState m)) [Annotation]
read' String
filename
  where
    read' :: String
-> ParsecT
     s u (ReaderT (Environment m) (StateT SystemState m)) [Annotation]
read' String
filename = do
        SystemInterface m
sys <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
Mr.asks forall (m :: * -> *). Environment m -> SystemInterface m
systemInterface
        Maybe (String, String)
contents <- forall {t :: (* -> *) -> * -> *} {t :: (* -> *) -> * -> *}
       {t :: (* -> *) -> * -> *} {m :: * -> *} {a}.
(MonadTrans t, MonadTrans t, MonadTrans t, Monad m,
 Monad (t (t m)), Monad (t m)) =>
m a -> t (t (t m)) a
system forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
SystemInterface m -> String -> m (Maybe (String, String))
siGetConfig SystemInterface m
sys String
filename
        case Maybe (String, String)
contents of
            Maybe (String, String)
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return []
            Just (String
file, String
str) -> forall {m :: * -> *} {s} {u}.
Monad m =>
String -> String -> ParsecT s u (SCBase m) [Annotation]
readConfig String
file String
str

    readConfig :: String -> String -> ParsecT s u (SCBase m) [Annotation]
readConfig String
filename String
contents = do
        Either ParseError [Annotation]
result <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> u -> String -> s -> m (Either ParseError a)
runParserT forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readConfigKVs UserState
initialUserState String
filename String
contents
        case Either ParseError [Annotation]
result of
            Right [Annotation]
result ->
                forall (m :: * -> *) a. Monad m => a -> m a
return [Annotation]
result

            Left ParseError
err -> do
                forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1134 forall a b. (a -> b) -> a -> b
$ String -> ParseError -> String
errorFor String
filename ParseError
err
                forall (m :: * -> *) a. Monad m => a -> m a
return []

    errorFor :: String -> ParseError -> String
errorFor String
filename ParseError
err =
        let line :: String
line = String
"line " forall a. [a] -> [a] -> [a]
++ (forall a. Show a => a -> String
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. SourcePos -> Line
sourceLine forall a b. (a -> b) -> a -> b
$ ParseError -> SourcePos
errorPos ParseError
err)
            suggestion :: String
suggestion = [Message] -> String
getStringFromParsec forall a b. (a -> b) -> a -> b
$ ParseError -> [Message]
errorMessages ParseError
err
        in
            String
"Failed to process " forall a. [a] -> [a] -> [a]
++ (ShowS
e4m String
filename) forall a. [a] -> [a] -> [a]
++ String
", " forall a. [a] -> [a] -> [a]
++ String
line forall a. [a] -> [a] -> [a]
++ String
": "
                forall a. [a] -> [a] -> [a]
++ String
suggestion

prop_readConfigKVs1 :: Bool
prop_readConfigKVs1 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readConfigKVs String
"disable=1234"
prop_readConfigKVs2 :: Bool
prop_readConfigKVs2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readConfigKVs String
"# Comment\ndisable=1234 # Comment\n"
prop_readConfigKVs3 :: Bool
prop_readConfigKVs3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readConfigKVs String
""
prop_readConfigKVs4 :: Bool
prop_readConfigKVs4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readConfigKVs String
"\n\n\n\n\t \n"
prop_readConfigKVs5 :: Bool
prop_readConfigKVs5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readConfigKVs String
"# shellcheck accepts annotation-like comments in rc files\ndisable=1234"
readConfigKVs :: ParsecT String UserState (SCBase m) [Annotation]
readConfigKVs = do
    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [()]
anySpacingOrComment
    [[Annotation]]
annotations <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) [Annotation]
readAnnotationWithoutPrefix Bool
False forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [()]
anySpacingOrComment)
    forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Annotation]]
annotations
anySpacingOrComment :: ParsecT String UserState (SCBase m) [()]
anySpacingOrComment =
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (forall (f :: * -> *) a. Functor f => f a -> f ()
void forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacingOrFail forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (f :: * -> *) a. Functor f => f a -> f ()
void forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readAnyComment)

prop_readScript1 :: Bool
prop_readScript1 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"#!/bin/bash\necho hello world\n"
prop_readScript2 :: Bool
prop_readScript2 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"#!/bin/bash\r\necho hello world\n"
prop_readScript3 :: Bool
prop_readScript3 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"#!/bin/bash\necho hello\xA0world"
prop_readScript4 :: Bool
prop_readScript4 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"#!/usr/bin/perl\nfoo=("
prop_readScript5 :: Bool
prop_readScript5 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"#!/bin/bash\n#This is an empty script\n\n"
prop_readScript6 :: Bool
prop_readScript6 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"#!/usr/bin/env -S X=FOO bash\n#This is an empty script\n\n"
prop_readScript7 :: Bool
prop_readScript7 = forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"#!/bin/zsh\n# shellcheck disable=SC1071\nfor f (a b); echo $f\n"
readScriptFile :: Bool -> ParsecT String UserState (SCBase m) Token
readScriptFile Bool
sourced = do
    IncompleteInterval
start <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    [Annotation]
rcAnnotations <- if Bool
sourced
                     then forall (m :: * -> *) a. Monad m => a -> m a
return []
                     else do
                        String
filename <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
Mr.asks forall (m :: * -> *). Environment m -> String
currentFilename
                        forall (m :: * -> *). Monad m => String -> SCParser m [Annotation]
readConfigFile String
filename

    -- Put the rc annotations on the stack so that one can ignore e.g. SC1084 in .shellcheckrc
    forall {s} {m :: * -> *} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
[Annotation] -> ParsecT s u m b -> ParsecT s u m b
withAnnotations [Annotation]
rcAnnotations forall a b. (a -> b) -> a -> b
$ do
        Bool
hasBom <- forall {s} {m :: * -> *} {t} {u} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m Bool
wasIncluded forall {s} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m) =>
ParsecT s u m String
readUtf8Bom
        Token
shebang <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readShebang forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {m :: * -> *} {s}. Monad m => ParsecT s UserState m Token
readEmptyLiteral
        let (T_Literal Id
_ String
shebangString) = Token
shebang
        forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
        IncompleteInterval
annotationStart <- forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        [Annotation]
fileAnnotations <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotations

        -- Similarly put the filewide annotations on the stack to allow earlier suppression
        forall {s} {m :: * -> *} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
[Annotation] -> ParsecT s u m b -> ParsecT s u m b
withAnnotations [Annotation]
fileAnnotations forall a b. (a -> b) -> a -> b
$ do
            forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
hasBom) forall a b. (a -> b) -> a -> b
$
                forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1082
                    String
"This file has a UTF-8 BOM. Remove it with: LC_CTYPE=C sed '1s/^...//' < yourscript ."
            let annotations :: [Annotation]
annotations = [Annotation]
fileAnnotations forall a. [a] -> [a] -> [a]
++ [Annotation]
rcAnnotations
            Id
annotationId <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
annotationStart
            let shellAnnotationSpecified :: Bool
shellAnnotationSpecified =
                    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (\Annotation
x -> case Annotation
x of ShellOverride {} -> Bool
True; Annotation
_ -> Bool
False) [Annotation]
annotations
            Bool
shellFlagSpecified <- forall a. Maybe a -> Bool
isJust forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
Mr.asks forall (m :: * -> *). Environment m -> Maybe Shell
shellTypeOverride
            let ignoreShebang :: Bool
ignoreShebang = Bool
shellAnnotationSpecified Bool -> Bool -> Bool
|| Bool
shellFlagSpecified

            forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
ignoreShebang forall a b. (a -> b) -> a -> b
$
                forall {m :: * -> *} {m :: * -> *}.
(MonadReader (Environment m) m, MonadState SystemState m) =>
SourcePos -> String -> m ()
verifyShebang SourcePos
pos (ShowS
executableFromShebang String
shebangString)
            if Bool
ignoreShebang Bool -> Bool -> Bool
|| String -> Maybe Bool
isValidShell (ShowS
executableFromShebang String
shebangString) forall a. Eq a => a -> a -> Bool
/= forall a. a -> Maybe a
Just Bool
False
              then do
                    [Token]
commands <- forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Token]
readCompoundListOrEmpty
                    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
                    forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
verifyEof
                    let script :: Token
script = Id -> [Annotation] -> Token -> Token
T_Annotation Id
annotationId [Annotation]
annotations forall a b. (a -> b) -> a -> b
$
                                    Id -> Token -> [Token] -> Token
T_Script Id
id Token
shebang [Token]
commands
                    forall (m :: * -> *). Monad m => Token -> SCParser m Token
reparseIndices Token
script
                else do
                    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar
                    Id
id <- forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
                    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> Token -> [Token] -> Token
T_Script Id
id Token
shebang []

  where
    verifyShebang :: SourcePos -> String -> m ()
verifyShebang SourcePos
pos String
s = do
        case String -> Maybe Bool
isValidShell String
s of
            Just Bool
True -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
            Just Bool
False -> forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1071 String
"ShellCheck only supports sh/bash/dash/ksh scripts. Sorry!"
            Maybe Bool
Nothing -> forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1008 String
"This shebang was unrecognized. ShellCheck only supports sh/bash/dash/ksh. Add a 'shell' directive to specify."

    isValidShell :: String -> Maybe Bool
isValidShell String
s =
        let good :: Bool
good = forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
s Bool -> Bool -> Bool
|| forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
s) [String]
goodShells
            bad :: Bool
bad = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
s) [String]
badShells
        in
            if Bool
good
                then forall a. a -> Maybe a
Just Bool
True
                else if Bool
bad
                        then forall a. a -> Maybe a
Just Bool
False
                        else forall a. Maybe a
Nothing

    goodShells :: [String]
goodShells = [
        String
"sh",
        String
"ash",
        String
"dash",
        String
"bash",
        String
"bats",
        String
"ksh"
        ]
    badShells :: [String]
badShells = [
        String
"awk",
        String
"csh",
        String
"expect",
        String
"perl",
        String
"python",
        String
"ruby",
        String
"tcsh",
        String
"zsh"
        ]

    readUtf8Bom :: ParsecT s u m String
readUtf8Bom = forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"Byte Order Mark" forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"\xFEFF"

readScript :: ParsecT String UserState (SCBase m) Token
readScript = forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) Token
readScriptFile Bool
False

-- Interactively run a specific parser in ghci:
-- debugParse readSimpleCommand "echo 'hello world'"
debugParse :: SCParser Identity v -> String -> Either ParseError v
debugParse SCParser Identity v
p String
string = forall a. Identity a -> a
runIdentity forall a b. (a -> b) -> a -> b
$ do
    (Either ParseError v
res, SystemState
_) <- forall (m :: * -> *) v.
Monad m =>
Environment m
-> SCParser m v
-> String
-> String
-> m (Either ParseError v, SystemState)
runParser Environment Identity
testEnvironment SCParser Identity v
p String
"-" String
string
    forall (m :: * -> *) a. Monad m => a -> m a
return Either ParseError v
res

-- Interactively run the complete parser in ghci:
-- debugParseScript "#!/bin/bash\necho 'Hello World'\n"
debugParseScript :: String -> ParseResult
debugParseScript String
string =
    ParseResult
result {
        -- Remove the noisiest parts
        prTokenPositions :: Map Id (Position, Position)
prTokenPositions = forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [
            (Line -> Id
Id Line
0, (Position
newPosition {
                posFile :: String
posFile = String
"removed for clarity",
                posLine :: Integer
posLine = -Integer
1,
                posColumn :: Integer
posColumn = -Integer
1
            }, Position
newPosition {
                posFile :: String
posFile = String
"removed for clarity",
                posLine :: Integer
posLine = -Integer
1,
                posColumn :: Integer
posColumn = -Integer
1
            }))]
    }
  where
    result :: ParseResult
result = forall a. Identity a -> a
runIdentity forall a b. (a -> b) -> a -> b
$
        forall (m :: * -> *).
Monad m =>
SystemInterface m -> ParseSpec -> m ParseResult
parseScript ([(String, String)] -> SystemInterface Identity
mockedSystemInterface []) forall a b. (a -> b) -> a -> b
$ ParseSpec
newParseSpec {
            psFilename :: String
psFilename = String
"debug",
            psScript :: String
psScript = String
string
        }

testEnvironment :: Environment Identity
testEnvironment =
    Environment {
        systemInterface :: SystemInterface Identity
systemInterface = ([(String, String)] -> SystemInterface Identity
mockedSystemInterface []),
        checkSourced :: Bool
checkSourced = Bool
False,
        currentFilename :: String
currentFilename = String
"myscript",
        ignoreRC :: Bool
ignoreRC = Bool
False,
        shellTypeOverride :: Maybe Shell
shellTypeOverride = forall a. Maybe a
Nothing
    }


isOk :: ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) a
p String
s =      forall {a}.
ParsecT String UserState (SCBase Identity) a
-> String -> Maybe Bool
parsesCleanly ParsecT String UserState (SCBase Identity) a
p String
s forall a. Eq a => a -> a -> Bool
== forall a. a -> Maybe a
Just Bool
True   -- The string parses with no warnings
isWarning :: ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) a
p String
s = forall {a}.
ParsecT String UserState (SCBase Identity) a
-> String -> Maybe Bool
parsesCleanly ParsecT String UserState (SCBase Identity) a
p String
s forall a. Eq a => a -> a -> Bool
== forall a. a -> Maybe a
Just Bool
False  -- The string parses with warnings
isNotOk :: ParsecT String UserState (SCBase Identity) a -> String -> Bool
isNotOk ParsecT String UserState (SCBase Identity) a
p String
s =   forall {a}.
ParsecT String UserState (SCBase Identity) a
-> String -> Maybe Bool
parsesCleanly ParsecT String UserState (SCBase Identity) a
p String
s forall a. Eq a => a -> a -> Bool
== forall a. Maybe a
Nothing     -- The string does not parse

parsesCleanly :: ParsecT String UserState (SCBase Identity) a
-> String -> Maybe Bool
parsesCleanly ParsecT String UserState (SCBase Identity) a
parser String
string = forall a. Identity a -> a
runIdentity forall a b. (a -> b) -> a -> b
$ do
    (Either ParseError UserState
res, SystemState
sys) <- forall (m :: * -> *) v.
Monad m =>
Environment m
-> SCParser m v
-> String
-> String
-> m (Either ParseError v, SystemState)
runParser Environment Identity
testEnvironment
                    (ParsecT String UserState (SCBase Identity) a
parser forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState) String
"-" String
string
    case (Either ParseError UserState
res, SystemState
sys) of
        (Right UserState
userState, SystemState
systemState) ->
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> Bool
null forall a b. (a -> b) -> a -> b
$ UserState -> [ParseNote]
parseNotes UserState
userState forall a. [a] -> [a] -> [a]
++ SystemState -> [ParseNote]
parseProblems SystemState
systemState
        (Left ParseError
_, SystemState
_) -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing

parseWithNotes :: ParsecT s b m a -> ParsecT s b m (a, b)
parseWithNotes ParsecT s b m a
parser = do
    a
item <- ParsecT s b m a
parser
    b
state <- forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
    forall (m :: * -> *) a. Monad m => a -> m a
return (a
item, b
state)

compareNotes :: ParseNote -> ParseNote -> Ordering
compareNotes (ParseNote SourcePos
pos1 SourcePos
pos1' Severity
level1 Integer
_ String
s1) (ParseNote SourcePos
pos2 SourcePos
pos2' Severity
level2 Integer
_ String
s2) = forall a. Ord a => a -> a -> Ordering
compare (SourcePos
pos1, SourcePos
pos1', Severity
level1) (SourcePos
pos2, SourcePos
pos2', Severity
level2)
sortNotes :: [ParseNote] -> [ParseNote]
sortNotes = forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy ParseNote -> ParseNote -> Ordering
compareNotes


makeErrorFor :: ParseError -> ParseNote
makeErrorFor ParseError
parsecError =
    SourcePos
-> SourcePos -> Severity -> Integer -> String -> ParseNote
ParseNote SourcePos
pos SourcePos
pos Severity
ErrorC Integer
1072 forall a b. (a -> b) -> a -> b
$
        [Message] -> String
getStringFromParsec forall a b. (a -> b) -> a -> b
$ ParseError -> [Message]
errorMessages ParseError
parsecError
    where
      pos :: SourcePos
pos = ParseError -> SourcePos
errorPos ParseError
parsecError

getStringFromParsec :: [Message] -> String
getStringFromParsec [Message]
errors =
        case forall a b. (a -> b) -> [a] -> [b]
map Message -> Maybe String
f [Message]
errors of
            [Maybe String]
r -> [String] -> String
unwords (forall a. Line -> [a] -> [a]
take Line
1 forall a b. (a -> b) -> a -> b
$ forall a. [Maybe a] -> [a]
catMaybes forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [a]
reverse [Maybe String]
r)  forall a. [a] -> [a] -> [a]
++
                String
" Fix any mentioned problems and try again."
    where
        f :: Message -> Maybe String
f Message
err =
            case Message
err of
                UnExpect String
s    ->  forall a. Maybe a
Nothing -- Due to not knowing Parsec, none of these
                SysUnExpect String
s ->  forall a. Maybe a
Nothing -- are actually helpful. <?> has been hidden
                Expect String
s      ->  forall a. Maybe a
Nothing -- and we only show explicit fail statements.
                Message String
s     ->  if forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
s then forall a. Maybe a
Nothing else forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ String
s forall a. [a] -> [a] -> [a]
++ String
"."

runParser :: Monad m =>
    Environment m ->
    SCParser m v ->
    String ->
    String ->
    m (Either ParseError v, SystemState)

runParser :: forall (m :: * -> *) v.
Monad m =>
Environment m
-> SCParser m v
-> String
-> String
-> m (Either ParseError v, SystemState)
runParser Environment m
env SCParser m v
p String
filename String
contents =
    forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
Ms.runStateT
        (forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
Mr.runReaderT
            (forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> u -> String -> s -> m (Either ParseError a)
runParserT SCParser m v
p UserState
initialUserState String
filename String
contents)
            Environment m
env)
        SystemState
initialSystemState
system :: m a -> t (t (t m)) a
system = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift

parseShell :: Environment m -> String -> String -> m ParseResult
parseShell Environment m
env String
name String
contents = do
    (Either ParseError (Token, UserState)
result, SystemState
state) <- forall (m :: * -> *) v.
Monad m =>
Environment m
-> SCParser m v
-> String
-> String
-> m (Either ParseError v, SystemState)
runParser Environment m
env (forall {m :: * -> *} {s} {b} {a}.
Monad m =>
ParsecT s b m a -> ParsecT s b m (a, b)
parseWithNotes forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript) String
name String
contents
    case Either ParseError (Token, UserState)
result of
        Right (Token
script, UserState
userstate) ->
            forall (m :: * -> *) a. Monad m => a -> m a
return ParseResult
newParseResult {
                prComments :: [PositionedComment]
prComments = forall a b. (a -> b) -> [a] -> [b]
map ParseNote -> PositionedComment
toPositionedComment forall a b. (a -> b) -> a -> b
$ forall a. Eq a => [a] -> [a]
nub forall a b. (a -> b) -> a -> b
$ UserState -> [ParseNote]
parseNotes UserState
userstate forall a. [a] -> [a] -> [a]
++ SystemState -> [ParseNote]
parseProblems SystemState
state,
                prTokenPositions :: Map Id (Position, Position)
prTokenPositions = forall a b k. (a -> b) -> Map k a -> Map k b
Map.map (SourcePos, SourcePos) -> (Position, Position)
startEndPosToPos (UserState -> Map Id (SourcePos, SourcePos)
positionMap UserState
userstate),
                prRoot :: Maybe Token
prRoot = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$
                    Token -> Map Id [Token] -> Token
reattachHereDocs Token
script (UserState -> Map Id [Token]
hereDocMap UserState
userstate)
            }
        Left ParseError
err -> do
            let context :: [Context]
context = SystemState -> [Context]
contextStack SystemState
state
            forall (m :: * -> *) a. Monad m => a -> m a
return ParseResult
newParseResult {
                prComments :: [PositionedComment]
prComments =
                    forall a b. (a -> b) -> [a] -> [b]
map ParseNote -> PositionedComment
toPositionedComment forall a b. (a -> b) -> a -> b
$
                        (forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {t :: * -> *}. Foldable t => t Context -> ParseNote -> Bool
isIgnored [Context]
context) forall a b. (a -> b) -> a -> b
$
                            [Context] -> [ParseNote]
notesForContext [Context]
context
                            forall a. [a] -> [a] -> [a]
++ [ParseError -> ParseNote
makeErrorFor ParseError
err])
                        forall a. [a] -> [a] -> [a]
++ SystemState -> [ParseNote]
parseProblems SystemState
state,
                prTokenPositions :: Map Id (Position, Position)
prTokenPositions = forall k a. Map k a
Map.empty,
                prRoot :: Maybe Token
prRoot = forall a. Maybe a
Nothing
            }
  where
    -- A final pass for ignoring parse errors after failed parsing
    isIgnored :: t Context -> ParseNote -> Bool
isIgnored t Context
stack ParseNote
note = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Bool -> Integer -> Context -> Bool
contextItemDisablesCode Bool
False (ParseNote -> Integer
codeForParseNote ParseNote
note)) t Context
stack

notesForContext :: [Context] -> [ParseNote]
notesForContext [Context]
list = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall a b. (a -> b) -> a -> b
($) [Context -> ParseNote
first, Context -> ParseNote
second] forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> [a]
filter Context -> Bool
isName [Context]
list
  where
    isName :: Context -> Bool
isName (ContextName SourcePos
_ String
_) = Bool
True
    isName Context
_ = Bool
False
    first :: Context -> ParseNote
first (ContextName SourcePos
pos String
str) = SourcePos
-> SourcePos -> Severity -> Integer -> String -> ParseNote
ParseNote SourcePos
pos SourcePos
pos Severity
ErrorC Integer
1073 forall a b. (a -> b) -> a -> b
$
        String
"Couldn't parse this " forall a. [a] -> [a] -> [a]
++ String
str forall a. [a] -> [a] -> [a]
++ String
". Fix to allow more checks."
    second :: Context -> ParseNote
second (ContextName SourcePos
pos String
str) = SourcePos
-> SourcePos -> Severity -> Integer -> String -> ParseNote
ParseNote SourcePos
pos SourcePos
pos Severity
InfoC Integer
1009 forall a b. (a -> b) -> a -> b
$
        String
"The mentioned syntax error was in this " forall a. [a] -> [a] -> [a]
++ String
str forall a. [a] -> [a] -> [a]
++ String
"."

-- Go over all T_UnparsedIndex and reparse them as either arithmetic or text
-- depending on declare -A statements.
reparseIndices :: Token -> ParsecT String UserState (SCBase m) Token
reparseIndices Token
root = forall (m :: * -> *). Monad m => Token -> SCParser m Token
process Token
root
  where
    process :: Token -> ParsecT String UserState (SCBase m) Token
process = forall (m :: * -> *).
Monad m =>
(Token -> m ())
-> (Token -> m ()) -> (Token -> m Token) -> Token -> m Token
analyze forall (m :: * -> *). Monad m => Token -> m ()
blank forall (m :: * -> *). Monad m => Token -> m ()
blank Token -> ParsecT String UserState (SCBase m) Token
f
    associative :: [String]
associative = Token -> [String]
getAssociativeArrays Token
root
    isAssociative :: String -> Bool
isAssociative String
s = String
s forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
associative
    f :: Token -> ParsecT String UserState (SCBase m) Token
f (T_Assignment Id
id AssignmentMode
mode String
name [Token]
indices Token
value) = do
        [Token]
newIndices <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (String -> Token -> ParsecT String UserState (SCBase m) Token
fixAssignmentIndex String
name) [Token]
indices
        Token
newValue <- case Token
value of
            (T_Array Id
id2 [Token]
words) -> do
                [Token]
newWords <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (String -> Token -> ParsecT String UserState (SCBase m) Token
fixIndexElement String
name) [Token]
words
                forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_Array Id
id2 [Token]
newWords
            Token
x -> forall (m :: * -> *) a. Monad m => a -> m a
return Token
x
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> AssignmentMode -> String -> [Token] -> Token -> Token
T_Assignment Id
id AssignmentMode
mode String
name [Token]
newIndices Token
newValue
    f (TA_Variable Id
id String
name [Token]
indices) = do
        [Token]
newIndices <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (String -> Token -> ParsecT String UserState (SCBase m) Token
fixAssignmentIndex String
name) [Token]
indices
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> String -> [Token] -> Token
TA_Variable Id
id String
name [Token]
newIndices
    f Token
t = forall (m :: * -> *) a. Monad m => a -> m a
return Token
t

    fixIndexElement :: String -> Token -> ParsecT String UserState (SCBase m) Token
fixIndexElement String
name Token
word =
        case Token
word of
            T_IndexedElement Id
id [Token]
indices Token
value -> do
                [Token]
new <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (String -> Token -> ParsecT String UserState (SCBase m) Token
fixAssignmentIndex String
name) [Token]
indices
                forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token -> Token
T_IndexedElement Id
id [Token]
new Token
value
            Token
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return Token
word

    fixAssignmentIndex :: String -> Token -> ParsecT String UserState (SCBase m) Token
fixAssignmentIndex String
name Token
word =
        case Token
word of
            T_UnparsedIndex Id
id SourcePos
pos String
src -> do
                Token
idx <- forall {m :: * -> *}.
Monad m =>
String
-> SourcePos -> String -> ParsecT String UserState (SCBase m) Token
parsed String
name SourcePos
pos String
src
                Token -> ParsecT String UserState (SCBase m) Token
process Token
idx -- Recursively parse for cases like x[y[z=1]]=1
            Token
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return Token
word

    parsed :: String
-> SourcePos -> String -> ParsecT String UserState (SCBase m) Token
parsed String
name SourcePos
pos String
src =
        if String -> Bool
isAssociative String
name
        then forall {m :: * -> *} {a} {u} {b}.
Monad m =>
SourcePos -> ParsecT a u m b -> a -> ParsecT a u m b
subParse SourcePos
pos (forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"associative array index" forall a b. (a -> b) -> a -> b
$ forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIndexSpan) String
src
        else forall {m :: * -> *} {a} {u} {b}.
Monad m =>
SourcePos -> ParsecT a u m b -> a -> ParsecT a u m b
subParse SourcePos
pos (forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"arithmetic array index expression" forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
space forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents) String
src

reattachHereDocs :: Token -> Map Id [Token] -> Token
reattachHereDocs Token
root Map Id [Token]
map =
    (Token -> Token) -> Token -> Token
doTransform Token -> Token
f Token
root
  where
    f :: Token -> Token
f t :: Token
t@(T_HereDoc Id
id Dashed
dash Quoted
quote String
string []) = forall a. a -> Maybe a -> a
fromMaybe Token
t forall a b. (a -> b) -> a -> b
$ do
        [Token]
list <- forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Id
id Map Id [Token]
map
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Id -> Dashed -> Quoted -> String -> [Token] -> Token
T_HereDoc Id
id Dashed
dash Quoted
quote String
string [Token]
list
    f Token
t = Token
t

toPositionedComment :: ParseNote -> PositionedComment
toPositionedComment :: ParseNote -> PositionedComment
toPositionedComment (ParseNote SourcePos
start SourcePos
end Severity
severity Integer
code String
message) =
    PositionedComment
newPositionedComment {
        pcStartPos :: Position
pcStartPos = (SourcePos -> Position
posToPos SourcePos
start)
      , pcEndPos :: Position
pcEndPos = (SourcePos -> Position
posToPos SourcePos
end)
      , pcComment :: Comment
pcComment = Comment
newComment {
          cSeverity :: Severity
cSeverity = Severity
severity
        , cCode :: Integer
cCode = Integer
code
        , cMessage :: String
cMessage = String
message
      }
    }

posToPos :: SourcePos -> Position
posToPos :: SourcePos -> Position
posToPos SourcePos
sp = Position
newPosition {
    posFile :: String
posFile = SourcePos -> String
sourceName SourcePos
sp,
    posLine :: Integer
posLine = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ SourcePos -> Line
sourceLine SourcePos
sp,
    posColumn :: Integer
posColumn = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ SourcePos -> Line
sourceColumn SourcePos
sp
}

startEndPosToPos :: (SourcePos, SourcePos) -> (Position, Position)
startEndPosToPos :: (SourcePos, SourcePos) -> (Position, Position)
startEndPosToPos (SourcePos
s, SourcePos
e) = (SourcePos -> Position
posToPos SourcePos
s, SourcePos -> Position
posToPos SourcePos
e)

-- TODO: Clean up crusty old code that this is layered on top of
parseScript :: Monad m =>
        SystemInterface m -> ParseSpec -> m ParseResult
parseScript :: forall (m :: * -> *).
Monad m =>
SystemInterface m -> ParseSpec -> m ParseResult
parseScript SystemInterface m
sys ParseSpec
spec =
    forall {m :: * -> *}.
Monad m =>
Environment m -> String -> String -> m ParseResult
parseShell Environment m
env (ParseSpec -> String
psFilename ParseSpec
spec) (ParseSpec -> String
psScript ParseSpec
spec)
  where
    env :: Environment m
env = Environment {
        systemInterface :: SystemInterface m
systemInterface = SystemInterface m
sys,
        checkSourced :: Bool
checkSourced = ParseSpec -> Bool
psCheckSourced ParseSpec
spec,
        currentFilename :: String
currentFilename = ParseSpec -> String
psFilename ParseSpec
spec,
        ignoreRC :: Bool
ignoreRC = ParseSpec -> Bool
psIgnoreRC ParseSpec
spec,
        shellTypeOverride :: Maybe Shell
shellTypeOverride = ParseSpec -> Maybe Shell
psShellTypeOverride ParseSpec
spec
    }

-- Same as 'try' but emit syntax errors if the parse fails.
tryWithErrors :: Monad m => SCParser m v -> SCParser m v
tryWithErrors :: forall (m :: * -> *) v. Monad m => SCParser m v -> SCParser m v
tryWithErrors SCParser m v
parser = do
    UserState
userstate <- forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
    [Context]
oldContext <- forall {m :: * -> *}. MonadState SystemState m => m [Context]
getCurrentContexts
    String
input <- forall (m :: * -> *) s u. Monad m => ParsecT s u m s
getInput
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    Either ParseError (v, SourcePos, String, UserState)
result <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> u -> String -> s -> m (Either ParseError a)
runParserT (forall (m :: * -> *) s u. Monad m => SourcePos -> ParsecT s u m ()
setPosition SourcePos
pos forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {m :: * -> *} {c} {d} {a}.
Monad m =>
ParsecT c d m a -> ParsecT c d m (a, SourcePos, c, d)
getResult SCParser m v
parser) UserState
userstate (SourcePos -> String
sourceName SourcePos
pos) String
input
    case Either ParseError (v, SourcePos, String, UserState)
result of
        Right (v
result, SourcePos
endPos, String
endInput, UserState
endState) -> do
            -- 'many' objects if we don't consume anything at all, so read a dummy value
            forall (f :: * -> *) a. Functor f => f a -> f ()
void forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof
            forall (m :: * -> *) u s. Monad m => u -> ParsecT s u m ()
putState UserState
endState
            forall (m :: * -> *) s u. Monad m => SourcePos -> ParsecT s u m ()
setPosition SourcePos
endPos
            forall (m :: * -> *) s u. Monad m => s -> ParsecT s u m ()
setInput String
endInput
            forall (m :: * -> *) a. Monad m => a -> m a
return v
result

        Left ParseError
err -> do
            [Context]
newContext <- forall {m :: * -> *}. MonadState SystemState m => m [Context]
getCurrentContexts
            forall {m :: * -> *}. MonadState SystemState m => ParseNote -> m ()
addParseProblem forall a b. (a -> b) -> a -> b
$ ParseError -> ParseNote
makeErrorFor ParseError
err
            forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall {m :: * -> *}. MonadState SystemState m => ParseNote -> m ()
addParseProblem forall a b. (a -> b) -> a -> b
$ [Context] -> [ParseNote]
notesForContext [Context]
newContext
            forall {m :: * -> *}. MonadState SystemState m => [Context] -> m ()
setCurrentContexts [Context]
oldContext
            forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
""
  where
    getResult :: ParsecT c d m a -> ParsecT c d m (a, SourcePos, c, d)
getResult ParsecT c d m a
p = do
        a
result <- ParsecT c d m a
p
        SourcePos
endPos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        c
endInput <- forall (m :: * -> *) s u. Monad m => ParsecT s u m s
getInput
        d
endState <- forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
        forall (m :: * -> *) a. Monad m => a -> m a
return (a
result, SourcePos
endPos, c
endInput, d
endState)

return []
runTests :: IO Bool
runTests = $Bool
String
[(String, Property)]
[(String, Property)] -> (Property -> IO Result) -> IO Bool
forall prop. Testable prop => prop -> IO Result
forall prop. Testable prop => prop -> Property
runQuickCheckAll :: [(String, Property)] -> (Property -> IO Result) -> IO Bool
property :: forall prop. Testable prop => prop -> Property
quickCheckResult :: forall prop. Testable prop => prop -> IO Result
prop_readScript7 :: Bool
prop_readScript6 :: Bool
prop_readScript5 :: Bool
prop_readScript4 :: Bool
prop_readScript3 :: Bool
prop_readScript2 :: Bool
prop_readScript1 :: Bool
prop_readConfigKVs5 :: Bool
prop_readConfigKVs4 :: Bool
prop_readConfigKVs3 :: Bool
prop_readConfigKVs2 :: Bool
prop_readConfigKVs1 :: Bool
prop_readShebang7 :: Bool
prop_readShebang6 :: Bool
prop_readShebang5 :: Bool
prop_readShebang4 :: Bool
prop_readShebang3 :: Bool
prop_readShebang2 :: Bool
prop_readShebang1 :: Bool
prop_readAssignmentWord15 :: Bool
prop_readAssignmentWord14 :: Bool
prop_readAssignmentWord13 :: Bool
prop_readAssignmentWord12 :: Bool
prop_readAssignmentWord11 :: Bool
prop_readAssignmentWord9c :: Bool
prop_readAssignmentWord9b :: Bool
prop_readAssignmentWord9a :: Bool
prop_readAssignmentWord9 :: Bool
prop_readAssignmentWord8 :: Bool
prop_readAssignmentWord7 :: Bool
prop_readAssignmentWord5 :: Bool
prop_readAssignmentWord2 :: Bool
prop_readAssignmentWord :: Bool
prop_readCompoundCommand :: Bool
prop_readConditionCommand :: Bool
prop_readCoProc3 :: Bool
prop_readCoProc2 :: Bool
prop_readCoProc1 :: Bool
prop_readFunctionDefinition13 :: Bool
prop_readFunctionDefinition12 :: Bool
prop_readFunctionDefinition11 :: Bool
prop_readFunctionDefinition10 :: Bool
prop_readFunctionDefinition9 :: Bool
prop_readFunctionDefinition8 :: Bool
prop_readFunctionDefinition7 :: Bool
prop_readFunctionDefinition6 :: Bool
prop_readFunctionDefinition5 :: Bool
prop_readFunctionDefinition4 :: Bool
prop_readFunctionDefinition1 :: Bool
prop_readFunctionDefinition :: Bool
prop_readCaseClause6 :: Bool
prop_readCaseClause5 :: Bool
prop_readCaseClause4 :: Bool
prop_readCaseClause3 :: Bool
prop_readCaseClause2 :: Bool
prop_readCaseClause :: Bool
prop_readSelectClause2 :: Bool
prop_readSelectClause1 :: Bool
prop_readForClause13 :: Bool
prop_readForClause12 :: Bool
prop_readForClause10 :: Bool
prop_readForClause9 :: Bool
prop_readForClause8 :: Bool
prop_readForClause7 :: Bool
prop_readForClause6 :: Bool
prop_readForClause5 :: Bool
prop_readForClause4 :: Bool
prop_readForClause3 :: Bool
prop_readForClause1 :: Bool
prop_readForClause :: Bool
prop_readUntilClause :: Bool
prop_readWhileClause :: Bool
prop_readBatsTest4 :: Bool
prop_readBatsTest3 :: Bool
prop_readBatsTest2 :: Bool
prop_readBatsTest1 :: Bool
prop_readBraceGroup3 :: Bool
prop_readBraceGroup2 :: Bool
prop_readBraceGroup :: Bool
prop_readSubshell :: Bool
prop_readIfClause6 :: Bool
prop_readIfClause5 :: Bool
prop_readIfClause4 :: Bool
prop_readIfClause3 :: Bool
prop_readIfClause2 :: Bool
prop_readIfClause :: Bool
prop_readTerm :: Bool
prop_readAndOr2 :: Bool
prop_readAndOr1 :: Bool
prop_readAndOr :: Bool
prop_readPipeline3 :: Bool
prop_readPipeline2 :: Bool
prop_readPipeline :: Bool
prop_readSimpleCommand15 :: Bool
prop_readSimpleCommand14 :: Bool
prop_readSimpleCommand13 :: Bool
prop_readSimpleCommand12 :: Bool
prop_readSimpleCommand11 :: Bool
prop_readSimpleCommand10 :: Bool
prop_readSimpleCommand9 :: Bool
prop_readSimpleCommand8 :: Bool
prop_readSimpleCommand7b :: Bool
prop_readSimpleCommand7 :: Bool
prop_readSimpleCommand6 :: Bool
prop_readSimpleCommand5 :: Bool
prop_readSimpleCommand4 :: Bool
prop_readSimpleCommand3 :: Bool
prop_readSimpleCommand2 :: Bool
prop_readSimpleCommand :: Bool
prop_readSeparator5 :: Bool
prop_readSeparator4 :: Bool
prop_readSeparator3 :: Bool
prop_readSeparator2 :: Bool
prop_readSeparator1 :: Bool
prop_readNewlineList1 :: Bool
prop_readHereString :: Bool
prop_readIoRedirect7 :: Bool
prop_readIoRedirect6 :: Bool
prop_readIoRedirect5 :: Bool
prop_readIoRedirect4 :: Bool
prop_readIoRedirect3 :: Bool
prop_readIoRedirect2 :: Bool
prop_readIoRedirect :: Bool
prop_readIoFile :: Bool
prop_readHereDoc23 :: Bool
prop_readHereDoc22 :: Bool
prop_readHereDoc21 :: Bool
prop_readHereDoc20 :: Bool
prop_readHereDoc18 :: Bool
prop_readHereDoc17 :: Bool
prop_readHereDoc16 :: Bool
prop_readHereDoc15 :: Bool
prop_readHereDoc14 :: Bool
prop_readHereDoc13 :: Bool
prop_readHereDoc12 :: Bool
prop_readHereDoc11 :: Bool
prop_readHereDoc10 :: Bool
prop_readHereDoc9 :: Bool
prop_readHereDoc8 :: Bool
prop_readHereDoc7 :: Bool
prop_readHereDoc6 :: Bool
prop_readHereDoc5 :: Bool
prop_readHereDoc4 :: Bool
prop_readHereDoc3 :: Bool
prop_readHereDoc2 :: Bool
prop_readHereDoc :: Bool
prop_readDollarLonely5 :: Bool
prop_readDollarLonely4 :: Bool
prop_readDollarLonely3 :: Bool
prop_readDollarLonely2 :: Bool
prop_readDollarLonely1 :: Bool
prop_readDollarVariable5 :: Bool
prop_readDollarVariable4 :: Bool
prop_readDollarVariable3 :: Bool
prop_readDollarVariable2 :: Bool
prop_readDollarVariable :: Bool
prop_readDollarExpansion3 :: Bool
prop_readDollarExpansion2 :: Bool
prop_readDollarExpansion1 :: Bool
prop_readDollarBraced4 :: Bool
prop_readDollarBraced3 :: Bool
prop_readDollarBraced2 :: Bool
prop_readDollarBraced1 :: Bool
prop_readDollarBraceCommandExpansion2 :: Bool
prop_readDollarBraceCommandExpansion1 :: Bool
prop_readArithmeticExpression :: Bool
prop_readDollarArithmetic2 :: Bool
prop_readDollarArithmetic :: Bool
prop_readDollarDoubleQuote :: Bool
prop_readDollarSingleQuote :: Bool
prop_readDollarExpression3 :: Bool
prop_readDollarExpression2 :: Bool
prop_readDollarExpression1 :: Bool
prop_readBraced8 :: Bool
prop_readBraced7 :: Bool
prop_readBraced6 :: Bool
prop_readBraced5 :: Bool
prop_readBraced4 :: Bool
prop_readBraced3 :: Bool
prop_readBraced2 :: Bool
prop_readBraced :: Bool
prop_readExtglob8 :: Bool
prop_readExtglob7 :: Bool
prop_readExtglob6 :: Bool
prop_readExtglob5 :: Bool
prop_readExtglob4 :: Bool
prop_readExtglob2 :: Bool
prop_readExtglob1 :: Bool
prop_readGlob10 :: Bool
prop_readGlob9 :: Bool
prop_readGlob8 :: Bool
prop_readGlob7 :: Bool
prop_readGlob6 :: Bool
prop_readGlob5 :: Bool
prop_readGlob4 :: Bool
prop_readGlob3 :: Bool
prop_readGlob2 :: Bool
prop_readGlob1 :: Bool
prop_readDoubleQuoted10 :: Bool
prop_readDoubleQuoted8 :: Bool
prop_readDoubleQuoted7 :: Bool
prop_readDoubleQuoted6 :: Bool
prop_readDoubleQuoted5 :: Bool
prop_readDoubleQuoted4 :: Bool
prop_readDoubleQuoted3 :: Bool
prop_readDoubleQuoted2 :: Bool
prop_readDoubleQuoted :: Bool
prop_readBackTicked8 :: Bool
prop_readBackTicked7 :: Bool
prop_readBackTicked6 :: Bool
prop_readBackTicked5 :: Bool
prop_readBackTicked4 :: Bool
prop_readBackTicked3 :: Bool
prop_readBackTicked2 :: Bool
prop_readBackTicked :: Bool
prop_readSingleQuoted8 :: Bool
prop_readSingleQuoted7 :: Bool
prop_readSingleQuoted6 :: Bool
prop_readSingleQuoted5 :: Bool
prop_readSingleQuoted4 :: Bool
prop_readSingleQuoted2 :: Bool
prop_readSingleQuoted :: Bool
prop_readProcSub3 :: Bool
prop_readProcSub2 :: Bool
prop_readProcSub1 :: Bool
prop_readNormalWord12 :: Bool
prop_readNormalWord11 :: Bool
prop_readNormalWord10 :: Bool
prop_readNormalWord9 :: Bool
prop_readNormalWord8 :: Bool
prop_readNormalWord7 :: Bool
prop_readNormalWord6 :: Bool
prop_readNormalWord5 :: Bool
prop_readNormalWord4 :: Bool
prop_readNormalWord3 :: Bool
prop_readNormalWord2 :: Bool
prop_readNormalWord :: Bool
prop_readAnyComment :: Bool
prop_readAnnotation11 :: Bool
prop_readAnnotation10 :: Bool
prop_readAnnotation9 :: Bool
prop_readAnnotation8 :: Bool
prop_readAnnotation7 :: Bool
prop_readAnnotation6 :: Bool
prop_readAnnotation5 :: Bool
prop_readAnnotation4 :: Bool
prop_readAnnotation3 :: Bool
prop_readAnnotation2 :: Bool
prop_readAnnotation1 :: Bool
prop_readCondition29 :: Bool
prop_readCondition28 :: Bool
prop_readCondition27 :: Bool
prop_readCondition26 :: Bool
prop_readCondition25 :: Bool
prop_readCondition23 :: Bool
prop_readCondition22 :: Bool
prop_readCondition21 :: Bool
prop_readCondition20 :: Bool
prop_readCondition19 :: Bool
prop_readCondition18 :: Bool
prop_readCondition17 :: Bool
prop_readCondition16 :: Bool
prop_readCondition15 :: Bool
prop_readCondition14 :: Bool
prop_readCondition13 :: Bool
prop_readCondition12 :: Bool
prop_readCondition11 :: Bool
prop_readCondition10b :: Bool
prop_readCondition10a :: Bool
prop_readCondition10 :: Bool
prop_readCondition9 :: Bool
prop_readCondition8 :: Bool
prop_readCondition7 :: Bool
prop_readCondition6 :: Bool
prop_readCondition5b :: Bool
prop_readCondition5a :: Bool
prop_readCondition5 :: Bool
prop_readCondition4 :: Bool
prop_readCondition3 :: Bool
prop_readCondition2 :: Bool
prop_readCondition :: Bool
prop_a23 :: Bool
prop_a22 :: Bool
prop_a21 :: Bool
prop_a20 :: Bool
prop_a19 :: Bool
prop_a18 :: Bool
prop_a17 :: Bool
prop_a16 :: Bool
prop_a15 :: Bool
prop_a14 :: Bool
prop_a13 :: Bool
prop_a12 :: Bool
prop_a11 :: Bool
prop_a10 :: Bool
prop_a9 :: Bool
prop_a8 :: Bool
prop_a7 :: Bool
prop_a6 :: Bool
prop_a5 :: Bool
prop_a4 :: Bool
prop_a3 :: Bool
prop_a2 :: Bool
prop_a1 :: Bool
prop_allspacing3 :: Bool
prop_allspacing2 :: Bool
prop_allspacing :: Bool
prop_spacing3 :: Bool
prop_spacing2 :: Bool
prop_spacing1 :: Bool
quickCheckAll