diff options
author | Joe Crayne <joe@jerkface.net> | 2018-11-22 12:24:19 -0500 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2018-11-22 12:24:19 -0500 |
commit | ac87e9c2b4d5526ceb3a952998cc784dc9e47496 (patch) | |
tree | 904793bd0bb309b3fb14a3df710302896fbb048a | |
parent | 50c2b769e64734c2f6b5a84cdef2de673b1b7d70 (diff) |
parse include stack from preprocessed c output.
-rw-r--r-- | c2haskell.hs | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/c2haskell.hs b/c2haskell.hs index 0c31c93..cc590c3 100644 --- a/c2haskell.hs +++ b/c2haskell.hs | |||
@@ -1,3 +1,4 @@ | |||
1 | {-# LANGUAGE OverloadedStrings #-} | ||
1 | {-# LANGUAGE BangPatterns #-} | 2 | {-# LANGUAGE BangPatterns #-} |
2 | {-# LANGUAGE DeriveFunctor #-} | 3 | {-# LANGUAGE DeriveFunctor #-} |
3 | {-# LANGUAGE FlexibleContexts #-} | 4 | {-# LANGUAGE FlexibleContexts #-} |
@@ -10,9 +11,12 @@ import Data.Generics.Aliases | |||
10 | import Data.Generics.Schemes | 11 | import Data.Generics.Schemes |
11 | -- import Debug.Trace | 12 | -- import Debug.Trace |
12 | import Control.Monad | 13 | import Control.Monad |
14 | import qualified Data.ByteString.Char8 as B | ||
13 | import Data.Char | 15 | import Data.Char |
14 | import Data.Data | 16 | import Data.Data |
15 | import Data.List | 17 | import Data.List |
18 | import qualified Data.IntMap as IntMap | ||
19 | ;import Data.IntMap (IntMap) | ||
16 | import qualified Data.Map as Map | 20 | import qualified Data.Map as Map |
17 | ;import Data.Map (Map) | 21 | ;import Data.Map (Map) |
18 | import Data.Maybe | 22 | import Data.Maybe |
@@ -21,6 +25,7 @@ import qualified Data.Set as Set | |||
21 | import Language.C.Data.Ident as C | 25 | import Language.C.Data.Ident as C |
22 | import Language.C as C hiding (prettyUsingInclude) | 26 | import Language.C as C hiding (prettyUsingInclude) |
23 | import Language.C.System.GCC | 27 | import Language.C.System.GCC |
28 | import Language.C.System.Preprocess | ||
24 | import Language.C.Data.Position | 29 | import Language.C.Data.Position |
25 | import Language.Haskell.Exts.Parser as HS | 30 | import Language.Haskell.Exts.Parser as HS |
26 | import Language.Haskell.Exts.Pretty as HS | 31 | import Language.Haskell.Exts.Pretty as HS |
@@ -336,6 +341,7 @@ data C2HaskellOptions = C2HaskellOptions | |||
336 | , prettyC :: Bool | 341 | , prettyC :: Bool |
337 | , prettyTree :: Bool | 342 | , prettyTree :: Bool |
338 | , verbose :: Bool | 343 | , verbose :: Bool |
344 | , preprocess :: Bool | ||
339 | } | 345 | } |
340 | 346 | ||
341 | defopts = C2HaskellOptions | 347 | defopts = C2HaskellOptions |
@@ -343,6 +349,7 @@ defopts = C2HaskellOptions | |||
343 | , prettyC = False | 349 | , prettyC = False |
344 | , prettyTree = False | 350 | , prettyTree = False |
345 | , verbose = False | 351 | , verbose = False |
352 | , preprocess = False | ||
346 | } | 353 | } |
347 | 354 | ||
348 | parseOptions [] opts = opts | 355 | parseOptions [] opts = opts |
@@ -355,9 +362,13 @@ parseOptions ("-t":args) opts = parseOptions args opts | |||
355 | parseOptions ("-p":args) opts = parseOptions args opts | 362 | parseOptions ("-p":args) opts = parseOptions args opts |
356 | { prettyC = True | 363 | { prettyC = True |
357 | } | 364 | } |
365 | parseOptions ("--cpp":args) opts = parseOptions args opts | ||
366 | { preprocess = True | ||
367 | } | ||
358 | parseOptions ("-v":args) opts = parseOptions args opts | 368 | parseOptions ("-v":args) opts = parseOptions args opts |
359 | { verbose = True | 369 | { verbose = True |
360 | } | 370 | } |
371 | parseOptions as x = error (show as) | ||
361 | 372 | ||
362 | getsig (k,si) = do | 373 | getsig (k,si) = do |
363 | d <- take 1 $ symbolSource si | 374 | d <- take 1 $ symbolSource si |
@@ -779,6 +790,33 @@ eraseNodeInfo _ = OnlyPos p (p,0) -- undefNode value doesn't ppShow well. | |||
779 | where | 790 | where |
780 | p = position 0 "" 0 0 Nothing | 791 | p = position 0 "" 0 0 Nothing |
781 | 792 | ||
793 | |||
794 | newtype IncludeStack = IncludeStack | ||
795 | { includes :: Map FilePath [[FilePath]] | ||
796 | } | ||
797 | deriving Show | ||
798 | |||
799 | emptyIncludes = IncludeStack Map.empty | ||
800 | |||
801 | openInclude fname stack (IncludeStack m) = IncludeStack $ Map.alter go fname m | ||
802 | where | ||
803 | go Nothing = Just [stack] | ||
804 | go (Just s) = Just $ stack : s | ||
805 | |||
806 | findQuoted xs = takeWhile (/='"') $ drop 1 $ dropWhile (/='"') xs | ||
807 | |||
808 | includeStack bs = foldr go (const emptyIncludes) incs [] | ||
809 | where | ||
810 | incs = filter (\b -> fmap fst (B.uncons b) == Just '#') $ B.lines bs | ||
811 | |||
812 | fp inc = findQuoted $ B.unpack inc | ||
813 | -- fno inc = read $ concat $ take 1 $ words $ drop 2 $ B.unpack inc | ||
814 | |||
815 | go inc xs stack | ||
816 | | "1" `elem` B.words inc = let f = fp inc in openInclude f stack (xs (f : stack)) | ||
817 | | "2" `elem` B.words inc = xs (drop 1 stack) | ||
818 | | otherwise = xs stack | ||
819 | |||
782 | main :: IO () | 820 | main :: IO () |
783 | main = do | 821 | main = do |
784 | self <- getProgName | 822 | self <- getProgName |
@@ -789,6 +827,12 @@ main = do | |||
789 | r <- parseCFile (newGCC "gcc") Nothing cargs fname | 827 | r <- parseCFile (newGCC "gcc") Nothing cargs fname |
790 | cs <- readComments fname | 828 | cs <- readComments fname |
791 | case () of | 829 | case () of |
830 | _ | preprocess hopts -- --cpp | ||
831 | -> do | ||
832 | r2 <- runPreprocessor (newGCC "gcc") (rawCppArgs cargs fname) | ||
833 | case r2 of | ||
834 | Left e -> print e | ||
835 | Right bs -> putStrLn $ ppShow $ includeStack $ bs | ||
792 | _ | prettyC hopts -- -p | 836 | _ | prettyC hopts -- -p |
793 | -> do | 837 | -> do |
794 | print (fmap prettyUsingInclude r) | 838 | print (fmap prettyUsingInclude r) |