1{- 2-- The main program for cpphs, a simple C pre-processor written in Haskell. 3 4-- Copyright (c) 2004 Malcolm Wallace 5-- This file is LGPL (relicensed from the GPL by Malcolm Wallace, October 2011). 6-} 7module Language.Preprocessor.Cpphs.RunCpphs ( runCpphs 8 , runCpphsPass1 9 , runCpphsPass2 10 , runCpphsReturningSymTab 11 ) where 12 13import Language.Preprocessor.Cpphs.CppIfdef (cppIfdef) 14import Language.Preprocessor.Cpphs.MacroPass(macroPass,macroPassReturningSymTab) 15import Language.Preprocessor.Cpphs.Options (CpphsOptions(..), BoolOptions(..) 16 ,trailing) 17import Language.Preprocessor.Cpphs.Tokenise (deWordStyle, tokenise) 18import Language.Preprocessor.Cpphs.Position (cleanPath, Posn) 19import Language.Preprocessor.Unlit as Unlit (unlit) 20 21 22runCpphs :: CpphsOptions -> FilePath -> String -> IO String 23runCpphs options filename input = do 24 pass1 <- runCpphsPass1 options filename input 25 runCpphsPass2 (boolopts options) (defines options) filename pass1 26 27runCpphsPass1 :: CpphsOptions -> FilePath -> String -> IO [(Posn,String)] 28runCpphsPass1 options' filename input = do 29 let options= options'{ includes= map (trailing "\\/") (includes options') } 30 let bools = boolopts options 31 preInc = case preInclude options of 32 [] -> "" 33 is -> concatMap (\f->"#include \""++f++"\"\n") is 34 ++ "#line 1 \""++cleanPath filename++"\"\n" 35 36 pass1 <- cppIfdef filename (defines options) (includes options) bools 37 (preInc++input) 38 return pass1 39 40runCpphsPass2 :: BoolOptions -> [(String,String)] -> FilePath -> [(Posn,String)] -> IO String 41runCpphsPass2 bools defines filename pass1 = do 42 pass2 <- macroPass defines bools pass1 43 let result= if not (macros bools) 44 then if stripC89 bools || stripEol bools 45 then concatMap deWordStyle $ 46 tokenise (stripEol bools) (stripC89 bools) 47 (ansi bools) (lang bools) pass1 48 else unlines (map snd pass1) 49 else pass2 50 pass3 = if literate bools then Unlit.unlit filename else id 51 return (pass3 result) 52 53runCpphsReturningSymTab :: CpphsOptions -> FilePath -> String 54 -> IO (String,[(String,String)]) 55runCpphsReturningSymTab options' filename input = do 56 let options= options'{ includes= map (trailing "\\/") (includes options') } 57 let bools = boolopts options 58 preInc = case preInclude options of 59 [] -> "" 60 is -> concatMap (\f->"#include \""++f++"\"\n") is 61 ++ "#line 1 \""++cleanPath filename++"\"\n" 62 (pass2,syms) <- 63 if macros bools then do 64 pass1 <- cppIfdef filename (defines options) (includes options) 65 bools (preInc++input) 66 macroPassReturningSymTab (defines options) bools pass1 67 else do 68 pass1 <- cppIfdef filename (defines options) (includes options) 69 bools{macros=True} (preInc++input) 70 (_,syms) <- macroPassReturningSymTab (defines options) bools pass1 71 pass1 <- cppIfdef filename (defines options) (includes options) 72 bools (preInc++input) 73 let result = if stripC89 bools || stripEol bools 74 then concatMap deWordStyle $ 75 tokenise (stripEol bools) (stripC89 bools) 76 (ansi bools) (lang bools) pass1 77 else init $ unlines (map snd pass1) 78 return (result,syms) 79 80 let pass3 = if literate bools then Unlit.unlit filename else id 81 return (pass3 pass2, syms) 82 83