@@ -42,14 +42,35 @@ One typical usage might look like:
42
42
-}
43
43
44
44
module Language.Fortran.Util.ModFile
45
- ( modFileSuffix , ModFile , ModFiles , emptyModFile , emptyModFiles
46
- , lookupModFileData , getLabelsModFileData , alterModFileData -- , alterModFileDataF
47
- , genModFile , regenModFile , encodeModFile , decodeModFile
48
- , StringMap , DeclMap , ParamVarMap , DeclContext (.. ), extractModuleMap , extractDeclMap
49
- , moduleFilename , combinedStringMap , combinedDeclMap , combinedModuleMap , combinedTypeEnv , combinedParamVarMap
45
+ (
46
+ -- * Main defitions
47
+ ModFile , ModFiles , emptyModFile , emptyModFiles , modFileSuffix
48
+ , lookupModFileData , getLabelsModFileData , alterModFileData , alterModFileDataF
49
+
50
+ -- * Creation
51
+ , genModFile , regenModFile
52
+
53
+ -- * En/decoding
54
+ , encodeModFile , decodeModFile , decodeModFiles , decodeModFiles'
55
+
56
+ -- * Operations
57
+ , moduleFilename
58
+ , StringMap , extractStringMap , combinedStringMap
59
+ , DeclContext (.. ), DeclMap , extractDeclMap , combinedDeclMap
60
+ , extractModuleMap , combinedModuleMap , combinedTypeEnv
61
+ , ParamVarMap , extractParamVarMap , combinedParamVarMap
50
62
, genUniqNameToFilenameMap
51
- , TimestampStatus (.. ), checkTimestamps )
52
- where
63
+ , TimestampStatus (.. ), checkTimestamps
64
+ ) where
65
+
66
+ import qualified Language.Fortran.AST as F
67
+ import qualified Language.Fortran.Analysis as FA
68
+ import qualified Language.Fortran.Analysis.BBlocks as FAB
69
+ import qualified Language.Fortran.Analysis.DataFlow as FAD
70
+ import qualified Language.Fortran.Analysis.Renaming as FAR
71
+ import qualified Language.Fortran.Analysis.Types as FAT
72
+ import qualified Language.Fortran.Util.Position as P
73
+ import Language.Fortran.Util.Files ( getDirContents )
53
74
54
75
import Control.Monad.State
55
76
import Data.Binary (Binary , encode , decodeOrFail )
@@ -59,22 +80,22 @@ import Data.Generics.Uniplate.Operations
59
80
import qualified Data.Map.Strict as M
60
81
import Data.Maybe
61
82
import GHC.Generics (Generic )
62
- import qualified Language.Fortran.AST as F
63
- import qualified Language.Fortran.Analysis as FA
64
- import qualified Language.Fortran.Analysis.BBlocks as FAB
65
- import qualified Language.Fortran.Analysis.DataFlow as FAD
66
- import qualified Language.Fortran.Analysis.Renaming as FAR
67
- import qualified Language.Fortran.Analysis.Types as FAT
68
- import qualified Language.Fortran.Util.Position as P
69
- import System.Directory
70
- import System.FilePath
83
+ import System.Directory ( doesFileExist , getModificationTime )
84
+ import qualified System.FilePath
85
+ import System.FilePath ( (-<.>) , (</>) )
86
+ import System.IO ( hPutStrLn , stderr )
71
87
72
88
--------------------------------------------------
73
89
74
90
-- | Standard ending of fortran-src-format "mod files"
75
91
modFileSuffix :: String
76
92
modFileSuffix = " .fsmod"
77
93
94
+ -- | Returns 'true' for filepaths with an extension that identifies them as a
95
+ -- mod file.
96
+ isModFile :: FilePath -> Bool
97
+ isModFile = System.FilePath. isExtensionOf modFileSuffix
98
+
78
99
-- | Context of a declaration: the ProgramUnit where it was declared.
79
100
data DeclContext = DCMain | DCBlockData | DCModule F. ProgramUnitName
80
101
| DCFunction (F. ProgramUnitName , F. ProgramUnitName ) -- ^ (uniqName, srcName)
@@ -149,9 +170,12 @@ getLabelsModFileData = M.keys . mfOtherData
149
170
alterModFileData :: (Maybe LB. ByteString -> Maybe LB. ByteString ) -> String -> ModFile -> ModFile
150
171
alterModFileData f k mf = mf { mfOtherData = M. alter f k . mfOtherData $ mf }
151
172
152
- -- For when stackage gets containers-0.5.8.1:
153
- -- alterModFileDataF :: Functor f => (Maybe B.ByteString -> f (Maybe B.ByteString)) -> String -> ModFile -> f ModFile
154
- -- alterModFileDataF f k mf = (\ od -> mf { mfOtherData = od }) <$> M.alterF f k (mfOtherData mf)
173
+ alterModFileDataF
174
+ :: Functor f
175
+ => (Maybe LB. ByteString -> f (Maybe LB. ByteString )) -> String -> ModFile
176
+ -> f ModFile
177
+ alterModFileDataF f k mf =
178
+ (\ od -> mf { mfOtherData = od }) <$> M. alterF f k (mfOtherData mf)
155
179
156
180
-- | Convert ModFiles to a strict ByteString for writing to file.
157
181
encodeModFile :: [ModFile ] -> LB. ByteString
@@ -171,6 +195,25 @@ decodeModFile bs = case decodeOrFail bs of
171
195
each mf = (revertStringMap sm mf { mfStringMap = M. empty }) { mfStringMap = sm }
172
196
where sm = mfStringMap mf
173
197
198
+ decodeModFiles :: [FilePath ] -> IO [(FilePath , ModFile )]
199
+ decodeModFiles = foldM (\ modFiles d -> do
200
+ -- Figure out the camfort mod files and parse them.
201
+ modFileNames <- filter isModFile `fmap` getDirContents d
202
+ addedModFiles <- fmap concat . forM modFileNames $ \ modFileName -> do
203
+ contents <- LB. readFile (d </> modFileName)
204
+ case decodeModFile contents of
205
+ Left msg -> do
206
+ hPutStrLn stderr $ modFileName ++ " : Error: " ++ msg
207
+ return [(modFileName, emptyModFile)]
208
+ Right mods -> do
209
+ hPutStrLn stderr $ modFileName ++ " : successfully parsed precompiled file."
210
+ return $ map (modFileName,) mods
211
+ return $ addedModFiles ++ modFiles
212
+ ) [] -- can't use emptyModFiles
213
+
214
+ decodeModFiles' :: [FilePath ] -> IO ModFiles
215
+ decodeModFiles' = fmap (map snd ) . decodeModFiles
216
+
174
217
-- | Extract the combined module map from a set of ModFiles. Useful
175
218
-- for parsing a Fortran file in a large context of other modules.
176
219
combinedModuleMap :: ModFiles -> FAR. ModuleMap
0 commit comments