summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2018-11-20 00:12:07 -0500
committerJoe Crayne <joe@jerkface.net>2018-11-20 00:12:07 -0500
commitaa9e2931acdda7663df96ae7bf5ac2c75d66b6ff (patch)
tree0f8cef3e2100f493e67798201af2fce122843e82
parentd7897ff1c2ac599a133b09bc48134a7f74af3d03 (diff)
Invoke linker to determine missing symbols.
-rw-r--r--c2haskell.hs53
1 files changed, 49 insertions, 4 deletions
diff --git a/c2haskell.hs b/c2haskell.hs
index 2fbbfc2..5602c10 100644
--- a/c2haskell.hs
+++ b/c2haskell.hs
@@ -28,6 +28,8 @@ import Language.Haskell.TH.Ppr
28import Language.Haskell.TH.Syntax as TH 28import Language.Haskell.TH.Syntax as TH
29import System.Environment 29import System.Environment
30import System.IO 30import System.IO
31import System.Process
32import System.Exit
31import Text.PrettyPrint (Doc, doubleQuotes, empty, text, vcat, ($$), 33import Text.PrettyPrint (Doc, doubleQuotes, empty, text, vcat, ($$),
32 (<+>)) 34 (<+>))
33import Text.Show.Pretty 35import Text.Show.Pretty
@@ -349,7 +351,7 @@ isAcceptableImport (TyCon _ _) = True
349isAcceptableImport (TyApp _ _ _) = True 351isAcceptableImport (TyApp _ _ _) = True
350isAcceptableImport _ = False 352isAcceptableImport _ = False
351 353
352c2haskell opts cs (CTranslUnit edecls _) = do 354c2haskell opts cs missings (CTranslUnit edecls _) = do
353 let db = foldr update initTranspile edecls 355 let db = foldr update initTranspile edecls
354 es = Map.filter (\d -> symbolLocal d && not (symbolStatic d)) (syms db) 356 es = Map.filter (\d -> symbolLocal d && not (symbolStatic d)) (syms db)
355 case selectFunction opts of 357 case selectFunction opts of
@@ -380,6 +382,17 @@ c2haskell opts cs (CTranslUnit edecls _) = do
380 $ HS.prettyPrint $ (HS.ForImp () (HS.CCall ()) Nothing (Just k) 382 $ HS.prettyPrint $ (HS.ForImp () (HS.CCall ()) Nothing (Just k)
381 (HS.Ident () k) 383 (HS.Ident () k)
382 htyp) 384 htyp)
385 forM_ missings $ \sym -> goMissing db sym
386 {-
387 forM_ (Map.lookup sym $ syms db) $ \si -> do
388 forM_ (take 1 $ symbolSource si) $ \d -> do
389 let ts = filter notKnown $ map tname $ pointers $ concatMap types $ sigf hsTransSig d
390 -- putStr $ commented (ppShow (fmap (const ()) d))
391 -- putStr $ commented (show $ pretty d)
392 let typ = (TyCon () (Special () (UnitCon ())))
393 -- when (null $ sig d) $ putStr $ commented (ppShow (fmap (const ()) d))
394 forM_ (sig d) $ \htyp -> do
395 putStrLn $ HS.prettyPrint htyp
383 396
384 -- mapM_ (putStrLn . HS.prettyPrint) (sig d) 397 -- mapM_ (putStrLn . HS.prettyPrint) (sig d)
385 {- 398 {-
@@ -393,8 +406,12 @@ c2haskell opts cs (CTranslUnit edecls _) = do
393 putStr $ commented "mutations" 406 putStr $ commented "mutations"
394 mapM_ (putStr . commented . show . pretty) (mutations (body d)) 407 mapM_ (putStr . commented . show . pretty) (mutations (body d))
395 -} 408 -}
396 Just cfun -> do 409 -}
397 forM_ (symbolSource $ syms db Map.! cfun) $ \d -> do 410 Just cfun -> goMissing db cfun
411
412goMissing db cfun = do
413 forM_ (Map.lookup cfun $ syms db) $ \si -> do
414 forM_ (take 1 $ symbolSource si) $ \d -> do
398 -- putStr $ commented (ppShow (fmap (const ()) d)) 415 -- putStr $ commented (ppShow (fmap (const ()) d))
399 -- putStr $ commented (show $ pretty d) 416 -- putStr $ commented (show $ pretty d)
400 -- when (verbose opts) $ print (sig d) 417 -- when (verbose opts) $ print (sig d)
@@ -476,6 +493,33 @@ usage args = do
476(<&>) :: Functor f => f a -> (a -> b) -> f b 493(<&>) :: Functor f => f a -> (a -> b) -> f b
477m <&> f = fmap f m 494m <&> f = fmap f m
478 495
496uniq xs = Map.keys $ foldr (\x m -> Map.insert x () m) Map.empty xs
497
498unquote :: String -> String
499unquote xs = zipWith const (drop 1 xs) (drop 2 xs)
500
501missingSymbols s = uniq $ do
502 e <- lines s
503 let (_,us) = break (=="undefined") $ words e
504 if null us then []
505 else do
506 let q = concat $ take 1 $ reverse us
507 c <- take 1 q
508 guard $ c=='`' || c=='\''
509 return $ unquote q
510
511
512linker cargs fname = do
513 (hin,hout,Just herr,hproc) <- createProcess (proc "gcc" $ cargs ++ [fname])
514 { std_err = CreatePipe }
515 linkerrs <- hGetContents herr
516 ecode <- waitForProcess hproc
517 case ecode of
518 ExitSuccess -> hPutStrLn stderr $ "Oops: "++fname++" has main() symbol."
519 _ -> return ()
520 return $ missingSymbols linkerrs
521
522
479main :: IO () 523main :: IO ()
480main = do 524main = do
481 self <- getProgName 525 self <- getProgName
@@ -490,4 +534,5 @@ main = do
490 then do 534 then do
491 print (fmap prettyUsingInclude r) 535 print (fmap prettyUsingInclude r)
492 else do 536 else do
493 either print (c2haskell hopts cs) r 537 syms <- linker cargs fname
538 either print (c2haskell hopts cs syms) r