packages feed

HSFFIG-1.1: programs/SPmain.hs

-- 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