import System.Environment (getArgs)
import System.Exit (exitWith, ExitCode(ExitFailure))
import System.IO (hPutStrLn, stderr)
import Control.Monad (when)
import Text.PrettyPrint.HughesPJ (render, text, (<+>), hsep)
import Language.C (parseCFile)
import Language.C.System.GCC (newGCC)
usageMsg :: String -> String
usageMsg prg = render $ text "Usage:" <+> text prg <+> hsep (map text ["CPP_OPTIONS","input_file.c"])
main :: IO ()
main = do
let usageErr = (hPutStrLn stderr (usageMsg "./ParseAndPrint") >> exitWith (ExitFailure 1))
args <- getArgs
when (length args < 1) usageErr
let (opts,input_file) = (init args, last args)
ast <- errorOnLeftM "Parse Error" $ parseCFile (newGCC "gcc") Nothing opts input_file
putStrLn $ (decorate (shows (fmap (const ShowPlaceholder) ast)) "")
errorOnLeft :: (Show a) => String -> (Either a b) -> IO b
errorOnLeft msg = either (error . ((msg ++ ": ")++).show) return
errorOnLeftM :: (Show a) => String -> IO (Either a b) -> IO b
errorOnLeftM msg action = action >>= errorOnLeft msg
data ShowPlaceholder = ShowPlaceholder
instance Show ShowPlaceholder where
showsPrec _ ShowPlaceholder = showString "_"
decorate :: ShowS -> ShowS
decorate app = showString "(" . app . showString ")"