regex-examples-0.9.0.0: examples/re-gen-modules.lhs
Regex Module Gen
================
All of the modules that make up the API are generated from the
`Text.RE.TDFA.ByteString.Lazy` module using this script.
The tool is self-testing: run it with no arguments (or `cabal test`).
\begin{code}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE CPP #-}
module Main (main) where
import Control.Exception
import qualified Data.ByteString.Lazy.Char8 as LBS
import qualified Data.Text as T
import Prelude.Compat
import qualified Shelly as SH
import System.Directory
import System.Environment
import System.Exit
import System.IO
import Text.RE.TDFA.ByteString.Lazy
import Text.RE.Tools.Sed
import Text.RE.Types.SearchReplace
main :: IO ()
main = do
(pn,as) <- (,) <$> getProgName <*> getArgs
case as of
[] -> test
["test"] -> test
["gen"] -> gen
_ -> do
hPutStrLn stderr $ "usage: " ++ pn ++ " [test|gen]"
exitWith $ ExitFailure 1
test :: IO ()
test = do
createDirectoryIfMissing False "tmp"
tdfa_ok <- and <$> mapM test' tdfa_edits
pcre_ok <- and <$> mapM test' pcre_edits
case tdfa_ok && pcre_ok of
True -> return ()
False -> exitWith $ ExitFailure 1
type SedScript = Edits IO RE LBS.ByteString
test' :: (ModPath,SedScript) -> IO Bool
test' (mp,scr) = do
putStrLn mp
tp <- is_text_present
sed scr (mod_filepath tp source_mp) tmp_pth
cmp (T.pack tmp_pth) (T.pack $ mod_filepath tp mp)
where
tmp_pth = "tmp/prog.hs"
gen :: IO ()
gen = do
mapM_ gen' tdfa_edits
mapM_ gen' pcre_edits
gen' :: (ModPath,SedScript) -> IO ()
gen' (mp,scr) = do
putStrLn mp
tp <- is_text_present
sed scr (mod_filepath tp source_mp) (mod_filepath tp mp)
tdfa_edits :: [(ModPath,SedScript)]
tdfa_edits =
[ tdfa_edit "Text.RE.TDFA.ByteString" "B.ByteString" "import qualified Data.ByteString as B"
, tdfa_edit "Text.RE.TDFA.Sequence" "(S.Seq Char)" "import qualified Data.Sequence as S"
, tdfa_edit "Text.RE.TDFA.String" "String" ""
, tdfa_edit "Text.RE.TDFA.Text" "T.Text" "import qualified Data.Text as T"
, tdfa_edit "Text.RE.TDFA.Text.Lazy" "TL.Text" "import qualified Data.Text.Lazy as TL"
]
pcre_edits :: [(ModPath,SedScript)]
pcre_edits =
[ pcre_edit "Text.RE.PCRE.ByteString" "B.ByteString" "import qualified Data.ByteString as B"
, pcre_edit "Text.RE.PCRE.ByteString.Lazy" "LBS.ByteString" "import qualified Data.ByteString.Lazy as LBS"
, pcre_edit "Text.RE.PCRE.Sequence" "(S.Seq Char)" "import qualified Data.Sequence as S"
, pcre_edit "Text.RE.PCRE.String" "String" ""
]
tdfa_edit :: ModPath
-> LBS.ByteString
-> LBS.ByteString
-> (ModPath,SedScript)
tdfa_edit mp bs_lbs import_lbs =
(,) mp $ Pipe
[ Template $ SearchReplace module_re $ LBS.pack mp
, Template $ SearchReplace import_re import_lbs
, Template $ SearchReplace bs_re bs_lbs
]
pcre_edit :: ModPath
-> LBS.ByteString
-> LBS.ByteString
-> (ModPath,SedScript)
pcre_edit mp bs_lbs import_lbs =
(,) mp $ Pipe
[ Template $ SearchReplace tdfa_re "PCRE"
, Template $ SearchReplace module_re $ LBS.pack mp
, Template $ SearchReplace import_re import_lbs
, Template $ SearchReplace bs_re bs_lbs
]
type ModPath = String
source_mp :: ModPath
source_mp = "Text.RE.TDFA.ByteString.Lazy"
tdfa_re, module_re, import_re, bs_re :: RE
tdfa_re = [re|TDFA|]
module_re = [re|Text.RE.TDFA.ByteString.Lazy|]
import_re = [re|import qualified Data.ByteString.Lazy.Char8 *as LBS|]
bs_re = [re|LBS.ByteString|]
mod_filepath :: Bool -> ModPath -> FilePath
mod_filepath text_present mp = pfx ++ map tr mp ++ ".hs"
where
pfx = case text_present of
True -> ""
False -> "src/"
tr '.' = '/'
tr c = c
is_text_present :: IO Bool
is_text_present = doesDirectoryExist "Text"
cmp :: T.Text -> T.Text -> IO Bool
cmp src dst = handle hdl $ do
_ <- SH.shelly $ SH.verbosely $
SH.run "cmp" [src,dst]
return True
where
hdl :: SomeException -> IO Bool
hdl se = do
hPutStrLn stderr $
"testing results against model answers failed: " ++ show se
return False
\end{code}