packages feed

curry-frontend-0.2.12: src/cymake.hs

-- -----------------------------------------------------------------------------
-- |
-- cymake - The Curry builder
--
--          Command line tool for generating Curry representations (e.g.
--          FlatCurry, AbstractCurry) for a Curry source file including
--          all imported modules.
--
-- September 2005, Martin Engelke (men@informatik.uni-kiel.de)
--
-- -----------------------------------------------------------------------------

module Main(main) where

import Data.List
import Data.Maybe
import System.Console.GetOpt
import System.Environment(getArgs, getProgName)
import System.Exit(ExitCode(..), exitWith)
import System.IO
import Control.Monad (unless)

import CurryBuilder(buildCurry)
import CurryCompilerOpts
import CurryHtml
import Curry.Files.CymakePath (cymakeVersion)


-- | The command line tool cymake
main :: IO ()
main = do
  prog <- getProgName
  args <- getArgs
  cymake prog args

-- | Checks the command line arguments and invokes the curry builder
cymake :: String -> [String] -> IO ()
cymake prog args
  | elem Help opts = printUsage prog
  | null files     = badUsage prog ["no files"]
  | null errs'
    && not (elem Html opts) = do
      unless (noVerb options')
        (putStrLn $ "This is cymake, version " ++ cymakeVersion)
      mapM_ (buildCurry options') files
  | null errs'     = do
                     let importFiles = nub $ importPaths opts'
                         outputFile  = maybe "" id (output opts')
                     mapM_ (source2html importFiles outputFile) files
  | otherwise      = badUsage prog errs'
  where
  (opts, files, errs) = getOpt Permute options args
  opts'               = foldr selectOption defaultOpts opts
  options'            = if flat opts' || flatXml opts' || abstract opts'
                        || untypedAbstract opts' || parseOnly opts'
                          then  opts'
                          else  opts'{ flat = True }
  errs'               = errs ++ check options' files

-- | Prints usage information of the command line tool.
printUsage :: String -> IO ()
printUsage prog = do
  putStrLn (usageInfo header options)
  exitWith ExitSuccess
  where header = "usage: " ++ prog ++ " [OPTION] ... MODULE ..."

-- | Prints errors
badUsage :: String -> [String] -> IO ()
badUsage prog errs = do
  putErrsLn $ map (\err -> prog ++ ": " ++ err) errs
  abortWith ["Try '" ++ prog ++ " -" ++ "-help' for more information"]

-- | Checks options and files and return a list of error messages
check :: Options -> [String] -> [String]
check opts files
   | null files
     = ["no files"]
   | isJust (output opts) && length files > 1
     = ["cannot specify -o with multiple targets"]
   | otherwise
     = []

-- | Prints an error message on 'stderr'
putErrLn :: String -> IO ()
putErrLn = hPutStrLn stderr

-- | Prints a list of error messages on 'stderr'
putErrsLn :: [String] -> IO ()
putErrsLn = mapM_ putErrLn

-- | Prints a list of error messages on 'stderr' and aborts the program with
--   exit code 1
abortWith :: [String] -> IO a
abortWith errs = putErrsLn errs >> exitWith (ExitFailure 1)

-- -----------------------------------------------------------------------------
-- -----------------------------------------------------------------------------