# -----------------------------------------------------------------------------
-# $Id: Makefile,v 1.33 1998/01/12 14:44:37 simonm Exp $
+# $Id: Makefile,v 1.34 1998/02/25 19:48:54 sof Exp $
 
 TOP = ..
 include $(TOP)/mk/boilerplate.mk
 hsSyn/HsExpr_HC_OPTS           = -K2m
 hsSyn/HsSyn_HC_OPTS            = -fno-omit-reexported-instances
 main/Main_HC_OPTS              = -fvia-C -DPROJECTVERSION=$(GhcProjectVersion)
+main/MkIface_HC_OPTS            = -DPROJECTVERSION=$(GhcProjectVersionInt)
 main/CmdLineOpts_HC_OPTS       = -fvia-C
 nativeGen/PprMach_HC_OPTS      = -K2m
 nativeGen/MachMisc_HC_OPTS     = -K2m -fvia-C
 parser/U_tree_HC_OPTS          = -H12m -fvia-C '-\#include"hspincl.h"'
 parser/U_ttype_HC_OPTS                 = -fvia-C '-\#include"hspincl.h"'
 prelude/PrimOp_HC_OPTS                 = -H12m -K3m
-reader/Lex_HC_OPTS             = -K2m -H16m -fvia-C
+reader/Lex_HC_OPTS             = -K2m -H16m -fvia-C -DPROJECTVERSION=$(GhcProjectVersionInt)
 
 # Heap was 6m with 2.10
 reader/ReadPrefix_HC_OPTS      = -fvia-C '-\#include"hspincl.h"' -H10m
 
 
        mkGeneratedSrcLoc,      -- Code generated within the compiler
 
-       incSrcLine
+       incSrcLine,
+       
+       srcLocFile              -- return the file name part.
     ) where
 
 #include "HsVersions.h"
 isNoSrcLoc NoSrcLoc = True
 isNoSrcLoc other    = False
 
