diff options
author | Joe Crayne <joe@jerkface.net> | 2018-11-20 20:52:01 -0500 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2018-11-20 20:52:01 -0500 |
commit | 86ce08d89199ae3ec142da4c83cdc7ab308e85f7 (patch) | |
tree | 0f2a93c8118fe1fea794492a70df3183f798b157 | |
parent | bb2f9fbbc4992cfff65b8ff59439046217a2c1ef (diff) |
Generate settable function pointer for monkey patching.
-rw-r--r-- | c2haskell.hs | 65 |
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 | |||
21 | import Language.C.Data.Ident as C | 21 | import Language.C.Data.Ident as C |
22 | import Language.C as C hiding (prettyUsingInclude) | 22 | import Language.C as C hiding (prettyUsingInclude) |
23 | import Language.C.System.GCC | 23 | import Language.C.System.GCC |
24 | import Language.C.Data.Position | ||
24 | import Language.Haskell.Exts.Parser as HS | 25 | import Language.Haskell.Exts.Parser as HS |
25 | import Language.Haskell.Exts.Pretty as HS | 26 | import Language.Haskell.Exts.Pretty as HS |
26 | import Language.Haskell.Exts.Syntax as HS | 27 | import Language.Haskell.Exts.Syntax as HS |
@@ -331,13 +332,15 @@ commented s = unlines $ map ("-- " ++) (lines s) | |||
331 | 332 | ||
332 | data C2HaskellOptions = C2HaskellOptions | 333 | data 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 | ||
338 | defopts = C2HaskellOptions | 340 | defopts = 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 | |||
345 | parseOptions ("-f":f:args) opts = parseOptions args opts | 348 | parseOptions ("-f":f:args) opts = parseOptions args opts |
346 | { selectFunction = Just f | 349 | { selectFunction = Just f |
347 | } | 350 | } |
351 | parseOptions ("-t":args) opts = parseOptions args opts | ||
352 | { prettyTree = True | ||
353 | } | ||
348 | parseOptions ("-p":args) opts = parseOptions args opts | 354 | parseOptions ("-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 | ||
463 | makeStatic :: [CDeclarationSpecifier NodeInfo] -> [CDeclarationSpecifier NodeInfo] | ||
464 | makeStatic xs = CStorageSpec (CStatic undefNode) : xs | ||
465 | -- makeStatic xs = CStorageSpec (CStatic ()) : xs | ||
466 | |||
467 | makePointer1 (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 | |||
473 | makePointer :: [(Maybe (CDeclarator NodeInfo), b, c)] | ||
474 | -> [(Maybe (CDeclarator NodeInfo), b, c)] | ||
475 | makePointer ((a,b,c):zs) = (makePointer1 a,b,c):zs | ||
476 | |||
477 | setNull1 :: Maybe (CInitializer NodeInfo) | ||
478 | setNull1 = Just (CInitExpr (CVar (C.Ident "NULL" 0 undefNode) undefNode) undefNode) | ||
479 | |||
480 | setNull ((a,_,b):zs) = (a,setNull1,b):zs | ||
481 | |||
482 | makeFunctionPointer :: CExternalDeclaration NodeInfo | ||
483 | -> CExternalDeclaration NodeInfo | ||
484 | makeFunctionPointer d@(CDeclExt (CDecl xs ys pos)) = changeName ("f_"++) $ CDeclExt (CDecl (makeStatic xs) (setNull $ makePointer ys) pos) | ||
485 | makeFunctionPointer d = d | ||
486 | |||
487 | changeName2 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)) | ||
489 | changeName2 f d = d | ||
490 | |||
491 | changeName1 f ((a,b,c):zs) = (changeName2 f a,b,c):zs | ||
492 | |||
493 | changeName f d@(CDeclExt (CDecl xs ys pos)) = CDeclExt (CDecl xs (changeName1 f ys) pos) | ||
494 | changeName f d = d | ||
450 | 495 | ||
451 | makeAcceptableDecl (HS.TypeDecl a (DHead b (HS.Ident c signame)) ftyp) | 496 | makeAcceptableDecl (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 | ||
608 | eraseNodeInfo :: NodeInfo -> NodeInfo | ||
609 | eraseNodeInfo _ = OnlyPos p (p,0) -- undefNode value doesn't ppShow well. | ||
610 | where | ||
611 | p = position 0 "" 0 0 Nothing | ||
563 | 612 | ||
564 | main :: IO () | 613 | main :: IO () |
565 | main = do | 614 | main = 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 |