packages feed

java-bridge-0.20130606.3: j2hs/Main.hss

{-# LANGUAGE Haskell2010
 #-}

module Main where

import Options
import Java2Haskell

import Foreign.Java.Bindings
import Foreign.Java.Utils
import Foreign.Java.JNI (javaBridgeVersion)

import System.Console.GetOpt
import System.Environment (getArgs, getProgName)

import Data.Maybe
import Data.NamedRecord
import Data.List
import Data.List.Split
import Data.Word

import Text.Printf

versionInfo = """
    Java <-> Haskell Bindings Generator (using java-bridge #{javaBridgeVersion})"""

-- | The flags (needed for the options list / GetOpt).
data Flag = Help
          | Version
          | Packages [String]
          | Classpath [String]
          | SearchDepth Word32
          | TargetDirectory String
          | CompleteSE6
          | OnlyReflect
          | Filtered
          | Verbose

-- | The Command line options as fed to the GetOpt parser.
options = [
    Option "h" ["help"] (NoArg Help)
        "Print this help text.",

    Option "V" ["version"] (NoArg Version)
        "Print version information.",

    Option "c" ["classpath"] (ReqArg readClasspath "")
        "The Java classpath to be used.",

    Option "P" ["packages"] (ReqArg readPackages "")
        "The packages to translate.",

    Option "d" ["search-depth"] (ReqArg readSearchDepth "")
        "The maximum search depth for dependent Java classes.",

    Option "v" ["verbose"] (NoArg Verbose)
        "Verbose output, prints extra diagnostic information.",

    Option "R" ["reflect"] (NoArg OnlyReflect)
        "Only reflect the given java files (mainly for debugging purposes).",

    Option "X" [] (NoArg CompleteSE6)
        "Completely translate Java SE.",

    Option "F" [] (NoArg Filtered)
        "Only translate a subset of the Java SE.",

    Option "t" ["target-directory"] (ReqArg TargetDirectory "")
        "The target directory for generated source files."

 ] where
    readPackages = Packages . splitOneOf ":;,"
    readClasspath = Classpath . splitOneOf ":;,"
    readSearchDepth = SearchDepth . read

parseArgs :: IO (Either (Options, [String]) [String])
-- ^ Parse command line arguments with the help of the GetOpt library.
parseArgs = do
    (opts, args, errs) <- getArgs >>= return . getOpt Permute options
    if null errs
        then return $ Left  (parseOpts newOptions opts, args)
        else return $ Right errs
  where
    parseOpts opts [] = opts
    parseOpts opts (x:xs) = flip parseOpts xs $
        case x of
            Help              -> opts `set` optShowHelp        := True
            Version           -> opts `set` optShowVersion     := True
            Verbose           -> opts `set` optVerbose         := True
            Filtered          -> opts `set` optFiltered        := True
            CompleteSE6       -> opts `set` optCompleteSE6     := True
            OnlyReflect       -> opts `set` optOnlyReflect     := True
            Classpath cp      -> opts `set` optClasspath       := cp
            Packages pkgs     -> opts `set` optPackages        := pkgs
            SearchDepth d     -> opts `set` optSearchDepth     := d
            TargetDirectory t -> opts `set` optTargetDirectory := t

main :: IO ()
-- ^ main: parseArgs and either 'run' or show errors.
main = parseArgs >>= either (uncurry run) (mapM_ putStr)

run :: Options -> [String] -> IO ()
-- ^ The actual main function.
run opts args
    | opts `get` optShowHelp = do
        progName <- getProgName
        putStrLn (usageInfo """
            #{versionInfo}
            
            Usage: #{progName} [options] command [files...]
            
            Use `#{progName} help' for information about commands.
            """ options)

    | opts `get` optShowVersion = putStrLn versionInfo
    | opts `get` optCompleteSE6 =
        if opts `get` optFiltered then j2hs opts (filter minimal  javaClassesSE6)
                                  else j2hs opts (filter justJava javaClassesSE6)

    | otherwise = getProgName >>= \progName -> putStr """
        No command given. Use `#{progName} help' for help.
        """
  where
    justJava = ("java" `isPrefixOf`)
    minimal name = pkg `elem` (opts `get` optPackages)
        where (pkg, _) = splitClassName name