+srcLocFile :: SrcLoc -> FAST_STRING
+srcLocFile (SrcLoc fname _) = fname
+
 incSrcLine :: SrcLoc -> SrcLoc
 incSrcLine (SrcLoc s l) = SrcLoc s (l +# 1#)
 incSrcLine loc         = loc
 
 
 #include "HsVersions.h"
 
-import IO              ( Handle, hPutStr, openFile, hClose, IOMode(..) )
+import IO              ( Handle, hPutStr, openFile, 
+                         hClose, hPutStrLn, IOMode(..) )
 
 import HsSyn
 import RdrHsSyn                ( RdrName(..) )
 startIface mod
   = case opt_ProduceHi of
       Nothing -> return Nothing -- not producing any .hi file
-      Just fn ->
-       openFile fn WriteMode   >>= \ if_hdl ->
-       hPutStr if_hdl ("{-# GHC_PRAGMA INTERFACE VERSION 20 #-}\n_interface_ "++ _UNPK_ mod ++ "\n") >>
+      Just fn -> do
+       if_hdl <- openFile fn WriteMode
+       hPutStrLn if_hdl ("_interface_ "++ _UNPK_ mod ++ ' ':show (PROJECTVERSION :: Int))
        return (Just if_hdl)
 
 endIface Nothing       = return ()
 
 
        -- Monad for parser
        IfaceToken(..), lexIface, IfM, thenIf, returnIf, getSrcLocIf,
+       checkVersion, 
        happyError,
        StringBuffer
 
 #include "HsVersions.h"
 
 import Char            (isDigit, isAlphanum, isUpper,isLower, isSpace, ord )
+import List             ( isSuffixOf )
 
 import {-# SOURCE #-} CostCentre
 
 import Demand          ( Demand(..) {- instance Read -} )
 import UniqFM           ( UniqFM, listToUFM, lookupUFM)
 import BasicTypes      ( NewOrData(..), IfaceFlavour(..) )
-import SrcLoc          ( SrcLoc, incSrcLine )
+import SrcLoc          ( SrcLoc, incSrcLine, srcLocFile )
 
 import Maybes          ( MaybeErr(..) )
 import ErrUtils                ( ErrMsg(..) )
 happyError :: IfM a
 happyError s l = Failed (ifaceParseErr l ([]::[IfaceToken]){-Todo-})
 
+
+{- 
+ Note that if the file we're processing ends with `hi-boot',
+ we accept it on faith as having the right version.
+ This is done so that .hi-boot files  that comes with hsc
+ don't have to be updated before every release, and it
+ allows us to share .hi-boot files with versions of hsc
+ that don't have .hi version checking (e.g., ghc-2.10's)
+
+ If the version number is 0, the checking is also turned off.
+-}
+checkVersion :: Maybe Integer -> IfM ()
+checkVersion mb@(Just v) s l
+ | (v==0) || (v == PROJECTVERSION) = Succeeded ()
+ | otherwise = Failed (ifaceVersionErr mb l ([]::[IfaceToken]){-Todo-})
+checkVersion mb@Nothing  s l 
+ | "hi-boot" `isSuffixOf` (_UNPK_ (srcLocFile l)) = Succeeded ()
+ | otherwise = Failed (ifaceVersionErr mb l ([]::[IfaceToken]){-Todo-})
+
 -----------------------------------------------------------------
 
 ifaceParseErr l toks
   = hsep [ppr l, ptext SLIT("Interface-file parse error;"),
           ptext SLIT("toks="), text (show (take 10 toks))]
+
+ifaceVersionErr hi_vers l toks
+  = hsep [ppr l, ptext SLIT("Interface file version error;"),
+          ptext SLIT("Expected"), int PROJECTVERSION, 
+         ptext SLIT(" found "), pp_version]
+    where
+     pp_version =
+      case hi_vers of
+        Nothing -> ptext SLIT("pre ghc-3.02 version")
+       Just v  -> ptext SLIT("version") <+> integer v
+
 \end{code}
 
 
 
 iface          :: { ParsedIface }
-iface          : INTERFACE CONID INTEGER
+iface          : INTERFACE CONID INTEGER checkVersion
                  inst_modules_part 
                  usages_part
                  exports_part fixities_part
                  { ParsedIface 
                        $2                      -- Module name
                        (fromInteger $3)        -- Module version
-                       $5                      -- Usages
-                       $6                      -- Exports
-                       $4                      -- Instance modules
-                       $7                      -- Fixities
-                       $9                      -- Decls
-                       $8                      -- Local instances
+                       $6                      -- Usages
+                       $7                      -- Exports
+                       $5                      -- Instance modules
+                       $8                      -- Fixities
+                       $10                     -- Decls
+                       $9                      -- Local instances
                    }
 
 
          : VARID                                               { head (_UNPK_ $1) }
          | CONID                                               { head (_UNPK_ $1) }
 
-
 -------------------------------------------------------------------
 
 src_loc :: { SrcLoc }
 src_loc :                              {% getSrcLocIf }
 
+checkVersion :: { () }
+          : {-empty-}                  {% checkVersion Nothing }
+          | INTEGER                    {% checkVersion (Just (fromInteger $1)) }
+
 ------------------------------------------------------------------- 
 
 --                     Haskell code 
 
 \begin{code}
 renameModule :: UniqSupply
             -> RdrNameHsModule
-            -> IO (Maybe (RenamedHsModule,     -- Output, after renaming
-                          InterfaceDetails,    -- Interface; for interface file generatino
-                          RnNameSupply,        -- Final env; for renaming derivings
-                          [Module]))           -- Imported modules; for profiling
+            -> IO (Maybe 
+                     ( RenamedHsModule   -- Output, after renaming
+                     , InterfaceDetails  -- Interface; for interface file generatino
+                     , RnNameSupply      -- Final env; for renaming derivings
+                     , [Module]          -- Imported modules; for profiling
+                     ))
 
 renameModule us this_mod@(HsModule mod_name vers exports imports fixities local_decls loc)
   =    -- Initialise the renamer monad
 
     }
 
     local($new_module_version) = &calcNewModuleVersion(@decl_names);
-    print NEWHI "_interface_ ", $ModuleName{'new'}, " $new_module_version\n";
+    print NEWHI "_interface_ ", $ModuleName{'new'}, " $new_module_version $GhcVersionInfo\n";
 
     if ( $Stuff{'new:instance_modules'} ) {
        print NEWHI "_instance_modules_\n";
            last hi_line;
        }
 
-       if ( /^_interface_ ([A-Z]\S*) (\d+)/ ) {
+       if ( /^_interface_ ([A-Z]\S*) (\d+)/ && $mod ne 'new' ) {
            $ModuleName{$mod}    = $1; # used to decide name of interface file.
            $ModuleVersion{$mod} = $2;
 
-       } elsif ( /^_interface_ ([A-Z]\S*)/ && $mod eq 'new' ) { # special case: no version
+       } elsif ( /^_interface_ ([A-Z]\S*) (\d+)/ && $mod eq 'new' ) { # special case: no version
            $ModuleName{'new'} = $1;
 
        } elsif ( /^_([a-z_]+)_$/ ) {
 
 --     primitive operations and types that GHC knows about.
 ---------------------------------------------------------------------------
 
-_interface_ PrelGHC 2
+_interface_ PrelGHC 2 0
 _exports_
 PrelGHC
   ->