-- An utility to split a source Haskell file -- generated by hsffig into smaller parts as guided -- by the special comments found in the file. module SPmain where import System.IO import Control.Monad import Data.Maybe import SplitBounds splitterMain args = do case args of [] -> usage >> return [] other -> splitModule $ head args -- Print the usage information. usage = putStrLn "Usage: splitter filename" -- Do the actual module split. The file name is expected -- to be in the form [path/]MODULENAME[.suffix]. Path will be preserved. -- Suffix will be replaced with .hs. Names of modules will be derived from -- MODULENAME. splitModule fn = do let [fnname, fnpath] = map reverse $ (\t -> [fst t, snd t]) $ break ( == '/') $ reverse fn (modbase, fnsuffix) = break ( == '.') fnname -- Open the file src <- (readFile fn) let srcln = lines src procLines [] Nothing fnpath srcln -- Line-by-line processor. procLines fnl _ _ [] = return fnl procLines fnl handle fnpath (l:ls) = do let derivefn app = fnpath ++ app ++ ".hs" skipline = do fnl' <- procLines fnl handle fnpath ls return $ fnl ++ fnl' startfile app = do handle' <- openFile (derivefn app) WriteMode fnl' <- procLines fnl (Just handle') fnpath ls return $ app : (fnl ++ fnl') endfile = do when (handle /= Nothing) $ hClose (fromJust handle) fnl' <- procLines fnl Nothing fnpath ls return $ fnl ++ fnl' nextline = do when (handle /= Nothing) $ hPutStrLn (fromJust handle) l fnl' <- procLines fnl handle fnpath ls return $ fnl ++ fnl' case l of _ | l == splitOpen -> skipline -- these comments _ | l == splitClose -> skipline -- are removed _ | (takeWhile (/= '/') l) == splitBegin -> startfile $ drop 1 $ dropWhile (/= '/') l _ | l == splitEnd -> endfile other -> nextline