{-# LANGUAGE NoImplicitPrelude          #-}
{-# LANGUAGE RecordWildCards            #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE CPP                        #-}
#if __GLASGOW_HASKELL__ >= 800
{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
#endif

module Text.RE.ZeInternals.PreludeMacros
  ( RegexType
  , WithCaptures(..)
  , MacroDescriptor(..)
  , RegexSource(..)
  , PreludeMacro(..)
  , presentPreludeMacro
  , preludeMacros
  , preludeMacroTable
  , preludeMacroSummary
  , preludeMacroSources
  , preludeMacroSource
  , preludeMacroEnv
  , preludeMacroDescriptor
  ) where

import           Data.Array
import qualified Data.HashMap.Lazy            as HML
import           Data.List
import           Data.Maybe
import qualified Data.Text                    as T
import           Data.Time
import           Prelude.Compat
import           Text.RE.REOptions
import           Text.RE.ZeInternals.TestBench
import           Text.RE.ZeInternals.TestBench.Parsers


-- | generate the standard prelude Macros used to parse REs
preludeMacros :: (Monad m,Functor m)
              => (String->m r)
              -> RegexType
              -> WithCaptures
              -> m (Macros r)
preludeMacros :: (String -> m r) -> RegexType -> WithCaptures -> m (Macros r)
preludeMacros String -> m r
prs RegexType
rty WithCaptures
wc = (String -> m r)
-> RegexType -> WithCaptures -> MacroEnv -> m (Macros r)
forall (m :: * -> *) r.
(Monad m, Functor m) =>
(String -> m r)
-> RegexType -> WithCaptures -> MacroEnv -> m (Macros r)
mkMacros String -> m r
prs RegexType
rty WithCaptures
wc (MacroEnv -> m (Macros r)) -> MacroEnv -> m (Macros r)
forall a b. (a -> b) -> a -> b
$ RegexType -> MacroEnv
preludeMacroEnv RegexType
rty

-- | format the standard prelude macros in a markdown table
preludeMacroTable :: RegexType -> String
preludeMacroTable :: RegexType -> String
preludeMacroTable RegexType
rty = RegexType -> MacroEnv -> String
formatMacroTable RegexType
rty (MacroEnv -> String) -> MacroEnv -> String
forall a b. (a -> b) -> a -> b
$ RegexType -> MacroEnv
preludeMacroEnv RegexType
rty

-- | generate a textual summary of the prelude macros
preludeMacroSummary :: RegexType -> PreludeMacro -> String
preludeMacroSummary :: RegexType -> PreludeMacro -> String
preludeMacroSummary RegexType
rty =
  RegexType -> MacroEnv -> MacroID -> String
formatMacroSummary RegexType
rty (RegexType -> MacroEnv
preludeMacroEnv RegexType
rty) (MacroID -> String)
-> (PreludeMacro -> MacroID) -> PreludeMacro -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PreludeMacro -> MacroID
prelude_macro_id

-- | generate a plain text table giving the RE for each macro with all
-- macros expanded (to NF)
preludeMacroSources :: RegexType -> String
preludeMacroSources :: RegexType -> String
preludeMacroSources RegexType
rty =
  RegexType -> WithCaptures -> MacroEnv -> String
formatMacroSources RegexType
rty WithCaptures
ExclCaptures (MacroEnv -> String) -> MacroEnv -> String
forall a b. (a -> b) -> a -> b
$ RegexType -> MacroEnv
preludeMacroEnv RegexType
rty

-- | generate plain text giving theexpanded RE for a single macro
preludeMacroSource :: RegexType -> PreludeMacro -> String
preludeMacroSource :: RegexType -> PreludeMacro -> String
preludeMacroSource RegexType
rty =
  RegexType -> WithCaptures -> MacroEnv -> MacroID -> String
formatMacroSource RegexType
rty WithCaptures
ExclCaptures (RegexType -> MacroEnv
preludeMacroEnv RegexType
rty) (MacroID -> String)
-> (PreludeMacro -> MacroID) -> PreludeMacro -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PreludeMacro -> MacroID
prelude_macro_id

-- | generate the `MacroEnv` for the standard prelude macros
preludeMacroEnv :: RegexType -> MacroEnv
preludeMacroEnv :: RegexType -> MacroEnv
preludeMacroEnv RegexType
rty = (MacroEnv -> MacroEnv) -> MacroEnv
forall a. (a -> a) -> a
fix ((MacroEnv -> MacroEnv) -> MacroEnv)
-> (MacroEnv -> MacroEnv) -> MacroEnv
forall a b. (a -> b) -> a -> b
$ RegexType -> MacroEnv -> MacroEnv
prelude_macro_env RegexType
rty

prelude_macro_env :: RegexType -> MacroEnv -> MacroEnv
prelude_macro_env :: RegexType -> MacroEnv -> MacroEnv
prelude_macro_env RegexType
rty MacroEnv
env = [(MacroID, MacroDescriptor)] -> MacroEnv
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HML.fromList ([(MacroID, MacroDescriptor)] -> MacroEnv)
-> [(MacroID, MacroDescriptor)] -> MacroEnv
forall a b. (a -> b) -> a -> b
$ [Maybe (MacroID, MacroDescriptor)] -> [(MacroID, MacroDescriptor)]
forall a. [Maybe a] -> [a]
catMaybes
  [ (,) (PreludeMacro -> MacroID
prelude_macro_id PreludeMacro
pm) (MacroDescriptor -> (MacroID, MacroDescriptor))
-> Maybe MacroDescriptor -> Maybe (MacroID, MacroDescriptor)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
preludeMacroDescriptor RegexType
rty MacroEnv
env PreludeMacro
pm
      | PreludeMacro
pm<-[PreludeMacro
forall a. Bounded a => a
minBound..PreludeMacro
forall a. Bounded a => a
maxBound]
      ]

-- | generate the `MacroDescriptor` for a given `PreludeMacro`
preludeMacroDescriptor :: RegexType
                       -> MacroEnv
                       -> PreludeMacro
                       -> Maybe MacroDescriptor
preludeMacroDescriptor :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
preludeMacroDescriptor RegexType
rty MacroEnv
env PreludeMacro
pm = case PreludeMacro
pm of
  PreludeMacro
PM_nat              -> RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
natural_macro          RegexType
rty MacroEnv
env PreludeMacro
pm
  PreludeMacro
PM_hex              -> RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
natural_hex_macro      RegexType
rty MacroEnv
env PreludeMacro
pm
  PreludeMacro
PM_int              -> RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
integer_macro          RegexType
rty MacroEnv
env PreludeMacro
pm
  PreludeMacro
PM_frac             -> RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
decimal_macro          RegexType
rty MacroEnv
env PreludeMacro
pm
  PreludeMacro
PM_string           -> RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
string_macro           RegexType
rty MacroEnv
env PreludeMacro
pm
  PreludeMacro
PM_string_simple    -> RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
string_simple_macro    RegexType
rty MacroEnv
env PreludeMacro
pm
  PreludeMacro
PM_id               -> RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
id_macro               RegexType
rty MacroEnv
env PreludeMacro
pm
  PreludeMacro
PM_id'              -> RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
id'_macro              RegexType
rty MacroEnv
env PreludeMacro
pm
  PreludeMacro
PM_id_              -> RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
id__macro              RegexType
rty MacroEnv
env PreludeMacro
pm
  PreludeMacro
PM_date             -> RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
date_macro             RegexType
rty MacroEnv
env PreludeMacro
pm
  PreludeMacro
PM_date_slashes     -> RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
date_slashes_macro     RegexType
rty MacroEnv
env PreludeMacro
pm
  PreludeMacro
PM_time             -> RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
time_macro             RegexType
rty MacroEnv
env PreludeMacro
pm
  PreludeMacro
PM_timezone         -> RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
timezone_macro         RegexType
rty MacroEnv
env PreludeMacro
pm
  PreludeMacro
PM_datetime         -> RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
datetime_macro         RegexType
rty MacroEnv
env PreludeMacro
pm
  PreludeMacro
PM_datetime_8601    -> RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
datetime_8601_macro    RegexType
rty MacroEnv
env PreludeMacro
pm
  PreludeMacro
PM_datetime_clf     -> RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
datetime_clf_macro     RegexType
rty MacroEnv
env PreludeMacro
pm
  PreludeMacro
PM_shortmonth       -> RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
shortmonth_macro       RegexType
rty MacroEnv
env PreludeMacro
pm
  PreludeMacro
PM_address_ipv4     -> RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
address_ipv4_macros    RegexType
rty MacroEnv
env PreludeMacro
pm
  PreludeMacro
PM_email_simple     -> RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
email_simple_macro     RegexType
rty MacroEnv
env PreludeMacro
pm
  PreludeMacro
PM_url              -> RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
url_macro              RegexType
rty MacroEnv
env PreludeMacro
pm
  PreludeMacro
PM_syslog_severity  -> RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
syslog_severity_macro  RegexType
rty MacroEnv
env PreludeMacro
pm

-- | an enumeration of all of the prelude macros
data PreludeMacro
  -- numbers
  = PM_nat
  | PM_hex
  | PM_int
  | PM_frac
  -- strings
  | PM_string
  | PM_string_simple
  -- identifiers
  | PM_id
  | PM_id'
  | PM_id_
  -- dates & times
  | PM_date
  | PM_date_slashes
  | PM_time
  | PM_timezone
  | PM_datetime
  | PM_datetime_8601
  | PM_datetime_clf
  | PM_shortmonth
  -- addresses
  | PM_address_ipv4
  | PM_email_simple
  | PM_url
  -- syslog
  | PM_syslog_severity
  deriving (PreludeMacro
PreludeMacro -> PreludeMacro -> Bounded PreludeMacro
forall a. a -> a -> Bounded a
maxBound :: PreludeMacro
$cmaxBound :: PreludeMacro
minBound :: PreludeMacro
$cminBound :: PreludeMacro
Bounded,Int -> PreludeMacro
PreludeMacro -> Int
PreludeMacro -> [PreludeMacro]
PreludeMacro -> PreludeMacro
PreludeMacro -> PreludeMacro -> [PreludeMacro]
PreludeMacro -> PreludeMacro -> PreludeMacro -> [PreludeMacro]
(PreludeMacro -> PreludeMacro)
-> (PreludeMacro -> PreludeMacro)
-> (Int -> PreludeMacro)
-> (PreludeMacro -> Int)
-> (PreludeMacro -> [PreludeMacro])
-> (PreludeMacro -> PreludeMacro -> [PreludeMacro])
-> (PreludeMacro -> PreludeMacro -> [PreludeMacro])
-> (PreludeMacro -> PreludeMacro -> PreludeMacro -> [PreludeMacro])
-> Enum PreludeMacro
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: PreludeMacro -> PreludeMacro -> PreludeMacro -> [PreludeMacro]
$cenumFromThenTo :: PreludeMacro -> PreludeMacro -> PreludeMacro -> [PreludeMacro]
enumFromTo :: PreludeMacro -> PreludeMacro -> [PreludeMacro]
$cenumFromTo :: PreludeMacro -> PreludeMacro -> [PreludeMacro]
enumFromThen :: PreludeMacro -> PreludeMacro -> [PreludeMacro]
$cenumFromThen :: PreludeMacro -> PreludeMacro -> [PreludeMacro]
enumFrom :: PreludeMacro -> [PreludeMacro]
$cenumFrom :: PreludeMacro -> [PreludeMacro]
fromEnum :: PreludeMacro -> Int
$cfromEnum :: PreludeMacro -> Int
toEnum :: Int -> PreludeMacro
$ctoEnum :: Int -> PreludeMacro
pred :: PreludeMacro -> PreludeMacro
$cpred :: PreludeMacro -> PreludeMacro
succ :: PreludeMacro -> PreludeMacro
$csucc :: PreludeMacro -> PreludeMacro
Enum,Eq PreludeMacro
Eq PreludeMacro
-> (PreludeMacro -> PreludeMacro -> Ordering)
-> (PreludeMacro -> PreludeMacro -> Bool)
-> (PreludeMacro -> PreludeMacro -> Bool)
-> (PreludeMacro -> PreludeMacro -> Bool)
-> (PreludeMacro -> PreludeMacro -> Bool)
-> (PreludeMacro -> PreludeMacro -> PreludeMacro)
-> (PreludeMacro -> PreludeMacro -> PreludeMacro)
-> Ord PreludeMacro
PreludeMacro -> PreludeMacro -> Bool
PreludeMacro -> PreludeMacro -> Ordering
PreludeMacro -> PreludeMacro -> PreludeMacro
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PreludeMacro -> PreludeMacro -> PreludeMacro
$cmin :: PreludeMacro -> PreludeMacro -> PreludeMacro
max :: PreludeMacro -> PreludeMacro -> PreludeMacro
$cmax :: PreludeMacro -> PreludeMacro -> PreludeMacro
>= :: PreludeMacro -> PreludeMacro -> Bool
$c>= :: PreludeMacro -> PreludeMacro -> Bool
> :: PreludeMacro -> PreludeMacro -> Bool
$c> :: PreludeMacro -> PreludeMacro -> Bool
<= :: PreludeMacro -> PreludeMacro -> Bool
$c<= :: PreludeMacro -> PreludeMacro -> Bool
< :: PreludeMacro -> PreludeMacro -> Bool
$c< :: PreludeMacro -> PreludeMacro -> Bool
compare :: PreludeMacro -> PreludeMacro -> Ordering
$ccompare :: PreludeMacro -> PreludeMacro -> Ordering
$cp1Ord :: Eq PreludeMacro
Ord,PreludeMacro -> PreludeMacro -> Bool
(PreludeMacro -> PreludeMacro -> Bool)
-> (PreludeMacro -> PreludeMacro -> Bool) -> Eq PreludeMacro
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PreludeMacro -> PreludeMacro -> Bool
$c/= :: PreludeMacro -> PreludeMacro -> Bool
== :: PreludeMacro -> PreludeMacro -> Bool
$c== :: PreludeMacro -> PreludeMacro -> Bool
Eq,Int -> PreludeMacro -> ShowS
[PreludeMacro] -> ShowS
PreludeMacro -> String
(Int -> PreludeMacro -> ShowS)
-> (PreludeMacro -> String)
-> ([PreludeMacro] -> ShowS)
-> Show PreludeMacro
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PreludeMacro] -> ShowS
$cshowList :: [PreludeMacro] -> ShowS
show :: PreludeMacro -> String
$cshow :: PreludeMacro -> String
showsPrec :: Int -> PreludeMacro -> ShowS
$cshowsPrec :: Int -> PreludeMacro -> ShowS
Show)

-- | naming the macros
presentPreludeMacro :: PreludeMacro -> String
presentPreludeMacro :: PreludeMacro -> String
presentPreludeMacro PreludeMacro
pm = case PreludeMacro
pm of
    PreludeMacro
PM_id_  -> String
prelude_prefixString -> ShowS
forall a. [a] -> [a] -> [a]
++String
"id-"
    PreludeMacro
_       -> PreludeMacro -> String
fmt PreludeMacro
pm
  where
    fmt :: PreludeMacro -> String
fmt = (String
prelude_prefixString -> ShowS
forall a. [a] -> [a] -> [a]
++) ShowS -> (PreludeMacro -> String) -> PreludeMacro -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Char) -> ShowS
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
tr ShowS -> (PreludeMacro -> String) -> PreludeMacro -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
3 ShowS -> (PreludeMacro -> String) -> PreludeMacro -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PreludeMacro -> String
forall a. Show a => a -> String
show

    tr :: Char -> Char
tr Char
'_' = Char
'.'
    tr Char
c   = Char
c

-- | all prelude macros are prefixed with this
prelude_prefix :: String
prelude_prefix :: String
prelude_prefix = String
"%"

prelude_macro_id :: PreludeMacro -> MacroID
prelude_macro_id :: PreludeMacro -> MacroID
prelude_macro_id = String -> MacroID
MacroID (String -> MacroID)
-> (PreludeMacro -> String) -> PreludeMacro -> MacroID
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PreludeMacro -> String
presentPreludeMacro

natural_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
natural_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
natural_macro RegexType
rty MacroEnv
env PreludeMacro
pm = MacroDescriptor -> Maybe MacroDescriptor
forall a. a -> Maybe a
Just (MacroDescriptor -> Maybe MacroDescriptor)
-> MacroDescriptor -> Maybe MacroDescriptor
forall a b. (a -> b) -> a -> b
$ RegexType
-> (String -> Maybe Int)
-> [(String, Int)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
forall a.
(Eq a, Show a) =>
RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
run_tests RegexType
rty String -> Maybe Int
forall a. Replace a => a -> Maybe Int
parseInteger [(String, Int)]
samples MacroEnv
env PreludeMacro
pm
  MacroDescriptor :: RegexSource
-> [String]
-> [String]
-> [TestResult]
-> Maybe FunctionID
-> String
-> MacroDescriptor
MacroDescriptor
    { macroSource :: RegexSource
macroSource          = RegexSource
"[0-9]+"
    , macroSamples :: [String]
macroSamples         = ((String, Int) -> String) -> [(String, Int)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, Int) -> String
forall a b. (a, b) -> a
fst [(String, Int)]
samples
    , macroCounterSamples :: [String]
macroCounterSamples = [String]
counter_samples
    , macroTestResults :: [TestResult]
macroTestResults    = []
    , macroParser :: Maybe FunctionID
macroParser          = FunctionID -> Maybe FunctionID
forall a. a -> Maybe a
Just FunctionID
"parseInteger"
    , macroDescription :: String
macroDescription     = String
"a string of one or more decimal digits"
    }
  where
    samples :: [(String,Int)]
    samples :: [(String, Int)]
samples =
      [ (,) String
"0"          Int
0
      , (,) String
"1234567890" Int
1234567890
      , (,) String
"00"         Int
0
      , (,) String
"01"         Int
1
      ]

    counter_samples :: [String]
counter_samples =
      [ String
""
      , String
"0A"
      , String
"-1"
      ]

natural_hex_macro :: RegexType
                  -> MacroEnv
                  -> PreludeMacro
                  -> Maybe MacroDescriptor
natural_hex_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
natural_hex_macro RegexType
rty MacroEnv
env PreludeMacro
pm = MacroDescriptor -> Maybe MacroDescriptor
forall a. a -> Maybe a
Just (MacroDescriptor -> Maybe MacroDescriptor)
-> MacroDescriptor -> Maybe MacroDescriptor
forall a b. (a -> b) -> a -> b
$ RegexType
-> (String -> Maybe Int)
-> [(String, Int)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
forall a.
(Eq a, Show a) =>
RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
run_tests RegexType
rty String -> Maybe Int
forall a. Replace a => a -> Maybe Int
parseHex [(String, Int)]
samples MacroEnv
env PreludeMacro
pm
  MacroDescriptor :: RegexSource
-> [String]
-> [String]
-> [TestResult]
-> Maybe FunctionID
-> String
-> MacroDescriptor
MacroDescriptor
    { macroSource :: RegexSource
macroSource          = RegexSource
"[0-9a-fA-F]+"
    , macroSamples :: [String]
macroSamples         = ((String, Int) -> String) -> [(String, Int)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, Int) -> String
forall a b. (a, b) -> a
fst [(String, Int)]
samples
    , macroCounterSamples :: [String]
macroCounterSamples = [String]
counter_samples
    , macroTestResults :: [TestResult]
macroTestResults    = []
    , macroParser :: Maybe FunctionID
macroParser          = FunctionID -> Maybe FunctionID
forall a. a -> Maybe a
Just FunctionID
"parseHex"
    , macroDescription :: String
macroDescription     = String
"a string of one or more hexadecimal digits"
    }
  where
    samples :: [(String,Int)]
    samples :: [(String, Int)]
samples =
      [ (,) String
"0"         Int
0x0
      , (,) String
"12345678"  Int
0x12345678
      , (,) String
"0abcdef"   Int
0xabcdef
      , (,) String
"0ABCDEF"   Int
0xabcdef
      , (,) String
"00"        Int
0x0
      , (,) String
"010"       Int
0x10
      ]

    counter_samples :: [String]
counter_samples =
      [ String
""
      , String
"0x10"
      , String
"0z"
      , String
"-1a"
      ]

integer_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
integer_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
integer_macro RegexType
rty MacroEnv
env PreludeMacro
pm = MacroDescriptor -> Maybe MacroDescriptor
forall a. a -> Maybe a
Just (MacroDescriptor -> Maybe MacroDescriptor)
-> MacroDescriptor -> Maybe MacroDescriptor
forall a b. (a -> b) -> a -> b
$ RegexType
-> (String -> Maybe Int)
-> [(String, Int)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
forall a.
(Eq a, Show a) =>
RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
run_tests RegexType
rty String -> Maybe Int
forall a. Replace a => a -> Maybe Int
parseInteger [(String, Int)]
samples MacroEnv
env PreludeMacro
pm
  MacroDescriptor :: RegexSource
-> [String]
-> [String]
-> [TestResult]
-> Maybe FunctionID
-> String
-> MacroDescriptor
MacroDescriptor
    { macroSource :: RegexSource
macroSource          = RegexSource
"-?[0-9]+"
    , macroSamples :: [String]
macroSamples         = ((String, Int) -> String) -> [(String, Int)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, Int) -> String
forall a b. (a, b) -> a
fst [(String, Int)]
samples
    , macroCounterSamples :: [String]
macroCounterSamples = [String]
counter_samples
    , macroTestResults :: [TestResult]
macroTestResults    = []
    , macroParser :: Maybe FunctionID
macroParser          = FunctionID -> Maybe FunctionID
forall a. a -> Maybe a
Just FunctionID
"parseInteger"
    , macroDescription :: String
macroDescription     = String
"a decimal integer"
    }
  where
    samples :: [(String,Int)]
    samples :: [(String, Int)]
samples =
      [ (,) String
"0"           Int
0
      , (,) String
"1234567890"  Int
1234567890
      , (,) String
"00"          Int
0
      , (,) String
"01"          Int
1
      , (,) String
"-1"       (Int -> (String, Int)) -> Int -> (String, Int)
forall a b. (a -> b) -> a -> b
$ -Int
1
      , (,) String
"-0"          Int
0
      ]

    counter_samples :: [String]
counter_samples =
      [ String
""
      , String
"0A"
      , String
"+0"
      ]

-- | a digit string macro
decimal_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
decimal_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
decimal_macro RegexType
rty MacroEnv
env PreludeMacro
pm = MacroDescriptor -> Maybe MacroDescriptor
forall a. a -> Maybe a
Just (MacroDescriptor -> Maybe MacroDescriptor)
-> MacroDescriptor -> Maybe MacroDescriptor
forall a b. (a -> b) -> a -> b
$ RegexType
-> (String -> Maybe Double)
-> [(String, Double)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
forall a.
(Eq a, Show a) =>
RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
run_tests RegexType
rty String -> Maybe Double
forall a. Replace a => a -> Maybe Double
parseDouble [(String, Double)]
samples MacroEnv
env PreludeMacro
pm
  MacroDescriptor :: RegexSource
-> [String]
-> [String]
-> [TestResult]
-> Maybe FunctionID
-> String
-> MacroDescriptor
MacroDescriptor
    { macroSource :: RegexSource
macroSource          = RegexSource
"-?[0-9]+(?:\\.[0-9]+)?"
    , macroSamples :: [String]
macroSamples         = ((String, Double) -> String) -> [(String, Double)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, Double) -> String
forall a b. (a, b) -> a
fst [(String, Double)]
samples
    , macroCounterSamples :: [String]
macroCounterSamples = [String]
counter_samples
    , macroTestResults :: [TestResult]
macroTestResults    = []
    , macroParser :: Maybe FunctionID
macroParser          = FunctionID -> Maybe FunctionID
forall a. a -> Maybe a
Just FunctionID
"parseInteger"
    , macroDescription :: String
macroDescription     = String
"a decimal natural number"
    }
  where
    samples :: [(String,Double)]
    samples :: [(String, Double)]
samples =
      [ (,) String
"0"             Double
0
      , (,) String
"1234567890"    Double
1234567890
      , (,) String
"00"            Double
0
      , (,) String
"01"            Double
1
      , (,) String
"-1"         (Double -> (String, Double)) -> Double -> (String, Double)
forall a b. (a -> b) -> a -> b
$ -Double
1
      , (,) String
"-0"            Double
0
      , (,) String
"0.1234567890"  Double
0.1234567890
      , (,) String
"-1.0"       (Double -> (String, Double)) -> Double -> (String, Double)
forall a b. (a -> b) -> a -> b
$ -Double
1.0
      ]

    counter_samples :: [String]
counter_samples =
      [ String
""
      , String
"0A"
      , String
"+0"
      , String
"0."
      , String
".0"
      , String
"."
      , String
"-"
      , String
"-."
      , String
"-1."
      , String
"-.1"
      ]

string_macro :: RegexType
             -> MacroEnv
             -> PreludeMacro
             -> Maybe MacroDescriptor
string_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
string_macro RegexType
rty MacroEnv
env PreludeMacro
pm
  | RegexType -> Bool
isPCRE RegexType
rty = Maybe MacroDescriptor
forall a. Maybe a
Nothing
  | Bool
otherwise  =
    MacroDescriptor -> Maybe MacroDescriptor
forall a. a -> Maybe a
Just (MacroDescriptor -> Maybe MacroDescriptor)
-> MacroDescriptor -> Maybe MacroDescriptor
forall a b. (a -> b) -> a -> b
$ RegexType
-> (String -> Maybe String)
-> [(String, String)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
forall a.
(Eq a, Show a) =>
RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
run_tests RegexType
rty ((Text -> String) -> Maybe Text -> Maybe String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> String
T.unpack (Maybe Text -> Maybe String)
-> (String -> Maybe Text) -> String -> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Maybe Text
forall a. Replace a => a -> Maybe Text
parseString) [(String, String)]
samples MacroEnv
env PreludeMacro
pm
      MacroDescriptor :: RegexSource
-> [String]
-> [String]
-> [TestResult]
-> Maybe FunctionID
-> String
-> MacroDescriptor
MacroDescriptor
        { macroSource :: RegexSource
macroSource          = RegexSource
"\"(?:[^\"\\]+|\\\\[\\\"])*\""
        , macroSamples :: [String]
macroSamples         = ((String, String) -> String) -> [(String, String)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, String) -> String
forall a b. (a, b) -> a
fst [(String, String)]
samples
        , macroCounterSamples :: [String]
macroCounterSamples = [String]
counter_samples
        , macroTestResults :: [TestResult]
macroTestResults    = []
        , macroParser :: Maybe FunctionID
macroParser          = FunctionID -> Maybe FunctionID
forall a. a -> Maybe a
Just FunctionID
"parseString"
        , macroDescription :: String
macroDescription     = String
"a double-quote string, with simple \\ escapes for \\s and \"s"
        }
  where
    samples :: [(String,String)]
    samples :: [(String, String)]
samples =
      [ (,) String
"\"\""                String
""
      , (,) String
"\"foo\""             String
"foo"
      , (,) String
"\"\\\"\""            String
"\""
      , (,) String
"\"\\\"\\\"\""        String
"\"\""
      , (,) String
"\"\\\"\\\\\\\"\""    String
"\"\\\""
      , (,) String
"\"\\\"foo\\\"\""     String
"\"foo\""
      , (,) String
"\"\""                String
""
      ]

    counter_samples :: [String]
counter_samples =
      [ String
"\""
      , String
"\"aa"
      ]

string_simple_macro :: RegexType
                    -> MacroEnv
                    -> PreludeMacro
                    -> Maybe MacroDescriptor
string_simple_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
string_simple_macro RegexType
rty MacroEnv
env PreludeMacro
pm =
  MacroDescriptor -> Maybe MacroDescriptor
forall a. a -> Maybe a
Just (MacroDescriptor -> Maybe MacroDescriptor)
-> MacroDescriptor -> Maybe MacroDescriptor
forall a b. (a -> b) -> a -> b
$ RegexType
-> (String -> Maybe String)
-> [(String, String)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
forall a.
(Eq a, Show a) =>
RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
run_tests RegexType
rty ((Text -> String) -> Maybe Text -> Maybe String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> String
T.unpack (Maybe Text -> Maybe String)
-> (String -> Maybe Text) -> String -> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Maybe Text
forall a. Replace a => a -> Maybe Text
parseSimpleString) [(String, String)]
samples MacroEnv
env PreludeMacro
pm
    MacroDescriptor :: RegexSource
-> [String]
-> [String]
-> [TestResult]
-> Maybe FunctionID
-> String
-> MacroDescriptor
MacroDescriptor
      { macroSource :: RegexSource
macroSource          = RegexSource
"\"[^\"[:cntrl:]]*\""
      , macroSamples :: [String]
macroSamples         = ((String, String) -> String) -> [(String, String)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, String) -> String
forall a b. (a, b) -> a
fst [(String, String)]
samples
      , macroCounterSamples :: [String]
macroCounterSamples = [String]
counter_samples
      , macroTestResults :: [TestResult]
macroTestResults    = []
      , macroParser :: Maybe FunctionID
macroParser          = FunctionID -> Maybe FunctionID
forall a. a -> Maybe a
Just FunctionID
"parseSimpleString"
      , macroDescription :: String
macroDescription     = String
"a simple quoted string"
      }
  where
    samples :: [(String,String)]
    samples :: [(String, String)]
samples =
      [ (,) String
"\"\""      String
""
      , (,) String
"\"foo\""   String
"foo"
      , (,) String
"\"\\\""    String
"\\"
      , (,) String
"\"\""      String
""
      ]

    counter_samples :: [String]
counter_samples =
      [ String
""
      , String
"\""
      , String
"\"\\\"\""
      , String
"\"\\\"\\\"\""
      , String
"\"\\\"\\\\\\\"\""
      , String
"\"\\\"foo\\\"\""
      , String
"\"aa"
      ]

id_macro :: RegexType
         -> MacroEnv
         -> PreludeMacro
         -> Maybe MacroDescriptor
id_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
id_macro RegexType
rty MacroEnv
env PreludeMacro
pm =
  MacroDescriptor -> Maybe MacroDescriptor
forall a. a -> Maybe a
Just (MacroDescriptor -> Maybe MacroDescriptor)
-> MacroDescriptor -> Maybe MacroDescriptor
forall a b. (a -> b) -> a -> b
$ RegexType
-> (String -> Maybe String)
-> [(String, String)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
forall a.
(Eq a, Show a) =>
RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
run_tests RegexType
rty String -> Maybe String
forall a. a -> Maybe a
Just [(String, String)]
samples MacroEnv
env PreludeMacro
pm
    MacroDescriptor :: RegexSource
-> [String]
-> [String]
-> [TestResult]
-> Maybe FunctionID
-> String
-> MacroDescriptor
MacroDescriptor
      { macroSource :: RegexSource
macroSource          = RegexSource
"_*[a-zA-Z][a-zA-Z0-9_]*"
      , macroSamples :: [String]
macroSamples         = ((String, String) -> String) -> [(String, String)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, String) -> String
forall a b. (a, b) -> a
fst [(String, String)]
samples
      , macroCounterSamples :: [String]
macroCounterSamples = [String]
counter_samples
      , macroTestResults :: [TestResult]
macroTestResults    = []
      , macroParser :: Maybe FunctionID
macroParser          = Maybe FunctionID
forall a. Maybe a
Nothing
      , macroDescription :: String
macroDescription     = String
"a standard C-style alphanumeric identifier (with _s)"
      }
  where
    samples :: [(String,String)]
    samples :: [(String, String)]
samples =
        [ String -> (String, String)
forall b. b -> (b, b)
f String
"a"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"A"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"A1"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"a_"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"a1_B2"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"_abc"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"__abc"
        ]
      where
        f :: b -> (b, b)
f b
s = (b
s,b
s)

    counter_samples :: [String]
counter_samples =
        [ String
""
        , String
"1"
        , String
"_"
        , String
"__"
        , String
"__1"
        , String
"1a"
        , String
"a'"
        ]

id'_macro :: RegexType
          -> MacroEnv
          -> PreludeMacro
          -> Maybe MacroDescriptor
id'_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
id'_macro RegexType
rty MacroEnv
env PreludeMacro
pm =
  MacroDescriptor -> Maybe MacroDescriptor
forall a. a -> Maybe a
Just (MacroDescriptor -> Maybe MacroDescriptor)
-> MacroDescriptor -> Maybe MacroDescriptor
forall a b. (a -> b) -> a -> b
$ RegexType
-> (String -> Maybe String)
-> [(String, String)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
forall a.
(Eq a, Show a) =>
RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
run_tests RegexType
rty String -> Maybe String
forall a. a -> Maybe a
Just [(String, String)]
samples MacroEnv
env PreludeMacro
pm
    MacroDescriptor :: RegexSource
-> [String]
-> [String]
-> [TestResult]
-> Maybe FunctionID
-> String
-> MacroDescriptor
MacroDescriptor
      { macroSource :: RegexSource
macroSource          = RegexSource
"_*[a-zA-Z][a-zA-Z0-9_']*"
      , macroSamples :: [String]
macroSamples         = ((String, String) -> String) -> [(String, String)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, String) -> String
forall a b. (a, b) -> a
fst [(String, String)]
samples
      , macroCounterSamples :: [String]
macroCounterSamples = [String]
counter_samples
      , macroTestResults :: [TestResult]
macroTestResults    = []
      , macroParser :: Maybe FunctionID
macroParser          = Maybe FunctionID
forall a. Maybe a
Nothing
      , macroDescription :: String
macroDescription     = String
"a standard Haskell-style alphanumeric identifier (with '_'s and '''s)"
      }
  where
    samples :: [(String,String)]
    samples :: [(String, String)]
samples =
        [ String -> (String, String)
forall b. b -> (b, b)
f String
"a"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"A"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"A1"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"a_"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"a1_B2"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"_abc"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"__abc"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"a'"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"_a'"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"a'b"
        ]
      where
        f :: b -> (b, b)
f b
s = (b
s,b
s)

    counter_samples :: [String]
counter_samples =
        [ String
""
        , String
"1"
        , String
"_"
        , String
"__"
        , String
"__1"
        , String
"1a"
        , String
"'"
        , String
"'a"
        , String
"_'"
        , String
"_1'"
        ]

id__macro :: RegexType
          -> MacroEnv
          -> PreludeMacro
          -> Maybe MacroDescriptor
id__macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
id__macro RegexType
rty MacroEnv
env PreludeMacro
pm =
  MacroDescriptor -> Maybe MacroDescriptor
forall a. a -> Maybe a
Just (MacroDescriptor -> Maybe MacroDescriptor)
-> MacroDescriptor -> Maybe MacroDescriptor
forall a b. (a -> b) -> a -> b
$ RegexType
-> (String -> Maybe String)
-> [(String, String)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
forall a.
(Eq a, Show a) =>
RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
run_tests RegexType
rty String -> Maybe String
forall a. a -> Maybe a
Just [(String, String)]
samples MacroEnv
env PreludeMacro
pm
    MacroDescriptor :: RegexSource
-> [String]
-> [String]
-> [TestResult]
-> Maybe FunctionID
-> String
-> MacroDescriptor
MacroDescriptor
      { macroSource :: RegexSource
macroSource          = RegexSource
"_*[a-zA-Z][a-zA-Z0-9_'-]*"
      , macroSamples :: [String]
macroSamples         = ((String, String) -> String) -> [(String, String)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, String) -> String
forall a b. (a, b) -> a
fst [(String, String)]
samples
      , macroCounterSamples :: [String]
macroCounterSamples = [String]
counter_samples
      , macroTestResults :: [TestResult]
macroTestResults    = []
      , macroParser :: Maybe FunctionID
macroParser          = Maybe FunctionID
forall a. Maybe a
Nothing
      , macroDescription :: String
macroDescription     = String
"an identifier with -s"
      }
  where
    samples :: [(String,String)]
    samples :: [(String, String)]
samples =
        [ String -> (String, String)
forall b. b -> (b, b)
f String
"a"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"A"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"A1"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"a_"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"a1_B2"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"_abc"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"__abc"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"a'"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"_a'"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"a'b"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"a-"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"a1-B2"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"a1-B2-"
        ]
      where
        f :: b -> (b, b)
f b
s = (b
s,b
s)

    counter_samples :: [String]
counter_samples =
        [ String
""
        , String
"1"
        , String
"_"
        , String
"__"
        , String
"__1"
        , String
"1a"
        , String
"'"
        , String
"'a"
        , String
"_'"
        , String
"_1'"
        ]

date_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
date_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
date_macro RegexType
rty MacroEnv
env PreludeMacro
pm =
  MacroDescriptor -> Maybe MacroDescriptor
forall a. a -> Maybe a
Just (MacroDescriptor -> Maybe MacroDescriptor)
-> MacroDescriptor -> Maybe MacroDescriptor
forall a b. (a -> b) -> a -> b
$ RegexType
-> (String -> Maybe Day)
-> [(String, Day)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
forall a.
(Eq a, Show a) =>
RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
run_tests RegexType
rty String -> Maybe Day
forall a. Replace a => a -> Maybe Day
parseDate [(String, Day)]
samples MacroEnv
env PreludeMacro
pm
    MacroDescriptor :: RegexSource
-> [String]
-> [String]
-> [TestResult]
-> Maybe FunctionID
-> String
-> MacroDescriptor
MacroDescriptor
      { macroSource :: RegexSource
macroSource          = RegexSource
"[0-9]{4}-[0-9]{2}-[0-9]{2}"
      , macroSamples :: [String]
macroSamples         = ((String, Day) -> String) -> [(String, Day)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, Day) -> String
forall a b. (a, b) -> a
fst [(String, Day)]
samples
      , macroCounterSamples :: [String]
macroCounterSamples = [String]
counter_samples
      , macroTestResults :: [TestResult]
macroTestResults    = []
      , macroParser :: Maybe FunctionID
macroParser          = FunctionID -> Maybe FunctionID
forall a. a -> Maybe a
Just FunctionID
"parseDate"
      , macroDescription :: String
macroDescription     = String
"a YYYY-MM-DD format date"
      }
  where
    samples :: [(String,Day)]
    samples :: [(String, Day)]
samples =
        [ String -> (String, Day)
forall b. Read b => String -> (String, b)
f String
"2016-12-31"
        , String -> (String, Day)
forall b. Read b => String -> (String, b)
f String
"0001-01-01"
        , String -> (String, Day)
forall b. Read b => String -> (String, b)
f String
"1000-01-01"
        ]
      where
        f :: String -> (String, b)
f String
s = (String
s,String -> b
forall a. Read a => String -> a
read String
s)

    counter_samples :: [String]
counter_samples =
        [ String
""
        , String
"2016/01/31"
        , String
"2016-1-31"
        , String
"2016-01-1"
        , String
"2016-001-01"
        ]

date_slashes_macro :: RegexType
                   -> MacroEnv
                   -> PreludeMacro
                   -> Maybe MacroDescriptor
date_slashes_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
date_slashes_macro RegexType
rty MacroEnv
env PreludeMacro
pm =
  MacroDescriptor -> Maybe MacroDescriptor
forall a. a -> Maybe a
Just (MacroDescriptor -> Maybe MacroDescriptor)
-> MacroDescriptor -> Maybe MacroDescriptor
forall a b. (a -> b) -> a -> b
$ RegexType
-> (String -> Maybe Day)
-> [(String, Day)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
forall a.
(Eq a, Show a) =>
RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
run_tests RegexType
rty String -> Maybe Day
forall a. Replace a => a -> Maybe Day
parseSlashesDate [(String, Day)]
samples MacroEnv
env PreludeMacro
pm
    MacroDescriptor :: RegexSource
-> [String]
-> [String]
-> [TestResult]
-> Maybe FunctionID
-> String
-> MacroDescriptor
MacroDescriptor
      { macroSource :: RegexSource
macroSource          = RegexSource
"[0-9]{4}/[0-9]{2}/[0-9]{2}"
      , macroSamples :: [String]
macroSamples         = ((String, Day) -> String) -> [(String, Day)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, Day) -> String
forall a b. (a, b) -> a
fst [(String, Day)]
samples
      , macroCounterSamples :: [String]
macroCounterSamples = [String]
counter_samples
      , macroTestResults :: [TestResult]
macroTestResults    = []
      , macroParser :: Maybe FunctionID
macroParser          = FunctionID -> Maybe FunctionID
forall a. a -> Maybe a
Just FunctionID
"parseSlashesDate"
      , macroDescription :: String
macroDescription     = String
"a YYYY/MM/DD format date"
      }
  where
    samples :: [(String,Day)]
    samples :: [(String, Day)]
samples =
        [ String -> (String, Day)
forall b. Read b => String -> (String, b)
f String
"2016/12/31"
        , String -> (String, Day)
forall b. Read b => String -> (String, b)
f String
"0001/01/01"
        , String -> (String, Day)
forall b. Read b => String -> (String, b)
f String
"1000/01/01"
        ]
      where
        f :: String -> (String, b)
f String
s = (String
s,String -> b
forall a. Read a => String -> a
read (String -> b) -> String -> b
forall a b. (a -> b) -> a -> b
$ (Char -> Char) -> ShowS
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
tr String
s)
          where
            tr :: Char -> Char
tr Char
'/' = Char
'-'
            tr Char
c   = Char
c

    counter_samples :: [String]
counter_samples =
        [ String
""
        , String
"2016-01-31"
        , String
"2016/1/31"
        , String
"2016/01/1"
        , String
"2016/001/01"
        ]

time_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
time_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
time_macro RegexType
rty MacroEnv
env PreludeMacro
pm =
  MacroDescriptor -> Maybe MacroDescriptor
forall a. a -> Maybe a
Just (MacroDescriptor -> Maybe MacroDescriptor)
-> MacroDescriptor -> Maybe MacroDescriptor
forall a b. (a -> b) -> a -> b
$ RegexType
-> (String -> Maybe TimeOfDay)
-> [(String, TimeOfDay)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
forall a.
(Eq a, Show a) =>
RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
run_tests RegexType
rty String -> Maybe TimeOfDay
forall a. Replace a => a -> Maybe TimeOfDay
parseTimeOfDay [(String, TimeOfDay)]
samples MacroEnv
env PreludeMacro
pm
    MacroDescriptor :: RegexSource
-> [String]
-> [String]
-> [TestResult]
-> Maybe FunctionID
-> String
-> MacroDescriptor
MacroDescriptor
      { macroSource :: RegexSource
macroSource          = RegexSource
"[0-9]{2}:[0-9]{2}:[0-9]{2}(?:[.][0-9]+)?"
      , macroSamples :: [String]
macroSamples         = ((String, TimeOfDay) -> String)
-> [(String, TimeOfDay)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, TimeOfDay) -> String
forall a b. (a, b) -> a
fst [(String, TimeOfDay)]
samples
      , macroCounterSamples :: [String]
macroCounterSamples = [String]
counter_samples
      , macroTestResults :: [TestResult]
macroTestResults    = []
      , macroParser :: Maybe FunctionID
macroParser          = FunctionID -> Maybe FunctionID
forall a. a -> Maybe a
Just FunctionID
"parseTimeOfDay"
      , macroDescription :: String
macroDescription     = String
"a HH:MM:SS[.Q+]"
      }
  where
    samples :: [(String,TimeOfDay)]
    samples :: [(String, TimeOfDay)]
samples =
        [ String -> Int -> Int -> Pico -> (String, TimeOfDay)
forall a. a -> Int -> Int -> Pico -> (a, TimeOfDay)
f String
"00:00:00"            Int
00 Int
00   Pico
0
        , String -> Int -> Int -> Pico -> (String, TimeOfDay)
forall a. a -> Int -> Int -> Pico -> (a, TimeOfDay)
f String
"23:59:59"            Int
23 Int
59   Pico
59
        , String -> Int -> Int -> Pico -> (String, TimeOfDay)
forall a. a -> Int -> Int -> Pico -> (a, TimeOfDay)
f String
"00:00:00.1234567890" Int
00 Int
00 (Pico -> (String, TimeOfDay)) -> Pico -> (String, TimeOfDay)
forall a b. (a -> b) -> a -> b
$ Pico
123456789 Pico -> Pico -> Pico
forall a. Fractional a => a -> a -> a
/ Pico
1000000000
        ]
      where
        f :: a -> Int -> Int -> Pico -> (a, TimeOfDay)
f a
s Int
h Int
m Pico
ps = (a
s,Int -> Int -> Pico -> TimeOfDay
TimeOfDay Int
h Int
m Pico
ps)

    counter_samples :: [String]
counter_samples =
        [ String
""
        , String
"235959"
        , String
"10:20"
        , String
"A00:00:00"
        , String
"00:00:00A"
        , String
"23:59:59."
        ]

timezone_macro :: RegexType
               -> MacroEnv
               -> PreludeMacro
               -> Maybe MacroDescriptor
timezone_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
timezone_macro RegexType
rty MacroEnv
env PreludeMacro
pm =
  MacroDescriptor -> Maybe MacroDescriptor
forall a. a -> Maybe a
Just (MacroDescriptor -> Maybe MacroDescriptor)
-> MacroDescriptor -> Maybe MacroDescriptor
forall a b. (a -> b) -> a -> b
$ RegexType
-> (String -> Maybe TimeZone)
-> [(String, TimeZone)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
forall a.
(Eq a, Show a) =>
RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
run_tests RegexType
rty String -> Maybe TimeZone
forall a. Replace a => a -> Maybe TimeZone
parseTimeZone [(String, TimeZone)]
samples MacroEnv
env PreludeMacro
pm
    MacroDescriptor :: RegexSource
-> [String]
-> [String]
-> [TestResult]
-> Maybe FunctionID
-> String
-> MacroDescriptor
MacroDescriptor
      { macroSource :: RegexSource
macroSource          = RegexSource
"(?:Z|[+-][0-9]{2}:?[0-9]{2})"
      , macroSamples :: [String]
macroSamples         = ((String, TimeZone) -> String) -> [(String, TimeZone)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, TimeZone) -> String
forall a b. (a, b) -> a
fst [(String, TimeZone)]
samples
      , macroCounterSamples :: [String]
macroCounterSamples = [String]
counter_samples
      , macroTestResults :: [TestResult]
macroTestResults    = []
      , macroParser :: Maybe FunctionID
macroParser          = FunctionID -> Maybe FunctionID
forall a. a -> Maybe a
Just FunctionID
"parseTimeZone"
      , macroDescription :: String
macroDescription     = String
"an IOS-8601 TZ specification"
      }
  where
    samples :: [(String,TimeZone)]
    samples :: [(String, TimeZone)]
samples =
        [ String -> TimeZone -> (String, TimeZone)
forall a b. a -> b -> (a, b)
f String
"Z"         (TimeZone -> (String, TimeZone)) -> TimeZone -> (String, TimeZone)
forall a b. (a -> b) -> a -> b
$ Int -> TimeZone
minutesToTimeZone     Int
0
        , String -> TimeZone -> (String, TimeZone)
forall a b. a -> b -> (a, b)
f String
"+00:00"    (TimeZone -> (String, TimeZone)) -> TimeZone -> (String, TimeZone)
forall a b. (a -> b) -> a -> b
$ Int -> TimeZone
minutesToTimeZone     Int
0
        , String -> TimeZone -> (String, TimeZone)
forall a b. a -> b -> (a, b)
f String
"+0000"     (TimeZone -> (String, TimeZone)) -> TimeZone -> (String, TimeZone)
forall a b. (a -> b) -> a -> b
$ Int -> TimeZone
minutesToTimeZone     Int
0
        , String -> TimeZone -> (String, TimeZone)
forall a b. a -> b -> (a, b)
f String
"+0200"     (TimeZone -> (String, TimeZone)) -> TimeZone -> (String, TimeZone)
forall a b. (a -> b) -> a -> b
$ Int -> TimeZone
minutesToTimeZone   Int
120
        , String -> TimeZone -> (String, TimeZone)
forall a b. a -> b -> (a, b)
f String
"-0100"     (TimeZone -> (String, TimeZone)) -> TimeZone -> (String, TimeZone)
forall a b. (a -> b) -> a -> b
$ Int -> TimeZone
minutesToTimeZone (Int -> TimeZone) -> Int -> TimeZone
forall a b. (a -> b) -> a -> b
$ -Int
60
        ]
      where
        f :: a -> b -> (a, b)
f = (,)

    counter_samples :: [String]
counter_samples =
        [ String
""
        , String
"00"
        , String
"A00:00"
        , String
"UTC"
        , String
"EST"
        , String
" EST"
        ]

datetime_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
datetime_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
datetime_macro RegexType
rty MacroEnv
env PreludeMacro
pm = MacroDescriptor -> Maybe MacroDescriptor
forall a. a -> Maybe a
Just (MacroDescriptor -> Maybe MacroDescriptor)
-> MacroDescriptor -> Maybe MacroDescriptor
forall a b. (a -> b) -> a -> b
$ RegexType
-> (String -> Maybe UTCTime)
-> [(String, UTCTime)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
forall a.
(Eq a, Show a) =>
RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
run_tests RegexType
rty String -> Maybe UTCTime
forall a. Replace a => a -> Maybe UTCTime
parseDateTime [(String, UTCTime)]
samples MacroEnv
env PreludeMacro
pm
  MacroDescriptor :: RegexSource
-> [String]
-> [String]
-> [TestResult]
-> Maybe FunctionID
-> String
-> MacroDescriptor
MacroDescriptor
    { macroSource :: RegexSource
macroSource          = RegexSource
"@{%date}[ T]@{%time}(?:@{%timezone}| UTC)?"
    , macroSamples :: [String]
macroSamples         = ((String, UTCTime) -> String) -> [(String, UTCTime)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, UTCTime) -> String
forall a b. (a, b) -> a
fst [(String, UTCTime)]
samples
    , macroCounterSamples :: [String]
macroCounterSamples = [String]
counter_samples
    , macroTestResults :: [TestResult]
macroTestResults    = []
    , macroParser :: Maybe FunctionID
macroParser          = FunctionID -> Maybe FunctionID
forall a. a -> Maybe a
Just FunctionID
"parseDateTime"
    , macroDescription :: String
macroDescription     = String
"ISO-8601 format date and time + simple variants"
    }
  where
    samples :: [(String,UTCTime)]
    samples :: [(String, UTCTime)]
samples =
        [ String -> String -> (String, UTCTime)
f String
"2016-12-31 23:37:22.525343 UTC" String
"2016-12-31 23:37:22.525343Z"
        , String -> String -> (String, UTCTime)
f String
"2016-12-31 23:37:22.525343"     String
"2016-12-31 23:37:22.525343Z"
        , String -> String -> (String, UTCTime)
f String
"2016-12-31 23:37:22"            String
"2016-12-31 23:37:22Z"
        , String -> String -> (String, UTCTime)
f String
"2016-12-31T23:37:22+0100"       String
"2016-12-31 23:37:22+0100"
        , String -> String -> (String, UTCTime)
f String
"2016-12-31T23:37:22-01:00"      String
"2016-12-31 23:37:22-0100"
        , String -> String -> (String, UTCTime)
f String
"2016-12-31T23:37:22-23:59"      String
"2016-12-31 23:37:22-2359"
        , String -> String -> (String, UTCTime)
f String
"2016-12-31T23:37:22Z"           String
"2016-12-31 23:37:22Z"
        ]
      where
        f :: String -> String -> (String,UTCTime)
        f :: String -> String -> (String, UTCTime)
f String
s String
r_s = (String
s,String -> UTCTime
forall a. Read a => String -> a
read String
r_s)

    counter_samples :: [String]
counter_samples =
        [ String
""
        , String
"2016-12-31 23:37:22.525343 EST"
        ]

datetime_8601_macro :: RegexType
                    -> MacroEnv
                    -> PreludeMacro
                    -> Maybe MacroDescriptor
datetime_8601_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
datetime_8601_macro RegexType
rty MacroEnv
env PreludeMacro
pm =
  MacroDescriptor -> Maybe MacroDescriptor
forall a. a -> Maybe a
Just (MacroDescriptor -> Maybe MacroDescriptor)
-> MacroDescriptor -> Maybe MacroDescriptor
forall a b. (a -> b) -> a -> b
$ RegexType
-> (String -> Maybe UTCTime)
-> [(String, UTCTime)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
forall a.
(Eq a, Show a) =>
RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
run_tests RegexType
rty String -> Maybe UTCTime
forall a. Replace a => a -> Maybe UTCTime
parseDateTime [(String, UTCTime)]
samples MacroEnv
env PreludeMacro
pm
    MacroDescriptor :: RegexSource
-> [String]
-> [String]
-> [TestResult]
-> Maybe FunctionID
-> String
-> MacroDescriptor
MacroDescriptor
      { macroSource :: RegexSource
macroSource          = RegexSource
"@{%date}T@{%time}@{%timezone}"
      , macroSamples :: [String]
macroSamples         = ((String, UTCTime) -> String) -> [(String, UTCTime)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, UTCTime) -> String
forall a b. (a, b) -> a
fst [(String, UTCTime)]
samples
      , macroCounterSamples :: [String]
macroCounterSamples = [String]
counter_samples
      , macroTestResults :: [TestResult]
macroTestResults    = []
      , macroParser :: Maybe FunctionID
macroParser          = FunctionID -> Maybe FunctionID
forall a. a -> Maybe a
Just FunctionID
"parseDateTime8601"
      , macroDescription :: String
macroDescription     = String
"YYYY-MM-DDTHH:MM:SS[.Q*](Z|[+-]HHMM) format date and time"
      }
  where
    samples :: [(String,UTCTime)]
    samples :: [(String, UTCTime)]
samples =
        [ String -> String -> (String, UTCTime)
f String
"2016-12-31T23:37:22.343Z"      String
"2016-12-31 23:37:22.343Z"
        , String -> String -> (String, UTCTime)
f String
"2016-12-31T23:37:22-0100"      String
"2016-12-31 23:37:22-0100"
        , String -> String -> (String, UTCTime)
f String
"2016-12-31T23:37:22+23:59"     String
"2016-12-31 23:37:22+2359"
        ]
      where
        f :: String -> String -> (String,UTCTime)
        f :: String -> String -> (String, UTCTime)
f String
s String
r_s = (String
s,String -> UTCTime
forall a. Read a => String -> a
read String
r_s)

    counter_samples :: [String]
counter_samples =
        [ String
""
        , String
"2016-12-31 23:37:22.525343 EST"
        ]

datetime_clf_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
datetime_clf_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
datetime_clf_macro RegexType
rty MacroEnv
env PreludeMacro
pm =
  MacroDescriptor -> Maybe MacroDescriptor
forall a. a -> Maybe a
Just (MacroDescriptor -> Maybe MacroDescriptor)
-> MacroDescriptor -> Maybe MacroDescriptor
forall a b. (a -> b) -> a -> b
$ RegexType
-> (String -> Maybe UTCTime)
-> [(String, UTCTime)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
forall a.
(Eq a, Show a) =>
RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
run_tests RegexType
rty String -> Maybe UTCTime
forall a. Replace a => a -> Maybe UTCTime
parseDateTimeCLF [(String, UTCTime)]
samples MacroEnv
env PreludeMacro
pm
    MacroDescriptor :: RegexSource
-> [String]
-> [String]
-> [TestResult]
-> Maybe FunctionID
-> String
-> MacroDescriptor
MacroDescriptor
      { macroSource :: RegexSource
macroSource          = RegexSource
re
      , macroSamples :: [String]
macroSamples         = ((String, UTCTime) -> String) -> [(String, UTCTime)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, UTCTime) -> String
forall a b. (a, b) -> a
fst [(String, UTCTime)]
samples
      , macroCounterSamples :: [String]
macroCounterSamples = [String]
counter_samples
      , macroTestResults :: [TestResult]
macroTestResults    = []
      , macroParser :: Maybe FunctionID
macroParser          = FunctionID -> Maybe FunctionID
forall a. a -> Maybe a
Just FunctionID
"parseDateTimeCLF"
      , macroDescription :: String
macroDescription     = String
"Common Log Format date+time: %d/%b/%Y:%H:%M:%S %z"
      }
  where
    samples :: [(String,UTCTime)]
    samples :: [(String, UTCTime)]
samples =
        [ String -> String -> (String, UTCTime)
f String
"10/Oct/2000:13:55:36 -0700"  String
"2000-10-10 13:55:36-0700"
        , String -> String -> (String, UTCTime)
f String
"10/Oct/2000:13:55:36 +07:00" String
"2000-10-10 13:55:36+0700"
        ]
      where
        f :: String -> String -> (String,UTCTime)
        f :: String -> String -> (String, UTCTime)
f String
s String
r_s = (String
s,String -> UTCTime
forall a. Read a => String -> a
read String
r_s)

    counter_samples :: [String]
counter_samples =
        [ String
""
        , String
"2016-12-31T23:37+0100"
        , String
"10/Oct/2000:13:55:36-0700"
        , String
"10/OCT/2000:13:55:36 -0700"
        , String
"10/Oct/2000:13:55 -0700"
        , String
"10/Oct/2000:13:55Z"
        ]

    re :: RegexSource
re = String -> RegexSource
RegexSource (String -> RegexSource) -> String -> RegexSource
forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords
      [ String
"[0-9]{2}/@{%shortmonth}/[0-9]{4}:[0-9]{2}:[0-9]{2}:[0-9]{2}"
      , String
"[+-][0-9]{2}:?[0-9]{2}"
      ]

shortmonth_macro :: RegexType
                 -> MacroEnv
                 -> PreludeMacro
                 -> Maybe MacroDescriptor
shortmonth_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
shortmonth_macro RegexType
rty MacroEnv
env PreludeMacro
pm =
  MacroDescriptor -> Maybe MacroDescriptor
forall a. a -> Maybe a
Just (MacroDescriptor -> Maybe MacroDescriptor)
-> MacroDescriptor -> Maybe MacroDescriptor
forall a b. (a -> b) -> a -> b
$ RegexType
-> (String -> Maybe Int)
-> [(String, Int)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
forall a.
(Eq a, Show a) =>
RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
run_tests RegexType
rty String -> Maybe Int
forall a. Replace a => a -> Maybe Int
parseShortMonth [(String, Int)]
samples MacroEnv
env PreludeMacro
pm
    MacroDescriptor :: RegexSource
-> [String]
-> [String]
-> [TestResult]
-> Maybe FunctionID
-> String
-> MacroDescriptor
MacroDescriptor
      { macroSource :: RegexSource
macroSource          = String -> RegexSource
bracketedRegexSource (String -> RegexSource) -> String -> RegexSource
forall a b. (a -> b) -> a -> b
$
                                String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"|" ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (Text -> String) -> [Text] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Text -> String
T.unpack ([Text] -> [String]) -> [Text] -> [String]
forall a b. (a -> b) -> a -> b
$ Array Int Text -> [Text]
forall i e. Array i e -> [e]
elems Array Int Text
shortMonthArray
      , macroSamples :: [String]
macroSamples         = ((String, Int) -> String) -> [(String, Int)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, Int) -> String
forall a b. (a, b) -> a
fst [(String, Int)]
samples
      , macroCounterSamples :: [String]
macroCounterSamples = [String]
counter_samples
      , macroTestResults :: [TestResult]
macroTestResults    = []
      , macroParser :: Maybe FunctionID
macroParser          = FunctionID -> Maybe FunctionID
forall a. a -> Maybe a
Just FunctionID
"parseShortMonth"
      , macroDescription :: String
macroDescription     = String
"three letter month name: Jan-Dec"
      }
  where
    samples :: [(String,Int)]
    samples :: [(String, Int)]
samples =
        [ String -> Int -> (String, Int)
forall a b. a -> b -> (a, b)
f String
"Jan"   Int
1
        , String -> Int -> (String, Int)
forall a b. a -> b -> (a, b)
f String
"Feb"   Int
2
        , String -> Int -> (String, Int)
forall a b. a -> b -> (a, b)
f String
"Dec"   Int
12
        ]
      where
        f :: a -> b -> (a, b)
f = (,)

    counter_samples :: [String]
counter_samples =
        [ String
""
        , String
"jan"
        , String
"DEC"
        , String
"January"
        , String
"01"
        , String
"1"
        ]

address_ipv4_macros :: RegexType
                    -> MacroEnv
                    -> PreludeMacro
                    -> Maybe MacroDescriptor
address_ipv4_macros :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
address_ipv4_macros RegexType
rty MacroEnv
env PreludeMacro
pm =
  MacroDescriptor -> Maybe MacroDescriptor
forall a. a -> Maybe a
Just (MacroDescriptor -> Maybe MacroDescriptor)
-> MacroDescriptor -> Maybe MacroDescriptor
forall a b. (a -> b) -> a -> b
$ RegexType
-> (String -> Maybe IPV4Address)
-> [(String, IPV4Address)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
forall a.
(Eq a, Show a) =>
RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
run_tests RegexType
rty String -> Maybe IPV4Address
forall a. Replace a => a -> Maybe IPV4Address
parseIPv4Address [(String, IPV4Address)]
samples MacroEnv
env PreludeMacro
pm
    MacroDescriptor :: RegexSource
-> [String]
-> [String]
-> [TestResult]
-> Maybe FunctionID
-> String
-> MacroDescriptor
MacroDescriptor
      { macroSource :: RegexSource
macroSource          = RegexSource
"[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}"
      , macroSamples :: [String]
macroSamples         = ((String, IPV4Address) -> String)
-> [(String, IPV4Address)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, IPV4Address) -> String
forall a b. (a, b) -> a
fst [(String, IPV4Address)]
samples
      , macroCounterSamples :: [String]
macroCounterSamples = [String]
counter_samples
      , macroTestResults :: [TestResult]
macroTestResults    = []
      , macroParser :: Maybe FunctionID
macroParser          = FunctionID -> Maybe FunctionID
forall a. a -> Maybe a
Just FunctionID
"parseSeverity"
      , macroDescription :: String
macroDescription     = String
"an a.b.c.d IPv4 address"
      }
  where
    samples :: [(String,IPV4Address)]
    samples :: [(String, IPV4Address)]
samples =
        [ String -> IPV4Address -> (String, IPV4Address)
forall a b. a -> b -> (a, b)
f String
"0.0.0.0"           (  Word8
0,  Word8
0,  Word8
0,  Word8
0)
        , String -> IPV4Address -> (String, IPV4Address)
forall a b. a -> b -> (a, b)
f String
"123.45.6.78"       (Word8
123, Word8
45,  Word8
6, Word8
78)
        , String -> IPV4Address -> (String, IPV4Address)
forall a b. a -> b -> (a, b)
f String
"9.9.9.9"           (  Word8
9,  Word8
9,  Word8
9,  Word8
9)
        , String -> IPV4Address -> (String, IPV4Address)
forall a b. a -> b -> (a, b)
f String
"255.255.255.255"   (Word8
255,Word8
255,Word8
255,Word8
255)
        ]
      where
        f :: a -> b -> (a, b)
f = (,)

    counter_samples :: [String]
counter_samples =
        [ String
""
        , String
"foo"
        , String
"1234.0.0.0"
        , String
"1.2.3"
        , String
"1.2.3."
        , String
"1.2..4"
        , String
"www.example.com"
        , String
"2001:0db8:85a3:0000:0000:8a2e:0370:7334"
        ]

syslog_severity_macro :: RegexType
                      -> MacroEnv
                      -> PreludeMacro
                      -> Maybe MacroDescriptor
syslog_severity_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
syslog_severity_macro RegexType
rty MacroEnv
env PreludeMacro
pm =
  MacroDescriptor -> Maybe MacroDescriptor
forall a. a -> Maybe a
Just (MacroDescriptor -> Maybe MacroDescriptor)
-> MacroDescriptor -> Maybe MacroDescriptor
forall a b. (a -> b) -> a -> b
$ RegexType
-> (String -> Maybe Severity)
-> [(String, Severity)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
forall a.
(Eq a, Show a) =>
RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
run_tests RegexType
rty String -> Maybe Severity
forall a. Replace a => a -> Maybe Severity
parseSeverity [(String, Severity)]
samples MacroEnv
env PreludeMacro
pm
    MacroDescriptor :: RegexSource
-> [String]
-> [String]
-> [TestResult]
-> Maybe FunctionID
-> String
-> MacroDescriptor
MacroDescriptor
      { macroSource :: RegexSource
macroSource          = RegexSource
re
      , macroSamples :: [String]
macroSamples         = ((String, Severity) -> String) -> [(String, Severity)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, Severity) -> String
forall a b. (a, b) -> a
fst [(String, Severity)]
samples
      , macroCounterSamples :: [String]
macroCounterSamples = [String]
counter_samples
      , macroTestResults :: [TestResult]
macroTestResults    = []
      , macroParser :: Maybe FunctionID
macroParser          = FunctionID -> Maybe FunctionID
forall a. a -> Maybe a
Just FunctionID
"parseSeverity"
      , macroDescription :: String
macroDescription     = String
"syslog severity keyword (debug-emerg)"
      }
  where
    samples :: [(String,Severity)]
    samples :: [(String, Severity)]
samples =
        [ String -> Severity -> (String, Severity)
forall a b. a -> b -> (a, b)
f String
"emerg"     Severity
Emerg
        , String -> Severity -> (String, Severity)
forall a b. a -> b -> (a, b)
f String
"panic"     Severity
Emerg
        , String -> Severity -> (String, Severity)
forall a b. a -> b -> (a, b)
f String
"alert"     Severity
Alert
        , String -> Severity -> (String, Severity)
forall a b. a -> b -> (a, b)
f String
"crit"      Severity
Crit
        , String -> Severity -> (String, Severity)
forall a b. a -> b -> (a, b)
f String
"err"       Severity
Err
        , String -> Severity -> (String, Severity)
forall a b. a -> b -> (a, b)
f String
"error"     Severity
Err
        , String -> Severity -> (String, Severity)
forall a b. a -> b -> (a, b)
f String
"warn"      Severity
Warning
        , String -> Severity -> (String, Severity)
forall a b. a -> b -> (a, b)
f String
"warning"   Severity
Warning
        , String -> Severity -> (String, Severity)
forall a b. a -> b -> (a, b)
f String
"notice"    Severity
Notice
        , String -> Severity -> (String, Severity)
forall a b. a -> b -> (a, b)
f String
"info"      Severity
Info
        , String -> Severity -> (String, Severity)
forall a b. a -> b -> (a, b)
f String
"debug"     Severity
Debug
        ]
      where
        f :: a -> b -> (a, b)
f = (,)

    counter_samples :: [String]
counter_samples =
        [ String
""
        , String
"Emergency"
        , String
"ALERT"
        ]

    re :: RegexSource
re = if RegexType -> Bool
isPCRE RegexType
rty
      then RegexSource
re_pcre
      else RegexSource
re_tdfa

    re_tdfa :: RegexSource
re_tdfa = String -> RegexSource
bracketedRegexSource (String -> RegexSource) -> String -> RegexSource
forall a b. (a -> b) -> a -> b
$
          String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"|" ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$
            [ Text -> String
T.unpack Text
kw
              | (Text
kw0,[Text]
kws) <- (Severity -> (Text, [Text])) -> [Severity] -> [(Text, [Text])]
forall a b. (a -> b) -> [a] -> [b]
map Severity -> (Text, [Text])
severityKeywords [Severity
forall a. Bounded a => a
minBound..Severity
forall a. Bounded a => a
maxBound]
              , Text
kw <- Text
kw0Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
:[Text]
kws
              ]

    re_pcre :: RegexSource
re_pcre = String -> RegexSource
bracketedRegexSource (String -> RegexSource) -> String -> RegexSource
forall a b. (a -> b) -> a -> b
$
          String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"|" ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$
            [ Text -> String
T.unpack Text
kw
              | (Text
kw0,[Text]
kws) <- (Severity -> (Text, [Text])) -> [Severity] -> [(Text, [Text])]
forall a b. (a -> b) -> [a] -> [b]
map Severity -> (Text, [Text])
severityKeywords ([Severity] -> [(Text, [Text])]) -> [Severity] -> [(Text, [Text])]
forall a b. (a -> b) -> a -> b
$
                                  (Severity -> Bool) -> [Severity] -> [Severity]
forall a. (a -> Bool) -> [a] -> [a]
filter (Severity -> Severity -> Bool
forall a. Eq a => a -> a -> Bool
/=Severity
Err) [Severity
forall a. Bounded a => a
minBound..Severity
forall a. Bounded a => a
maxBound]
              , Text
kw <- Text
kw0Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
:[Text]
kws
              ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String
"err(?:or)?"]

email_simple_macro :: RegexType
                   -> MacroEnv
                   -> PreludeMacro
                   -> Maybe MacroDescriptor
email_simple_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
email_simple_macro RegexType
rty MacroEnv
env PreludeMacro
pm =
  MacroDescriptor -> Maybe MacroDescriptor
forall a. a -> Maybe a
Just (MacroDescriptor -> Maybe MacroDescriptor)
-> MacroDescriptor -> Maybe MacroDescriptor
forall a b. (a -> b) -> a -> b
$ RegexType
-> (String -> Maybe String)
-> [(String, String)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
forall a.
(Eq a, Show a) =>
RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
run_tests RegexType
rty String -> Maybe String
forall a. a -> Maybe a
Just [(String, String)]
samples MacroEnv
env PreludeMacro
pm
    MacroDescriptor :: RegexSource
-> [String]
-> [String]
-> [TestResult]
-> Maybe FunctionID
-> String
-> MacroDescriptor
MacroDescriptor
      { macroSource :: RegexSource
macroSource          = RegexSource
"[a-zA-Z0-9%_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9.-]+"
      , macroSamples :: [String]
macroSamples         = ((String, String) -> String) -> [(String, String)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, String) -> String
forall a b. (a, b) -> a
fst [(String, String)]
samples
      , macroCounterSamples :: [String]
macroCounterSamples = [String]
counter_samples
      , macroTestResults :: [TestResult]
macroTestResults    = []
      , macroParser :: Maybe FunctionID
macroParser          = Maybe FunctionID
forall a. Maybe a
Nothing
      , macroDescription :: String
macroDescription     = String
"an email address"
      }
  where
    samples :: [(String,String)]
    samples :: [(String, String)]
samples =
        [ String -> (String, String)
forall b. b -> (b, b)
f String
"user-name%foo.bar.com@an-example.com"
        ]
      where
        f :: b -> (b, b)
f b
s = (b
s,b
s)

    counter_samples :: [String]
counter_samples =
        [ String
""
        , String
"not-an-email-address"
        , String
"@not-an-email-address"
        ]
-- | see https://mathiasbynens.be/demo/url-regex
-- (based on @stephenhay URL)
url_macro :: RegexType
          -> MacroEnv
          -> PreludeMacro
          -> Maybe MacroDescriptor
url_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
url_macro RegexType
rty MacroEnv
env PreludeMacro
pm =
  MacroDescriptor -> Maybe MacroDescriptor
forall a. a -> Maybe a
Just (MacroDescriptor -> Maybe MacroDescriptor)
-> MacroDescriptor -> Maybe MacroDescriptor
forall a b. (a -> b) -> a -> b
$ RegexType
-> (String -> Maybe String)
-> [(String, String)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
forall a.
(Eq a, Show a) =>
RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
run_tests RegexType
rty String -> Maybe String
forall a. a -> Maybe a
Just [(String, String)]
samples MacroEnv
env PreludeMacro
pm
    MacroDescriptor :: RegexSource
-> [String]
-> [String]
-> [TestResult]
-> Maybe FunctionID
-> String
-> MacroDescriptor
MacroDescriptor
      { macroSource :: RegexSource
macroSource          = RegexSource
"([hH][tT][tT][pP][sS]?|[fF][tT][pP])://[^[:space:]/$.?#].[^[:space:]]*"
      , macroSamples :: [String]
macroSamples         = ((String, String) -> String) -> [(String, String)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, String) -> String
forall a b. (a, b) -> a
fst [(String, String)]
samples
      , macroCounterSamples :: [String]
macroCounterSamples = [String]
counter_samples
      , macroTestResults :: [TestResult]
macroTestResults    = []
      , macroParser :: Maybe FunctionID
macroParser          = Maybe FunctionID
forall a. Maybe a
Nothing
      , macroDescription :: String
macroDescription     = String
"a URL"
      }
  where
    samples :: [(String,String)]
    samples :: [(String, String)]
samples =
        [ String -> (String, String)
forall b. b -> (b, b)
f String
"https://mathiasbynens.be/demo/url-regex"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"http://foo.com/blah_blah"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"http://foo.com/blah_blah/"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"http://foo.com/blah_blah_(wikipedia)"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"http://foo.com/blah_blah_(wikipedia)_(again)"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"http://www.example.com/wpstyle/?p=364"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"HTTPS://foo.bar/?q=Test%20URL-encoded%20stuff"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"HTTP://223.255.255.254"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"ftp://223.255.255.254"
        , String -> (String, String)
forall b. b -> (b, b)
f String
"FTP://223.255.255.254"
        ]
      where
        f :: b -> (b, b)
f b
s = (b
s,b
s)

    counter_samples :: [String]
counter_samples =
        [ String
""
        , String
"http://"
        , String
"http://."
        , String
"http://.."
        , String
"http://../"
        , String
"http://?"
        , String
"http://??"
        , String
"http://foo.bar?q=Spaces should be encoded"
        , String
"//"
        , String
"http://##/"
        , String
"http://##"
        , String
"http://##/"
        ]

run_tests :: (Eq a,Show a)
          => RegexType
          -> (String->Maybe a)
          -> [(String,a)]
          -> MacroEnv
          -> PreludeMacro
          -> MacroDescriptor
          -> MacroDescriptor
run_tests :: RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
run_tests RegexType
rty String -> Maybe a
parser [(String, a)]
vector MacroEnv
env =
  RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> MacroID
-> MacroDescriptor
-> MacroDescriptor
forall a.
(Eq a, Show a) =>
RegexType
-> (String -> Maybe a)
-> [(String, a)]
-> MacroEnv
-> MacroID
-> MacroDescriptor
-> MacroDescriptor
runTests RegexType
rty String -> Maybe a
parser [(String, a)]
vector MacroEnv
env (MacroID -> MacroDescriptor -> MacroDescriptor)
-> (PreludeMacro -> MacroID)
-> PreludeMacro
-> MacroDescriptor
-> MacroDescriptor
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PreludeMacro -> MacroID
prelude_macro_id

bracketedRegexSource :: String -> RegexSource
bracketedRegexSource :: String -> RegexSource
bracketedRegexSource String
re_s = String -> RegexSource
RegexSource (String -> RegexSource) -> String -> RegexSource
forall a b. (a -> b) -> a -> b
$ String
"(?:" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
re_s String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"

fix :: (a->a) -> a
fix :: (a -> a) -> a
fix a -> a
f = a -> a
f ((a -> a) -> a
forall a. (a -> a) -> a
fix a -> a
f)