diff options
author | Joe Crayne <joe@jerkface.net> | 2018-11-22 21:14:09 -0500 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2018-11-22 21:14:09 -0500 |
commit | df1bd7353b41f4c4214b77934085889b84be8839 (patch) | |
tree | 754af1fa973def4535c3947b7523ed193d0e49ea | |
parent | ac87e9c2b4d5526ceb3a952998cc784dc9e47496 (diff) |
Use parsed include stack for for pretty-printed C.
-rw-r--r-- | c2haskell.hs | 58 |
1 files changed, 40 insertions, 18 deletions
diff --git a/c2haskell.hs b/c2haskell.hs index cc590c3..48b30e3 100644 --- a/c2haskell.hs +++ b/c2haskell.hs | |||
@@ -7,6 +7,7 @@ | |||
7 | {-# LANGUAGE QuasiQuotes #-} | 7 | {-# LANGUAGE QuasiQuotes #-} |
8 | {-# LANGUAGE TemplateHaskell #-} | 8 | {-# LANGUAGE TemplateHaskell #-} |
9 | 9 | ||
10 | import Control.Arrow (left) | ||
10 | import Data.Generics.Aliases | 11 | import Data.Generics.Aliases |
11 | import Data.Generics.Schemes | 12 | import Data.Generics.Schemes |
12 | -- import Debug.Trace | 13 | -- import Debug.Trace |
@@ -48,23 +49,38 @@ trace _ = id | |||
48 | -- | 49 | -- |
49 | -- The resulting file may not compile (because of missing @#define@ directives and similar things), but is very useful | 50 | -- The resulting file may not compile (because of missing @#define@ directives and similar things), but is very useful |
50 | -- for testing, as otherwise the pretty printed file will be cluttered with declarations from system headers. | 51 | -- for testing, as otherwise the pretty printed file will be cluttered with declarations from system headers. |
51 | prettyUsingInclude :: CTranslUnit -> Doc | 52 | prettyUsingInclude :: IncludeStack -> CTranslUnit -> Doc |
52 | prettyUsingInclude (CTranslUnit edecls _) = | 53 | prettyUsingInclude incs (CTranslUnit edecls _) = |
53 | includeWarning headerFiles | 54 | vcat (map (either includeHeader pretty) $ sortBy sysfst mappedDecls) |
54 | $$ | ||
55 | vcat (map (either includeHeader pretty) mappedDecls) | ||
56 | where | 55 | where |
57 | (headerFiles,mappedDecls) = foldr (addDecl . tagIncludedDecls) (Set.empty,[]) edecls | 56 | (headerFiles,mappedDecls) = foldr (addDecl . tagIncludedDecls) (Set.empty,[]) edecls |
58 | tagIncludedDecls edecl | maybe False isHeaderFile (fileOfNode edecl) = Left ((posFile . posOf) edecl) | 57 | tagIncludedDecls edecl | maybe False isHeaderFile (fileOfNode edecl) = Left ((includeTopLevel incs . posFile . posOf) edecl) |
59 | | otherwise = Right edecl | 58 | | otherwise = Right edecl |
60 | addDecl decl@(Left headerRef) (headerSet, ds) | 59 | addDecl decl@(Left headerRef) (headerSet, ds) |
61 | | Set.member headerRef headerSet = (headerSet, ds) | 60 | | null headerRef || Set.member headerRef headerSet |
62 | | otherwise = (Set.insert headerRef headerSet, decl : ds) | 61 | = (headerSet, ds) |
62 | | otherwise = (Set.insert headerRef headerSet, decl : ds) | ||
63 | addDecl decl (headerSet,ds) = (headerSet, decl : ds) | 63 | addDecl decl (headerSet,ds) = (headerSet, decl : ds) |
64 | includeHeader hFile = text "#include" <+> doubleQuotes (text hFile) | 64 | |
65 | includeHeader hFile = text "#include" <+> text hFile | ||
65 | isHeaderFile = (".h" `isSuffixOf`) | 66 | isHeaderFile = (".h" `isSuffixOf`) |
66 | includeWarning hs | Set.null hs = empty | 67 | |
67 | | otherwise = text "/* Warning: The #include directives in this file aren't necessarily correct. */" | 68 | sysfst (Left ('"':a)) (Left ('<':b)) = Prelude.GT |
69 | sysfst (Left a) (Left b) = trace (show (a,b)) $ Prelude.GT | ||
70 | sysfst _ _ = Prelude.LT | ||
71 | |||
72 | |||
73 | includeTopLevel (IncludeStack incs) f = do | ||
74 | stacks <- maybeToList $ Map.lookup f incs | ||
75 | stack <- take 1 stacks | ||
76 | top <- take 1 $ drop 4 $ reverse stack | ||
77 | if take 1 top == "/" | ||
78 | then let ws = groupBy (\_ c -> c /='/') top | ||
79 | (xs,ys) = break (=="/include") ws | ||
80 | ys' = drop 1 ys | ||
81 | in if not (null ys') then '<': drop 1 (concat ys') ++ ">" | ||
82 | else '"':top++"\"" | ||
83 | else '"':top ++"\"" | ||
68 | 84 | ||
69 | specs :: CExternalDeclaration a -> [CDeclarationSpecifier a] | 85 | specs :: CExternalDeclaration a -> [CDeclarationSpecifier a] |
70 | specs (CFDefExt (CFunDef ss _ _ _ _)) = ss | 86 | specs (CFDefExt (CFunDef ss _ _ _ _)) = ss |
@@ -397,7 +413,10 @@ makeAcceptableImport (HS.TyFun a (TyCon c (UnQual d (HS.Ident e x))) xs) | |||
397 | makeAcceptableImport t = t | 413 | makeAcceptableImport t = t |
398 | 414 | ||
399 | -- c2haskell :: Foldable t => C2HaskellOptions -> p -> t String -> CTranslationUnit NodeInfo -> IO () | 415 | -- c2haskell :: Foldable t => C2HaskellOptions -> p -> t String -> CTranslationUnit NodeInfo -> IO () |
400 | c2haskell opts cs missings (CTranslUnit edecls _) = do | 416 | c2haskell :: Foldable t => |
417 | C2HaskellOptions | ||
418 | -> p1 -> t String -> IncludeStack -> CTranslationUnit NodeInfo -> IO () | ||
419 | c2haskell opts cs missings incs (CTranslUnit edecls _) = do | ||
401 | let db = foldr update initTranspile edecls | 420 | let db = foldr update initTranspile edecls |
402 | es = Map.filter (\d -> symbolLocal d && not (symbolStatic d)) (syms db) | 421 | es = Map.filter (\d -> symbolLocal d && not (symbolStatic d)) (syms db) |
403 | case selectFunction opts of | 422 | case selectFunction opts of |
@@ -824,21 +843,24 @@ main = do | |||
824 | let usageString = self ++ " [-v] [-p] [-f <sym>] -- [gcc options] <cfile>" | 843 | let usageString = self ++ " [-v] [-p] [-f <sym>] -- [gcc options] <cfile>" |
825 | let m = usage args | 844 | let m = usage args |
826 | fromMaybe (putStrLn usageString) $ m <&> \(hopts,cargs,fname) -> do | 845 | fromMaybe (putStrLn usageString) $ m <&> \(hopts,cargs,fname) -> do |
827 | r <- parseCFile (newGCC "gcc") Nothing cargs fname | 846 | prer <- runPreprocessor (newGCC "gcc") (rawCppArgs cargs fname) |
847 | let r = do | ||
848 | pre <- left Left $ prer | ||
849 | c <- left Right $ parseC pre (initPos fname) | ||
850 | return (includeStack pre,c) | ||
828 | cs <- readComments fname | 851 | cs <- readComments fname |
829 | case () of | 852 | case () of |
830 | _ | preprocess hopts -- --cpp | 853 | _ | preprocess hopts -- --cpp |
831 | -> do | 854 | -> do |
832 | r2 <- runPreprocessor (newGCC "gcc") (rawCppArgs cargs fname) | 855 | case prer of |
833 | case r2 of | ||
834 | Left e -> print e | 856 | Left e -> print e |
835 | Right bs -> putStrLn $ ppShow $ includeStack $ bs | 857 | Right bs -> putStrLn $ ppShow $ includeStack $ bs |
836 | _ | prettyC hopts -- -p | 858 | _ | prettyC hopts -- -p |
837 | -> do | 859 | -> do |
838 | print (fmap prettyUsingInclude r) | 860 | print (fmap (\(incs,decls) -> prettyUsingInclude incs decls) r) |
839 | _ | prettyTree hopts -- -t | 861 | _ | prettyTree hopts -- -t |
840 | -> do | 862 | -> do |
841 | putStrLn $ ppShow $ everywhere (mkT eraseNodeInfo) <$> r | 863 | putStrLn $ ppShow $ everywhere (mkT eraseNodeInfo) . snd <$> r |
842 | _ -> do | 864 | _ -> do |
843 | syms <- linker cargs fname | 865 | syms <- linker cargs fname |
844 | either print (c2haskell hopts cs syms) r | 866 | either print (uncurry $ c2haskell hopts cs syms) r |