diff --git a/src/compiler/GF/Compile/ReadFiles.hs b/src/compiler/GF/Compile/ReadFiles.hs index 3182e192c..9396b3a2f 100644 --- a/src/compiler/GF/Compile/ReadFiles.hs +++ b/src/compiler/GF/Compile/ReadFiles.hs @@ -20,7 +20,7 @@ module GF.Compile.ReadFiles ( getAllFiles,ModName,ModEnv,importsOfModule, - findFile,gfImports,gfoImports, + findFile,gfImports,gfoImports,VersionTagged(..), parseSource,getOptionsFromFile,getPragmas) where import Prelude hiding (catch) @@ -32,7 +32,7 @@ import GF.Data.Operations import GF.Grammar.Lexer import GF.Grammar.Parser import GF.Grammar.Grammar -import GF.Grammar.Binary(decodeModuleHeader) +import GF.Grammar.Binary(VersionTagged(..),decodeModuleHeader) import System.IO(mkTextEncoding) import GF.Text.Coding(decodeUnicodeIO) @@ -107,10 +107,10 @@ getAllFiles opts ps env file = do case st of CSEnv -> return (st, (name, maybe [] snd mb_envmod)) CSRead -> do let gfo = if isGFO file then file else gf2gfo opts file - mb_imps <- gfoImports gfo - case mb_imps of - Just imps -> return (st,imps) - Nothing + t_imps <- gfoImports gfo + case t_imps of + Tagged imps -> return (st,imps) + WrongVersion | isGFO file -> raise (file ++ " is compiled with different GF version and I can't find the source file") | otherwise -> do imps <- gfImports opts file return (CSComp,imps) @@ -143,7 +143,7 @@ findFile gfoDir ps name = gfImports opts file = importsOfModule `fmap` parseModHeader opts file -gfoImports gfo = fmap importsOfModule `fmap` liftIO (decodeModuleHeader gfo) +gfoImports gfo = fmap importsOfModule `fmap` decodeModuleHeader gfo -------------------------------------------------------------------------------- diff --git a/src/compiler/GF/CompileInParallel.hs b/src/compiler/GF/CompileInParallel.hs index 4f5c0f76b..07c29febd 100644 --- a/src/compiler/GF/CompileInParallel.hs +++ b/src/compiler/GF/CompileInParallel.hs @@ -9,7 +9,7 @@ import qualified GF.System.Directory as D import GF.System.Catch(catch,try) import Data.List(nub,isPrefixOf,intercalate,partition) import qualified Data.Map as M -import GF.Compile.ReadFiles(getOptionsFromFile,findFile,gfImports,gfoImports) +import GF.Compile.ReadFiles(getOptionsFromFile,findFile,gfImports,gfoImports,VersionTagged(..)) import GF.CompileOne(reuseGFO,useTheSource) import GF.Infra.Option import GF.Infra.UseIO @@ -177,8 +177,10 @@ getPathFromFile lib_dir cmdline_opts file = getImports opts file = if isGFO file then gfoImports' file else gfImports opts file where - gfoImports' file = maybe bad return =<< gfoImports file - where bad = raise $ file++": bad .gfo file" + gfoImports' file = check =<< gfoImports file + where + check (Tagged imps) = return imps + check WrongVersion = raise $ file++": .gfo file version mismatch" relativeTo lib_dir cwd path = if length librel Binary (VersionTagged a) where then fmap Tagged get else return WrongVersion +instance Functor VersionTagged where + fmap f (Tagged a) = Tagged (f a) + fmap f WrongVersion = WrongVersion + gfoBinVersion = (b1,b2,b3,b4) where [b1,b2,b3,b4] = map (toEnum.fromEnum) gfoVersion :: [Word8] @@ -324,23 +326,14 @@ decodeModule fpath = liftIO $ check =<< decodeFile' fpath where check (Tagged m) = return m check _ = fail ".gfo file version mismatch" -{- -decodeModuleHeader fpath = decodeFile_ fpath getVersionedMod + +-- | Read just the module header, the returned 'Module' will have an empty body +decodeModuleHeader :: MonadIO io => FilePath -> io (VersionTagged Module) +decodeModuleHeader = liftIO . fmap (fmap conv) . decodeFile' where - getVersionedMod = do - ver <- getGFOVersion - if ver == gfoVersion - then do (m,mtype,mstatus,mflags,mextend,mwith,mopens,med,msrc) <- get - return (Just (m,ModInfo mtype mstatus mflags mextend mwith mopens med msrc Nothing Map.empty)) - else return Nothing ---} ---{- -decodeModuleHeader fpath = fmap check $ decodeFile' fpath - where - check (Tagged (m,mtype,mstatus,mflags,mextend,mwith,mopens,med,msrc)) = - (Just (m,ModInfo mtype mstatus mflags mextend mwith mopens med msrc Nothing Map.empty)) - check _ = Nothing ---} + conv (m,mtype,mstatus,mflags,mextend,mwith,mopens,med,msrc) = + (m,ModInfo mtype mstatus mflags mextend mwith mopens med msrc Nothing Map.empty) + encodeModule :: MonadIO io => FilePath -> SourceModule -> io () encodeModule fpath mo = liftIO $ encodeFile fpath (Tagged mo) diff --git a/src/runtime/haskell/PGF/Binary.hs b/src/runtime/haskell/PGF/Binary.hs index a7f6bf881..e0e50f4be 100644 --- a/src/runtime/haskell/PGF/Binary.hs +++ b/src/runtime/haskell/PGF/Binary.hs @@ -15,7 +15,7 @@ import qualified Data.IntMap as IntMap import Control.Monad pgfMajorVersion, pgfMinorVersion :: Word16 -version@(pgfMajorVersion, pgfMinorVersion) = (2,0) +version@(pgfMajorVersion, pgfMinorVersion) = (2,1) instance Binary PGF where put pgf = do putWord16be pgfMajorVersion @@ -23,11 +23,14 @@ instance Binary PGF where put (gflags pgf) put (absname pgf, abstract pgf) put (concretes pgf) - get = do v1 <- getWord16be - v2 <- getWord16be - case (v1,v2) of - v | v==version -> getPGF' - | v==Old.version -> Old.getPGF' + get = do major<- getWord16be + minor <- getWord16be + let v = (major,minor) + if major==pgfMajorVersion && minor<=pgfMinorVersion + then getPGF' + else if v==Old.version + then Old.getPGF' + else fail $ "Unsupported PGF version "++show (major,minor) getPGF'=do gflags <- get (absname,abstract) <- get