module Main where import System import List import Char data Test = Expr String | Test [String] String deriving Show main = do src <- readFile "../System/FilePath/Internal.hs" let tests = concatMap getTest $ zip [1..] (lines src) writeFile "FilePath_Test.hs" (prefix ++ genTests tests) prefix = unlines ["import AutoTest" ,"import qualified System.FilePath.Windows as W" ,"import qualified System.FilePath.Posix as P" ,"main = do" ] getTest :: (Int,String) -> [(Int,Test)] getTest (line,xs) | "-- > " `isPrefixOf` xs = f $ drop 5 xs where f x | "Windows:" `isPrefixOf` x = let res = grabTest (drop 8 x) in [g "W" res] | "Posix:" `isPrefixOf` x = let res = grabTest (drop 6 x) in [g "P" res] | otherwise = let res = grabTest x in [g "W" res, g "P" res] g p (Expr x) = (line,Expr (h p x)) g p (Test a x) = (line,Test a (h p x)) h p x = joinLex $ map (addPrefix p) $ splitLex x getTest _ = [] addPrefix :: String -> String -> String addPrefix pre str | all isAlpha str && length str > 1 && not (str `elem` prelude) = pre ++ "." ++ str | otherwise = str prelude = ["elem","uncurry","snd","fst","not","null","if","then","else","True","False","concat"] grabTest :: String -> Test grabTest x = if null free then Expr x else Test free x where free = nub [x | x <- lexs, length x == 1, all isAlpha x] lexs = splitLex x splitLex :: String -> [String] splitLex x = case lex x of [("","")] -> [] [(x,y)] -> x : splitLex y y -> error $ "GenTests.splitLex, " ++ show x ++ " -> " ++ show y joinLex :: [String] -> String joinLex = unwords -- would be concat, but GHC has 'issues' rejoinTests :: [String] -> String rejoinTests xs = unlines $ [" block" ++ show i | i <- [1..length res]] ++ concat (zipWith rejoin [1..] res) where res = divide xs divide [] = [] divide x = a : divide b where (a,b) = splitAt 50 x rejoin n xs = ("block" ++ show n ++ " = do") : xs genTests :: [(Int, Test)] -> String genTests xs = rejoinTests $ concatMap f $ zip [1..] xs where f (tno,(lno,test)) = [" putStrLn \"Test " ++ show tno ++ ", from line " ++ show lno ++ "\"" ," " ++ genTest test] -- the result must be a line of the type "IO ()" genTest :: Test -> String genTest (Expr x) = "constTest (" ++ x ++ ")" genTest (Test free x) = "quickSafe (\\" ++ concatMap ((' ':) . f) free ++ " -> (" ++ x ++ "))" where f [a] | a >= 'x' = "(QFilePath " ++ [a] ++ ")" f x = x