Bump version of .gfo and .pgf files, improve error messages on version mismatch

Becacuse of the new special tokens added to the Symbol type, .gfo and .pgf
files produced with the current version of GF can not always be used with
older versions of GF and the PGF run-time system.

The PGF version number was increased from (2,0) to (2,1). GF can still
read version (2,0) and (1,0), so old PGF files continue to work.

The GFO version was increased from "GF03" to "GF04".
This commit is contained in:
hallgren
2015-06-23 12:58:14 +00:00
parent 984c09923c
commit 22ba8d34ff
4 changed files with 35 additions and 37 deletions

View File

@@ -20,7 +20,7 @@
module GF.Compile.ReadFiles module GF.Compile.ReadFiles
( getAllFiles,ModName,ModEnv,importsOfModule, ( getAllFiles,ModName,ModEnv,importsOfModule,
findFile,gfImports,gfoImports, findFile,gfImports,gfoImports,VersionTagged(..),
parseSource,getOptionsFromFile,getPragmas) where parseSource,getOptionsFromFile,getPragmas) where
import Prelude hiding (catch) import Prelude hiding (catch)
@@ -32,7 +32,7 @@ import GF.Data.Operations
import GF.Grammar.Lexer import GF.Grammar.Lexer
import GF.Grammar.Parser import GF.Grammar.Parser
import GF.Grammar.Grammar import GF.Grammar.Grammar
import GF.Grammar.Binary(decodeModuleHeader) import GF.Grammar.Binary(VersionTagged(..),decodeModuleHeader)
import System.IO(mkTextEncoding) import System.IO(mkTextEncoding)
import GF.Text.Coding(decodeUnicodeIO) import GF.Text.Coding(decodeUnicodeIO)
@@ -107,10 +107,10 @@ getAllFiles opts ps env file = do
case st of case st of
CSEnv -> return (st, (name, maybe [] snd mb_envmod)) CSEnv -> return (st, (name, maybe [] snd mb_envmod))
CSRead -> do let gfo = if isGFO file then file else gf2gfo opts file CSRead -> do let gfo = if isGFO file then file else gf2gfo opts file
mb_imps <- gfoImports gfo t_imps <- gfoImports gfo
case mb_imps of case t_imps of
Just imps -> return (st,imps) Tagged imps -> return (st,imps)
Nothing WrongVersion
| isGFO file -> raise (file ++ " is compiled with different GF version and I can't find the source file") | isGFO file -> raise (file ++ " is compiled with different GF version and I can't find the source file")
| otherwise -> do imps <- gfImports opts file | otherwise -> do imps <- gfImports opts file
return (CSComp,imps) return (CSComp,imps)
@@ -143,7 +143,7 @@ findFile gfoDir ps name =
gfImports opts file = importsOfModule `fmap` parseModHeader opts file gfImports opts file = importsOfModule `fmap` parseModHeader opts file
gfoImports gfo = fmap importsOfModule `fmap` liftIO (decodeModuleHeader gfo) gfoImports gfo = fmap importsOfModule `fmap` decodeModuleHeader gfo
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View File

@@ -9,7 +9,7 @@ import qualified GF.System.Directory as D
import GF.System.Catch(catch,try) import GF.System.Catch(catch,try)
import Data.List(nub,isPrefixOf,intercalate,partition) import Data.List(nub,isPrefixOf,intercalate,partition)
import qualified Data.Map as M 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.CompileOne(reuseGFO,useTheSource)
import GF.Infra.Option import GF.Infra.Option
import GF.Infra.UseIO import GF.Infra.UseIO
@@ -177,8 +177,10 @@ getPathFromFile lib_dir cmdline_opts file =
getImports opts file = getImports opts file =
if isGFO file then gfoImports' file else gfImports opts file if isGFO file then gfoImports' file else gfImports opts file
where where
gfoImports' file = maybe bad return =<< gfoImports file gfoImports' file = check =<< gfoImports file
where bad = raise $ file++": bad .gfo file" where
check (Tagged imps) = return imps
check WrongVersion = raise $ file++": .gfo file version mismatch"
relativeTo lib_dir cwd path = relativeTo lib_dir cwd path =
if length librel<length cwdrel then librel else cwdrel if length librel<length cwdrel then librel else cwdrel

