summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2018-11-20 20:52:01 -0500
committerJoe Crayne <joe@jerkface.net>2018-11-20 20:52:01 -0500
commit86ce08d89199ae3ec142da4c83cdc7ab308e85f7 (patch)
tree0f2a93c8118fe1fea794492a70df3183f798b157
parentbb2f9fbbc4992cfff65b8ff59439046217a2c1ef (diff)
Generate settable function pointer for monkey patching.
-rw-r--r--c2haskell.hs65
1 files changed, 59 insertions, 6 deletions
diff --git a/c2haskell.hs b/c2haskell.hs
index 832e613..4f2644b 100644
--- a/c2haskell.hs
+++ b/c2haskell.hs
@@ -21,6 +21,7 @@ import qualified Data.Set as Set
21import Language.C.Data.Ident as C 21import Language.C.Data.Ident as C
22import Language.C as C hiding (prettyUsingInclude) 22import Language.C as C hiding (prettyUsingInclude)
23import Language.C.System.GCC 23import Language.C.System.GCC
24import Language.C.Data.Position
24import Language.Haskell.Exts.Parser as HS 25import Language.Haskell.Exts.Parser as HS
25import Language.Haskell.Exts.Pretty as HS 26import Language.Haskell.Exts.Pretty as HS
26import Language.Haskell.Exts.Syntax as HS 27import Language.Haskell.Exts.Syntax as HS
@@ -331,13 +332,15 @@ commented s = unlines $ map ("-- " ++) (lines s)
331 332
332data C2HaskellOptions = C2HaskellOptions 333data C2HaskellOptions = C2HaskellOptions
333 { selectFunction :: Maybe String 334 { selectFunction :: Maybe String
334 , prettyC :: Bool 335 , prettyC :: Bool
335 , verbose :: Bool 336 , prettyTree :: Bool
337 , verbose :: Bool
336 } 338 }
337 339
338defopts = C2HaskellOptions 340defopts = C2HaskellOptions
339 { selectFunction = Nothing 341 { selectFunction = Nothing
340 , prettyC = False 342 , prettyC = False
343 , prettyTree = False
341 , verbose = False 344 , verbose = False
342 } 345 }
343 346
@@ -345,6 +348,9 @@ parseOptions [] opts = opts
345parseOptions ("-f":f:args) opts = parseOptions args opts 348parseOptions ("-f":f:args) opts = parseOptions args opts
346 { selectFunction = Just f 349 { selectFunction = Just f
347 } 350 }
351parseOptions ("-t":args) opts = parseOptions args opts
352 { prettyTree = True
353 }
348parseOptions ("-p":args) opts = parseOptions args opts 354parseOptions ("-p":args) opts = parseOptions args opts
349 { prettyC = True 355 { prettyC = True
350 } 356 }
@@ -446,7 +452,46 @@ c2haskell opts cs missings (CTranslUnit edecls _) = do
446 mapM_ (putStr . commented . show . pretty) (mutations (body d)) 452 mapM_ (putStr . commented . show . pretty) (mutations (body d))
447 -} 453 -}
448 -} 454 -}
449 Just cfun -> goMissing db cfun 455 Just cfun -> do
456 forM_ (Map.lookup cfun $ syms db) $ \si -> do
457 forM_ (take 1 $ symbolSource si) $ \d -> do
458 putStrLn $ show $ pretty d
459 putStrLn $ show $ pretty $ makeFunctionPointer d
460 putStrLn $ take 2048 $ ppShow $ everywhere (mkT eraseNodeInfo) <$> makeFunctionPointer d
461
462-- TODO: make idempotent
463makeStatic :: [CDeclarationSpecifier NodeInfo] -> [CDeclarationSpecifier NodeInfo]
464makeStatic xs = CStorageSpec (CStatic undefNode) : xs
465-- makeStatic xs = CStorageSpec (CStatic ()) : xs
466
467makePointer1 (Just (CDeclr a bs c d e))
468 = (Just (CDeclr a (p:bs) c d e))
469 where
470 p = CPtrDeclr [] undefNode
471 -- p = CPtrDeclr [] ()
472
473makePointer :: [(Maybe (CDeclarator NodeInfo), b, c)]
474 -> [(Maybe (CDeclarator NodeInfo), b, c)]
475makePointer ((a,b,c):zs) = (makePointer1 a,b,c):zs
476
477setNull1 :: Maybe (CInitializer NodeInfo)
478setNull1 = Just (CInitExpr (CVar (C.Ident "NULL" 0 undefNode) undefNode) undefNode)
479
480setNull ((a,_,b):zs) = (a,setNull1,b):zs
481
482makeFunctionPointer :: CExternalDeclaration NodeInfo
483 -> CExternalDeclaration NodeInfo
484makeFunctionPointer d@(CDeclExt (CDecl xs ys pos)) = changeName ("f_"++) $ CDeclExt (CDecl (makeStatic xs) (setNull $ makePointer ys) pos)
485makeFunctionPointer d = d
486
487changeName2 f (Just (CDeclr (Just (C.Ident nm n p)) bs c d e))
488 = (Just (CDeclr (Just (C.Ident (f nm) n p)) bs c d e))
489changeName2 f d = d
490
491changeName1 f ((a,b,c):zs) = (changeName2 f a,b,c):zs
492
493changeName f d@(CDeclExt (CDecl xs ys pos)) = CDeclExt (CDecl xs (changeName1 f ys) pos)
494changeName f d = d
450 495
451makeAcceptableDecl (HS.TypeDecl a (DHead b (HS.Ident c signame)) ftyp) 496makeAcceptableDecl (HS.TypeDecl a (DHead b (HS.Ident c signame)) ftyp)
452 = (HS.TypeDecl a (DHead b (HS.Ident c signame)) (makeFunctionUseIO $ makeAcceptableImport ftyp)) 497 = (HS.TypeDecl a (DHead b (HS.Ident c signame)) (makeFunctionUseIO $ makeAcceptableImport ftyp))
@@ -560,6 +605,10 @@ linker cargs fname = do
560 _ -> return () 605 _ -> return ()
561 return $ missingSymbols linkerrs 606 return $ missingSymbols linkerrs
562 607
608eraseNodeInfo :: NodeInfo -> NodeInfo
609eraseNodeInfo _ = OnlyPos p (p,0) -- undefNode value doesn't ppShow well.
610 where
611 p = position 0 "" 0 0 Nothing
563 612
564main :: IO () 613main :: IO ()
565main = do 614main = do
@@ -570,9 +619,13 @@ main = do
570 fromMaybe (putStrLn usageString) $ m <&> \(hopts,cargs,fname) -> do 619 fromMaybe (putStrLn usageString) $ m <&> \(hopts,cargs,fname) -> do
571 r <- parseCFile (newGCC "gcc") Nothing cargs fname 620 r <- parseCFile (newGCC "gcc") Nothing cargs fname
572 cs <- readComments fname 621 cs <- readComments fname
573 if prettyC hopts -- -p 622 case () of
574 then do 623 _ | prettyC hopts -- -p
624 -> do
575 print (fmap prettyUsingInclude r) 625 print (fmap prettyUsingInclude r)
576 else do 626 _ | prettyTree hopts -- -t
627 -> do
628 putStrLn $ ppShow $ everywhere (mkT eraseNodeInfo) <$> r
629 _ -> do
577 syms <- linker cargs fname 630 syms <- linker cargs fname
578 either print (c2haskell hopts cs syms) r 631 either print (c2haskell hopts cs syms) r