{-# LANGUAGE FlexibleContexts #-}
module ShellCheck.Regex where
import Data.List
import Data.Maybe
import Control.Monad
import Text.Regex.TDFA
mkRegex :: String -> Regex
mkRegex :: String -> Regex
mkRegex String
str =
let make :: String -> Regex
make :: String -> Regex
make = String -> Regex
forall regex compOpt execOpt source.
RegexMaker regex compOpt execOpt source =>
source -> regex
makeRegex
in
String -> Regex
make String
str
matches :: String -> Regex -> Bool
matches :: String -> Regex -> Bool
matches = (Regex -> String -> Bool) -> String -> Regex -> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip Regex -> String -> Bool
forall regex source target.
RegexContext regex source target =>
regex -> source -> target
match
matchRegex :: Regex -> String -> Maybe [String]
matchRegex :: Regex -> String -> Maybe [String]
matchRegex Regex
re String
str = do
(String
_, String
_, String
_, [String]
groups) <- Regex -> String -> Maybe (String, String, String, [String])
forall regex source target (m :: * -> *).
(RegexContext regex source target, MonadFail m) =>
regex -> source -> m target
matchM Regex
re String
str :: Maybe (String,String,String,[String])
[String] -> Maybe [String]
forall (m :: * -> *) a. Monad m => a -> m a
return [String]
groups
matchAllStrings :: Regex -> String -> [String]
matchAllStrings :: Regex -> String -> [String]
matchAllStrings Regex
re = (String -> Maybe (String, String)) -> String -> [String]
forall b a. (b -> Maybe (a, b)) -> b -> [a]
unfoldr String -> Maybe (String, String)
f
where
f :: String -> Maybe (String, String)
f :: String -> Maybe (String, String)
f String
str = do
(String
_, String
match, String
rest, [String]
_) <- Regex -> String -> Maybe (String, String, String, [String])
forall regex source target (m :: * -> *).
(RegexContext regex source target, MonadFail m) =>
regex -> source -> m target
matchM Regex
re String
str :: Maybe (String, String, String, [String])
(String, String) -> Maybe (String, String)
forall (m :: * -> *) a. Monad m => a -> m a
return (String
match, String
rest)
matchAllSubgroups :: Regex -> String -> [[String]]
matchAllSubgroups :: Regex -> String -> [[String]]
matchAllSubgroups Regex
re = (String -> Maybe ([String], String)) -> String -> [[String]]
forall b a. (b -> Maybe (a, b)) -> b -> [a]
unfoldr String -> Maybe ([String], String)
f
where
f :: String -> Maybe ([String], String)
f :: String -> Maybe ([String], String)
f String
str = do
(String
_, String
_, String
rest, [String]
groups) <- Regex -> String -> Maybe (String, String, String, [String])
forall regex source target (m :: * -> *).
(RegexContext regex source target, MonadFail m) =>
regex -> source -> m target
matchM Regex
re String
str :: Maybe (String, String, String, [String])
([String], String) -> Maybe ([String], String)
forall (m :: * -> *) a. Monad m => a -> m a
return ([String]
groups, String
rest)
subRegex :: Regex -> String -> String -> String
subRegex :: Regex -> String -> String -> String
subRegex Regex
re String
input String
replacement = String -> String
f String
input
where
f :: String -> String
f String
str = String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe String
str (Maybe String -> String) -> Maybe String -> String
forall a b. (a -> b) -> a -> b
$ do
(String
before, String
match, String
after) <- Regex -> String -> Maybe (String, String, String)
forall regex source target (m :: * -> *).
(RegexContext regex source target, MonadFail m) =>
regex -> source -> m target
matchM Regex
re String
str :: Maybe (String, String, String)
Bool -> Maybe () -> Maybe ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
match) (Maybe () -> Maybe ()) -> Maybe () -> Maybe ()
forall a b. (a -> b) -> a -> b
$ String -> Maybe ()
forall a. HasCallStack => String -> a
error (String
"Internal error: substituted empty in " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
str)
String -> Maybe String
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ String
before String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
replacement String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
f String
after
splitOn :: String -> Regex -> [String]
splitOn :: String -> Regex -> [String]
splitOn String
input Regex
re =
case Regex -> String -> Maybe (String, String, String)
forall regex source target (m :: * -> *).
(RegexContext regex source target, MonadFail m) =>
regex -> source -> m target
matchM Regex
re String
input :: Maybe (String, String, String) of
Just (String
before, String
match, String
after) -> String
before String -> [String] -> [String]
forall a. a -> [a] -> [a]
: String
after String -> Regex -> [String]
`splitOn` Regex
re
Maybe (String, String, String)
Nothing -> [String
input]