View File

@@ -7,15 +7,13 @@
-- --
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
module GF.Grammar.Binary(decodeModule,decodeModuleHeader,encodeModule) where module GF.Grammar.Binary(VersionTagged(..),decodeModuleHeader,decodeModule,encodeModule) where
import Prelude hiding (catch) import Prelude hiding (catch)
import Control.Exception(catch,ErrorCall(..),throwIO) import Control.Exception(catch,ErrorCall(..),throwIO)
--import Data.Char
import PGF.Internal(Binary(..),Word8,putWord8,getWord8,encodeFile,decodeFile) import PGF.Internal(Binary(..),Word8,putWord8,getWord8,encodeFile,decodeFile)
--import Control.Monad import qualified Data.Map as Map(empty)
import qualified Data.Map as Map
import qualified Data.ByteString.Char8 as BS import qualified Data.ByteString.Char8 as BS
import GF.Data.Operations import GF.Data.Operations
@@ -28,7 +26,7 @@ import PGF() -- Binary instances
import PGF.Internal(Literal(..)) import PGF.Internal(Literal(..))
-- Please change this every time when the GFO format is changed -- Please change this every time when the GFO format is changed
gfoVersion = "GF03" gfoVersion = "GF04"
instance Binary Ident where instance Binary Ident where
put id = put (ident2utf8 id) put id = put (ident2utf8 id)
@@ -315,6 +313,10 @@ instance Binary a => Binary (VersionTagged a) where
then fmap Tagged get then fmap Tagged get
else return WrongVersion else return WrongVersion
instance Functor VersionTagged where
fmap f (Tagged a) = Tagged (f a)
fmap f WrongVersion = WrongVersion
gfoBinVersion = (b1,b2,b3,b4) gfoBinVersion = (b1,b2,b3,b4)
where [b1,b2,b3,b4] = map (toEnum.fromEnum) gfoVersion :: [Word8] where [b1,b2,b3,b4] = map (toEnum.fromEnum) gfoVersion :: [Word8]
@@ -324,23 +326,14 @@ decodeModule fpath = liftIO $ check =<< decodeFile' fpath
where where
check (Tagged m) = return m check (Tagged m) = return m
check _ = fail ".gfo file version mismatch" 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 where
getVersionedMod = do conv (m,mtype,mstatus,mflags,mextend,mwith,mopens,med,msrc) =
ver <- getGFOVersion (m,ModInfo mtype mstatus mflags mextend mwith mopens med msrc Nothing Map.empty)
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
--}
encodeModule :: MonadIO io => FilePath -> SourceModule -> io () encodeModule :: MonadIO io => FilePath -> SourceModule -> io ()
encodeModule fpath mo = liftIO $ encodeFile fpath (Tagged mo) encodeModule fpath mo = liftIO $ encodeFile fpath (Tagged mo)

View File

@@ -15,7 +15,7 @@ import qualified Data.IntMap as IntMap
import Control.Monad import Control.Monad
pgfMajorVersion, pgfMinorVersion :: Word16 pgfMajorVersion, pgfMinorVersion :: Word16
version@(pgfMajorVersion, pgfMinorVersion) = (2,0) version@(pgfMajorVersion, pgfMinorVersion) = (2,1)
instance Binary PGF where instance Binary PGF where
put pgf = do putWord16be pgfMajorVersion put pgf = do putWord16be pgfMajorVersion
@@ -23,11 +23,14 @@ instance Binary PGF where
put (gflags pgf) put (gflags pgf)
put (absname pgf, abstract pgf) put (absname pgf, abstract pgf)
put (concretes pgf) put (concretes pgf)
get = do v1 <- getWord16be get = do major<- getWord16be
v2 <- getWord16be minor <- getWord16be
case (v1,v2) of let v = (major,minor)
v | v==version -> getPGF' if major==pgfMajorVersion && minor<=pgfMinorVersion
| v==Old.version -> Old.getPGF' then getPGF'
else if v==Old.version
then Old.getPGF'
else fail $ "Unsupported PGF version "++show (major,minor)
getPGF'=do gflags <- get getPGF'=do gflags <- get
(absname,abstract) <- get (absname,abstract) <- get