[use lazy bytestrings for reading source files
John Meacham <john@repetae.net>**20080211191929] hunk ./Ho/Build.hs 65
+import qualified UTF8
hunk ./Ho/Build.hs 77
+-- IDEF - immutable import information
hunk ./Ho/Build.hs 89
+cff_idef  = chunkType "IDEF"
hunk ./Ho/Build.hs 110
-findFirstFile :: String -> [(String,a)] -> IO (Handle,MD5.Hash,FileName,a)
-findFirstFile err [] = FrontEnd.Warning.err "missing-dep" ("Module not found: " ++ err) >> return (undefined,MD5.emptyHash,undefined,undefined)
+findFirstFile :: String -> [(String,a)] -> IO (LBS.ByteString,FileName,a)
+findFirstFile err [] = FrontEnd.Warning.err "missing-dep" ("Module not found: " ++ err) >> fail ("Module not found: " ++ err) -- return (error "findFirstFile not found","",undefined)
hunk ./Ho/Build.hs 113
-    fh <- openBinaryFile x ReadMode
-    hash <- MD5.md5Handle fh
-    return (fh,hash,x,a)
+    bs <- LBS.readFile x
+    return (bs,x,a)
hunk ./Ho/Build.hs 160
-            (_,hash,_,ho_name) <- moduleFind r_dm (Left m)
-            if hash == MD5.emptyHash
-                then fail $ "could not find ho file: " ++ show m
-                else loadHoFile r_dm ho_name
+            (_,_,ho_name) <- moduleFind r_dm (Left m)
+            loadHoFile r_dm ho_name
hunk ./Ho/Build.hs 165
-loadHoFile r_dm ho_name = ans where
-    ans = do
-        ho_name' <- shortenPath ho_name
-        Just (hoh,ho) <- checkForHoFile ho_name
-        let cd (m,h) | h /= MD5.emptyHash = do
-                (_,h',fn,_) <- moduleFind r_dm (Left m)
-                unless (h == h') $
-                    if h' == MD5.emptyHash then do
-                        putVerboseLn $ ho_name' <+> "not found at" <+> show m
-                        fail "odd module thing"
-                    else do
-                        fn <- shortenPath fn
-                        putVerboseLn $ ho_name' <+> "is out of date due to changed file:" <+> fn
-                        fail "Module out of date"
-            cd _ = return ()
-            cd' (m,h) = do
-                (h',_) <- checkHoFile r_dm m
-                unless (h == hohHash h') $ do
-                    putVerboseLn $ ho_name' <+> "is out of date due to modified ho file:" <+> (show m)
-                    True <- return False
-                    return ()
-        flip catch (\e -> poison r_dm (map fst $ hohDepends hoh) >> ioError e) $ do
-        mapM_ cd (hohDepends hoh)
-        mapM_ cd' (hohModDepends hoh)
-        putVerboseLn $ "Found ho file:   " <+> ho_name'
-        forM_ (fsts $ hohDepends hoh) $ \m -> do
-            modifyIORef r_dm (Map.insert m (ModuleHo hoh ho))
-        return (hoh,ho)
+loadHoFile r_dm ho_name = do
+    ho_name' <- shortenPath ho_name
+    Just (hoh,ho) <- checkForHoFile ho_name
+    let cd (m,h) | h /= MD5.emptyHash = do
+            (lbs,fn,_) <- moduleFind r_dm (Left m)
+            let h' = MD5.md5lazy lbs
+            unless (h == h') $ do
+                fn <- shortenPath fn
+                putVerboseLn $ ho_name' <+> "is out of date due to changed file:" <+> fn
+                fail "Module out of date"
+        cd _ = return ()
+        cd' (m,h) = do
+            (h',_) <- checkHoFile r_dm m
+            unless (h == hohHash h') $ do
+                putVerboseLn $ ho_name' <+> "is out of date due to modified ho file:" <+> (show m)
+                True <- return False
+                return ()
+    flip catch (\e -> poison r_dm (map fst $ hohDepends hoh) >> ioError e) $ do
+    mapM_ cd (hohDepends hoh)
+    mapM_ cd' (hohModDepends hoh)
+    putVerboseLn $ "Found ho file:   " <+> ho_name'
+    forM_ (fsts $ hohDepends hoh) $ \m -> do
+        modifyIORef r_dm (Map.insert m (ModuleHo hoh ho))
+    return (hoh,ho)
hunk ./Ho/Build.hs 198
-moduleFind :: DoneMap -> Either Module String -> IO (Handle,MD5.Hash,FileName,FileName)
+moduleFind :: DoneMap -> Either Module String -> IO (LBS.ByteString,FileName,FileName)
hunk ./Ho/Build.hs 215
-        dm <- readIORef r_dm
-        let (name,spath) = case ms of
-                Left m -> (fromModule m, searchPaths (fromModule m))
-                Right n -> (n,[(n,reverse $ 'o':'h':dropWhile (/= '.') (reverse n))])
-            nogood = case ms of
-                Left m -> modifyIORef r_dm (Map.insert m ModuleNotThere) >> return []
-                Right n -> return []
-        (fh,hash,fname,ho_name) <- findFirstFile name spath
-        if hash == MD5.emptyHash then nogood else do
-        mho <- if useHo && not (optIgnoreHo options) then checkTheHoFile r_dm ho_name else return Nothing
-        case mho of
-            Just (hoh,_) -> return $ fsts (hohDepends hoh)
-            Nothing -> do
-                hs <- parseHsSource fname fh
-                wdump FD.Progress $ do
-                    sp <- shortenPath fname
-                    putErrLn $ "Found dependency:" <+> name <+> "at" <+> sp
-                --if hsModuleName hs `mmember` dm then do putStrLn $ "Found a module name we already have: " ++ show (hsModuleName hs); nogood else do
-                modifyIORef r_dm (Map.insert (hsModuleName hs) ModuleParsed { modParsed = hs, modHoName = ho_name, modName = fname, modHash = hash })
-                mapM_ (fetchModule r_dm) $  map Left (hsModuleRequires hs)
-                return $ [hsModuleName hs]
+    dm <- readIORef r_dm
+    let (name,spath) = case ms of
+            Left m -> (fromModule m, searchPaths (fromModule m))
+            Right n -> (n,[(n,reverse $ 'o':'h':dropWhile (/= '.') (reverse n))])
+    fff <- catch (Just `fmap` findFirstFile name spath) (\_ -> return Nothing)
+    case fff of
+        Nothing ->  case ms of
+            Left m -> modifyIORef r_dm (Map.insert m ModuleNotThere) >> return []
+            Right n -> return []
+        Just (lbs,fname,ho_name) -> do
+            mho <- if useHo && not (optIgnoreHo options) then checkTheHoFile r_dm ho_name else return Nothing
+            case mho of
+                Just (hoh,_) -> return $ fsts (hohDepends hoh)
+                Nothing -> do
+                    hs <- parseHsSource fname lbs
+                    wdump FD.Progress $ do
+                        sp <- shortenPath fname
+                        putErrLn $ "Found dependency:" <+> name <+> "at" <+> sp
+                    --if hsModuleName hs `mmember` dm then do putStrLn $ "Found a module name we already have: " ++ show (hsModuleName hs); nogood else do
+                    let hash = MD5.md5lazy lbs
+                    modifyIORef r_dm (Map.insert (hsModuleName hs) ModuleParsed { modParsed = hs, modHoName = ho_name, modName = fname, modHash = hash })
+                    mapM_ (fetchModule r_dm) $  map Left (hsModuleRequires hs)
+                    return $ [hsModuleName hs]
hunk ./Ho/Build.hs 384
-parseHsSource :: String -> Handle -> IO HsModule
-parseHsSource fn fh = do
-    pos <- hGetPosn fh
-    ls <- replicateM 15 (ioM $ hGetLine fh)
+parseHsSource :: String -> LBS.ByteString -> IO HsModule
+parseHsSource fn lbs = do
+    let txt = UTF8.fromUTF $ LBS.unpack lbs
hunk ./Ho/Build.hs 391
-    let fopts s = s `member` optFOptsSet opt where opt = f (concatMap concat ls)
-    hSetPosn pos
+    let fopts s = s `member` optFOptsSet opt where opt = f (take 1024 txt)
hunk ./Ho/Build.hs 393
-        _ | fopts FO.Cpp -> hClose fh >> readSystem "cpp" ["-D__JHC__","-CC","-traditional", "--", fn]
-          | fopts FO.M4 ->  hClose fh >> readSystem "m4" ["-D__JHC__", "-s", fn]
-          | otherwise -> CharIO.hGetContents fh
+        _ | fopts FO.Cpp -> readSystem "cpp" ["-D__JHC__","-CC","-traditional", "--", fn]
+          | fopts FO.M4 ->  readSystem "m4" ["-D__JHC__", "-s", fn]
+          | otherwise -> return txt
hunk ./Ho/Type.hs 49
+
+
+-- this is the immutable information about modules that depnends only on their contents
+-- it can be trusted even if the ho file itself is out of date.
+data HoIDeps = HoIDeps {
+    hoIDeps :: Map.Map MD5.Hash (Module,[Module])
+    }