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
).
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE CPP #-}
module Main (main) where
import qualified Data.ByteString.Lazy.Char8 as LBS
import qualified Data.Monoid as M
import qualified Data.Text as T
import Prelude.Compat
import System.Directory
import System.Environment
import System.Exit
import System.IO
import TestKit
import Text.RE.TDFA.ByteString.Lazy
import Text.RE.Tools.Sed
type ModPath = String
main :: IO ()
= do
main <- (,) <$> getProgName <*> getArgs
(pn,as) case as of
-> test
[] "test"] -> test
["gen"] -> gen
[-> do
_ $ "usage: " ++ pn ++ " [test|gen]"
hPutStrLn stderr $ ExitFailure 1
exitWith
------------------------------------------------------------------------
-- Testing
------------------------------------------------------------------------
test :: IO ()
= do
test False "tmp"
createDirectoryIfMissing <- and <$> mapM (test' source_api_mp) tdfa_api_edits
tdfa_ap_ok <- and <$> mapM (test' source_api_mp) pcre_api_edits
pcre_ap_ok case tdfa_ap_ok && pcre_ap_ok of
True -> return ()
False -> exitWith $ ExitFailure 1
type SedScript = Edits IO RE LBS.ByteString
test' :: ModPath -> (ModPath,SedScript) -> IO Bool
= do
test' src_mp (mp,scr) putStrLn mp
<- is_text_present
tp <- read_file $ mod_filepath tp src_mp
lbs <- sortImports <$> sed' scr lbs
lbs'
write_file tmp_pth lbs'$ mod_filepath tp mp)
cmp (T.pack tmp_pth) (T.pack where
= "tmp/prog.hs"
tmp_pth
------------------------------------------------------------------------
-- Generating
------------------------------------------------------------------------
gen :: IO ()
= do
gen mapM_ (gen' source_api_mp) tdfa_api_edits
mapM_ (gen' source_api_mp) pcre_api_edits
mapM_ (gen' source_ed_mp ) tdfa_ed_edits
mapM_ (gen' source_ed_mp ) pcre_ed_edits
gen' :: FilePath -> (ModPath,SedScript) -> IO ()
= do
gen' src_mp (mp,scr) putStrLn mp
<- is_text_present
tp <- read_file $ mod_filepath tp src_mp
lbs <- sortImports <$> sed' scr lbs
lbs'
write_file (mod_filepath tp mp) lbs'
------------------------------------------------------------------------
-- The API edits
------------------------------------------------------------------------
tdfa_api_edits :: [(ModPath,SedScript)]
=
tdfa_api_edits "TDFA.ByteString" "B.ByteString" "import qualified Data.ByteString as B"
[ tdfa_api_edit "TDFA.Sequence" "(S.Seq Char)" "import qualified Data.Sequence as S"
, tdfa_api_edit "TDFA.String" "String" ""
, tdfa_api_edit "TDFA.Text" "T.Text" "import qualified Data.Text as T"
, tdfa_api_edit "TDFA.Text.Lazy" "TL.Text" "import qualified Data.Text.Lazy as TL"
, tdfa_api_edit
]
pcre_api_edits :: [(ModPath,SedScript)]
=
pcre_api_edits "PCRE.ByteString" "B.ByteString" "import qualified Data.ByteString as B" False
[ pcre_api_edit "PCRE.ByteString.Lazy" "LBS.ByteString" "import qualified Data.ByteString.Lazy as LBS" False
, pcre_api_edit "PCRE.Sequence" "(S.Seq Char)" "import qualified Data.Sequence as S" False
, pcre_api_edit "PCRE.String" "String" "" False
, pcre_api_edit "PCRE.Text" "T.Text" "import qualified Data.Text as T" True
, pcre_api_edit "PCRE.Text.Lazy" "TL.Text" "import qualified Data.Text.Lazy as TL" True
, pcre_api_edit
]
tdfa_api_edit :: ModPath
-> LBS.ByteString
-> LBS.ByteString
-> (ModPath,SedScript)
import_lbs =
tdfa_api_edit mp bs_lbs $ Pipe
(,) fmp Template $ SearchReplace module_re $ LBS.pack mp
[ Template $ SearchReplace import_re import_lbs
, Template $ SearchReplace bs_re bs_lbs
,
]where
= "Text.RE." ++ mp
fmp
pcre_api_edit :: ModPath
-> LBS.ByteString
-> LBS.ByteString
-> Bool
-> (ModPath,SedScript)
import_lbs is_orp =
pcre_api_edit mp bs_lbs $ Pipe $
(,) fmp Template $ SearchReplace tdfa_re "PCRE"
[ Template $ SearchReplace module_re $ LBS.pack mp
, Template $ SearchReplace import_re import_lbs
, Template $ SearchReplace bs_re bs_lbs
, ++
] Template $ SearchReplace orp_re $ orphan_import mp
[ | is_orp
]where
= "Text.RE." ++ mp
fmp
source_api_mp :: ModPath
= "Text.RE.TDFA.ByteString.Lazy"
source_api_mp
orphan_import :: ModPath -> LBS.ByteString
= "import Text.Regex." M.<> LBS.pack mp M.<> "()"
orphan_import mp
import_re, bs_re, orp_re :: RE
tdfa_re, module_re, = [re|TDFA|]
tdfa_re = [re|TDFA.ByteString.Lazy|]
module_re import_re = [re|import qualified Data.ByteString.Lazy.Char8 *as LBS|]
= [re|LBS.ByteString|]
bs_re = [re|^-- NB regex-base instance imports.*$|]
orp_re
------------------------------------------------------------------------
-- The ed quasi quoter edits
------------------------------------------------------------------------
source_ed_mp :: ModPath
= "Text.RE.ZeInternals.SearchReplace.TDFA.ByteString.Lazy"
source_ed_mp
tdfa_ed_edits :: [(ModPath,SedScript)]
=
tdfa_ed_edits "Text.RE.ZeInternals.SearchReplace.TDFA.ByteString" $ Pipe
[ (,) Template [ed|SearchReplace.TDFA.ByteString.Lazy///SearchReplace.TDFA.ByteString|]
[ Template [ed|Data.ByteString.Lazy.Char8 as LBS///Data.ByteString.Char8 as B|]
, Template [ed|LBS.ByteString///B.ByteString|]
,
]"Text.RE.ZeInternals.SearchReplace.TDFA.Sequence" $ Pipe
, (,) Template [ed|SearchReplace.TDFA.ByteString.Lazy///SearchReplace.TDFA.Sequence|]
[ Template [ed|Data.ByteString.Lazy.Char8 as LBS///Data.Sequence as S|]
, Template [ed|LBS.ByteString///(S.Seq Char)|]
,
]"Text.RE.ZeInternals.SearchReplace.TDFA.String" $ Pipe
, (,) Template [ed|SearchReplace.TDFA.ByteString.Lazy///SearchReplace.TDFA.String|]
[ Template [ed|import qualified Data.ByteString.Lazy.Char8 as LBS///|]
, Template [ed|LBS.ByteString///String|]
,
]"Text.RE.ZeInternals.SearchReplace.TDFA.Text" $ Pipe
, (,) Template [ed|SearchReplace.TDFA.ByteString.Lazy///SearchReplace.TDFA.Text|]
[ Template [ed|Data.ByteString.Lazy.Char8 as LBS///Data.Text as T|]
, Template [ed|LBS.ByteString///T.Text|]
,
]"Text.RE.ZeInternals.SearchReplace.TDFA.Text.Lazy" $ Pipe
, (,) Template [ed|SearchReplace.TDFA.ByteString.Lazy///SearchReplace.TDFA.Text.Lazy|]
[ Template [ed|Data.ByteString.Lazy.Char8 as LBS///Data.Text.Lazy as TL|]
, Template [ed|LBS.ByteString///TL.Text|]
,
]
]
pcre_ed_edits :: [(ModPath,SedScript)]
=
pcre_ed_edits "Text.RE.ZeInternals.SearchReplace.PCRE.ByteString" $ pipe
[ (,) Template [ed|SearchReplace.TDFA.ByteString.Lazy///SearchReplace.PCRE.ByteString|]
[ Template [ed|Data.ByteString.Lazy.Char8 as LBS///Data.ByteString.Char8 as B|]
, Template [ed|LBS.ByteString///B.ByteString|]
,
]"Text.RE.ZeInternals.SearchReplace.PCRE.ByteString.Lazy" $ pipe
, (,) Template [ed|SearchReplace.TDFA.ByteString.Lazy///SearchReplace.PCRE.ByteString.Lazy|]
[ Template [ed|Text.RE.ZeInternals.TDFA///Text.RE.ZeInternals.PCRE|]
,
]"Text.RE.ZeInternals.SearchReplace.PCRE.Sequence" $ pipe
, (,) Template [ed|SearchReplace.TDFA.ByteString.Lazy///SearchReplace.PCRE.Sequence|]
[ Template [ed|Data.ByteString.Lazy.Char8 as LBS///Data.Sequence as S|]
, Template [ed|LBS.ByteString///(S.Seq Char)|]
, Template [ed|Text.RE.ZeInternals.TDFA///Text.RE.ZeInternals.PCRE|]
,
]"Text.RE.ZeInternals.SearchReplace.PCRE.String" $ pipe
, (,) Template [ed|SearchReplace.TDFA.ByteString.Lazy///SearchReplace.PCRE.String|]
[ Template [ed|import qualified Data.ByteString.Lazy.Char8 as LBS///|]
, Template [ed|LBS.ByteString///String|]
, Template [ed|Text.RE.ZeInternals.TDFA///Text.RE.ZeInternals.PCRE|]
,
]"Text.RE.ZeInternals.SearchReplace.PCRE.Text" $ pipe
, (,) Template [ed|SearchReplace.TDFA.ByteString.Lazy///SearchReplace.PCRE.Text|]
[ Template [ed|Data.ByteString.Lazy.Char8 as LBS///Data.Text as T|]
, Template [ed|LBS.ByteString///T.Text|]
,
]"Text.RE.ZeInternals.SearchReplace.PCRE.Text.Lazy" $ pipe
, (,) Template [ed|SearchReplace.TDFA.ByteString.Lazy///SearchReplace.PCRE.Text.Lazy|]
[ Template [ed|Data.ByteString.Lazy.Char8 as LBS///Data.Text.Lazy as TL|]
, Template [ed|LBS.ByteString///TL.Text|]
,
]
]where
= Pipe $ as ++
pipe as Template [ed|Text.RE.ZeInternals.TDFA///Text.RE.ZeInternals.PCRE|]
[ Template [ed|Text.RE.ZeInternals.SearchReplace.TDFAEdPrime///Text.RE.ZeInternals.SearchReplace.PCREEdPrime|]
,
]
------------------------------------------------------------------------
-- Helpers
------------------------------------------------------------------------
mod_filepath :: Bool -> ModPath -> FilePath
= pfx ++ map tr mp ++ ".hs"
mod_filepath text_present mp where
= case text_present of
pfx True -> ""
False -> "src/"
'.' = '/'
tr = c
tr c
is_text_present :: IO Bool
= doesDirectoryExist "Text" is_text_present