You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(4) |
Jun
|
Jul
(68) |
Aug
(4) |
Sep
|
Oct
(23) |
Nov
(95) |
Dec
(9) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(3) |
Feb
|
Mar
|
Apr
(51) |
May
(81) |
Jun
(2) |
Jul
(86) |
Aug
(143) |
Sep
(3) |
Oct
(31) |
Nov
(63) |
Dec
(90) |
2005 |
Jan
(277) |
Feb
(157) |
Mar
(99) |
Apr
(195) |
May
(151) |
Jun
(148) |
Jul
(98) |
Aug
(123) |
Sep
(20) |
Oct
(174) |
Nov
(155) |
Dec
(26) |
2006 |
Jan
(51) |
Feb
(19) |
Mar
(16) |
Apr
(12) |
May
(5) |
Jun
|
Jul
(11) |
Aug
(7) |
Sep
(10) |
Oct
(31) |
Nov
(174) |
Dec
(56) |
2007 |
Jan
(45) |
Feb
(52) |
Mar
(10) |
Apr
(5) |
May
(47) |
Jun
(16) |
Jul
(80) |
Aug
(29) |
Sep
(14) |
Oct
(59) |
Nov
(46) |
Dec
(16) |
2008 |
Jan
(10) |
Feb
(1) |
Mar
|
Apr
|
May
(49) |
Jun
(26) |
Jul
(8) |
Aug
(4) |
Sep
(25) |
Oct
(53) |
Nov
(9) |
Dec
(1) |
2009 |
Jan
(66) |
Feb
(11) |
Mar
(1) |
Apr
(14) |
May
(8) |
Jun
(1) |
Jul
(2) |
Aug
(2) |
Sep
(9) |
Oct
(23) |
Nov
(35) |
Dec
|
2010 |
Jan
(7) |
Feb
(2) |
Mar
(39) |
Apr
(19) |
May
(161) |
Jun
(19) |
Jul
(32) |
Aug
(65) |
Sep
(113) |
Oct
(120) |
Nov
(2) |
Dec
|
2012 |
Jan
|
Feb
(5) |
Mar
(4) |
Apr
(7) |
May
(9) |
Jun
(14) |
Jul
(1) |
Aug
|
Sep
(1) |
Oct
(1) |
Nov
(12) |
Dec
(2) |
2013 |
Jan
(1) |
Feb
(17) |
Mar
(4) |
Apr
(4) |
May
(9) |
Jun
|
Jul
(8) |
Aug
|
Sep
(2) |
Oct
|
Nov
|
Dec
|
From: Andy S. <And...@co...> - 2010-05-01 16:23:27
|
Sat May 1 12:20:11 EDT 2010 Andy Stewart <laz...@gm...> * Fix compile error of webkit. Ignore-this: 2f6fe99208c5e17d4fd906b2f70b18b9 hunk ./webkit/Graphics/UI/Gtk/WebKit/Download.chs 77 -{#import Graphics.UI.Gtk.WebKit.Signals#} hunk ./webkit/Graphics/UI/Gtk/WebKit/HitTestResult.chs 40 -{#import Graphics.UI.Gtk.WebKit.Signals#} hunk ./webkit/Graphics/UI/Gtk/WebKit/Internal.chs 43 -{#import Graphics.UI.Gtk.WebKit.Signals#} hunk ./webkit/Graphics/UI/Gtk/WebKit/NetworkRequest.chs 47 -{#import Graphics.UI.Gtk.WebKit.Signals#} hunk ./webkit/Graphics/UI/Gtk/WebKit/NetworkResponse.chs 44 -{#import Graphics.UI.Gtk.WebKit.Signals#} hunk ./webkit/Graphics/UI/Gtk/WebKit/SecurityOrigin.chs 49 -{#import Graphics.UI.Gtk.WebKit.Signals#} hunk ./webkit/Graphics/UI/Gtk/WebKit/SoupAuthDialog.chs 37 -{#import Graphics.UI.Gtk.WebKit.Signals#} hunk ./webkit/Graphics/UI/Gtk/WebKit/WebBackForwardList.chs 61 -{#import Graphics.UI.Gtk.WebKit.Signals#} hunk ./webkit/Graphics/UI/Gtk/WebKit/WebDataSource.chs 58 -{#import Graphics.UI.Gtk.WebKit.Signals#} hunk ./webkit/Graphics/UI/Gtk/WebKit/WebDatabase.chs 49 -{#import Graphics.UI.Gtk.WebKit.Signals#} hunk ./webkit/Graphics/UI/Gtk/WebKit/WebFrame.chs 74 -{#import Graphics.UI.Gtk.WebKit.Signals#} hunk ./webkit/Graphics/UI/Gtk/WebKit/WebHistoryItem.chs 60 -{#import Graphics.UI.Gtk.WebKit.Signals#} hunk ./webkit/Graphics/UI/Gtk/WebKit/WebInspector.chs 59 -{#import Graphics.UI.Gtk.WebKit.Signals#} hunk ./webkit/Graphics/UI/Gtk/WebKit/WebNavigationAction.chs 52 -{#import Graphics.UI.Gtk.WebKit.Signals#} hunk ./webkit/Graphics/UI/Gtk/WebKit/WebPolicyDecision.chs 45 -{#import Graphics.UI.Gtk.WebKit.Signals#} hunk ./webkit/Graphics/UI/Gtk/WebKit/WebResource.chs 54 -{#import Graphics.UI.Gtk.WebKit.Signals#} hunk ./webkit/Graphics/UI/Gtk/WebKit/WebSettings.chs 85 -{#import Graphics.UI.Gtk.WebKit.Signals#} hunk ./webkit/Graphics/UI/Gtk/WebKit/WebView.chs 199 -{#import Graphics.UI.Gtk.WebKit.Signals#} hunk ./webkit/Graphics/UI/Gtk/WebKit/WebWindowFeatures.chs 60 -{#import Graphics.UI.Gtk.WebKit.Signals#} hunk ./webkit/webkit.cabal 65 - Graphics.UI.Gtk.WebKit.Signals hunk ./webkit/webkit.cabal 70 - x-Signals-File: Graphics/UI/Gtk/WebKit/Signals.chs - x-Signals-Modname: Graphics.UI.Gtk.WebKit.Signals |
From: Andy S. <And...@co...> - 2010-05-01 16:23:24
|
Sat May 1 12:17:39 EDT 2010 Andy Stewart <laz...@gm...> * Fix compile error of gnomevfs. Ignore-this: 8300370414f8840fcb7897e199025d75 hunk ./gnomevfs/System/Gnome/VFS/Drive.chs 90 -{#import System.Gnome.VFS.Signals#} hunk ./gnomevfs/System/Gnome/VFS/VolumeMonitor.chs 68 -{#import System.Gnome.VFS.Signals#} hunk ./gnomevfs/gnomevfs.cabal 25 -x-Types-Forward: *System.Glib.GObject +x-Types-Forward: *System.Glib.GObject Graphics.UI.GtkInternals hunk ./gnomevfs/gnomevfs.cabal 62 - System.Gnome.VFS.Signals[_^I_][_^I_] [_$_] hunk ./gnomevfs/gnomevfs.cabal 71 - x-Signals-File: System/Gnome/VFS/Signals.chs - x-Signals-Modname: System.Gnome.VFS.Signals |
From: Andy S. <And...@co...> - 2010-05-01 16:23:24
|
Sat May 1 12:18:26 EDT 2010 Andy Stewart <laz...@gm...> * Fix compile error of gtksourceview2. Ignore-this: d7f05977a77f1330d14915e5895b526c hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceBuffer.chs 70 -{#import Graphics.UI.Gtk.SourceView.Signals#} hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceLanguage.chs 52 -{#import Graphics.UI.Gtk.SourceView.Signals#} hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceLanguageManager.chs 49 -{#import Graphics.UI.Gtk.SourceView.Signals#} hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceView.chs 79 -{#import Graphics.UI.Gtk.SourceView.Signals#} hunk ./gtksourceview2/gtksourceview2.cabal 54 - Graphics.UI.Gtk.SourceView.Signals hunk ./gtksourceview2/gtksourceview2.cabal 59 - x-Signals-File: Graphics/UI/Gtk/SourceView/Signals.chs - x-Signals-Modname: Graphics.UI.Gtk.SourceView.Signals |
From: Andy S. <And...@co...> - 2010-05-01 16:23:23
|
Sat May 1 12:15:04 EDT 2010 Andy Stewart <laz...@gm...> * Fix compile error of gconf. Ignore-this: 67c9dc2b5c337476bf3fb5ef5aa3ceb4 hunk ./gconf/System/Gnome/GConf/GConfClient.chs 95 -{#import System.Gnome.GConf.Signals#} hunk ./gconf/gconf.cabal 44 - System.Gnome.GConf.Signals[_^I_][_^I_] [_$_] hunk ./gconf/gconf.cabal 49 - x-Signals-File: System/Gnome/GConf/Signals.chs - x-Signals-Modname: System.Gnome.GConf.Signals |
From: Andy S. <And...@co...> - 2010-05-01 16:23:22
|
Sat May 1 12:16:12 EDT 2010 Andy Stewart <laz...@gm...> * Fix compile error of gio. Ignore-this: 30af23f768bf3823c55db6db33fae8e9 hunk ./gio/System/GIO/Async/Cancellable.chs 51 -{#import System.GIO.Signals#} hunk ./gio/gio.cabal 24 -x-Types-Forward: *System.Glib.GObject +x-Types-Forward: *System.Glib.GObject Graphics.UI.GtkInternals hunk ./gio/gio.cabal 47 - System.GIO.Signals[_^I_][_^I_] [_$_] hunk ./gio/gio.cabal 52 - x-Signals-File: System/GIO/Signals.chs - x-Signals-Modname: System.GIO.Signals |
From: Axel S. <si...@co...> - 2010-05-01 15:19:41
|
Sat May 1 11:09:33 EDT 2010 Axe...@in... * Replace Setup.hs by the default setup files. Ignore-this: b4c2102781b831bd3b787bde35ffcda6 addfile ./webkit/Gtk2HsSetup.hs hunk ./webkit/Gtk2HsSetup.hs 1 +{-# LANGUAGE CPP #-} + +#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ + ((major) * 10000) \ + + ((minor) * 100) \ + + ((micro) * 1)) + +#define CABAL_VERSION_CHECK(major,minor,micro) \ + (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) + +-- now, this is bad, but Cabal doesn't seem to actually pass any information about +-- its version to CPP, so guess the version depending on the version of GHC +#ifdef CABAL_VERSION_MINOR +#ifndef CABAL_VERSION_MAJOR +#define CABAL_VERSION_MAJOR 1 +#endif +#ifndef CABAL_VERSION_MICRO +#define CABAL_VERSION_MICRO 0 +#endif +#define CABAL_VERSION CABAL_VERSION_ENCODE( \ + CABAL_VERSION_MAJOR, \ + CABAL_VERSION_MINOR, \ + CABAL_VERSION_MICRO) +#else +#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) +#if (__GLASGOW_HASKELL__ >= 612) +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) +#else +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) +#endif +#endif + +-- | Build a Gtk2hs package. +-- +module Gtk2HsSetup ( gtk2hsUserHooks, getPkgConfigPackages ) where + +import Distribution.Simple +import Distribution.Simple.PreProcess +import Distribution.InstalledPackageInfo ( importDirs ) +import Distribution.Simple.PackageIndex ( +#if CABAL_VERSION_CHECK(1,8,0) + lookupInstalledPackageId +#else + lookupPackageId +#endif + ) +import Distribution.PackageDescription as PD ( PackageDescription(..), + updatePackageDescription, + BuildInfo(..), + emptyBuildInfo, allBuildInfo, + Library(..), + libModules) +import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), + InstallDirs(..), +#if CABAL_VERSION_CHECK(1,8,0) + componentPackageDeps, +#else + packageDeps, +#endif + absoluteInstallDirs) +import Distribution.Simple.Compiler ( Compiler(..) ) +import Distribution.Simple.Program ( + Program(..), ConfiguredProgram(..), + rawSystemProgramConf, rawSystemProgramStdoutConf, + c2hsProgram, pkgConfigProgram, + simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) +import Distribution.ModuleName ( ModuleName, components, toFilePath ) +import Distribution.Simple.Utils +import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), + defaultCopyFlags, ConfigFlags(configVerbosity), + fromFlag, toFlag) +import Distribution.Simple.BuildPaths ( autogenModulesDir ) +import Distribution.Text ( simpleParse, display ) +import System.FilePath +import System.Directory ( doesFileExist ) +import Distribution.Version (Version(..)) +import Distribution.Verbosity +import Control.Monad (unless) +import Data.Maybe (fromMaybe) +import Data.List (isPrefixOf, nub) +import Data.Char (isAlpha) +import qualified Data.Map as M +import qualified Data.Set as S + + +-- the name of the c2hs pre-compiled header file +precompFile = "precompchs.bin" + +gtk2hsUserHooks = simpleUserHooks { + hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], + hookedPreProcessors = [("chs", ourC2hs)], + confHook = \pd cf -> + confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, + postConf = \args cf pd lbi -> do + genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi + postConf simpleUserHooks args cf pd lbi, + buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> + (buildHook simpleUserHooks) pd lbi uh bf, + copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), + instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest + } + +-- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later +adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo +adjustLocalBuildInfo lbi = + let extra = (Just libBi, []) + libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi + , buildDir lbi ] } + in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } + +ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor +ourC2hs bi lbi = PreProcessor { + platformIndependent = False, + runPreProcessor = runC2HS bi lbi +} + +runC2HS :: BuildInfo -> LocalBuildInfo -> + (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () +runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do + -- have the header file name if we don't have the precompiled header yet + header <- case lookup "x-c2hs-header" (customFieldsBI bi) of + Just h -> return h + Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ + "that sets the C header file to process .chs.pp files.") + + -- c2hs will output files in out dir, removing any leading path of the input file. + -- Thus, append the dir of the input file to the output dir. + let (outFileDir, newOutFile) = splitFileName outFile + let newOutDir = outDir </> outFileDir + -- additional .chi files might be needed that other packages have installed; + -- we assume that these are installed in the same place as .hi files + let chiDirs = [ dir | +#if CABAL_VERSION_CHECK(1,8,0) + ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), + dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] +#else + ipi <- packageDeps lbi, + dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] +#endif + rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ + map ("--include=" ++) (outDir:chiDirs) + ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] + ++ ["--output-dir=" ++ newOutDir, + "--output=" ++ newOutFile, + "--precomp=" ++ buildDir lbi </> precompFile, + header, inDir </> inFile] + +getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] +getCppOptions bi lbi + = nub $ + ["-I" ++ dir | dir <- PD.includeDirs bi] + ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] + +installCHI :: PackageDescription -- ^information from the .cabal file + -> LocalBuildInfo -- ^information from the configure step + -> Verbosity -> CopyDest -- ^flags sent to copy or install + -> IO () +installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do + let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest + -- cannot use the recommended 'findModuleFiles' since it fails if there exists + -- a modules that does not have a .chi file + mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) + (map toFilePath +#if CABAL_VERSION_CHECK(1,8,0) + (PD.libModules lib) +#else + (PD.libModules pkg) +#endif + ) + let files = [ f | Just f <- mFiles ] +#if CABAL_VERSION_CHECK(1,8,0) + installOrdinaryFiles verbosity libPref files +#else + copyFiles verbosity libPref files +#endif + + [_$_] +installCHI _ _ _ _ = return () + +------------------------------------------------------------------------------ +-- Generating the type hierarchy and signal callback .hs files. +------------------------------------------------------------------------------ + +typeGenProgram :: Program +typeGenProgram = (simpleProgram "gtk2hsTypeGen") + +signalGenProgram :: Program +signalGenProgram = (simpleProgram "gtk2hsHookGenerator") + +c2hsLocal :: Program +c2hsLocal = (simpleProgram "gtk2hsC2hs") + +genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () +genSynthezisedFiles verb pd lbi = do + + cPkgs <- getPkgConfigPackages verb lbi pd + + let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) + ++customFieldsPD pd + typeOpts :: [ProgArg] + typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) + | (field,content) <- xList, + "x-types-" `isPrefixOf` field, + field /= "x-types-file"] + ++ [ "--tag=" ++ tag + | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs + , let name' = filter isAlpha (display name) + , tag <- name' + : [ name' ++ "-" ++ show major ++ "." ++ show digit + | digit <- [0,2..minor] ] + ] + + signalsOpts :: [ProgArg] + signalsOpts = concat [ map (\val -> '-':'-':drop 10 field++'=':val) (words content) + | (field,content) <- xList, + "x-signals-" `isPrefixOf` field, + field /= "x-signals-file"] + + genFile :: Program -> [ProgArg] -> FilePath -> IO () + genFile prog args outFile = do + res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args + rewriteFile outFile res + + case lookup "x-types-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") + genFile typeGenProgram typeOpts f + + case lookup "x-signals-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") + genFile signalGenProgram signalsOpts f + +--FIXME: Cabal should tell us the selected pkg-config package versions in the +-- LocalBuildInfo or equivalent. +-- In the mean time, ask pkg-config again. + +getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] +getPkgConfigPackages verbosity lbi pkg = + sequence + [ do version <- pkgconfig ["--modversion", display pkgname] + case simpleParse version of + Nothing -> die $ "parsing output of pkg-config --modversion failed" + Just v -> return (PackageIdentifier pkgname v) + | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] + where + pkgconfig = rawSystemProgramStdoutConf verbosity + pkgConfigProgram (withPrograms lbi) + +------------------------------------------------------------------------------ +-- Dependency calculation amongst .chs files. +------------------------------------------------------------------------------ + +-- Given all files of the package, find those that end in .chs and extract the +-- .chs files they depend upon. Then return the PackageDescription with these +-- files rearranged so that they are built in a sequence that files that are +-- needed by other files are built first. +fixDeps :: PackageDescription -> IO PackageDescription +fixDeps pd...@PD...ckageDescription { + PD.library = Just li...@PD...brary { + PD.exposedModules = expMods, + PD.libBuildInfo = bi@PD.BuildInfo { + PD.hsSourceDirs = srcDirs, + PD.otherModules = othMods + }}} = do + let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs + (joinPath (components m)) + mExpFiles <- mapM findModule expMods + mOthFiles <- mapM findModule othMods + + -- tag all exposed files with True so we throw an error if we need to build + -- an exposed module before an internal modules (we cannot express this) + let modDeps = zipWith (ModDep True []) expMods mExpFiles++ + zipWith (ModDep False []) othMods mOthFiles + modDeps <- mapM extractDeps modDeps + let (expMods, othMods) = span mdExposed $ sortTopological modDeps + badOther = map (fromMaybe "<no file>" . mdLocation) $ + filter (not . mdExposed) expMods + unless (null badOther) $ + die ("internal chs modules "++intercalate "," badOther++ + " depend on exposed chs modules; cabal needs to build internal modules first") + return pd { PD.library = Just lib { + PD.exposedModules = map mdOriginal expMods, + PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } + }} + +data ModDep = ModDep { + mdExposed :: Bool, + mdRequires :: [ModuleName], + mdOriginal :: ModuleName, + mdLocation :: Maybe FilePath +} + +instance Show ModDep where + show x = show (mdLocation x) + +instance Eq ModDep where + ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 +instance Ord ModDep where + compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 + +-- Extract the dependencies of this file. This is intentionally rather naive as it +-- ignores CPP conditionals. We just require everything which means that the +-- existance of a .chs module may not depend on some CPP condition. [_$_] +extractDeps :: ModDep -> IO ModDep +extractDeps md@ModDep { mdLocation = Nothing } = return md +extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do + let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of + ('i':'m':'p':'o':'r':'t':' ':ys) -> + case simpleParse (takeWhile ((/=) '#') ys) of + Just m -> findImports (m:acc) xxs [_$_] + Nothing -> die ("cannot parse chs import in "++f++":\n"++ + "offending line is {#"++xs) + -- no more imports after the first non-import hook + _ -> return acc + findImports acc (_:xxs) = findImports acc xxs + findImports acc [] = return acc + mods <- findImports [] (lines con) + return md { mdRequires = mods } + +-- Find a total order of the set of modules that are partially sorted by their +-- dependencies on each other. The function returns the sorted list of modules +-- together with a list of modules that are required but not supplied by this +-- in the input set of modules. +sortTopological :: [ModDep] -> [ModDep] +sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) + where + set = M.fromList (map (\m -> (mdOriginal m, m)) ms) + visit (out,visited) m + | m `S.member` visited = (out,visited) + | otherwise = case m `M.lookup` set of + Nothing -> (out, m `S.insert` visited) + Just md -> (md:out', visited') + where + (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) hunk ./webkit/Setup.hs 1 -{-# LANGUAGE CPP #-} +-- Setup file for a Gtk2Hs module. Contains only adjustments specific to this module, +-- all Gtk2Hs-specific boilerplate is stored in Gtk2HsSetup.hs which should be kept +-- identical across all modules. +import Gtk2HsSetup ( gtk2hsUserHooks ) +import Distribution.Simple ( defaultMainWithHooks ) hunk ./webkit/Setup.hs 7 -#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ - ((major) * 10000) \ - + ((minor) * 100) \ - + ((micro) * 1)) - -#define CABAL_VERSION_CHECK(major,minor,micro) \ - (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) - --- now, this is bad, but Cabal doesn't seem to actually pass any information about --- its version to CPP, so guess the version depending on the version of GHC -#ifdef CABAL_VERSION_MINOR -#ifndef CABAL_VERSION_MAJOR -#define CABAL_VERSION_MAJOR 1 -#endif -#ifndef CABAL_VERSION_MICRO -#define CABAL_VERSION_MICRO 0 -#endif -#define CABAL_VERSION CABAL_VERSION_ENCODE( \ - CABAL_VERSION_MAJOR, \ - CABAL_VERSION_MINOR, \ - CABAL_VERSION_MICRO) -#else -#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) -#if (__GLASGOW_HASKELL__ >= 612) -#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) -#else -#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) -#endif -#endif - --- | Build a Gtk2hs package. --- -import Distribution.Simple -import Distribution.Simple.PreProcess -import Distribution.InstalledPackageInfo ( importDirs ) -import Distribution.Simple.PackageIndex ( -#if CABAL_VERSION_CHECK(1,8,0) - lookupInstalledPackageId -#else - lookupPackageId -#endif - ) -import Distribution.PackageDescription as PD ( PackageDescription(..), - updatePackageDescription, - BuildInfo(..), - emptyBuildInfo, allBuildInfo, - Library(..), - libModules) -import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), - InstallDirs(..), -#if CABAL_VERSION_CHECK(1,8,0) - componentPackageDeps, -#else - packageDeps, -#endif - absoluteInstallDirs) -import Distribution.Simple.Compiler ( Compiler(..) ) -import Distribution.Simple.Program ( - Program(..), ConfiguredProgram(..), - rawSystemProgramConf, rawSystemProgramStdoutConf, - c2hsProgram, pkgConfigProgram, - simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) -import Distribution.ModuleName ( ModuleName, components, toFilePath ) -import Distribution.Simple.Utils -import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), - defaultCopyFlags, ConfigFlags(configVerbosity), - fromFlag, toFlag) -import Distribution.Simple.BuildPaths ( autogenModulesDir ) -import Distribution.Text ( simpleParse, display ) -import System.FilePath -import System.Directory ( doesFileExist ) -import Distribution.Version (Version(..)) -import Distribution.Verbosity -import Control.Monad (unless) -import Data.Maybe (fromMaybe) -import Data.List (isPrefixOf, nub) -import Data.Char (isAlpha) -import qualified Data.Map as M -import qualified Data.Set as S - - --- the name of the c2hs pre-compiled header file -precompFile = "precompchs.bin" - -main = defaultMainWithHooks simpleUserHooks { - hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], - hookedPreProcessors = [("chs", ourC2hs)], - confHook = \pd cf -> - confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, - postConf = \args cf pd lbi -> do - genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi - postConf simpleUserHooks args cf pd lbi, - buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> - (buildHook simpleUserHooks) pd lbi uh bf, - copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> - installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), - instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> - installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest - } - --- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later -adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo -adjustLocalBuildInfo lbi = - let extra = (Just libBi, []) - libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi - , buildDir lbi ] } - in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } - -ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor -ourC2hs bi lbi = PreProcessor { - platformIndependent = False, - runPreProcessor = runC2HS bi lbi -} - -runC2HS :: BuildInfo -> LocalBuildInfo -> - (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () -runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do - -- have the header file name if we don't have the precompiled header yet - header <- case lookup "x-c2hs-header" (customFieldsBI bi) of - Just h -> return h - Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ - "that sets the C header file to process .chs.pp files.") - - -- c2hs will output files in out dir, removing any leading path of the input file. - -- Thus, append the dir of the input file to the output dir. - let (outFileDir, newOutFile) = splitFileName outFile - let newOutDir = outDir </> outFileDir - -- additional .chi files might be needed that other packages have installed; - -- we assume that these are installed in the same place as .hi files - let chiDirs = [ dir | -#if CABAL_VERSION_CHECK(1,8,0) - ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), - dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] -#else - ipi <- packageDeps lbi, - dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] -#endif - rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ - map ("--include=" ++) (outDir:chiDirs) - ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] - ++ ["--output-dir=" ++ newOutDir, - "--output=" ++ newOutFile, - "--precomp=" ++ buildDir lbi </> precompFile, - header, inDir </> inFile] - -getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] -getCppOptions bi lbi - = nub $ - ["-I" ++ dir | dir <- PD.includeDirs bi] - ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] - -installCHI :: PackageDescription -- ^information from the .cabal file - -> LocalBuildInfo -- ^information from the configure step - -> Verbosity -> CopyDest -- ^flags sent to copy or install - -> IO () -installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do - let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest - -- cannot use the recommended 'findModuleFiles' since it fails if there exists - -- a modules that does not have a .chi file - mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) - (map toFilePath -#if CABAL_VERSION_CHECK(1,8,0) - (PD.libModules lib) -#else - (PD.libModules pkg) -#endif - ) - let files = [ f | Just f <- mFiles ] -#if CABAL_VERSION_CHECK(1,8,0) - installOrdinaryFiles verbosity libPref files -#else - copyFiles verbosity libPref files -#endif - - [_$_] -installCHI _ _ _ _ = return () - ------------------------------------------------------------------------------- --- Generating the type hierarchy and signal callback .hs files. ------------------------------------------------------------------------------- - -typeGenProgram :: Program -typeGenProgram = (simpleProgram "gtk2hsTypeGen") - -signalGenProgram :: Program -signalGenProgram = (simpleProgram "gtk2hsHookGenerator") - -c2hsLocal :: Program -c2hsLocal = (simpleProgram "gtk2hsC2hs") - -genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () -genSynthezisedFiles verb pd lbi = do - - cPkgs <- getPkgConfigPackages verb lbi pd - - let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) - ++customFieldsPD pd - typeOpts :: [ProgArg] - typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) - | (field,content) <- xList, - "x-types-" `isPrefixOf` field, - field /= "x-types-file"] - ++ [ "--tag=" ++ tag - | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs - , let name' = filter isAlpha (display name) - , tag <- name' - : [ name' ++ "-" ++ show major ++ "." ++ show digit - | digit <- [0,2..minor] ] - ] - - genFile :: Program -> [ProgArg] -> FilePath -> IO () - genFile prog args outFile = do - res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args - rewriteFile outFile res - - case lookup "x-types-file" xList of - Nothing -> return () - Just f -> do - info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") - genFile typeGenProgram typeOpts f - - case (lookup "x-signals-file" xList, - lookup "x-signals-modname" xList) of - (Just _, Nothing) -> die "You need to specify the module name (X-Signals-ModName) \ - \to generate a signal file." - (Just f, Just mod) -> do - info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") - genFile signalGenProgram [mod] f - (_,_) -> return () - ---FIXME: Cabal should tell us the selected pkg-config package versions in the --- LocalBuildInfo or equivalent. --- In the mean time, ask pkg-config again. - -getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] -getPkgConfigPackages verbosity lbi pkg = - sequence - [ do version <- pkgconfig ["--modversion", display pkgname] - case simpleParse version of - Nothing -> die $ "parsing output of pkg-config --modversion failed" - Just v -> return (PackageIdentifier pkgname v) - | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] - where - pkgconfig = rawSystemProgramStdoutConf verbosity - pkgConfigProgram (withPrograms lbi) - ------------------------------------------------------------------------------- --- Dependency calculation amongst .chs files. ------------------------------------------------------------------------------- - --- Given all files of the package, find those that end in .chs and extract the --- .chs files they depend upon. Then return the PackageDescription with these --- files rearranged so that they are built in a sequence that files that are --- needed by other files are built first. -fixDeps :: PackageDescription -> IO PackageDescription -fixDeps pd...@PD...ckageDescription { - PD.library = Just li...@PD...brary { - PD.exposedModules = expMods, - PD.libBuildInfo = bi@PD.BuildInfo { - PD.hsSourceDirs = srcDirs, - PD.otherModules = othMods - }}} = do - let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs - (joinPath (components m)) - mExpFiles <- mapM findModule expMods - mOthFiles <- mapM findModule othMods - - -- tag all exposed files with True so we throw an error if we need to build - -- an exposed module before an internal modules (we cannot express this) - let modDeps = zipWith (ModDep True []) expMods mExpFiles++ - zipWith (ModDep False []) othMods mOthFiles - modDeps <- mapM extractDeps modDeps - let (expMods, othMods) = span mdExposed $ sortTopological modDeps - badOther = map (fromMaybe "<no file>" . mdLocation) $ - filter (not . mdExposed) expMods - unless (null badOther) $ - die ("internal chs modules "++intercalate "," badOther++ - " depend on exposed chs modules; cabal needs to build internal modules first") - return pd { PD.library = Just lib { - PD.exposedModules = map mdOriginal expMods, - PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } - }} - -data ModDep = ModDep { - mdExposed :: Bool, - mdRequires :: [ModuleName], - mdOriginal :: ModuleName, - mdLocation :: Maybe FilePath -} - -instance Show ModDep where - show x = show (mdLocation x) - -instance Eq ModDep where - ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 -instance Ord ModDep where - compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 - --- Extract the dependencies of this file. This is intentionally rather naive as it --- ignores CPP conditionals. We just require everything which means that the --- existance of a .chs module may not depend on some CPP condition. [_$_] -extractDeps :: ModDep -> IO ModDep -extractDeps md@ModDep { mdLocation = Nothing } = return md -extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do - let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of - ('i':'m':'p':'o':'r':'t':' ':ys) -> - case simpleParse (takeWhile ((/=) '#') ys) of - Just m -> findImports (m:acc) xxs [_$_] - Nothing -> die ("cannot parse chs import in "++f++":\n"++ - "offending line is {#"++xs) - -- no more imports after the first non-import hook - _ -> return acc - findImports acc (_:xxs) = findImports acc xxs - findImports acc [] = return acc - mods <- findImports [] (lines con) - return md { mdRequires = mods } - --- Find a total order of the set of modules that are partially sorted by their --- dependencies on each other. The function returns the sorted list of modules --- together with a list of modules that are required but not supplied by this --- in the input set of modules. -sortTopological :: [ModDep] -> [ModDep] -sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) - where - set = M.fromList (map (\m -> (mdOriginal m, m)) ms) - visit (out,visited) m - | m `S.member` visited = (out,visited) - | otherwise = case m `M.lookup` set of - Nothing -> (out, m `S.insert` visited) - Just md -> (md:out', visited') - where - (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) +main = defaultMainWithHooks gtk2hsUserHooks |
From: Axel S. <si...@co...> - 2010-05-01 15:19:40
|
Sat May 1 11:07:55 EDT 2010 Axe...@in... * Replace Setup.hs by the default setup files. Ignore-this: cdc12e9af9b22e54ef4ac288dc8b9000 addfile ./vte/Gtk2HsSetup.hs hunk ./vte/Gtk2HsSetup.hs 1 +{-# LANGUAGE CPP #-} + +#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ + ((major) * 10000) \ + + ((minor) * 100) \ + + ((micro) * 1)) + +#define CABAL_VERSION_CHECK(major,minor,micro) \ + (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) + +-- now, this is bad, but Cabal doesn't seem to actually pass any information about +-- its version to CPP, so guess the version depending on the version of GHC +#ifdef CABAL_VERSION_MINOR +#ifndef CABAL_VERSION_MAJOR +#define CABAL_VERSION_MAJOR 1 +#endif +#ifndef CABAL_VERSION_MICRO +#define CABAL_VERSION_MICRO 0 +#endif +#define CABAL_VERSION CABAL_VERSION_ENCODE( \ + CABAL_VERSION_MAJOR, \ + CABAL_VERSION_MINOR, \ + CABAL_VERSION_MICRO) +#else +#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) +#if (__GLASGOW_HASKELL__ >= 612) +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) +#else +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) +#endif +#endif + +-- | Build a Gtk2hs package. +-- +module Gtk2HsSetup ( gtk2hsUserHooks, getPkgConfigPackages ) where + +import Distribution.Simple +import Distribution.Simple.PreProcess +import Distribution.InstalledPackageInfo ( importDirs ) +import Distribution.Simple.PackageIndex ( +#if CABAL_VERSION_CHECK(1,8,0) + lookupInstalledPackageId +#else + lookupPackageId +#endif + ) +import Distribution.PackageDescription as PD ( PackageDescription(..), + updatePackageDescription, + BuildInfo(..), + emptyBuildInfo, allBuildInfo, + Library(..), + libModules) +import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), + InstallDirs(..), +#if CABAL_VERSION_CHECK(1,8,0) + componentPackageDeps, +#else + packageDeps, +#endif + absoluteInstallDirs) +import Distribution.Simple.Compiler ( Compiler(..) ) +import Distribution.Simple.Program ( + Program(..), ConfiguredProgram(..), + rawSystemProgramConf, rawSystemProgramStdoutConf, + c2hsProgram, pkgConfigProgram, + simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) +import Distribution.ModuleName ( ModuleName, components, toFilePath ) +import Distribution.Simple.Utils +import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), + defaultCopyFlags, ConfigFlags(configVerbosity), + fromFlag, toFlag) +import Distribution.Simple.BuildPaths ( autogenModulesDir ) +import Distribution.Text ( simpleParse, display ) +import System.FilePath +import System.Directory ( doesFileExist ) +import Distribution.Version (Version(..)) +import Distribution.Verbosity +import Control.Monad (unless) +import Data.Maybe (fromMaybe) +import Data.List (isPrefixOf, nub) +import Data.Char (isAlpha) +import qualified Data.Map as M +import qualified Data.Set as S + + +-- the name of the c2hs pre-compiled header file +precompFile = "precompchs.bin" + +gtk2hsUserHooks = simpleUserHooks { + hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], + hookedPreProcessors = [("chs", ourC2hs)], + confHook = \pd cf -> + confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, + postConf = \args cf pd lbi -> do + genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi + postConf simpleUserHooks args cf pd lbi, + buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> + (buildHook simpleUserHooks) pd lbi uh bf, + copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), + instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest + } + +-- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later +adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo +adjustLocalBuildInfo lbi = + let extra = (Just libBi, []) + libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi + , buildDir lbi ] } + in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } + +ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor +ourC2hs bi lbi = PreProcessor { + platformIndependent = False, + runPreProcessor = runC2HS bi lbi +} + +runC2HS :: BuildInfo -> LocalBuildInfo -> + (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () +runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do + -- have the header file name if we don't have the precompiled header yet + header <- case lookup "x-c2hs-header" (customFieldsBI bi) of + Just h -> return h + Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ + "that sets the C header file to process .chs.pp files.") + + -- c2hs will output files in out dir, removing any leading path of the input file. + -- Thus, append the dir of the input file to the output dir. + let (outFileDir, newOutFile) = splitFileName outFile + let newOutDir = outDir </> outFileDir + -- additional .chi files might be needed that other packages have installed; + -- we assume that these are installed in the same place as .hi files + let chiDirs = [ dir | +#if CABAL_VERSION_CHECK(1,8,0) + ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), + dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] +#else + ipi <- packageDeps lbi, + dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] +#endif + rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ + map ("--include=" ++) (outDir:chiDirs) + ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] + ++ ["--output-dir=" ++ newOutDir, + "--output=" ++ newOutFile, + "--precomp=" ++ buildDir lbi </> precompFile, + header, inDir </> inFile] + +getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] +getCppOptions bi lbi + = nub $ + ["-I" ++ dir | dir <- PD.includeDirs bi] + ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] + +installCHI :: PackageDescription -- ^information from the .cabal file + -> LocalBuildInfo -- ^information from the configure step + -> Verbosity -> CopyDest -- ^flags sent to copy or install + -> IO () +installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do + let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest + -- cannot use the recommended 'findModuleFiles' since it fails if there exists + -- a modules that does not have a .chi file + mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) + (map toFilePath +#if CABAL_VERSION_CHECK(1,8,0) + (PD.libModules lib) +#else + (PD.libModules pkg) +#endif + ) + let files = [ f | Just f <- mFiles ] +#if CABAL_VERSION_CHECK(1,8,0) + installOrdinaryFiles verbosity libPref files +#else + copyFiles verbosity libPref files +#endif + + [_$_] +installCHI _ _ _ _ = return () + +------------------------------------------------------------------------------ +-- Generating the type hierarchy and signal callback .hs files. +------------------------------------------------------------------------------ + +typeGenProgram :: Program +typeGenProgram = (simpleProgram "gtk2hsTypeGen") + +signalGenProgram :: Program +signalGenProgram = (simpleProgram "gtk2hsHookGenerator") + +c2hsLocal :: Program +c2hsLocal = (simpleProgram "gtk2hsC2hs") + +genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () +genSynthezisedFiles verb pd lbi = do + + cPkgs <- getPkgConfigPackages verb lbi pd + + let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) + ++customFieldsPD pd + typeOpts :: [ProgArg] + typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) + | (field,content) <- xList, + "x-types-" `isPrefixOf` field, + field /= "x-types-file"] + ++ [ "--tag=" ++ tag + | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs + , let name' = filter isAlpha (display name) + , tag <- name' + : [ name' ++ "-" ++ show major ++ "." ++ show digit + | digit <- [0,2..minor] ] + ] + + signalsOpts :: [ProgArg] + signalsOpts = concat [ map (\val -> '-':'-':drop 10 field++'=':val) (words content) + | (field,content) <- xList, + "x-signals-" `isPrefixOf` field, + field /= "x-signals-file"] + + genFile :: Program -> [ProgArg] -> FilePath -> IO () + genFile prog args outFile = do + res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args + rewriteFile outFile res + + case lookup "x-types-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") + genFile typeGenProgram typeOpts f + + case lookup "x-signals-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") + genFile signalGenProgram signalsOpts f + +--FIXME: Cabal should tell us the selected pkg-config package versions in the +-- LocalBuildInfo or equivalent. +-- In the mean time, ask pkg-config again. + +getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] +getPkgConfigPackages verbosity lbi pkg = + sequence + [ do version <- pkgconfig ["--modversion", display pkgname] + case simpleParse version of + Nothing -> die $ "parsing output of pkg-config --modversion failed" + Just v -> return (PackageIdentifier pkgname v) + | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] + where + pkgconfig = rawSystemProgramStdoutConf verbosity + pkgConfigProgram (withPrograms lbi) + +------------------------------------------------------------------------------ +-- Dependency calculation amongst .chs files. +------------------------------------------------------------------------------ + +-- Given all files of the package, find those that end in .chs and extract the +-- .chs files they depend upon. Then return the PackageDescription with these +-- files rearranged so that they are built in a sequence that files that are +-- needed by other files are built first. +fixDeps :: PackageDescription -> IO PackageDescription +fixDeps pd...@PD...ckageDescription { + PD.library = Just li...@PD...brary { + PD.exposedModules = expMods, + PD.libBuildInfo = bi@PD.BuildInfo { + PD.hsSourceDirs = srcDirs, + PD.otherModules = othMods + }}} = do + let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs + (joinPath (components m)) + mExpFiles <- mapM findModule expMods + mOthFiles <- mapM findModule othMods + + -- tag all exposed files with True so we throw an error if we need to build + -- an exposed module before an internal modules (we cannot express this) + let modDeps = zipWith (ModDep True []) expMods mExpFiles++ + zipWith (ModDep False []) othMods mOthFiles + modDeps <- mapM extractDeps modDeps + let (expMods, othMods) = span mdExposed $ sortTopological modDeps + badOther = map (fromMaybe "<no file>" . mdLocation) $ + filter (not . mdExposed) expMods + unless (null badOther) $ + die ("internal chs modules "++intercalate "," badOther++ + " depend on exposed chs modules; cabal needs to build internal modules first") + return pd { PD.library = Just lib { + PD.exposedModules = map mdOriginal expMods, + PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } + }} + +data ModDep = ModDep { + mdExposed :: Bool, + mdRequires :: [ModuleName], + mdOriginal :: ModuleName, + mdLocation :: Maybe FilePath +} + +instance Show ModDep where + show x = show (mdLocation x) + +instance Eq ModDep where + ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 +instance Ord ModDep where + compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 + +-- Extract the dependencies of this file. This is intentionally rather naive as it +-- ignores CPP conditionals. We just require everything which means that the +-- existance of a .chs module may not depend on some CPP condition. [_$_] +extractDeps :: ModDep -> IO ModDep +extractDeps md@ModDep { mdLocation = Nothing } = return md +extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do + let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of + ('i':'m':'p':'o':'r':'t':' ':ys) -> + case simpleParse (takeWhile ((/=) '#') ys) of + Just m -> findImports (m:acc) xxs [_$_] + Nothing -> die ("cannot parse chs import in "++f++":\n"++ + "offending line is {#"++xs) + -- no more imports after the first non-import hook + _ -> return acc + findImports acc (_:xxs) = findImports acc xxs + findImports acc [] = return acc + mods <- findImports [] (lines con) + return md { mdRequires = mods } + +-- Find a total order of the set of modules that are partially sorted by their +-- dependencies on each other. The function returns the sorted list of modules +-- together with a list of modules that are required but not supplied by this +-- in the input set of modules. +sortTopological :: [ModDep] -> [ModDep] +sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) + where + set = M.fromList (map (\m -> (mdOriginal m, m)) ms) + visit (out,visited) m + | m `S.member` visited = (out,visited) + | otherwise = case m `M.lookup` set of + Nothing -> (out, m `S.insert` visited) + Just md -> (md:out', visited') + where + (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) hunk ./vte/Setup.hs 1 -{-# LANGUAGE CPP #-} +-- Setup file for a Gtk2Hs module. Contains only adjustments specific to this module, +-- all Gtk2Hs-specific boilerplate is stored in Gtk2HsSetup.hs which should be kept +-- identical across all modules. +import Gtk2HsSetup ( gtk2hsUserHooks ) +import Distribution.Simple ( defaultMainWithHooks ) hunk ./vte/Setup.hs 7 -#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ - ((major) * 10000) \ - + ((minor) * 100) \ - + ((micro) * 1)) - -#define CABAL_VERSION_CHECK(major,minor,micro) \ - (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) - --- now, this is bad, but Cabal doesn't seem to actually pass any information about --- its version to CPP, so guess the version depending on the version of GHC -#ifdef CABAL_VERSION_MINOR -#ifndef CABAL_VERSION_MAJOR -#define CABAL_VERSION_MAJOR 1 -#endif -#ifndef CABAL_VERSION_MICRO -#define CABAL_VERSION_MICRO 0 -#endif -#define CABAL_VERSION CABAL_VERSION_ENCODE( \ - CABAL_VERSION_MAJOR, \ - CABAL_VERSION_MINOR, \ - CABAL_VERSION_MICRO) -#else -#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) -#if (__GLASGOW_HASKELL__ >= 612) -#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) -#else -#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) -#endif -#endif - --- | Build a Gtk2hs package. --- -import Distribution.Simple -import Distribution.Simple.PreProcess -import Distribution.InstalledPackageInfo ( importDirs ) -import Distribution.Simple.PackageIndex ( -#if CABAL_VERSION_CHECK(1,8,0) - lookupInstalledPackageId -#else - lookupPackageId -#endif - ) -import Distribution.PackageDescription as PD ( PackageDescription(..), - updatePackageDescription, - BuildInfo(..), - emptyBuildInfo, allBuildInfo, - Library(..), - libModules) -import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), - InstallDirs(..), -#if CABAL_VERSION_CHECK(1,8,0) - componentPackageDeps, -#else - packageDeps, -#endif - absoluteInstallDirs) -import Distribution.Simple.Compiler ( Compiler(..) ) -import Distribution.Simple.Program ( - Program(..), ConfiguredProgram(..), - rawSystemProgramConf, rawSystemProgramStdoutConf, - c2hsProgram, pkgConfigProgram, - simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) -import Distribution.ModuleName ( ModuleName, components, toFilePath ) -import Distribution.Simple.Utils -import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), - defaultCopyFlags, ConfigFlags(configVerbosity), - fromFlag, toFlag) -import Distribution.Simple.BuildPaths ( autogenModulesDir ) -import Distribution.Text ( simpleParse, display ) -import System.FilePath -import System.Directory ( doesFileExist ) -import Distribution.Version (Version(..)) -import Distribution.Verbosity -import Control.Monad (unless) -import Data.Maybe (fromMaybe) -import Data.List (isPrefixOf, nub) -import Data.Char (isAlpha) -import qualified Data.Map as M -import qualified Data.Set as S - - --- the name of the c2hs pre-compiled header file -precompFile = "precompchs.bin" - -main = defaultMainWithHooks simpleUserHooks { - hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], - hookedPreProcessors = [("chs", ourC2hs)], - confHook = \pd cf -> - confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, - postConf = \args cf pd lbi -> do - genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi - postConf simpleUserHooks args cf pd lbi, - buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> - (buildHook simpleUserHooks) pd lbi uh bf, - copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> - installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), - instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> - installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest - } - --- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later -adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo -adjustLocalBuildInfo lbi = - let extra = (Just libBi, []) - libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi - , buildDir lbi ] } - in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } - -ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor -ourC2hs bi lbi = PreProcessor { - platformIndependent = False, - runPreProcessor = runC2HS bi lbi -} - -runC2HS :: BuildInfo -> LocalBuildInfo -> - (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () -runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do - -- have the header file name if we don't have the precompiled header yet - header <- case lookup "x-c2hs-header" (customFieldsBI bi) of - Just h -> return h - Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ - "that sets the C header file to process .chs.pp files.") - - -- c2hs will output files in out dir, removing any leading path of the input file. - -- Thus, append the dir of the input file to the output dir. - let (outFileDir, newOutFile) = splitFileName outFile - let newOutDir = outDir </> outFileDir - -- additional .chi files might be needed that other packages have installed; - -- we assume that these are installed in the same place as .hi files - let chiDirs = [ dir | -#if CABAL_VERSION_CHECK(1,8,0) - ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), - dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] -#else - ipi <- packageDeps lbi, - dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] -#endif - rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ - map ("--include=" ++) (outDir:chiDirs) - ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] - ++ ["--output-dir=" ++ newOutDir, - "--output=" ++ newOutFile, - "--precomp=" ++ buildDir lbi </> precompFile, - header, inDir </> inFile] - -getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] -getCppOptions bi lbi - = nub $ - ["-I" ++ dir | dir <- PD.includeDirs bi] - ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] - -installCHI :: PackageDescription -- ^information from the .cabal file - -> LocalBuildInfo -- ^information from the configure step - -> Verbosity -> CopyDest -- ^flags sent to copy or install - -> IO () -installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do - let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest - -- cannot use the recommended 'findModuleFiles' since it fails if there exists - -- a modules that does not have a .chi file - mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) - (map toFilePath -#if CABAL_VERSION_CHECK(1,8,0) - (PD.libModules lib) -#else - (PD.libModules pkg) -#endif - ) - let files = [ f | Just f <- mFiles ] -#if CABAL_VERSION_CHECK(1,8,0) - installOrdinaryFiles verbosity libPref files -#else - copyFiles verbosity libPref files -#endif - - [_$_] -installCHI _ _ _ _ = return () - ------------------------------------------------------------------------------- --- Generating the type hierarchy and signal callback .hs files. ------------------------------------------------------------------------------- - -typeGenProgram :: Program -typeGenProgram = (simpleProgram "gtk2hsTypeGen") - -signalGenProgram :: Program -signalGenProgram = (simpleProgram "gtk2hsHookGenerator") - -c2hsLocal :: Program -c2hsLocal = (simpleProgram "gtk2hsC2hs") - -genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () -genSynthezisedFiles verb pd lbi = do - - cPkgs <- getPkgConfigPackages verb lbi pd - - let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) - ++customFieldsPD pd - typeOpts :: [ProgArg] - typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) - | (field,content) <- xList, - "x-types-" `isPrefixOf` field, - field /= "x-types-file"] - ++ [ "--tag=" ++ tag - | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs - , let name' = filter isAlpha (display name) - , tag <- name' - : [ name' ++ "-" ++ show major ++ "." ++ show digit - | digit <- [0,2..minor] ] - ] - - genFile :: Program -> [ProgArg] -> FilePath -> IO () - genFile prog args outFile = do - res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args - rewriteFile outFile res - - case lookup "x-types-file" xList of - Nothing -> return () - Just f -> do - info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") - genFile typeGenProgram typeOpts f - - case (lookup "x-signals-file" xList, - lookup "x-signals-modname" xList) of - (Just _, Nothing) -> die "You need to specify the module name (X-Signals-ModName) \ - \to generate a signal file." - (Just f, Just mod) -> do - info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") - genFile signalGenProgram [mod] f - (_,_) -> return () - ---FIXME: Cabal should tell us the selected pkg-config package versions in the --- LocalBuildInfo or equivalent. --- In the mean time, ask pkg-config again. - -getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] -getPkgConfigPackages verbosity lbi pkg = - sequence - [ do version <- pkgconfig ["--modversion", display pkgname] - case simpleParse version of - Nothing -> die $ "parsing output of pkg-config --modversion failed" - Just v -> return (PackageIdentifier pkgname v) - | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] - where - pkgconfig = rawSystemProgramStdoutConf verbosity - pkgConfigProgram (withPrograms lbi) - ------------------------------------------------------------------------------- --- Dependency calculation amongst .chs files. ------------------------------------------------------------------------------- - --- Given all files of the package, find those that end in .chs and extract the --- .chs files they depend upon. Then return the PackageDescription with these --- files rearranged so that they are built in a sequence that files that are --- needed by other files are built first. -fixDeps :: PackageDescription -> IO PackageDescription -fixDeps pd...@PD...ckageDescription { - PD.library = Just li...@PD...brary { - PD.exposedModules = expMods, - PD.libBuildInfo = bi@PD.BuildInfo { - PD.hsSourceDirs = srcDirs, - PD.otherModules = othMods - }}} = do - let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs - (joinPath (components m)) - mExpFiles <- mapM findModule expMods - mOthFiles <- mapM findModule othMods - - -- tag all exposed files with True so we throw an error if we need to build - -- an exposed module before an internal modules (we cannot express this) - let modDeps = zipWith (ModDep True []) expMods mExpFiles++ - zipWith (ModDep False []) othMods mOthFiles - modDeps <- mapM extractDeps modDeps - let (expMods, othMods) = span mdExposed $ sortTopological modDeps - badOther = map (fromMaybe "<no file>" . mdLocation) $ - filter (not . mdExposed) expMods - unless (null badOther) $ - die ("internal chs modules "++intercalate "," badOther++ - " depend on exposed chs modules; cabal needs to build internal modules first") - return pd { PD.library = Just lib { - PD.exposedModules = map mdOriginal expMods, - PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } - }} - -data ModDep = ModDep { - mdExposed :: Bool, - mdRequires :: [ModuleName], - mdOriginal :: ModuleName, - mdLocation :: Maybe FilePath -} - -instance Show ModDep where - show x = show (mdLocation x) - -instance Eq ModDep where - ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 -instance Ord ModDep where - compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 - --- Extract the dependencies of this file. This is intentionally rather naive as it --- ignores CPP conditionals. We just require everything which means that the --- existance of a .chs module may not depend on some CPP condition. [_$_] -extractDeps :: ModDep -> IO ModDep -extractDeps md@ModDep { mdLocation = Nothing } = return md -extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do - let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of - ('i':'m':'p':'o':'r':'t':' ':ys) -> - case simpleParse (takeWhile ((/=) '#') ys) of - Just m -> findImports (m:acc) xxs [_$_] - Nothing -> die ("cannot parse chs import in "++f++":\n"++ - "offending line is {#"++xs) - -- no more imports after the first non-import hook - _ -> return acc - findImports acc (_:xxs) = findImports acc xxs - findImports acc [] = return acc - mods <- findImports [] (lines con) - return md { mdRequires = mods } - --- Find a total order of the set of modules that are partially sorted by their --- dependencies on each other. The function returns the sorted list of modules --- together with a list of modules that are required but not supplied by this --- in the input set of modules. -sortTopological :: [ModDep] -> [ModDep] -sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) - where - set = M.fromList (map (\m -> (mdOriginal m, m)) ms) - visit (out,visited) m - | m `S.member` visited = (out,visited) - | otherwise = case m `M.lookup` set of - Nothing -> (out, m `S.insert` visited) - Just md -> (md:out', visited') - where - (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) +main = defaultMainWithHooks gtk2hsUserHooks |
From: Axel S. <si...@co...> - 2010-05-01 15:19:39
|
Sat May 1 11:06:05 EDT 2010 Axe...@in... * Replace Setup.hs by the default setup files. Ignore-this: 58710ee1f00cd1242057f1cbdcee94ff addfile ./svgcairo/Gtk2HsSetup.hs hunk ./svgcairo/Gtk2HsSetup.hs 1 +{-# LANGUAGE CPP #-} + +#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ + ((major) * 10000) \ + + ((minor) * 100) \ + + ((micro) * 1)) + +#define CABAL_VERSION_CHECK(major,minor,micro) \ + (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) + +-- now, this is bad, but Cabal doesn't seem to actually pass any information about +-- its version to CPP, so guess the version depending on the version of GHC +#ifdef CABAL_VERSION_MINOR +#ifndef CABAL_VERSION_MAJOR +#define CABAL_VERSION_MAJOR 1 +#endif +#ifndef CABAL_VERSION_MICRO +#define CABAL_VERSION_MICRO 0 +#endif +#define CABAL_VERSION CABAL_VERSION_ENCODE( \ + CABAL_VERSION_MAJOR, \ + CABAL_VERSION_MINOR, \ + CABAL_VERSION_MICRO) +#else +#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) +#if (__GLASGOW_HASKELL__ >= 612) +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) +#else +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) +#endif +#endif + +-- | Build a Gtk2hs package. +-- +module Gtk2HsSetup ( gtk2hsUserHooks, getPkgConfigPackages ) where + +import Distribution.Simple +import Distribution.Simple.PreProcess +import Distribution.InstalledPackageInfo ( importDirs ) +import Distribution.Simple.PackageIndex ( +#if CABAL_VERSION_CHECK(1,8,0) + lookupInstalledPackageId +#else + lookupPackageId +#endif + ) +import Distribution.PackageDescription as PD ( PackageDescription(..), + updatePackageDescription, + BuildInfo(..), + emptyBuildInfo, allBuildInfo, + Library(..), + libModules) +import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), + InstallDirs(..), +#if CABAL_VERSION_CHECK(1,8,0) + componentPackageDeps, +#else + packageDeps, +#endif + absoluteInstallDirs) +import Distribution.Simple.Compiler ( Compiler(..) ) +import Distribution.Simple.Program ( + Program(..), ConfiguredProgram(..), + rawSystemProgramConf, rawSystemProgramStdoutConf, + c2hsProgram, pkgConfigProgram, + simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) +import Distribution.ModuleName ( ModuleName, components, toFilePath ) +import Distribution.Simple.Utils +import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), + defaultCopyFlags, ConfigFlags(configVerbosity), + fromFlag, toFlag) +import Distribution.Simple.BuildPaths ( autogenModulesDir ) +import Distribution.Text ( simpleParse, display ) +import System.FilePath +import System.Directory ( doesFileExist ) +import Distribution.Version (Version(..)) +import Distribution.Verbosity +import Control.Monad (unless) +import Data.Maybe (fromMaybe) +import Data.List (isPrefixOf, nub) +import Data.Char (isAlpha) +import qualified Data.Map as M +import qualified Data.Set as S + + +-- the name of the c2hs pre-compiled header file +precompFile = "precompchs.bin" + +gtk2hsUserHooks = simpleUserHooks { + hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], + hookedPreProcessors = [("chs", ourC2hs)], + confHook = \pd cf -> + confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, + postConf = \args cf pd lbi -> do + genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi + postConf simpleUserHooks args cf pd lbi, + buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> + (buildHook simpleUserHooks) pd lbi uh bf, + copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), + instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest + } + +-- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later +adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo +adjustLocalBuildInfo lbi = + let extra = (Just libBi, []) + libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi + , buildDir lbi ] } + in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } + +ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor +ourC2hs bi lbi = PreProcessor { + platformIndependent = False, + runPreProcessor = runC2HS bi lbi +} + +runC2HS :: BuildInfo -> LocalBuildInfo -> + (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () +runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do + -- have the header file name if we don't have the precompiled header yet + header <- case lookup "x-c2hs-header" (customFieldsBI bi) of + Just h -> return h + Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ + "that sets the C header file to process .chs.pp files.") + + -- c2hs will output files in out dir, removing any leading path of the input file. + -- Thus, append the dir of the input file to the output dir. + let (outFileDir, newOutFile) = splitFileName outFile + let newOutDir = outDir </> outFileDir + -- additional .chi files might be needed that other packages have installed; + -- we assume that these are installed in the same place as .hi files + let chiDirs = [ dir | +#if CABAL_VERSION_CHECK(1,8,0) + ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), + dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] +#else + ipi <- packageDeps lbi, + dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] +#endif + rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ + map ("--include=" ++) (outDir:chiDirs) + ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] + ++ ["--output-dir=" ++ newOutDir, + "--output=" ++ newOutFile, + "--precomp=" ++ buildDir lbi </> precompFile, + header, inDir </> inFile] + +getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] +getCppOptions bi lbi + = nub $ + ["-I" ++ dir | dir <- PD.includeDirs bi] + ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] + +installCHI :: PackageDescription -- ^information from the .cabal file + -> LocalBuildInfo -- ^information from the configure step + -> Verbosity -> CopyDest -- ^flags sent to copy or install + -> IO () +installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do + let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest + -- cannot use the recommended 'findModuleFiles' since it fails if there exists + -- a modules that does not have a .chi file + mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) + (map toFilePath +#if CABAL_VERSION_CHECK(1,8,0) + (PD.libModules lib) +#else + (PD.libModules pkg) +#endif + ) + let files = [ f | Just f <- mFiles ] +#if CABAL_VERSION_CHECK(1,8,0) + installOrdinaryFiles verbosity libPref files +#else + copyFiles verbosity libPref files +#endif + + [_$_] +installCHI _ _ _ _ = return () + +------------------------------------------------------------------------------ +-- Generating the type hierarchy and signal callback .hs files. +------------------------------------------------------------------------------ + +typeGenProgram :: Program +typeGenProgram = (simpleProgram "gtk2hsTypeGen") + +signalGenProgram :: Program +signalGenProgram = (simpleProgram "gtk2hsHookGenerator") + +c2hsLocal :: Program +c2hsLocal = (simpleProgram "gtk2hsC2hs") + +genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () +genSynthezisedFiles verb pd lbi = do + + cPkgs <- getPkgConfigPackages verb lbi pd + + let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) + ++customFieldsPD pd + typeOpts :: [ProgArg] + typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) + | (field,content) <- xList, + "x-types-" `isPrefixOf` field, + field /= "x-types-file"] + ++ [ "--tag=" ++ tag + | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs + , let name' = filter isAlpha (display name) + , tag <- name' + : [ name' ++ "-" ++ show major ++ "." ++ show digit + | digit <- [0,2..minor] ] + ] + + signalsOpts :: [ProgArg] + signalsOpts = concat [ map (\val -> '-':'-':drop 10 field++'=':val) (words content) + | (field,content) <- xList, + "x-signals-" `isPrefixOf` field, + field /= "x-signals-file"] + + genFile :: Program -> [ProgArg] -> FilePath -> IO () + genFile prog args outFile = do + res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args + rewriteFile outFile res + + case lookup "x-types-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") + genFile typeGenProgram typeOpts f + + case lookup "x-signals-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") + genFile signalGenProgram signalsOpts f + +--FIXME: Cabal should tell us the selected pkg-config package versions in the +-- LocalBuildInfo or equivalent. +-- In the mean time, ask pkg-config again. + +getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] +getPkgConfigPackages verbosity lbi pkg = + sequence + [ do version <- pkgconfig ["--modversion", display pkgname] + case simpleParse version of + Nothing -> die $ "parsing output of pkg-config --modversion failed" + Just v -> return (PackageIdentifier pkgname v) + | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] + where + pkgconfig = rawSystemProgramStdoutConf verbosity + pkgConfigProgram (withPrograms lbi) + +------------------------------------------------------------------------------ +-- Dependency calculation amongst .chs files. +------------------------------------------------------------------------------ + +-- Given all files of the package, find those that end in .chs and extract the +-- .chs files they depend upon. Then return the PackageDescription with these +-- files rearranged so that they are built in a sequence that files that are +-- needed by other files are built first. +fixDeps :: PackageDescription -> IO PackageDescription +fixDeps pd...@PD...ckageDescription { + PD.library = Just li...@PD...brary { + PD.exposedModules = expMods, + PD.libBuildInfo = bi@PD.BuildInfo { + PD.hsSourceDirs = srcDirs, + PD.otherModules = othMods + }}} = do + let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs + (joinPath (components m)) + mExpFiles <- mapM findModule expMods + mOthFiles <- mapM findModule othMods + + -- tag all exposed files with True so we throw an error if we need to build + -- an exposed module before an internal modules (we cannot express this) + let modDeps = zipWith (ModDep True []) expMods mExpFiles++ + zipWith (ModDep False []) othMods mOthFiles + modDeps <- mapM extractDeps modDeps + let (expMods, othMods) = span mdExposed $ sortTopological modDeps + badOther = map (fromMaybe "<no file>" . mdLocation) $ + filter (not . mdExposed) expMods + unless (null badOther) $ + die ("internal chs modules "++intercalate "," badOther++ + " depend on exposed chs modules; cabal needs to build internal modules first") + return pd { PD.library = Just lib { + PD.exposedModules = map mdOriginal expMods, + PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } + }} + +data ModDep = ModDep { + mdExposed :: Bool, + mdRequires :: [ModuleName], + mdOriginal :: ModuleName, + mdLocation :: Maybe FilePath +} + +instance Show ModDep where + show x = show (mdLocation x) + +instance Eq ModDep where + ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 +instance Ord ModDep where + compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 + +-- Extract the dependencies of this file. This is intentionally rather naive as it +-- ignores CPP conditionals. We just require everything which means that the +-- existance of a .chs module may not depend on some CPP condition. [_$_] +extractDeps :: ModDep -> IO ModDep +extractDeps md@ModDep { mdLocation = Nothing } = return md +extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do + let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of + ('i':'m':'p':'o':'r':'t':' ':ys) -> + case simpleParse (takeWhile ((/=) '#') ys) of + Just m -> findImports (m:acc) xxs [_$_] + Nothing -> die ("cannot parse chs import in "++f++":\n"++ + "offending line is {#"++xs) + -- no more imports after the first non-import hook + _ -> return acc + findImports acc (_:xxs) = findImports acc xxs + findImports acc [] = return acc + mods <- findImports [] (lines con) + return md { mdRequires = mods } + +-- Find a total order of the set of modules that are partially sorted by their +-- dependencies on each other. The function returns the sorted list of modules +-- together with a list of modules that are required but not supplied by this +-- in the input set of modules. +sortTopological :: [ModDep] -> [ModDep] +sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) + where + set = M.fromList (map (\m -> (mdOriginal m, m)) ms) + visit (out,visited) m + | m `S.member` visited = (out,visited) + | otherwise = case m `M.lookup` set of + Nothing -> (out, m `S.insert` visited) + Just md -> (md:out', visited') + where + (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) hunk ./svgcairo/Setup.hs 1 -{-# LANGUAGE CPP #-} +-- Setup file for a Gtk2Hs module. Contains only adjustments specific to this module, +-- all Gtk2Hs-specific boilerplate is stored in Gtk2HsSetup.hs which should be kept +-- identical across all modules. +import Gtk2HsSetup ( gtk2hsUserHooks ) +import Distribution.Simple ( defaultMainWithHooks ) hunk ./svgcairo/Setup.hs 7 -#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ - ((major) * 10000) \ - + ((minor) * 100) \ - + ((micro) * 1)) - -#define CABAL_VERSION_CHECK(major,minor,micro) \ - (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) - --- now, this is bad, but Cabal doesn't seem to actually pass any information about --- its version to CPP, so guess the version depending on the version of GHC -#ifdef CABAL_VERSION_MINOR -#ifndef CABAL_VERSION_MAJOR -#define CABAL_VERSION_MAJOR 1 -#endif -#ifndef CABAL_VERSION_MICRO -#define CABAL_VERSION_MICRO 0 -#endif -#define CABAL_VERSION CABAL_VERSION_ENCODE( \ - CABAL_VERSION_MAJOR, \ - CABAL_VERSION_MINOR, \ - CABAL_VERSION_MICRO) -#else -#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) -#if (__GLASGOW_HASKELL__ >= 612) -#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) -#else -#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) -#endif -#endif - --- | Build a Gtk2hs package. --- -import Distribution.Simple -import Distribution.Simple.PreProcess -import Distribution.InstalledPackageInfo ( importDirs ) -import Distribution.Simple.PackageIndex ( -#if CABAL_VERSION_CHECK(1,8,0) - lookupInstalledPackageId -#else - lookupPackageId -#endif - ) -import Distribution.PackageDescription as PD ( PackageDescription(..), - updatePackageDescription, - BuildInfo(..), - emptyBuildInfo, allBuildInfo, - Library(..), - libModules) -import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), - InstallDirs(..), -#if CABAL_VERSION_CHECK(1,8,0) - componentPackageDeps, -#else - packageDeps, -#endif - absoluteInstallDirs) -import Distribution.Simple.Compiler ( Compiler(..) ) -import Distribution.Simple.Program ( - Program(..), ConfiguredProgram(..), - rawSystemProgramConf, rawSystemProgramStdoutConf, - c2hsProgram, pkgConfigProgram, - simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) -import Distribution.ModuleName ( ModuleName, components, toFilePath ) -import Distribution.Simple.Utils -import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), - defaultCopyFlags, ConfigFlags(configVerbosity), - fromFlag, toFlag) -import Distribution.Simple.BuildPaths ( autogenModulesDir ) -import Distribution.Text ( simpleParse, display ) -import System.FilePath -import System.Directory ( doesFileExist ) -import Distribution.Version (Version(..)) -import Distribution.Verbosity -import Control.Monad (unless) -import Data.Maybe (fromMaybe) -import Data.List (isPrefixOf, nub) -import Data.Char (isAlpha) -import qualified Data.Map as M -import qualified Data.Set as S - - --- the name of the c2hs pre-compiled header file -precompFile = "precompchs.bin" - -main = defaultMainWithHooks simpleUserHooks { - hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], - hookedPreProcessors = [("chs", ourC2hs)], - confHook = \pd cf -> - confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, - postConf = \args cf pd lbi -> do - genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi - postConf simpleUserHooks args cf pd lbi, - buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> - (buildHook simpleUserHooks) pd lbi uh bf, - copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> - installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), - instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> - installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest - } - --- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later -adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo -adjustLocalBuildInfo lbi = - let extra = (Just libBi, []) - libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi - , buildDir lbi ] } - in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } - -ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor -ourC2hs bi lbi = PreProcessor { - platformIndependent = False, - runPreProcessor = runC2HS bi lbi -} - -runC2HS :: BuildInfo -> LocalBuildInfo -> - (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () -runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do - -- have the header file name if we don't have the precompiled header yet - header <- case lookup "x-c2hs-header" (customFieldsBI bi) of - Just h -> return h - Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ - "that sets the C header file to process .chs.pp files.") - - -- c2hs will output files in out dir, removing any leading path of the input file. - -- Thus, append the dir of the input file to the output dir. - let (outFileDir, newOutFile) = splitFileName outFile - let newOutDir = outDir </> outFileDir - -- additional .chi files might be needed that other packages have installed; - -- we assume that these are installed in the same place as .hi files - let chiDirs = [ dir | -#if CABAL_VERSION_CHECK(1,8,0) - ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), - dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] -#else - ipi <- packageDeps lbi, - dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] -#endif - rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ - map ("--include=" ++) (outDir:chiDirs) - ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] - ++ ["--output-dir=" ++ newOutDir, - "--output=" ++ newOutFile, - "--precomp=" ++ buildDir lbi </> precompFile, - header, inDir </> inFile] - -getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] -getCppOptions bi lbi - = nub $ - ["-I" ++ dir | dir <- PD.includeDirs bi] - ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] - -installCHI :: PackageDescription -- ^information from the .cabal file - -> LocalBuildInfo -- ^information from the configure step - -> Verbosity -> CopyDest -- ^flags sent to copy or install - -> IO () -installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do - let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest - -- cannot use the recommended 'findModuleFiles' since it fails if there exists - -- a modules that does not have a .chi file - mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) - (map toFilePath -#if CABAL_VERSION_CHECK(1,8,0) - (PD.libModules lib) -#else - (PD.libModules pkg) -#endif - ) - let files = [ f | Just f <- mFiles ] -#if CABAL_VERSION_CHECK(1,8,0) - installOrdinaryFiles verbosity libPref files -#else - copyFiles verbosity libPref files -#endif - - [_$_] -installCHI _ _ _ _ = return () - ------------------------------------------------------------------------------- --- Generating the type hierarchy and signal callback .hs files. ------------------------------------------------------------------------------- - -typeGenProgram :: Program -typeGenProgram = (simpleProgram "gtk2hsTypeGen") - -signalGenProgram :: Program -signalGenProgram = (simpleProgram "gtk2hsHookGenerator") - -c2hsLocal :: Program -c2hsLocal = (simpleProgram "gtk2hsC2hs") - -genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () -genSynthezisedFiles verb pd lbi = do - - cPkgs <- getPkgConfigPackages verb lbi pd - - let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) - ++customFieldsPD pd - typeOpts :: [ProgArg] - typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) - | (field,content) <- xList, - "x-types-" `isPrefixOf` field, - field /= "x-types-file"] - ++ [ "--tag=" ++ tag - | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs - , let name' = filter isAlpha (display name) - , tag <- name' - : [ name' ++ "-" ++ show major ++ "." ++ show digit - | digit <- [0,2..minor] ] - ] - - genFile :: Program -> [ProgArg] -> FilePath -> IO () - genFile prog args outFile = do - res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args - rewriteFile outFile res - - case lookup "x-types-file" xList of - Nothing -> return () - Just f -> do - info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") - genFile typeGenProgram typeOpts f - - case (lookup "x-signals-file" xList, - lookup "x-signals-modname" xList) of - (Just _, Nothing) -> die "You need to specify the module name (X-Signals-ModName) \ - \to generate a signal file." - (Just f, Just mod) -> do - info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") - genFile signalGenProgram [mod] f - (_,_) -> return () - ---FIXME: Cabal should tell us the selected pkg-config package versions in the --- LocalBuildInfo or equivalent. --- In the mean time, ask pkg-config again. - -getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] -getPkgConfigPackages verbosity lbi pkg = - sequence - [ do version <- pkgconfig ["--modversion", display pkgname] - case simpleParse version of - Nothing -> die $ "parsing output of pkg-config --modversion failed" - Just v -> return (PackageIdentifier pkgname v) - | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] - where - pkgconfig = rawSystemProgramStdoutConf verbosity - pkgConfigProgram (withPrograms lbi) - ------------------------------------------------------------------------------- --- Dependency calculation amongst .chs files. ------------------------------------------------------------------------------- - --- Given all files of the package, find those that end in .chs and extract the --- .chs files they depend upon. Then return the PackageDescription with these --- files rearranged so that they are built in a sequence that files that are --- needed by other files are built first. -fixDeps :: PackageDescription -> IO PackageDescription -fixDeps pd...@PD...ckageDescription { - PD.library = Just li...@PD...brary { - PD.exposedModules = expMods, - PD.libBuildInfo = bi@PD.BuildInfo { - PD.hsSourceDirs = srcDirs, - PD.otherModules = othMods - }}} = do - let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs - (joinPath (components m)) - mExpFiles <- mapM findModule expMods - mOthFiles <- mapM findModule othMods - - -- tag all exposed files with True so we throw an error if we need to build - -- an exposed module before an internal modules (we cannot express this) - let modDeps = zipWith (ModDep True []) expMods mExpFiles++ - zipWith (ModDep False []) othMods mOthFiles - modDeps <- mapM extractDeps modDeps - let (expMods, othMods) = span mdExposed $ sortTopological modDeps - badOther = map (fromMaybe "<no file>" . mdLocation) $ - filter (not . mdExposed) expMods - unless (null badOther) $ - die ("internal chs modules "++intercalate "," badOther++ - " depend on exposed chs modules; cabal needs to build internal modules first") - return pd { PD.library = Just lib { - PD.exposedModules = map mdOriginal expMods, - PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } - }} - -data ModDep = ModDep { - mdExposed :: Bool, - mdRequires :: [ModuleName], - mdOriginal :: ModuleName, - mdLocation :: Maybe FilePath -} - -instance Show ModDep where - show x = show (mdLocation x) - -instance Eq ModDep where - ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 -instance Ord ModDep where - compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 - --- Extract the dependencies of this file. This is intentionally rather naive as it --- ignores CPP conditionals. We just require everything which means that the --- existance of a .chs module may not depend on some CPP condition. [_$_] -extractDeps :: ModDep -> IO ModDep -extractDeps md@ModDep { mdLocation = Nothing } = return md -extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do - let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of - ('i':'m':'p':'o':'r':'t':' ':ys) -> - case simpleParse (takeWhile ((/=) '#') ys) of - Just m -> findImports (m:acc) xxs [_$_] - Nothing -> die ("cannot parse chs import in "++f++":\n"++ - "offending line is {#"++xs) - -- no more imports after the first non-import hook - _ -> return acc - findImports acc (_:xxs) = findImports acc xxs - findImports acc [] = return acc - mods <- findImports [] (lines con) - return md { mdRequires = mods } - --- Find a total order of the set of modules that are partially sorted by their --- dependencies on each other. The function returns the sorted list of modules --- together with a list of modules that are required but not supplied by this --- in the input set of modules. -sortTopological :: [ModDep] -> [ModDep] -sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) - where - set = M.fromList (map (\m -> (mdOriginal m, m)) ms) - visit (out,visited) m - | m `S.member` visited = (out,visited) - | otherwise = case m `M.lookup` set of - Nothing -> (out, m `S.insert` visited) - Just md -> (md:out', visited') - where - (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) +main = defaultMainWithHooks gtk2hsUserHooks |
From: Axel S. <si...@co...> - 2010-05-01 15:19:38
|
Sat May 1 11:05:26 EDT 2010 Axe...@in... * Make SOE a really simple package, since it is. Ignore-this: f35f2729f101b34f3e9d47b60ead6171 hunk ./soegtk/Setup.hs 1 -{-# LANGUAGE CPP #-} - -#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ - ((major) * 10000) \ - + ((minor) * 100) \ - + ((micro) * 1)) - -#define CABAL_VERSION_CHECK(major,minor,micro) \ - (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) - --- now, this is bad, but Cabal doesn't seem to actually pass any information about --- its version to CPP, so guess the version depending on the version of GHC -#ifdef CABAL_VERSION_MINOR -#ifndef CABAL_VERSION_MAJOR -#define CABAL_VERSION_MAJOR 1 -#endif -#ifndef CABAL_VERSION_MICRO -#define CABAL_VERSION_MICRO 0 -#endif -#define CABAL_VERSION CABAL_VERSION_ENCODE( \ - CABAL_VERSION_MAJOR, \ - CABAL_VERSION_MINOR, \ - CABAL_VERSION_MICRO) -#else -#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) -#if (__GLASGOW_HASKELL__ >= 612) -#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) -#else -#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) -#endif -#endif - --- | Build a Gtk2hs package. --- -import Distribution.Simple -import Distribution.Simple.PreProcess -import Distribution.InstalledPackageInfo ( importDirs ) -import Distribution.Simple.PackageIndex ( -#if CABAL_VERSION_CHECK(1,8,0) - lookupInstalledPackageId -#else - lookupPackageId -#endif - ) -import Distribution.PackageDescription as PD ( PackageDescription(..), - updatePackageDescription, - BuildInfo(..), - emptyBuildInfo, allBuildInfo, - Library(..), - libModules) -import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), - InstallDirs(..), -#if CABAL_VERSION_CHECK(1,8,0) - componentPackageDeps, -#else - packageDeps, -#endif - absoluteInstallDirs) -import Distribution.Simple.Compiler ( Compiler(..) ) -import Distribution.Simple.Program ( - Program(..), ConfiguredProgram(..), - rawSystemProgramConf, rawSystemProgramStdoutConf, - c2hsProgram, pkgConfigProgram, - simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) -import Distribution.ModuleName ( ModuleName, components, toFilePath ) -import Distribution.Simple.Utils -import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), - defaultCopyFlags, ConfigFlags(configVerbosity), - fromFlag, toFlag) -import Distribution.Simple.BuildPaths ( autogenModulesDir ) -import Distribution.Text ( simpleParse, display ) -import System.FilePath -import System.Directory ( doesFileExist ) -import Distribution.Version (Version(..)) -import Distribution.Verbosity -import Control.Monad (unless) -import Data.Maybe (fromMaybe) -import Data.List (isPrefixOf, nub) -import Data.Char (isAlpha) -import qualified Data.Map as M -import qualified Data.Set as S - - --- the name of the c2hs pre-compiled header file -precompFile = "precompchs.bin" - -main = defaultMainWithHooks simpleUserHooks { - hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], - hookedPreProcessors = [("chs", ourC2hs)], - confHook = \pd cf -> - confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, - postConf = \args cf pd lbi -> do - genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi - postConf simpleUserHooks args cf pd lbi, - buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> - (buildHook simpleUserHooks) pd lbi uh bf, - copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> - installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), - instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> - installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest - } - --- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later -adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo -adjustLocalBuildInfo lbi = - let extra = (Just libBi, []) - libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi - , buildDir lbi ] } - in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } - -ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor -ourC2hs bi lbi = PreProcessor { - platformIndependent = False, - runPreProcessor = runC2HS bi lbi -} - -runC2HS :: BuildInfo -> LocalBuildInfo -> - (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () -runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do - -- have the header file name if we don't have the precompiled header yet - header <- case lookup "x-c2hs-header" (customFieldsBI bi) of - Just h -> return h - Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ - "that sets the C header file to process .chs.pp files.") - - -- c2hs will output files in out dir, removing any leading path of the input file. - -- Thus, append the dir of the input file to the output dir. - let (outFileDir, newOutFile) = splitFileName outFile - let newOutDir = outDir </> outFileDir - -- additional .chi files might be needed that other packages have installed; - -- we assume that these are installed in the same place as .hi files - let chiDirs = [ dir | -#if CABAL_VERSION_CHECK(1,8,0) - ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), - dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] -#else - ipi <- packageDeps lbi, - dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] -#endif - rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ - map ("--include=" ++) (outDir:chiDirs) - ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] - ++ ["--output-dir=" ++ newOutDir, - "--output=" ++ newOutFile, - "--precomp=" ++ buildDir lbi </> precompFile, - header, inDir </> inFile] - -getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] -getCppOptions bi lbi - = nub $ - ["-I" ++ dir | dir <- PD.includeDirs bi] - ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] - -installCHI :: PackageDescription -- ^information from the .cabal file - -> LocalBuildInfo -- ^information from the configure step - -> Verbosity -> CopyDest -- ^flags sent to copy or install - -> IO () -installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do - let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest - -- cannot use the recommended 'findModuleFiles' since it fails if there exists - -- a modules that does not have a .chi file - mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) - (map toFilePath -#if CABAL_VERSION_CHECK(1,8,0) - (PD.libModules lib) -#else - (PD.libModules pkg) -#endif - ) - let files = [ f | Just f <- mFiles ] -#if CABAL_VERSION_CHECK(1,8,0) - installOrdinaryFiles verbosity libPref files -#else - copyFiles verbosity libPref files -#endif - - [_$_] -installCHI _ _ _ _ = return () - ------------------------------------------------------------------------------- --- Generating the type hierarchy and signal callback .hs files. ------------------------------------------------------------------------------- - -typeGenProgram :: Program -typeGenProgram = (simpleProgram "gtk2hsTypeGen") - -signalGenProgram :: Program -signalGenProgram = (simpleProgram "gtk2hsHookGenerator") - -c2hsLocal :: Program -c2hsLocal = (simpleProgram "gtk2hsC2hs") - -genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () -genSynthezisedFiles verb pd lbi = do - - cPkgs <- getPkgConfigPackages verb lbi pd - - let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) - ++customFieldsPD pd - typeOpts :: [ProgArg] - typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) - | (field,content) <- xList, - "x-types-" `isPrefixOf` field, - field /= "x-types-file"] - ++ [ "--tag=" ++ tag - | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs - , let name' = filter isAlpha (display name) - , tag <- name' - : [ name' ++ "-" ++ show major ++ "." ++ show digit - | digit <- [0,2..minor] ] - ] - - genFile :: Program -> [ProgArg] -> FilePath -> IO () - genFile prog args outFile = do - res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args - rewriteFile outFile res - - case lookup "x-types-file" xList of - Nothing -> return () - Just f -> do - info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") - genFile typeGenProgram typeOpts f - - case (lookup "x-signals-file" xList, - lookup "x-signals-modname" xList) of - (Just _, Nothing) -> die "You need to specify the module name (X-Signals-ModName) \ - \to generate a signal file." - (Just f, Just mod) -> do - info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") - genFile signalGenProgram [mod] f - (_,_) -> return () - ---FIXME: Cabal should tell us the selected pkg-config package versions in the --- LocalBuildInfo or equivalent. --- In the mean time, ask pkg-config again. - -getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] -getPkgConfigPackages verbosity lbi pkg = - sequence - [ do version <- pkgconfig ["--modversion", display pkgname] - case simpleParse version of - Nothing -> die $ "parsing output of pkg-config --modversion failed" - Just v -> return (PackageIdentifier pkgname v) - | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] - where - pkgconfig = rawSystemProgramStdoutConf verbosity - pkgConfigProgram (withPrograms lbi) - ------------------------------------------------------------------------------- --- Dependency calculation amongst .chs files. ------------------------------------------------------------------------------- - --- Given all files of the package, find those that end in .chs and extract the --- .chs files they depend upon. Then return the PackageDescription with these --- files rearranged so that they are built in a sequence that files that are --- needed by other files are built first. -fixDeps :: PackageDescription -> IO PackageDescription -fixDeps pd...@PD...ckageDescription { - PD.library = Just li...@PD...brary { - PD.exposedModules = expMods, - PD.libBuildInfo = bi@PD.BuildInfo { - PD.hsSourceDirs = srcDirs, - PD.otherModules = othMods - }}} = do - let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs - (joinPath (components m)) - mExpFiles <- mapM findModule expMods - mOthFiles <- mapM findModule othMods - - -- tag all exposed files with True so we throw an error if we need to build - -- an exposed module before an internal modules (we cannot express this) - let modDeps = zipWith (ModDep True []) expMods mExpFiles++ - zipWith (ModDep False []) othMods mOthFiles - modDeps <- mapM extractDeps modDeps - let (expMods, othMods) = span mdExposed $ sortTopological modDeps - badOther = map (fromMaybe "<no file>" . mdLocation) $ - filter (not . mdExposed) expMods - unless (null badOther) $ - die ("internal chs modules "++intercalate "," badOther++ - " depend on exposed chs modules; cabal needs to build internal modules first") - return pd { PD.library = Just lib { - PD.exposedModules = map mdOriginal expMods, - PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } - }} - -data ModDep = ModDep { - mdExposed :: Bool, - mdRequires :: [ModuleName], - mdOriginal :: ModuleName, - mdLocation :: Maybe FilePath -} - -instance Show ModDep where - show x = show (mdLocation x) - -instance Eq ModDep where - ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 -instance Ord ModDep where - compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 - --- Extract the dependencies of this file. This is intentionally rather naive as it --- ignores CPP conditionals. We just require everything which means that the --- existance of a .chs module may not depend on some CPP condition. [_$_] -extractDeps :: ModDep -> IO ModDep -extractDeps md@ModDep { mdLocation = Nothing } = return md -extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do - let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of - ('i':'m':'p':'o':'r':'t':' ':ys) -> - case simpleParse (takeWhile ((/=) '#') ys) of - Just m -> findImports (m:acc) xxs [_$_] - Nothing -> die ("cannot parse chs import in "++f++":\n"++ - "offending line is {#"++xs) - -- no more imports after the first non-import hook - _ -> return acc - findImports acc (_:xxs) = findImports acc xxs - findImports acc [] = return acc - mods <- findImports [] (lines con) - return md { mdRequires = mods } - --- Find a total order of the set of modules that are partially sorted by their --- dependencies on each other. The function returns the sorted list of modules --- together with a list of modules that are required but not supplied by this --- in the input set of modules. -sortTopological :: [ModDep] -> [ModDep] -sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) - where - set = M.fromList (map (\m -> (mdOriginal m, m)) ms) - visit (out,visited) m - | m `S.member` visited = (out,visited) - | otherwise = case m `M.lookup` set of - Nothing -> (out, m `S.insert` visited) - Just md -> (md:out', visited') - where - (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) rmfile ./soegtk/Setup.hs hunk ./soegtk/soegtk.cabal 8 -Build-Type: Custom +Build-Type: Simple hunk ./soegtk/soegtk.cabal 36 - x-c2hs-Header: gtk/gtk.h - pkgconfig-depends: gtk+-2.0 -[_^I_][_^I_][_$_] |
From: Axel S. <si...@co...> - 2010-05-01 15:19:37
|
Sat May 1 10:54:19 EDT 2010 Axe...@in... * Replace Setup.hs by the default setup files. Ignore-this: 6becb507b1606e949d0d13720d361850 addfile ./gnomevfs/Gtk2HsSetup.hs hunk ./gnomevfs/Gtk2HsSetup.hs 1 +{-# LANGUAGE CPP #-} + +#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ + ((major) * 10000) \ + + ((minor) * 100) \ + + ((micro) * 1)) + +#define CABAL_VERSION_CHECK(major,minor,micro) \ + (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) + +-- now, this is bad, but Cabal doesn't seem to actually pass any information about +-- its version to CPP, so guess the version depending on the version of GHC +#ifdef CABAL_VERSION_MINOR +#ifndef CABAL_VERSION_MAJOR +#define CABAL_VERSION_MAJOR 1 +#endif +#ifndef CABAL_VERSION_MICRO +#define CABAL_VERSION_MICRO 0 +#endif +#define CABAL_VERSION CABAL_VERSION_ENCODE( \ + CABAL_VERSION_MAJOR, \ + CABAL_VERSION_MINOR, \ + CABAL_VERSION_MICRO) +#else +#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) +#if (__GLASGOW_HASKELL__ >= 612) +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) +#else +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) +#endif +#endif + +-- | Build a Gtk2hs package. +-- +module Gtk2HsSetup ( gtk2hsUserHooks, getPkgConfigPackages ) where + +import Distribution.Simple +import Distribution.Simple.PreProcess +import Distribution.InstalledPackageInfo ( importDirs ) +import Distribution.Simple.PackageIndex ( +#if CABAL_VERSION_CHECK(1,8,0) + lookupInstalledPackageId +#else + lookupPackageId +#endif + ) +import Distribution.PackageDescription as PD ( PackageDescription(..), + updatePackageDescription, + BuildInfo(..), + emptyBuildInfo, allBuildInfo, + Library(..), + libModules) +import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), + InstallDirs(..), +#if CABAL_VERSION_CHECK(1,8,0) + componentPackageDeps, +#else + packageDeps, +#endif + absoluteInstallDirs) +import Distribution.Simple.Compiler ( Compiler(..) ) +import Distribution.Simple.Program ( + Program(..), ConfiguredProgram(..), + rawSystemProgramConf, rawSystemProgramStdoutConf, + c2hsProgram, pkgConfigProgram, + simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) +import Distribution.ModuleName ( ModuleName, components, toFilePath ) +import Distribution.Simple.Utils +import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), + defaultCopyFlags, ConfigFlags(configVerbosity), + fromFlag, toFlag) +import Distribution.Simple.BuildPaths ( autogenModulesDir ) +import Distribution.Text ( simpleParse, display ) +import System.FilePath +import System.Directory ( doesFileExist ) +import Distribution.Version (Version(..)) +import Distribution.Verbosity +import Control.Monad (unless) +import Data.Maybe (fromMaybe) +import Data.List (isPrefixOf, nub) +import Data.Char (isAlpha) +import qualified Data.Map as M +import qualified Data.Set as S + + +-- the name of the c2hs pre-compiled header file +precompFile = "precompchs.bin" + +gtk2hsUserHooks = simpleUserHooks { + hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], + hookedPreProcessors = [("chs", ourC2hs)], + confHook = \pd cf -> + confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, + postConf = \args cf pd lbi -> do + genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi + postConf simpleUserHooks args cf pd lbi, + buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> + (buildHook simpleUserHooks) pd lbi uh bf, + copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), + instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest + } + +-- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later +adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo +adjustLocalBuildInfo lbi = + let extra = (Just libBi, []) + libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi + , buildDir lbi ] } + in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } + +ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor +ourC2hs bi lbi = PreProcessor { + platformIndependent = False, + runPreProcessor = runC2HS bi lbi +} + +runC2HS :: BuildInfo -> LocalBuildInfo -> + (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () +runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do + -- have the header file name if we don't have the precompiled header yet + header <- case lookup "x-c2hs-header" (customFieldsBI bi) of + Just h -> return h + Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ + "that sets the C header file to process .chs.pp files.") + + -- c2hs will output files in out dir, removing any leading path of the input file. + -- Thus, append the dir of the input file to the output dir. + let (outFileDir, newOutFile) = splitFileName outFile + let newOutDir = outDir </> outFileDir + -- additional .chi files might be needed that other packages have installed; + -- we assume that these are installed in the same place as .hi files + let chiDirs = [ dir | +#if CABAL_VERSION_CHECK(1,8,0) + ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), + dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] +#else + ipi <- packageDeps lbi, + dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] +#endif + rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ + map ("--include=" ++) (outDir:chiDirs) + ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] + ++ ["--output-dir=" ++ newOutDir, + "--output=" ++ newOutFile, + "--precomp=" ++ buildDir lbi </> precompFile, + header, inDir </> inFile] + +getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] +getCppOptions bi lbi + = nub $ + ["-I" ++ dir | dir <- PD.includeDirs bi] + ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] + +installCHI :: PackageDescription -- ^information from the .cabal file + -> LocalBuildInfo -- ^information from the configure step + -> Verbosity -> CopyDest -- ^flags sent to copy or install + -> IO () +installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do + let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest + -- cannot use the recommended 'findModuleFiles' since it fails if there exists + -- a modules that does not have a .chi file + mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) + (map toFilePath +#if CABAL_VERSION_CHECK(1,8,0) + (PD.libModules lib) +#else + (PD.libModules pkg) +#endif + ) + let files = [ f | Just f <- mFiles ] +#if CABAL_VERSION_CHECK(1,8,0) + installOrdinaryFiles verbosity libPref files +#else + copyFiles verbosity libPref files +#endif + + [_$_] +installCHI _ _ _ _ = return () + +------------------------------------------------------------------------------ +-- Generating the type hierarchy and signal callback .hs files. +------------------------------------------------------------------------------ + +typeGenProgram :: Program +typeGenProgram = (simpleProgram "gtk2hsTypeGen") + +signalGenProgram :: Program +signalGenProgram = (simpleProgram "gtk2hsHookGenerator") + +c2hsLocal :: Program +c2hsLocal = (simpleProgram "gtk2hsC2hs") + +genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () +genSynthezisedFiles verb pd lbi = do + + cPkgs <- getPkgConfigPackages verb lbi pd + + let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) + ++customFieldsPD pd + typeOpts :: [ProgArg] + typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) + | (field,content) <- xList, + "x-types-" `isPrefixOf` field, + field /= "x-types-file"] + ++ [ "--tag=" ++ tag + | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs + , let name' = filter isAlpha (display name) + , tag <- name' + : [ name' ++ "-" ++ show major ++ "." ++ show digit + | digit <- [0,2..minor] ] + ] + + signalsOpts :: [ProgArg] + signalsOpts = concat [ map (\val -> '-':'-':drop 10 field++'=':val) (words content) + | (field,content) <- xList, + "x-signals-" `isPrefixOf` field, + field /= "x-signals-file"] + + genFile :: Program -> [ProgArg] -> FilePath -> IO () + genFile prog args outFile = do + res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args + rewriteFile outFile res + + case lookup "x-types-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") + genFile typeGenProgram typeOpts f + + case lookup "x-signals-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") + genFile signalGenProgram signalsOpts f + +--FIXME: Cabal should tell us the selected pkg-config package versions in the +-- LocalBuildInfo or equivalent. +-- In the mean time, ask pkg-config again. + +getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] +getPkgConfigPackages verbosity lbi pkg = + sequence + [ do version <- pkgconfig ["--modversion", display pkgname] + case simpleParse version of + Nothing -> die $ "parsing output of pkg-config --modversion failed" + Just v -> return (PackageIdentifier pkgname v) + | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] + where + pkgconfig = rawSystemProgramStdoutConf verbosity + pkgConfigProgram (withPrograms lbi) + +------------------------------------------------------------------------------ +-- Dependency calculation amongst .chs files. +------------------------------------------------------------------------------ + +-- Given all files of the package, find those that end in .chs and extract the +-- .chs files they depend upon. Then return the PackageDescription with these +-- files rearranged so that they are built in a sequence that files that are +-- needed by other files are built first. +fixDeps :: PackageDescription -> IO PackageDescription +fixDeps pd...@PD...ckageDescription { + PD.library = Just li...@PD...brary { + PD.exposedModules = expMods, + PD.libBuildInfo = bi@PD.BuildInfo { + PD.hsSourceDirs = srcDirs, + PD.otherModules = othMods + }}} = do + let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs + (joinPath (components m)) + mExpFiles <- mapM findModule expMods + mOthFiles <- mapM findModule othMods + + -- tag all exposed files with True so we throw an error if we need to build + -- an exposed module before an internal modules (we cannot express this) + let modDeps = zipWith (ModDep True []) expMods mExpFiles++ + zipWith (ModDep False []) othMods mOthFiles + modDeps <- mapM extractDeps modDeps + let (expMods, othMods) = span mdExposed $ sortTopological modDeps + badOther = map (fromMaybe "<no file>" . mdLocation) $ + filter (not . mdExposed) expMods + unless (null badOther) $ + die ("internal chs modules "++intercalate "," badOther++ + " depend on exposed chs modules; cabal needs to build internal modules first") + return pd { PD.library = Just lib { + PD.exposedModules = map mdOriginal expMods, + PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } + }} + +data ModDep = ModDep { + mdExposed :: Bool, + mdRequires :: [ModuleName], + mdOriginal :: ModuleName, + mdLocation :: Maybe FilePath +} + +instance Show ModDep where + show x = show (mdLocation x) + +instance Eq ModDep where + ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 +instance Ord ModDep where + compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 + +-- Extract the dependencies of this file. This is intentionally rather naive as it +-- ignores CPP conditionals. We just require everything which means that the +-- existance of a .chs module may not depend on some CPP condition. [_$_] +extractDeps :: ModDep -> IO ModDep +extractDeps md@ModDep { mdLocation = Nothing } = return md +extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do + let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of + ('i':'m':'p':'o':'r':'t':' ':ys) -> + case simpleParse (takeWhile ((/=) '#') ys) of + Just m -> findImports (m:acc) xxs [_$_] + Nothing -> die ("cannot parse chs import in "++f++":\n"++ + "offending line is {#"++xs) + -- no more imports after the first non-import hook + _ -> return acc + findImports acc (_:xxs) = findImports acc xxs + findImports acc [] = return acc + mods <- findImports [] (lines con) + return md { mdRequires = mods } + +-- Find a total order of the set of modules that are partially sorted by their +-- dependencies on each other. The function returns the sorted list of modules +-- together with a list of modules that are required but not supplied by this +-- in the input set of modules. +sortTopological :: [ModDep] -> [ModDep] +sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) + where + set = M.fromList (map (\m -> (mdOriginal m, m)) ms) + visit (out,visited) m + | m `S.member` visited = (out,visited) + | otherwise = case m `M.lookup` set of + Nothing -> (out, m `S.insert` visited) + Just md -> (md:out', visited') + where + (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) hunk ./gnomevfs/Setup.hs 1 -{-# LANGUAGE CPP #-} +-- Setup file for a Gtk2Hs module. Contains only adjustments specific to this module, +-- all Gtk2Hs-specific boilerplate is stored in Gtk2HsSetup.hs which should be kept +-- identical across all modules. +import Gtk2HsSetup ( gtk2hsUserHooks ) +import Distribution.Simple ( defaultMainWithHooks ) hunk ./gnomevfs/Setup.hs 7 -#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ - ((major) * 10000) \ - + ((minor) * 100) \ - + ((micro) * 1)) - -#define CABAL_VERSION_CHECK(major,minor,micro) \ - (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) - --- now, this is bad, but Cabal doesn't seem to actually pass any information about --- its version to CPP, so guess the version depending on the version of GHC -#ifdef CABAL_VERSION_MINOR -#ifndef CABAL_VERSION_MAJOR -#define CABAL_VERSION_MAJOR 1 -#endif -#ifndef CABAL_VERSION_MICRO -#define CABAL_VERSION_MICRO 0 -#endif -#define CABAL_VERSION CABAL_VERSION_ENCODE( \ - CABAL_VERSION_MAJOR, \ - CABAL_VERSION_MINOR, \ - CABAL_VERSION_MICRO) -#else -#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) -#if (__GLASGOW_HASKELL__ >= 612) -#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) -#else -#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) -#endif -#endif - --- | Build a Gtk2hs package. --- -import Distribution.Simple -import Distribution.Simple.PreProcess -import Distribution.InstalledPackageInfo ( importDirs ) -import Distribution.Simple.PackageIndex ( -#if CABAL_VERSION_CHECK(1,8,0) - lookupInstalledPackageId -#else - lookupPackageId -#endif - ) -import Distribution.PackageDescription as PD ( PackageDescription(..), - updatePackageDescription, - BuildInfo(..), - emptyBuildInfo, allBuildInfo, - Library(..), - libModules) -import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), - InstallDirs(..), -#if CABAL_VERSION_CHECK(1,8,0) - componentPackageDeps, -#else - packageDeps, -#endif - absoluteInstallDirs) -import Distribution.Simple.Compiler ( Compiler(..) ) -import Distribution.Simple.Program ( - Program(..), ConfiguredProgram(..), - rawSystemProgramConf, rawSystemProgramStdoutConf, - c2hsProgram, pkgConfigProgram, - simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) -import Distribution.ModuleName ( ModuleName, components, toFilePath ) -import Distribution.Simple.Utils -import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), - defaultCopyFlags, ConfigFlags(configVerbosity), - fromFlag, toFlag) -import Distribution.Simple.BuildPaths ( autogenModulesDir ) -import Distribution.Text ( simpleParse, display ) -import System.FilePath -import System.Directory ( doesFileExist ) -import Distribution.Version (Version(..)) -import Distribution.Verbosity -import Control.Monad (unless) -import Data.Maybe (fromMaybe) -import Data.List (isPrefixOf, nub) -import Data.Char (isAlpha) -import qualified Data.Map as M -import qualified Data.Set as S - - --- the name of the c2hs pre-compiled header file -precompFile = "precompchs.bin" - -main = defaultMainWithHooks simpleUserHooks { - hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], - hookedPreProcessors = [("chs", ourC2hs)], - confHook = \pd cf -> - confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, - postConf = \args cf pd lbi -> do - genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi - postConf simpleUserHooks args cf pd lbi, - buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> - (buildHook simpleUserHooks) pd lbi uh bf, - copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> - installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), - instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> - installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest - } - --- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later -adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo -adjustLocalBuildInfo lbi = - let extra = (Just libBi, []) - libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi - , buildDir lbi ] } - in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } - -ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor -ourC2hs bi lbi = PreProcessor { - platformIndependent = False, - runPreProcessor = runC2HS bi lbi -} - -runC2HS :: BuildInfo -> LocalBuildInfo -> - (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () -runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do - -- have the header file name if we don't have the precompiled header yet - header <- case lookup "x-c2hs-header" (customFieldsBI bi) of - Just h -> return h - Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ - "that sets the C header file to process .chs.pp files.") - - -- c2hs will output files in out dir, removing any leading path of the input file. - -- Thus, append the dir of the input file to the output dir. - let (outFileDir, newOutFile) = splitFileName outFile - let newOutDir = outDir </> outFileDir - -- additional .chi files might be needed that other packages have installed; - -- we assume that these are installed in the same place as .hi files - let chiDirs = [ dir | -#if CABAL_VERSION_CHECK(1,8,0) - ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), - dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] -#else - ipi <- packageDeps lbi, - dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] -#endif - rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ - map ("--include=" ++) (outDir:chiDirs) - ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] - ++ ["--output-dir=" ++ newOutDir, - "--output=" ++ newOutFile, - "--precomp=" ++ buildDir lbi </> precompFile, - header, inDir </> inFile] - -getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] -getCppOptions bi lbi - = nub $ - ["-I" ++ dir | dir <- PD.includeDirs bi] - ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] - -installCHI :: PackageDescription -- ^information from the .cabal file - -> LocalBuildInfo -- ^information from the configure step - -> Verbosity -> CopyDest -- ^flags sent to copy or install - -> IO () -installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do - let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest - -- cannot use the recommended 'findModuleFiles' since it fails if there exists - -- a modules that does not have a .chi file - mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) - (map toFilePath -#if CABAL_VERSION_CHECK(1,8,0) - (PD.libModules lib) -#else - (PD.libModules pkg) -#endif - ) - let files = [ f | Just f <- mFiles ] -#if CABAL_VERSION_CHECK(1,8,0) - installOrdinaryFiles verbosity libPref files -#else - copyFiles verbosity libPref files -#endif - - [_$_] -installCHI _ _ _ _ = return () - ------------------------------------------------------------------------------- --- Generating the type hierarchy and signal callback .hs files. ------------------------------------------------------------------------------- - -typeGenProgram :: Program -typeGenProgram = (simpleProgram "gtk2hsTypeGen") - -signalGenProgram :: Program -signalGenProgram = (simpleProgram "gtk2hsHookGenerator") - -c2hsLocal :: Program -c2hsLocal = (simpleProgram "gtk2hsC2hs") - -genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () -genSynthezisedFiles verb pd lbi = do - - cPkgs <- getPkgConfigPackages verb lbi pd - - let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) - ++customFieldsPD pd - typeOpts :: [ProgArg] - typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) - | (field,content) <- xList, - "x-types-" `isPrefixOf` field, - field /= "x-types-file"] - ++ [ "--tag=" ++ tag - | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs - , let name' = filter isAlpha (display name) - , tag <- name' - : [ name' ++ "-" ++ show major ++ "." ++ show digit - | digit <- [0,2..minor] ] - ] - - genFile :: Program -> [ProgArg] -> FilePath -> IO () - genFile prog args outFile = do - res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args - rewriteFile outFile res - - case lookup "x-types-file" xList of - Nothing -> return () - Just f -> do - info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") - genFile typeGenProgram typeOpts f - - case (lookup "x-signals-file" xList, - lookup "x-signals-modname" xList) of - (Just _, Nothing) -> die "You need to specify the module name (X-Signals-ModName) \ - \to generate a signal file." - (Just f, Just mod) -> do - info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") - genFile signalGenProgram [mod] f - (_,_) -> return () - ---FIXME: Cabal should tell us the selected pkg-config package versions in the --- LocalBuildInfo or equivalent. --- In the mean time, ask pkg-config again. - -getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] -getPkgConfigPackages verbosity lbi pkg = - sequence - [ do version <- pkgconfig ["--modversion", display pkgname] - case simpleParse version of - Nothing -> die $ "parsing output of pkg-config --modversion failed" - Just v -> return (PackageIdentifier pkgname v) - | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] - where - pkgconfig = rawSystemProgramStdoutConf verbosity - pkgConfigProgram (withPrograms lbi) - ------------------------------------------------------------------------------- --- Dependency calculation amongst .chs files. ------------------------------------------------------------------------------- - --- Given all files of the package, find those that end in .chs and extract the --- .chs files they depend upon. Then return the PackageDescription with these --- files rearranged so that they are built in a sequence that files that are --- needed by other files are built first. -fixDeps :: PackageDescription -> IO PackageDescription -fixDeps pd...@PD...ckageDescription { - PD.library = Just li...@PD...brary { - PD.exposedModules = expMods, - PD.libBuildInfo = bi@PD.BuildInfo { - PD.hsSourceDirs = srcDirs, - PD.otherModules = othMods - }}} = do - let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs - (joinPath (components m)) - mExpFiles <- mapM findModule expMods - mOthFiles <- mapM findModule othMods - - -- tag all exposed files with True so we throw an error if we need to build - -- an exposed module before an internal modules (we cannot express this) - let modDeps = zipWith (ModDep True []) expMods mExpFiles++ - zipWith (ModDep False []) othMods mOthFiles - modDeps <- mapM extractDeps modDeps - let (expMods, othMods) = span mdExposed $ sortTopological modDeps - badOther = map (fromMaybe "<no file>" . mdLocation) $ - filter (not . mdExposed) expMods - unless (null badOther) $ - die ("internal chs modules "++intercalate "," badOther++ - " depend on exposed chs modules; cabal needs to build internal modules first") - return pd { PD.library = Just lib { - PD.exposedModules = map mdOriginal expMods, - PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } - }} - -data ModDep = ModDep { - mdExposed :: Bool, - mdRequires :: [ModuleName], - mdOriginal :: ModuleName, - mdLocation :: Maybe FilePath -} - -instance Show ModDep where - show x = show (mdLocation x) - -instance Eq ModDep where - ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 -instance Ord ModDep where - compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 - --- Extract the dependencies of this file. This is intentionally rather naive as it --- ignores CPP conditionals. We just require everything which means that the --- existance of a .chs module may not depend on some CPP condition. [_$_] -extractDeps :: ModDep -> IO ModDep -extractDeps md@ModDep { mdLocation = Nothing } = return md -extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do - let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of - ('i':'m':'p':'o':'r':'t':' ':ys) -> - case simpleParse (takeWhile ((/=) '#') ys) of - Just m -> findImports (m:acc) xxs [_$_] - Nothing -> die ("cannot parse chs import in "++f++":\n"++ - "offending line is {#"++xs) - -- no more imports after the first non-import hook - _ -> return acc - findImports acc (_:xxs) = findImports acc xxs - findImports acc [] = return acc - mods <- findImports [] (lines con) - return md { mdRequires = mods } - --- Find a total order of the set of modules that are partially sorted by their --- dependencies on each other. The function returns the sorted list of modules --- together with a list of modules that are required but not supplied by this --- in the input set of modules. -sortTopological :: [ModDep] -> [ModDep] -sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) - where - set = M.fromList (map (\m -> (mdOriginal m, m)) ms) - visit (out,visited) m - | m `S.member` visited = (out,visited) - | otherwise = case m `M.lookup` set of - Nothing -> (out, m `S.insert` visited) - Just md -> (md:out', visited') - where - (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) +main = defaultMainWithHooks gtk2hsUserHooks |
From: Axel S. <si...@co...> - 2010-05-01 15:19:36
|
Sat May 1 11:01:56 EDT 2010 Axe...@in... * Replace Setup.hs by the default setup files. Ignore-this: 9e17194a9abf7cd0b31061249694edda addfile ./gtksourceview2/Gtk2HsSetup.hs hunk ./gtksourceview2/Gtk2HsSetup.hs 1 +{-# LANGUAGE CPP #-} + +#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ + ((major) * 10000) \ + + ((minor) * 100) \ + + ((micro) * 1)) + +#define CABAL_VERSION_CHECK(major,minor,micro) \ + (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) + +-- now, this is bad, but Cabal doesn't seem to actually pass any information about +-- its version to CPP, so guess the version depending on the version of GHC +#ifdef CABAL_VERSION_MINOR +#ifndef CABAL_VERSION_MAJOR +#define CABAL_VERSION_MAJOR 1 +#endif +#ifndef CABAL_VERSION_MICRO +#define CABAL_VERSION_MICRO 0 +#endif +#define CABAL_VERSION CABAL_VERSION_ENCODE( \ + CABAL_VERSION_MAJOR, \ + CABAL_VERSION_MINOR, \ + CABAL_VERSION_MICRO) +#else +#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) +#if (__GLASGOW_HASKELL__ >= 612) +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) +#else +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) +#endif +#endif + +-- | Build a Gtk2hs package. +-- +module Gtk2HsSetup ( gtk2hsUserHooks, getPkgConfigPackages ) where + +import Distribution.Simple +import Distribution.Simple.PreProcess +import Distribution.InstalledPackageInfo ( importDirs ) +import Distribution.Simple.PackageIndex ( +#if CABAL_VERSION_CHECK(1,8,0) + lookupInstalledPackageId +#else + lookupPackageId +#endif + ) +import Distribution.PackageDescription as PD ( PackageDescription(..), + updatePackageDescription, + BuildInfo(..), + emptyBuildInfo, allBuildInfo, + Library(..), + libModules) +import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), + InstallDirs(..), +#if CABAL_VERSION_CHECK(1,8,0) + componentPackageDeps, +#else + packageDeps, +#endif + absoluteInstallDirs) +import Distribution.Simple.Compiler ( Compiler(..) ) +import Distribution.Simple.Program ( + Program(..), ConfiguredProgram(..), + rawSystemProgramConf, rawSystemProgramStdoutConf, + c2hsProgram, pkgConfigProgram, + simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) +import Distribution.ModuleName ( ModuleName, components, toFilePath ) +import Distribution.Simple.Utils +import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), + defaultCopyFlags, ConfigFlags(configVerbosity), + fromFlag, toFlag) +import Distribution.Simple.BuildPaths ( autogenModulesDir ) +import Distribution.Text ( simpleParse, display ) +import System.FilePath +import System.Directory ( doesFileExist ) +import Distribution.Version (Version(..)) +import Distribution.Verbosity +import Control.Monad (unless) +import Data.Maybe (fromMaybe) +import Data.List (isPrefixOf, nub) +import Data.Char (isAlpha) +import qualified Data.Map as M +import qualified Data.Set as S + + +-- the name of the c2hs pre-compiled header file +precompFile = "precompchs.bin" + +gtk2hsUserHooks = simpleUserHooks { + hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], + hookedPreProcessors = [("chs", ourC2hs)], + confHook = \pd cf -> + confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, + postConf = \args cf pd lbi -> do + genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi + postConf simpleUserHooks args cf pd lbi, + buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> + (buildHook simpleUserHooks) pd lbi uh bf, + copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), + instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest + } + +-- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later +adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo +adjustLocalBuildInfo lbi = + let extra = (Just libBi, []) + libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi + , buildDir lbi ] } + in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } + +ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor +ourC2hs bi lbi = PreProcessor { + platformIndependent = False, + runPreProcessor = runC2HS bi lbi +} + +runC2HS :: BuildInfo -> LocalBuildInfo -> + (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () +runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do + -- have the header file name if we don't have the precompiled header yet + header <- case lookup "x-c2hs-header" (customFieldsBI bi) of + Just h -> return h + Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ + "that sets the C header file to process .chs.pp files.") + + -- c2hs will output files in out dir, removing any leading path of the input file. + -- Thus, append the dir of the input file to the output dir. + let (outFileDir, newOutFile) = splitFileName outFile + let newOutDir = outDir </> outFileDir + -- additional .chi files might be needed that other packages have installed; + -- we assume that these are installed in the same place as .hi files + let chiDirs = [ dir | +#if CABAL_VERSION_CHECK(1,8,0) + ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), + dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] +#else + ipi <- packageDeps lbi, + dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] +#endif + rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ + map ("--include=" ++) (outDir:chiDirs) + ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] + ++ ["--output-dir=" ++ newOutDir, + "--output=" ++ newOutFile, + "--precomp=" ++ buildDir lbi </> precompFile, + header, inDir </> inFile] + +getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] +getCppOptions bi lbi + = nub $ + ["-I" ++ dir | dir <- PD.includeDirs bi] + ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] + +installCHI :: PackageDescription -- ^information from the .cabal file + -> LocalBuildInfo -- ^information from the configure step + -> Verbosity -> CopyDest -- ^flags sent to copy or install + -> IO () +installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do + let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest + -- cannot use the recommended 'findModuleFiles' since it fails if there exists + -- a modules that does not have a .chi file + mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) + (map toFilePath +#if CABAL_VERSION_CHECK(1,8,0) + (PD.libModules lib) +#else + (PD.libModules pkg) +#endif + ) + let files = [ f | Just f <- mFiles ] +#if CABAL_VERSION_CHECK(1,8,0) + installOrdinaryFiles verbosity libPref files +#else + copyFiles verbosity libPref files +#endif + + [_$_] +installCHI _ _ _ _ = return () + +------------------------------------------------------------------------------ +-- Generating the type hierarchy and signal callback .hs files. +------------------------------------------------------------------------------ + +typeGenProgram :: Program +typeGenProgram = (simpleProgram "gtk2hsTypeGen") + +signalGenProgram :: Program +signalGenProgram = (simpleProgram "gtk2hsHookGenerator") + +c2hsLocal :: Program +c2hsLocal = (simpleProgram "gtk2hsC2hs") + +genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () +genSynthezisedFiles verb pd lbi = do + + cPkgs <- getPkgConfigPackages verb lbi pd + + let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) + ++customFieldsPD pd + typeOpts :: [ProgArg] + typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) + | (field,content) <- xList, + "x-types-" `isPrefixOf` field, + field /= "x-types-file"] + ++ [ "--tag=" ++ tag + | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs + , let name' = filter isAlpha (display name) + , tag <- name' + : [ name' ++ "-" ++ show major ++ "." ++ show digit + | digit <- [0,2..minor] ] + ] + + signalsOpts :: [ProgArg] + signalsOpts = concat [ map (\val -> '-':'-':drop 10 field++'=':val) (words content) + | (field,content) <- xList, + "x-signals-" `isPrefixOf` field, + field /= "x-signals-file"] + + genFile :: Program -> [ProgArg] -> FilePath -> IO () + genFile prog args outFile = do + res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args + rewriteFile outFile res + + case lookup "x-types-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") + genFile typeGenProgram typeOpts f + + case lookup "x-signals-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") + genFile signalGenProgram signalsOpts f + +--FIXME: Cabal should tell us the selected pkg-config package versions in the +-- LocalBuildInfo or equivalent. +-- In the mean time, ask pkg-config again. + +getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] +getPkgConfigPackages verbosity lbi pkg = + sequence + [ do version <- pkgconfig ["--modversion", display pkgname] + case simpleParse version of + Nothing -> die $ "parsing output of pkg-config --modversion failed" + Just v -> return (PackageIdentifier pkgname v) + | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] + where + pkgconfig = rawSystemProgramStdoutConf verbosity + pkgConfigProgram (withPrograms lbi) + +------------------------------------------------------------------------------ +-- Dependency calculation amongst .chs files. +------------------------------------------------------------------------------ + +-- Given all files of the package, find those that end in .chs and extract the +-- .chs files they depend upon. Then return the PackageDescription with these +-- files rearranged so that they are built in a sequence that files that are +-- needed by other files are built first. +fixDeps :: PackageDescription -> IO PackageDescription +fixDeps pd...@PD...ckageDescription { + PD.library = Just li...@PD...brary { + PD.exposedModules = expMods, + PD.libBuildInfo = bi@PD.BuildInfo { + PD.hsSourceDirs = srcDirs, + PD.otherModules = othMods + }}} = do + let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs + (joinPath (components m)) + mExpFiles <- mapM findModule expMods + mOthFiles <- mapM findModule othMods + + -- tag all exposed files with True so we throw an error if we need to build + -- an exposed module before an internal modules (we cannot express this) + let modDeps = zipWith (ModDep True []) expMods mExpFiles++ + zipWith (ModDep False []) othMods mOthFiles + modDeps <- mapM extractDeps modDeps + let (expMods, othMods) = span mdExposed $ sortTopological modDeps + badOther = map (fromMaybe "<no file>" . mdLocation) $ + filter (not . mdExposed) expMods + unless (null badOther) $ + die ("internal chs modules "++intercalate "," badOther++ + " depend on exposed chs modules; cabal needs to build internal modules first") + return pd { PD.library = Just lib { + PD.exposedModules = map mdOriginal expMods, + PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } + }} + +data ModDep = ModDep { + mdExposed :: Bool, + mdRequires :: [ModuleName], + mdOriginal :: ModuleName, + mdLocation :: Maybe FilePath +} + +instance Show ModDep where + show x = show (mdLocation x) + +instance Eq ModDep where + ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 +instance Ord ModDep where + compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 + +-- Extract the dependencies of this file. This is intentionally rather naive as it +-- ignores CPP conditionals. We just require everything which means that the +-- existance of a .chs module may not depend on some CPP condition. [_$_] +extractDeps :: ModDep -> IO ModDep +extractDeps md@ModDep { mdLocation = Nothing } = return md +extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do + let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of + ('i':'m':'p':'o':'r':'t':' ':ys) -> + case simpleParse (takeWhile ((/=) '#') ys) of + Just m -> findImports (m:acc) xxs [_$_] + Nothing -> die ("cannot parse chs import in "++f++":\n"++ + "offending line is {#"++xs) + -- no more imports after the first non-import hook + _ -> return acc + findImports acc (_:xxs) = findImports acc xxs + findImports acc [] = return acc + mods <- findImports [] (lines con) + return md { mdRequires = mods } + +-- Find a total order of the set of modules that are partially sorted by their +-- dependencies on each other. The function returns the sorted list of modules +-- together with a list of modules that are required but not supplied by this +-- in the input set of modules. +sortTopological :: [ModDep] -> [ModDep] +sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) + where + set = M.fromList (map (\m -> (mdOriginal m, m)) ms) + visit (out,visited) m + | m `S.member` visited = (out,visited) + | otherwise = case m `M.lookup` set of + Nothing -> (out, m `S.insert` visited) + Just md -> (md:out', visited') + where + (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) hunk ./gtksourceview2/Setup.hs 1 -{-# LANGUAGE CPP #-} +-- Setup file for a Gtk2Hs module. Contains only adjustments specific to this module, +-- all Gtk2Hs-specific boilerplate is stored in Gtk2HsSetup.hs which should be kept +-- identical across all modules. +import Gtk2HsSetup ( gtk2hsUserHooks ) +import Distribution.Simple ( defaultMainWithHooks ) hunk ./gtksourceview2/Setup.hs 7 -#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ - ((major) * 10000) \ - + ((minor) * 100) \ - + ((micro) * 1)) - -#define CABAL_VERSION_CHECK(major,minor,micro) \ - (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) - --- now, this is bad, but Cabal doesn't seem to actually pass any information about --- its version to CPP, so guess the version depending on the version of GHC -#ifdef CABAL_VERSION_MINOR -#ifndef CABAL_VERSION_MAJOR -#define CABAL_VERSION_MAJOR 1 -#endif -#ifndef CABAL_VERSION_MICRO -#define CABAL_VERSION_MICRO 0 -#endif -#define CABAL_VERSION CABAL_VERSION_ENCODE( \ - CABAL_VERSION_MAJOR, \ - CABAL_VERSION_MINOR, \ - CABAL_VERSION_MICRO) -#else -#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) -#if (__GLASGOW_HASKELL__ >= 612) -#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) -#else -#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) -#endif -#endif - --- | Build a Gtk2hs package. --- -import Distribution.Simple -import Distribution.Simple.PreProcess -import Distribution.InstalledPackageInfo ( importDirs ) -import Distribution.Simple.PackageIndex ( -#if CABAL_VERSION_CHECK(1,8,0) - lookupInstalledPackageId -#else - lookupPackageId -#endif - ) -import Distribution.PackageDescription as PD ( PackageDescription(..), - updatePackageDescription, - BuildInfo(..), - emptyBuildInfo, allBuildInfo, - Library(..), - libModules) -import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), - InstallDirs(..), -#if CABAL_VERSION_CHECK(1,8,0) - componentPackageDeps, -#else - packageDeps, -#endif - absoluteInstallDirs) -import Distribution.Simple.Compiler ( Compiler(..) ) -import Distribution.Simple.Program ( - Program(..), ConfiguredProgram(..), - rawSystemProgramConf, rawSystemProgramStdoutConf, - c2hsProgram, pkgConfigProgram, - simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) -import Distribution.ModuleName ( ModuleName, components, toFilePath ) -import Distribution.Simple.Utils -import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), - defaultCopyFlags, ConfigFlags(configVerbosity), - fromFlag, toFlag) -import Distribution.Simple.BuildPaths ( autogenModulesDir ) -import Distribution.Text ( simpleParse, display ) -import System.FilePath -import System.Directory ( doesFileExist ) -import Distribution.Version (Version(..)) -import Distribution.Verbosity -import Control.Monad (unless) -import Data.Maybe (fromMaybe) -import Data.List (isPrefixOf, nub) -import Data.Char (isAlpha) -import qualified Data.Map as M -import qualified Data.Set as S - - --- the name of the c2hs pre-compiled header file -precompFile = "precompchs.bin" - -main = defaultMainWithHooks simpleUserHooks { - hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], - hookedPreProcessors = [("chs", ourC2hs)], - confHook = \pd cf -> - confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, - postConf = \args cf pd lbi -> do - genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi - postConf simpleUserHooks args cf pd lbi, - buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> - (buildHook simpleUserHooks) pd lbi uh bf, - copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> - installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), - instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> - installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest - } - --- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later -adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo -adjustLocalBuildInfo lbi = - let extra = (Just libBi, []) - libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi - , buildDir lbi ] } - in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } - -ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor -ourC2hs bi lbi = PreProcessor { - platformIndependent = False, - runPreProcessor = runC2HS bi lbi -} - -runC2HS :: BuildInfo -> LocalBuildInfo -> - (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () -runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do - -- have the header file name if we don't have the precompiled header yet - header <- case lookup "x-c2hs-header" (customFieldsBI bi) of - Just h -> return h - Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ - "that sets the C header file to process .chs.pp files.") - - -- c2hs will output files in out dir, removing any leading path of the input file. - -- Thus, append the dir of the input file to the output dir. - let (outFileDir, newOutFile) = splitFileName outFile - let newOutDir = outDir </> outFileDir - -- additional .chi files might be needed that other packages have installed; - -- we assume that these are installed in the same place as .hi files - let chiDirs = [ dir | -#if CABAL_VERSION_CHECK(1,8,0) - ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), - dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] -#else - ipi <- packageDeps lbi, - dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] -#endif - rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ - map ("--include=" ++) (outDir:chiDirs) - ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] - ++ ["--output-dir=" ++ newOutDir, - "--output=" ++ newOutFile, - "--precomp=" ++ buildDir lbi </> precompFile, - header, inDir </> inFile] - -getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] -getCppOptions bi lbi - = nub $ - ["-I" ++ dir | dir <- PD.includeDirs bi] - ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] - -installCHI :: PackageDescription -- ^information from the .cabal file - -> LocalBuildInfo -- ^information from the configure step - -> Verbosity -> CopyDest -- ^flags sent to copy or install - -> IO () -installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do - let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest - -- cannot use the recommended 'findModuleFiles' since it fails if there exists - -- a modules that does not have a .chi file - mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) - (map toFilePath -#if CABAL_VERSION_CHECK(1,8,0) - (PD.libModules lib) -#else - (PD.libModules pkg) -#endif - ) - let files = [ f | Just f <- mFiles ] -#if CABAL_VERSION_CHECK(1,8,0) - installOrdinaryFiles verbosity libPref files -#else - copyFiles verbosity libPref files -#endif - - [_$_] -installCHI _ _ _ _ = return () - ------------------------------------------------------------------------------- --- Generating the type hierarchy and signal callback .hs files. ------------------------------------------------------------------------------- - -typeGenProgram :: Program -typeGenProgram = (simpleProgram "gtk2hsTypeGen") - -signalGenProgram :: Program -signalGenProgram = (simpleProgram "gtk2hsHookGenerator") - -c2hsLocal :: Program -c2hsLocal = (simpleProgram "gtk2hsC2hs") - -genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () -genSynthezisedFiles verb pd lbi = do - - cPkgs <- getPkgConfigPackages verb lbi pd - - let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) - ++customFieldsPD pd - typeOpts :: [ProgArg] - typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) - | (field,content) <- xList, - "x-types-" `isPrefixOf` field, - field /= "x-types-file"] - ++ [ "--tag=" ++ tag - | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs - , let name' = filter isAlpha (display name) - , tag <- name' - : [ name' ++ "-" ++ show major ++ "." ++ show digit - | digit <- [0,2..minor] ] - ] - - genFile :: Program -> [ProgArg] -> FilePath -> IO () - genFile prog args outFile = do - res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args - rewriteFile outFile res - - case lookup "x-types-file" xList of - Nothing -> return () - Just f -> do - info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") - genFile typeGenProgram typeOpts f - - case (lookup "x-signals-file" xList, - lookup "x-signals-modname" xList) of - (Just _, Nothing) -> die "You need to specify the module name (X-Signals-ModName) \ - \to generate a signal file." - (Just f, Just mod) -> do - info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") - genFile signalGenProgram [mod] f - (_,_) -> return () - ---FIXME: Cabal should tell us the selected pkg-config package versions in the --- LocalBuildInfo or equivalent. --- In the mean time, ask pkg-config again. - -getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] -getPkgConfigPackages verbosity lbi pkg = - sequence - [ do version <- pkgconfig ["--modversion", display pkgname] - case simpleParse version of - Nothing -> die $ "parsing output of pkg-config --modversion failed" - Just v -> return (PackageIdentifier pkgname v) - | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] - where - pkgconfig = rawSystemProgramStdoutConf verbosity - pkgConfigProgram (withPrograms lbi) - ------------------------------------------------------------------------------- --- Dependency calculation amongst .chs files. ------------------------------------------------------------------------------- - --- Given all files of the package, find those that end in .chs and extract the --- .chs files they depend upon. Then return the PackageDescription with these --- files rearranged so that they are built in a sequence that files that are --- needed by other files are built first. -fixDeps :: PackageDescription -> IO PackageDescription -fixDeps pd...@PD...ckageDescription { - PD.library = Just li...@PD...brary { - PD.exposedModules = expMods, - PD.libBuildInfo = bi@PD.BuildInfo { - PD.hsSourceDirs = srcDirs, - PD.otherModules = othMods - }}} = do - let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs - (joinPath (components m)) - mExpFiles <- mapM findModule expMods - mOthFiles <- mapM findModule othMods - - -- tag all exposed files with True so we throw an error if we need to build - -- an exposed module before an internal modules (we cannot express this) - let modDeps = zipWith (ModDep True []) expMods mExpFiles++ - zipWith (ModDep False []) othMods mOthFiles - modDeps <- mapM extractDeps modDeps - let (expMods, othMods) = span mdExposed $ sortTopological modDeps - badOther = map (fromMaybe "<no file>" . mdLocation) $ - filter (not . mdExposed) expMods - unless (null badOther) $ - die ("internal chs modules "++intercalate "," badOther++ - " depend on exposed chs modules; cabal needs to build internal modules first") - return pd { PD.library = Just lib { - PD.exposedModules = map mdOriginal expMods, - PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } - }} - -data ModDep = ModDep { - mdExposed :: Bool, - mdRequires :: [ModuleName], - mdOriginal :: ModuleName, - mdLocation :: Maybe FilePath -} - -instance Show ModDep where - show x = show (mdLocation x) - -instance Eq ModDep where - ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 -instance Ord ModDep where - compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 - --- Extract the dependencies of this file. This is intentionally rather naive as it --- ignores CPP conditionals. We just require everything which means that the --- existance of a .chs module may not depend on some CPP condition. [_$_] -extractDeps :: ModDep -> IO ModDep -extractDeps md@ModDep { mdLocation = Nothing } = return md -extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do - let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of - ('i':'m':'p':'o':'r':'t':' ':ys) -> - case simpleParse (takeWhile ((/=) '#') ys) of - Just m -> findImports (m:acc) xxs [_$_] - Nothing -> die ("cannot parse chs import in "++f++":\n"++ - "offending line is {#"++xs) - -- no more imports after the first non-import hook - _ -> return acc - findImports acc (_:xxs) = findImports acc xxs - findImports acc [] = return acc - mods <- findImports [] (lines con) - return md { mdRequires = mods } - --- Find a total order of the set of modules that are partially sorted by their --- dependencies on each other. The function returns the sorted list of modules --- together with a list of modules that are required but not supplied by this --- in the input set of modules. -sortTopological :: [ModDep] -> [ModDep] -sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) - where - set = M.fromList (map (\m -> (mdOriginal m, m)) ms) - visit (out,visited) m - | m `S.member` visited = (out,visited) - | otherwise = case m `M.lookup` set of - Nothing -> (out, m `S.insert` visited) - Just md -> (md:out', visited') - where - (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) +main = defaultMainWithHooks gtk2hsUserHooks |
From: Axel S. <si...@co...> - 2010-05-01 15:19:35
|
Sat May 1 10:54:57 EDT 2010 Axe...@in... * Replace Setup.hs by the default setup files. Ignore-this: 90c6e9badb9b88a25c58a07e3dec6d11 addfile ./gtkglext/Gtk2HsSetup.hs hunk ./gtkglext/Gtk2HsSetup.hs 1 +{-# LANGUAGE CPP #-} + +#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ + ((major) * 10000) \ + + ((minor) * 100) \ + + ((micro) * 1)) + +#define CABAL_VERSION_CHECK(major,minor,micro) \ + (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) + +-- now, this is bad, but Cabal doesn't seem to actually pass any information about +-- its version to CPP, so guess the version depending on the version of GHC +#ifdef CABAL_VERSION_MINOR +#ifndef CABAL_VERSION_MAJOR +#define CABAL_VERSION_MAJOR 1 +#endif +#ifndef CABAL_VERSION_MICRO +#define CABAL_VERSION_MICRO 0 +#endif +#define CABAL_VERSION CABAL_VERSION_ENCODE( \ + CABAL_VERSION_MAJOR, \ + CABAL_VERSION_MINOR, \ + CABAL_VERSION_MICRO) +#else +#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) +#if (__GLASGOW_HASKELL__ >= 612) +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) +#else +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) +#endif +#endif + +-- | Build a Gtk2hs package. +-- +module Gtk2HsSetup ( gtk2hsUserHooks, getPkgConfigPackages ) where + +import Distribution.Simple +import Distribution.Simple.PreProcess +import Distribution.InstalledPackageInfo ( importDirs ) +import Distribution.Simple.PackageIndex ( +#if CABAL_VERSION_CHECK(1,8,0) + lookupInstalledPackageId +#else + lookupPackageId +#endif + ) +import Distribution.PackageDescription as PD ( PackageDescription(..), + updatePackageDescription, + BuildInfo(..), + emptyBuildInfo, allBuildInfo, + Library(..), + libModules) +import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), + InstallDirs(..), +#if CABAL_VERSION_CHECK(1,8,0) + componentPackageDeps, +#else + packageDeps, +#endif + absoluteInstallDirs) +import Distribution.Simple.Compiler ( Compiler(..) ) +import Distribution.Simple.Program ( + Program(..), ConfiguredProgram(..), + rawSystemProgramConf, rawSystemProgramStdoutConf, + c2hsProgram, pkgConfigProgram, + simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) +import Distribution.ModuleName ( ModuleName, components, toFilePath ) +import Distribution.Simple.Utils +import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), + defaultCopyFlags, ConfigFlags(configVerbosity), + fromFlag, toFlag) +import Distribution.Simple.BuildPaths ( autogenModulesDir ) +import Distribution.Text ( simpleParse, display ) +import System.FilePath +import System.Directory ( doesFileExist ) +import Distribution.Version (Version(..)) +import Distribution.Verbosity +import Control.Monad (unless) +import Data.Maybe (fromMaybe) +import Data.List (isPrefixOf, nub) +import Data.Char (isAlpha) +import qualified Data.Map as M +import qualified Data.Set as S + + +-- the name of the c2hs pre-compiled header file +precompFile = "precompchs.bin" + +gtk2hsUserHooks = simpleUserHooks { + hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], + hookedPreProcessors = [("chs", ourC2hs)], + confHook = \pd cf -> + confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, + postConf = \args cf pd lbi -> do + genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi + postConf simpleUserHooks args cf pd lbi, + buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> + (buildHook simpleUserHooks) pd lbi uh bf, + copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), + instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest + } + +-- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later +adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo +adjustLocalBuildInfo lbi = + let extra = (Just libBi, []) + libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi + , buildDir lbi ] } + in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } + +ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor +ourC2hs bi lbi = PreProcessor { + platformIndependent = False, + runPreProcessor = runC2HS bi lbi +} + +runC2HS :: BuildInfo -> LocalBuildInfo -> + (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () +runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do + -- have the header file name if we don't have the precompiled header yet + header <- case lookup "x-c2hs-header" (customFieldsBI bi) of + Just h -> return h + Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ + "that sets the C header file to process .chs.pp files.") + + -- c2hs will output files in out dir, removing any leading path of the input file. + -- Thus, append the dir of the input file to the output dir. + let (outFileDir, newOutFile) = splitFileName outFile + let newOutDir = outDir </> outFileDir + -- additional .chi files might be needed that other packages have installed; + -- we assume that these are installed in the same place as .hi files + let chiDirs = [ dir | +#if CABAL_VERSION_CHECK(1,8,0) + ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), + dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] +#else + ipi <- packageDeps lbi, + dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] +#endif + rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ + map ("--include=" ++) (outDir:chiDirs) + ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] + ++ ["--output-dir=" ++ newOutDir, + "--output=" ++ newOutFile, + "--precomp=" ++ buildDir lbi </> precompFile, + header, inDir </> inFile] + +getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] +getCppOptions bi lbi + = nub $ + ["-I" ++ dir | dir <- PD.includeDirs bi] + ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] + +installCHI :: PackageDescription -- ^information from the .cabal file + -> LocalBuildInfo -- ^information from the configure step + -> Verbosity -> CopyDest -- ^flags sent to copy or install + -> IO () +installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do + let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest + -- cannot use the recommended 'findModuleFiles' since it fails if there exists + -- a modules that does not have a .chi file + mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) + (map toFilePath +#if CABAL_VERSION_CHECK(1,8,0) + (PD.libModules lib) +#else + (PD.libModules pkg) +#endif + ) + let files = [ f | Just f <- mFiles ] +#if CABAL_VERSION_CHECK(1,8,0) + installOrdinaryFiles verbosity libPref files +#else + copyFiles verbosity libPref files +#endif + + [_$_] +installCHI _ _ _ _ = return () + +------------------------------------------------------------------------------ +-- Generating the type hierarchy and signal callback .hs files. +------------------------------------------------------------------------------ + +typeGenProgram :: Program +typeGenProgram = (simpleProgram "gtk2hsTypeGen") + +signalGenProgram :: Program +signalGenProgram = (simpleProgram "gtk2hsHookGenerator") + +c2hsLocal :: Program +c2hsLocal = (simpleProgram "gtk2hsC2hs") + +genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () +genSynthezisedFiles verb pd lbi = do + + cPkgs <- getPkgConfigPackages verb lbi pd + + let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) + ++customFieldsPD pd + typeOpts :: [ProgArg] + typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) + | (field,content) <- xList, + "x-types-" `isPrefixOf` field, + field /= "x-types-file"] + ++ [ "--tag=" ++ tag + | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs + , let name' = filter isAlpha (display name) + , tag <- name' + : [ name' ++ "-" ++ show major ++ "." ++ show digit + | digit <- [0,2..minor] ] + ] + + signalsOpts :: [ProgArg] + signalsOpts = concat [ map (\val -> '-':'-':drop 10 field++'=':val) (words content) + | (field,content) <- xList, + "x-signals-" `isPrefixOf` field, + field /= "x-signals-file"] + + genFile :: Program -> [ProgArg] -> FilePath -> IO () + genFile prog args outFile = do + res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args + rewriteFile outFile res + + case lookup "x-types-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") + genFile typeGenProgram typeOpts f + + case lookup "x-signals-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") + genFile signalGenProgram signalsOpts f + +--FIXME: Cabal should tell us the selected pkg-config package versions in the +-- LocalBuildInfo or equivalent. +-- In the mean time, ask pkg-config again. + +getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] +getPkgConfigPackages verbosity lbi pkg = + sequence + [ do version <- pkgconfig ["--modversion", display pkgname] + case simpleParse version of + Nothing -> die $ "parsing output of pkg-config --modversion failed" + Just v -> return (PackageIdentifier pkgname v) + | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] + where + pkgconfig = rawSystemProgramStdoutConf verbosity + pkgConfigProgram (withPrograms lbi) + +------------------------------------------------------------------------------ +-- Dependency calculation amongst .chs files. +------------------------------------------------------------------------------ + +-- Given all files of the package, find those that end in .chs and extract the +-- .chs files they depend upon. Then return the PackageDescription with these +-- files rearranged so that they are built in a sequence that files that are +-- needed by other files are built first. +fixDeps :: PackageDescription -> IO PackageDescription +fixDeps pd...@PD...ckageDescription { + PD.library = Just li...@PD...brary { + PD.exposedModules = expMods, + PD.libBuildInfo = bi@PD.BuildInfo { + PD.hsSourceDirs = srcDirs, + PD.otherModules = othMods + }}} = do + let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs + (joinPath (components m)) + mExpFiles <- mapM findModule expMods + mOthFiles <- mapM findModule othMods + + -- tag all exposed files with True so we throw an error if we need to build + -- an exposed module before an internal modules (we cannot express this) + let modDeps = zipWith (ModDep True []) expMods mExpFiles++ + zipWith (ModDep False []) othMods mOthFiles + modDeps <- mapM extractDeps modDeps + let (expMods, othMods) = span mdExposed $ sortTopological modDeps + badOther = map (fromMaybe "<no file>" . mdLocation) $ + filter (not . mdExposed) expMods + unless (null badOther) $ + die ("internal chs modules "++intercalate "," badOther++ + " depend on exposed chs modules; cabal needs to build internal modules first") + return pd { PD.library = Just lib { + PD.exposedModules = map mdOriginal expMods, + PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } + }} + +data ModDep = ModDep { + mdExposed :: Bool, + mdRequires :: [ModuleName], + mdOriginal :: ModuleName, + mdLocation :: Maybe FilePath +} + +instance Show ModDep where + show x = show (mdLocation x) + +instance Eq ModDep where + ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 +instance Ord ModDep where + compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 + +-- Extract the dependencies of this file. This is intentionally rather naive as it +-- ignores CPP conditionals. We just require everything which means that the +-- existance of a .chs module may not depend on some CPP condition. [_$_] +extractDeps :: ModDep -> IO ModDep +extractDeps md@ModDep { mdLocation = Nothing } = return md +extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do + let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of + ('i':'m':'p':'o':'r':'t':' ':ys) -> + case simpleParse (takeWhile ((/=) '#') ys) of + Just m -> findImports (m:acc) xxs [_$_] + Nothing -> die ("cannot parse chs import in "++f++":\n"++ + "offending line is {#"++xs) + -- no more imports after the first non-import hook + _ -> return acc + findImports acc (_:xxs) = findImports acc xxs + findImports acc [] = return acc + mods <- findImports [] (lines con) + return md { mdRequires = mods } + +-- Find a total order of the set of modules that are partially sorted by their +-- dependencies on each other. The function returns the sorted list of modules +-- together with a list of modules that are required but not supplied by this +-- in the input set of modules. +sortTopological :: [ModDep] -> [ModDep] +sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) + where + set = M.fromList (map (\m -> (mdOriginal m, m)) ms) + visit (out,visited) m + | m `S.member` visited = (out,visited) + | otherwise = case m `M.lookup` set of + Nothing -> (out, m `S.insert` visited) + Just md -> (md:out', visited') + where + (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) hunk ./gtkglext/Setup.hs 1 -{-# LANGUAGE CPP #-} +-- Setup file for a Gtk2Hs module. Contains only adjustments specific to this module, +-- all Gtk2Hs-specific boilerplate is stored in Gtk2HsSetup.hs which should be kept +-- identical across all modules. +import Gtk2HsSetup ( gtk2hsUserHooks ) +import Distribution.Simple ( defaultMainWithHooks ) hunk ./gtkglext/Setup.hs 7 -#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ - ((major) * 10000) \ - + ((minor) * 100) \ - + ((micro) * 1)) - -#define CABAL_VERSION_CHECK(major,minor,micro) \ - (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) - --- now, this is bad, but Cabal doesn't seem to actually pass any information about --- its version to CPP, so guess the version depending on the version of GHC -#ifdef CABAL_VERSION_MINOR -#ifndef CABAL_VERSION_MAJOR -#define CABAL_VERSION_MAJOR 1 -#endif -#ifndef CABAL_VERSION_MICRO -#define CABAL_VERSION_MICRO 0 -#endif -#define CABAL_VERSION CABAL_VERSION_ENCODE( \ - CABAL_VERSION_MAJOR, \ - CABAL_VERSION_MINOR, \ - CABAL_VERSION_MICRO) -#else -#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) -#if (__GLASGOW_HASKELL__ >= 612) -#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) -#else -#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) -#endif -#endif - --- | Build a Gtk2hs package. --- -import Distribution.Simple -import Distribution.Simple.PreProcess -import Distribution.InstalledPackageInfo ( importDirs ) -import Distribution.Simple.PackageIndex ( -#if CABAL_VERSION_CHECK(1,8,0) - lookupInstalledPackageId -#else - lookupPackageId -#endif - ) -import Distribution.PackageDescription as PD ( PackageDescription(..), - updatePackageDescription, - BuildInfo(..), - emptyBuildInfo, allBuildInfo, - Library(..), - libModules) -import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), - InstallDirs(..), -#if CABAL_VERSION_CHECK(1,8,0) - componentPackageDeps, -#else - packageDeps, -#endif - absoluteInstallDirs) -import Distribution.Simple.Compiler ( Compiler(..) ) -import Distribution.Simple.Program ( - Program(..), ConfiguredProgram(..), - rawSystemProgramConf, rawSystemProgramStdoutConf, - c2hsProgram, pkgConfigProgram, - simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) -import Distribution.ModuleName ( ModuleName, components, toFilePath ) -import Distribution.Simple.Utils -import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), - defaultCopyFlags, ConfigFlags(configVerbosity), - fromFlag, toFlag) -import Distribution.Simple.BuildPaths ( autogenModulesDir ) -import Distribution.Text ( simpleParse, display ) -import System.FilePath -import System.Directory ( doesFileExist ) -import Distribution.Version (Version(..)) -import Distribution.Verbosity -import Control.Monad (unless) -import Data.Maybe (fromMaybe) -import Data.List (isPrefixOf, nub) -import Data.Char (isAlpha) -import qualified Data.Map as M -import qualified Data.Set as S - - --- the name of the c2hs pre-compiled header file -precompFile = "precompchs.bin" - -main = defaultMainWithHooks simpleUserHooks { - hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], - hookedPreProcessors = [("chs", ourC2hs)], - confHook = \pd cf -> - confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, - postConf = \args cf pd lbi -> do - genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi - postConf simpleUserHooks args cf pd lbi, - buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> - (buildHook simpleUserHooks) pd lbi uh bf, - copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> - installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), - instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> - installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest - } - --- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later -adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo -adjustLocalBuildInfo lbi = - let extra = (Just libBi, []) - libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi - , buildDir lbi ] } - in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } - -ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor -ourC2hs bi lbi = PreProcessor { - platformIndependent = False, - runPreProcessor = runC2HS bi lbi -} - -runC2HS :: BuildInfo -> LocalBuildInfo -> - (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () -runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do - -- have the header file name if we don't have the precompiled header yet - header <- case lookup "x-c2hs-header" (customFieldsBI bi) of - Just h -> return h - Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ - "that sets the C header file to process .chs.pp files.") - - -- c2hs will output files in out dir, removing any leading path of the input file. - -- Thus, append the dir of the input file to the output dir. - let (outFileDir, newOutFile) = splitFileName outFile - let newOutDir = outDir </> outFileDir - -- additional .chi files might be needed that other packages have installed; - -- we assume that these are installed in the same place as .hi files - let chiDirs = [ dir | -#if CABAL_VERSION_CHECK(1,8,0) - ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), - dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] -#else - ipi <- packageDeps lbi, - dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] -#endif - rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ - map ("--include=" ++) (outDir:chiDirs) - ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] - ++ ["--output-dir=" ++ newOutDir, - "--output=" ++ newOutFile, - "--precomp=" ++ buildDir lbi </> precompFile, - header, inDir </> inFile] - -getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] -getCppOptions bi lbi - = nub $ - ["-I" ++ dir | dir <- PD.includeDirs bi] - ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] - -installCHI :: PackageDescription -- ^information from the .cabal file - -> LocalBuildInfo -- ^information from the configure step - -> Verbosity -> CopyDest -- ^flags sent to copy or install - -> IO () -installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do - let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest - -- cannot use the recommended 'findModuleFiles' since it fails if there exists - -- a modules that does not have a .chi file - mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) - (map toFilePath -#if CABAL_VERSION_CHECK(1,8,0) - (PD.libModules lib) -#else - (PD.libModules pkg) -#endif - ) - let files = [ f | Just f <- mFiles ] -#if CABAL_VERSION_CHECK(1,8,0) - installOrdinaryFiles verbosity libPref files -#else - copyFiles verbosity libPref files -#endif - - [_$_] -installCHI _ _ _ _ = return () - ------------------------------------------------------------------------------- --- Generating the type hierarchy and signal callback .hs files. ------------------------------------------------------------------------------- - -typeGenProgram :: Program -typeGenProgram = (simpleProgram "gtk2hsTypeGen") - -signalGenProgram :: Program -signalGenProgram = (simpleProgram "gtk2hsHookGenerator") - -c2hsLocal :: Program -c2hsLocal = (simpleProgram "gtk2hsC2hs") - -genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () -genSynthezisedFiles verb pd lbi = do - - cPkgs <- getPkgConfigPackages verb lbi pd - - let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) - ++customFieldsPD pd - typeOpts :: [ProgArg] - typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) - | (field,content) <- xList, - "x-types-" `isPrefixOf` field, - field /= "x-types-file"] - ++ [ "--tag=" ++ tag - | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs - , let name' = filter isAlpha (display name) - , tag <- name' - : [ name' ++ "-" ++ show major ++ "." ++ show digit - | digit <- [0,2..minor] ] - ] - - genFile :: Program -> [ProgArg] -> FilePath -> IO () - genFile prog args outFile = do - res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args - rewriteFile outFile res - - case lookup "x-types-file" xList of - Nothing -> return () - Just f -> do - info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") - genFile typeGenProgram typeOpts f - - case (lookup "x-signals-file" xList, - lookup "x-signals-modname" xList) of - (Just _, Nothing) -> die "You need to specify the module name (X-Signals-ModName) \ - \to generate a signal file." - (Just f, Just mod) -> do - info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") - genFile signalGenProgram [mod] f - (_,_) -> return () - ---FIXME: Cabal should tell us the selected pkg-config package versions in the --- LocalBuildInfo or equivalent. --- In the mean time, ask pkg-config again. - -getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] -getPkgConfigPackages verbosity lbi pkg = - sequence - [ do version <- pkgconfig ["--modversion", display pkgname] - case simpleParse version of - Nothing -> die $ "parsing output of pkg-config --modversion failed" - Just v -> return (PackageIdentifier pkgname v) - | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] - where - pkgconfig = rawSystemProgramStdoutConf verbosity - pkgConfigProgram (withPrograms lbi) - ------------------------------------------------------------------------------- --- Dependency calculation amongst .chs files. ------------------------------------------------------------------------------- - --- Given all files of the package, find those that end in .chs and extract the --- .chs files they depend upon. Then return the PackageDescription with these --- files rearranged so that they are built in a sequence that files that are --- needed by other files are built first. -fixDeps :: PackageDescription -> IO PackageDescription -fixDeps pd...@PD...ckageDescription { - PD.library = Just li...@PD...brary { - PD.exposedModules = expMods, - PD.libBuildInfo = bi@PD.BuildInfo { - PD.hsSourceDirs = srcDirs, - PD.otherModules = othMods - }}} = do - let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs - (joinPath (components m)) - mExpFiles <- mapM findModule expMods - mOthFiles <- mapM findModule othMods - - -- tag all exposed files with True so we throw an error if we need to build - -- an exposed module before an internal modules (we cannot express this) - let modDeps = zipWith (ModDep True []) expMods mExpFiles++ - zipWith (ModDep False []) othMods mOthFiles - modDeps <- mapM extractDeps modDeps - let (expMods, othMods) = span mdExposed $ sortTopological modDeps - badOther = map (fromMaybe "<no file>" . mdLocation) $ - filter (not . mdExposed) expMods - unless (null badOther) $ - die ("internal chs modules "++intercalate "," badOther++ - " depend on exposed chs modules; cabal needs to build internal modules first") - return pd { PD.library = Just lib { - PD.exposedModules = map mdOriginal expMods, - PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } - }} - -data ModDep = ModDep { - mdExposed :: Bool, - mdRequires :: [ModuleName], - mdOriginal :: ModuleName, - mdLocation :: Maybe FilePath -} - -instance Show ModDep where - show x = show (mdLocation x) - -instance Eq ModDep where - ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 -instance Ord ModDep where - compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 - --- Extract the dependencies of this file. This is intentionally rather naive as it --- ignores CPP conditionals. We just require everything which means that the --- existance of a .chs module may not depend on some CPP condition. [_$_] -extractDeps :: ModDep -> IO ModDep -extractDeps md@ModDep { mdLocation = Nothing } = return md -extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do - let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of - ('i':'m':'p':'o':'r':'t':' ':ys) -> - case simpleParse (takeWhile ((/=) '#') ys) of - Just m -> findImports (m:acc) xxs [_$_] - Nothing -> die ("cannot parse chs import in "++f++":\n"++ - "offending line is {#"++xs) - -- no more imports after the first non-import hook - _ -> return acc - findImports acc (_:xxs) = findImports acc xxs - findImports acc [] = return acc - mods <- findImports [] (lines con) - return md { mdRequires = mods } - --- Find a total order of the set of modules that are partially sorted by their --- dependencies on each other. The function returns the sorted list of modules --- together with a list of modules that are required but not supplied by this --- in the input set of modules. -sortTopological :: [ModDep] -> [ModDep] -sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) - where - set = M.fromList (map (\m -> (mdOriginal m, m)) ms) - visit (out,visited) m - | m `S.member` visited = (out,visited) - | otherwise = case m `M.lookup` set of - Nothing -> (out, m `S.insert` visited) - Just md -> (md:out', visited') - where - (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) +main = defaultMainWithHooks gtk2hsUserHooks |
From: Axel S. <si...@co...> - 2010-05-01 15:19:32
|
Sat May 1 10:46:08 EDT 2010 Axe...@in... * Replace Setup.hs by the default setup files. Ignore-this: 43ea6510fb65dfbb2e76130cb274a364 addfile ./glade/Gtk2HsSetup.hs hunk ./glade/Gtk2HsSetup.hs 1 +{-# LANGUAGE CPP #-} + +#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ + ((major) * 10000) \ + + ((minor) * 100) \ + + ((micro) * 1)) + +#define CABAL_VERSION_CHECK(major,minor,micro) \ + (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) + +-- now, this is bad, but Cabal doesn't seem to actually pass any information about +-- its version to CPP, so guess the version depending on the version of GHC +#ifdef CABAL_VERSION_MINOR +#ifndef CABAL_VERSION_MAJOR +#define CABAL_VERSION_MAJOR 1 +#endif +#ifndef CABAL_VERSION_MICRO +#define CABAL_VERSION_MICRO 0 +#endif +#define CABAL_VERSION CABAL_VERSION_ENCODE( \ + CABAL_VERSION_MAJOR, \ + CABAL_VERSION_MINOR, \ + CABAL_VERSION_MICRO) +#else +#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) +#if (__GLASGOW_HASKELL__ >= 612) +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) +#else +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) +#endif +#endif + +-- | Build a Gtk2hs package. +-- +module Gtk2HsSetup ( gtk2hsUserHooks, getPkgConfigPackages ) where + +import Distribution.Simple +import Distribution.Simple.PreProcess +import Distribution.InstalledPackageInfo ( importDirs ) +import Distribution.Simple.PackageIndex ( +#if CABAL_VERSION_CHECK(1,8,0) + lookupInstalledPackageId +#else + lookupPackageId +#endif + ) +import Distribution.PackageDescription as PD ( PackageDescription(..), + updatePackageDescription, + BuildInfo(..), + emptyBuildInfo, allBuildInfo, + Library(..), + libModules) +import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), + InstallDirs(..), +#if CABAL_VERSION_CHECK(1,8,0) + componentPackageDeps, +#else + packageDeps, +#endif + absoluteInstallDirs) +import Distribution.Simple.Compiler ( Compiler(..) ) +import Distribution.Simple.Program ( + Program(..), ConfiguredProgram(..), + rawSystemProgramConf, rawSystemProgramStdoutConf, + c2hsProgram, pkgConfigProgram, + simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) +import Distribution.ModuleName ( ModuleName, components, toFilePath ) +import Distribution.Simple.Utils +import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), + defaultCopyFlags, ConfigFlags(configVerbosity), + fromFlag, toFlag) +import Distribution.Simple.BuildPaths ( autogenModulesDir ) +import Distribution.Text ( simpleParse, display ) +import System.FilePath +import System.Directory ( doesFileExist ) +import Distribution.Version (Version(..)) +import Distribution.Verbosity +import Control.Monad (unless) +import Data.Maybe (fromMaybe) +import Data.List (isPrefixOf, nub) +import Data.Char (isAlpha) +import qualified Data.Map as M +import qualified Data.Set as S + + +-- the name of the c2hs pre-compiled header file +precompFile = "precompchs.bin" + +gtk2hsUserHooks = simpleUserHooks { + hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], + hookedPreProcessors = [("chs", ourC2hs)], + confHook = \pd cf -> + confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, + postConf = \args cf pd lbi -> do + genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi + postConf simpleUserHooks args cf pd lbi, + buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> + (buildHook simpleUserHooks) pd lbi uh bf, + copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), + instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest + } + +-- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later +adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo +adjustLocalBuildInfo lbi = + let extra = (Just libBi, []) + libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi + , buildDir lbi ] } + in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } + +ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor +ourC2hs bi lbi = PreProcessor { + platformIndependent = False, + runPreProcessor = runC2HS bi lbi +} + +runC2HS :: BuildInfo -> LocalBuildInfo -> + (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () +runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do + -- have the header file name if we don't have the precompiled header yet + header <- case lookup "x-c2hs-header" (customFieldsBI bi) of + Just h -> return h + Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ + "that sets the C header file to process .chs.pp files.") + + -- c2hs will output files in out dir, removing any leading path of the input file. + -- Thus, append the dir of the input file to the output dir. + let (outFileDir, newOutFile) = splitFileName outFile + let newOutDir = outDir </> outFileDir + -- additional .chi files might be needed that other packages have installed; + -- we assume that these are installed in the same place as .hi files + let chiDirs = [ dir | +#if CABAL_VERSION_CHECK(1,8,0) + ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), + dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] +#else + ipi <- packageDeps lbi, + dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] +#endif + rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ + map ("--include=" ++) (outDir:chiDirs) + ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] + ++ ["--output-dir=" ++ newOutDir, + "--output=" ++ newOutFile, + "--precomp=" ++ buildDir lbi </> precompFile, + header, inDir </> inFile] + +getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] +getCppOptions bi lbi + = nub $ + ["-I" ++ dir | dir <- PD.includeDirs bi] + ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] + +installCHI :: PackageDescription -- ^information from the .cabal file + -> LocalBuildInfo -- ^information from the configure step + -> Verbosity -> CopyDest -- ^flags sent to copy or install + -> IO () +installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do + let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest + -- cannot use the recommended 'findModuleFiles' since it fails if there exists + -- a modules that does not have a .chi file + mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) + (map toFilePath +#if CABAL_VERSION_CHECK(1,8,0) + (PD.libModules lib) +#else + (PD.libModules pkg) +#endif + ) + let files = [ f | Just f <- mFiles ] +#if CABAL_VERSION_CHECK(1,8,0) + installOrdinaryFiles verbosity libPref files +#else + copyFiles verbosity libPref files +#endif + + [_$_] +installCHI _ _ _ _ = return () + +------------------------------------------------------------------------------ +-- Generating the type hierarchy and signal callback .hs files. +------------------------------------------------------------------------------ + +typeGenProgram :: Program +typeGenProgram = (simpleProgram "gtk2hsTypeGen") + +signalGenProgram :: Program +signalGenProgram = (simpleProgram "gtk2hsHookGenerator") + +c2hsLocal :: Program +c2hsLocal = (simpleProgram "gtk2hsC2hs") + +genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () +genSynthezisedFiles verb pd lbi = do + + cPkgs <- getPkgConfigPackages verb lbi pd + + let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) + ++customFieldsPD pd + typeOpts :: [ProgArg] + typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) + | (field,content) <- xList, + "x-types-" `isPrefixOf` field, + field /= "x-types-file"] + ++ [ "--tag=" ++ tag + | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs + , let name' = filter isAlpha (display name) + , tag <- name' + : [ name' ++ "-" ++ show major ++ "." ++ show digit + | digit <- [0,2..minor] ] + ] + + signalsOpts :: [ProgArg] + signalsOpts = concat [ map (\val -> '-':'-':drop 10 field++'=':val) (words content) + | (field,content) <- xList, + "x-signals-" `isPrefixOf` field, + field /= "x-signals-file"] + + genFile :: Program -> [ProgArg] -> FilePath -> IO () + genFile prog args outFile = do + res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args + rewriteFile outFile res + + case lookup "x-types-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") + genFile typeGenProgram typeOpts f + + case lookup "x-signals-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") + genFile signalGenProgram signalsOpts f + +--FIXME: Cabal should tell us the selected pkg-config package versions in the +-- LocalBuildInfo or equivalent. +-- In the mean time, ask pkg-config again. + +getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] +getPkgConfigPackages verbosity lbi pkg = + sequence + [ do version <- pkgconfig ["--modversion", display pkgname] + case simpleParse version of + Nothing -> die $ "parsing output of pkg-config --modversion failed" + Just v -> return (PackageIdentifier pkgname v) + | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] + where + pkgconfig = rawSystemProgramStdoutConf verbosity + pkgConfigProgram (withPrograms lbi) + +------------------------------------------------------------------------------ +-- Dependency calculation amongst .chs files. +------------------------------------------------------------------------------ + +-- Given all files of the package, find those that end in .chs and extract the +-- .chs files they depend upon. Then return the PackageDescription with these +-- files rearranged so that they are built in a sequence that files that are +-- needed by other files are built first. +fixDeps :: PackageDescription -> IO PackageDescription +fixDeps pd...@PD...ckageDescription { + PD.library = Just li...@PD...brary { + PD.exposedModules = expMods, + PD.libBuildInfo = bi@PD.BuildInfo { + PD.hsSourceDirs = srcDirs, + PD.otherModules = othMods + }}} = do + let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs + (joinPath (components m)) + mExpFiles <- mapM findModule expMods + mOthFiles <- mapM findModule othMods + + -- tag all exposed files with True so we throw an error if we need to build + -- an exposed module before an internal modules (we cannot express this) + let modDeps = zipWith (ModDep True []) expMods mExpFiles++ + zipWith (ModDep False []) othMods mOthFiles + modDeps <- mapM extractDeps modDeps + let (expMods, othMods) = span mdExposed $ sortTopological modDeps + badOther = map (fromMaybe "<no file>" . mdLocation) $ + filter (not . mdExposed) expMods + unless (null badOther) $ + die ("internal chs modules "++intercalate "," badOther++ + " depend on exposed chs modules; cabal needs to build internal modules first") + return pd { PD.library = Just lib { + PD.exposedModules = map mdOriginal expMods, + PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } + }} + +data ModDep = ModDep { + mdExposed :: Bool, + mdRequires :: [ModuleName], + mdOriginal :: ModuleName, + mdLocation :: Maybe FilePath +} + +instance Show ModDep where + show x = show (mdLocation x) + +instance Eq ModDep where + ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 +instance Ord ModDep where + compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 + +-- Extract the dependencies of this file. This is intentionally rather naive as it +-- ignores CPP conditionals. We just require everything which means that the +-- existance of a .chs module may not depend on some CPP condition. [_$_] +extractDeps :: ModDep -> IO ModDep +extractDeps md@ModDep { mdLocation = Nothing } = return md +extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do + let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of + ('i':'m':'p':'o':'r':'t':' ':ys) -> + case simpleParse (takeWhile ((/=) '#') ys) of + Just m -> findImports (m:acc) xxs [_$_] + Nothing -> die ("cannot parse chs import in "++f++":\n"++ + "offending line is {#"++xs) + -- no more imports after the first non-import hook + _ -> return acc + findImports acc (_:xxs) = findImports acc xxs + findImports acc [] = return acc + mods <- findImports [] (lines con) + return md { mdRequires = mods } + +-- Find a total order of the set of modules that are partially sorted by their +-- dependencies on each other. The function returns the sorted list of modules +-- together with a list of modules that are required but not supplied by this +-- in the input set of modules. +sortTopological :: [ModDep] -> [ModDep] +sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) + where + set = M.fromList (map (\m -> (mdOriginal m, m)) ms) + visit (out,visited) m + | m `S.member` visited = (out,visited) + | otherwise = case m `M.lookup` set of + Nothing -> (out, m `S.insert` visited) + Just md -> (md:out', visited') + where + (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) hunk ./glade/Setup.hs 1 -{-# LANGUAGE CPP #-} +-- Setup file for a Gtk2Hs module. Contains only adjustments specific to this module, +-- all Gtk2Hs-specific boilerplate is stored in Gtk2HsSetup.hs which should be kept +-- identical across all modules. +import Gtk2HsSetup ( gtk2hsUserHooks ) +import Distribution.Simple ( defaultMainWithHooks ) hunk ./glade/Setup.hs 7 -#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ - ((major) * 10000) \ - + ((minor) * 100) \ - + ((micro) * 1)) - -#define CABAL_VERSION_CHECK(major,minor,micro) \ - (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) - --- now, this is bad, but Cabal doesn't seem to actually pass any information about --- its version to CPP, so guess the version depending on the version of GHC -#ifdef CABAL_VERSION_MINOR -#ifndef CABAL_VERSION_MAJOR -#define CABAL_VERSION_MAJOR 1 -#endif -#ifndef CABAL_VERSION_MICRO -#define CABAL_VERSION_MICRO 0 -#endif -#define CABAL_VERSION CABAL_VERSION_ENCODE( \ - CABAL_VERSION_MAJOR, \ - CABAL_VERSION_MINOR, \ - CABAL_VERSION_MICRO) -#else -#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) -#if (__GLASGOW_HASKELL__ >= 612) -#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) -#else -#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) -#endif -#endif - --- | Build a Gtk2hs package. --- -import Distribution.Simple -import Distribution.Simple.PreProcess -import Distribution.InstalledPackageInfo ( importDirs ) -import Distribution.Simple.PackageIndex ( -#if CABAL_VERSION_CHECK(1,8,0) - lookupInstalledPackageId -#else - lookupPackageId -#endif - ) -import Distribution.PackageDescription as PD ( PackageDescription(..), - updatePackageDescription, - BuildInfo(..), - emptyBuildInfo, allBuildInfo, - Library(..), - libModules) -import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), - InstallDirs(..), -#if CABAL_VERSION_CHECK(1,8,0) - componentPackageDeps, -#else - packageDeps, -#endif - absoluteInstallDirs) -import Distribution.Simple.Compiler ( Compiler(..) ) -import Distribution.Simple.Program ( - Program(..), ConfiguredProgram(..), - rawSystemProgramConf, rawSystemProgramStdoutConf, - c2hsProgram, pkgConfigProgram, - simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) -import Distribution.ModuleName ( ModuleName, components, toFilePath ) -import Distribution.Simple.Utils -import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), - defaultCopyFlags, ConfigFlags(configVerbosity), - fromFlag, toFlag) -import Distribution.Simple.BuildPaths ( autogenModulesDir ) -import Distribution.Text ( simpleParse, display ) -import System.FilePath -import System.Directory ( doesFileExist ) -import Distribution.Version (Version(..)) -import Distribution.Verbosity -import Control.Monad (unless) -import Data.Maybe (fromMaybe) -import Data.List (isPrefixOf, nub) -import Data.Char (isAlpha) -import qualified Data.Map as M -import qualified Data.Set as S - - --- the name of the c2hs pre-compiled header file -precompFile = "precompchs.bin" - -main = defaultMainWithHooks simpleUserHooks { - hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], - hookedPreProcessors = [("chs", ourC2hs)], - confHook = \pd cf -> - confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, - postConf = \args cf pd lbi -> do - genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi - postConf simpleUserHooks args cf pd lbi, - buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> - (buildHook simpleUserHooks) pd lbi uh bf, - copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> - installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), - instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> - installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest - } - --- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later -adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo -adjustLocalBuildInfo lbi = - let extra = (Just libBi, []) - libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi - , buildDir lbi ] } - in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } - -ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor -ourC2hs bi lbi = PreProcessor { - platformIndependent = False, - runPreProcessor = runC2HS bi lbi -} - -runC2HS :: BuildInfo -> LocalBuildInfo -> - (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () -runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do - -- have the header file name if we don't have the precompiled header yet - header <- case lookup "x-c2hs-header" (customFieldsBI bi) of - Just h -> return h - Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ - "that sets the C header file to process .chs.pp files.") - - -- c2hs will output files in out dir, removing any leading path of the input file. - -- Thus, append the dir of the input file to the output dir. - let (outFileDir, newOutFile) = splitFileName outFile - let newOutDir = outDir </> outFileDir - -- additional .chi files might be needed that other packages have installed; - -- we assume that these are installed in the same place as .hi files - let chiDirs = [ dir | -#if CABAL_VERSION_CHECK(1,8,0) - ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), - dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] -#else - ipi <- packageDeps lbi, - dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] -#endif - rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ - map ("--include=" ++) (outDir:chiDirs) - ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] - ++ ["--output-dir=" ++ newOutDir, - "--output=" ++ newOutFile, - "--precomp=" ++ buildDir lbi </> precompFile, - header, inDir </> inFile] - -getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] -getCppOptions bi lbi - = nub $ - ["-I" ++ dir | dir <- PD.includeDirs bi] - ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] - -installCHI :: PackageDescription -- ^information from the .cabal file - -> LocalBuildInfo -- ^information from the configure step - -> Verbosity -> CopyDest -- ^flags sent to copy or install - -> IO () -installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do - let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest - -- cannot use the recommended 'findModuleFiles' since it fails if there exists - -- a modules that does not have a .chi file - mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) - (map toFilePath -#if CABAL_VERSION_CHECK(1,8,0) - (PD.libModules lib) -#else - (PD.libModules pkg) -#endif - ) - let files = [ f | Just f <- mFiles ] -#if CABAL_VERSION_CHECK(1,8,0) - installOrdinaryFiles verbosity libPref files -#else - copyFiles verbosity libPref files -#endif - - [_$_] -installCHI _ _ _ _ = return () - ------------------------------------------------------------------------------- --- Generating the type hierarchy and signal callback .hs files. ------------------------------------------------------------------------------- - -typeGenProgram :: Program -typeGenProgram = (simpleProgram "gtk2hsTypeGen") - -signalGenProgram :: Program -signalGenProgram = (simpleProgram "gtk2hsHookGenerator") - -c2hsLocal :: Program -c2hsLocal = (simpleProgram "gtk2hsC2hs") - -genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () -genSynthezisedFiles verb pd lbi = do - - cPkgs <- getPkgConfigPackages verb lbi pd - - let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) - ++customFieldsPD pd - typeOpts :: [ProgArg] - typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) - | (field,content) <- xList, - "x-types-" `isPrefixOf` field, - field /= "x-types-file"] - ++ [ "--tag=" ++ tag - | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs - , let name' = filter isAlpha (display name) - , tag <- name' - : [ name' ++ "-" ++ show major ++ "." ++ show digit - | digit <- [0,2..minor] ] - ] - - genFile :: Program -> [ProgArg] -> FilePath -> IO () - genFile prog args outFile = do - res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args - rewriteFile outFile res - - case lookup "x-types-file" xList of - Nothing -> return () - Just f -> do - info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") - genFile typeGenProgram typeOpts f - - case (lookup "x-signals-file" xList, - lookup "x-signals-modname" xList) of - (Just _, Nothing) -> die "You need to specify the module name (X-Signals-ModName) \ - \to generate a signal file." - (Just f, Just mod) -> do - info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") - genFile signalGenProgram [mod] f - (_,_) -> return () - ---FIXME: Cabal should tell us the selected pkg-config package versions in the --- LocalBuildInfo or equivalent. --- In the mean time, ask pkg-config again. - -getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] -getPkgConfigPackages verbosity lbi pkg = - sequence - [ do version <- pkgconfig ["--modversion", display pkgname] - case simpleParse version of - Nothing -> die $ "parsing output of pkg-config --modversion failed" - Just v -> return (PackageIdentifier pkgname v) - | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] - where - pkgconfig = rawSystemProgramStdoutConf verbosity - pkgConfigProgram (withPrograms lbi) - ------------------------------------------------------------------------------- --- Dependency calculation amongst .chs files. ------------------------------------------------------------------------------- - --- Given all files of the package, find those that end in .chs and extract the --- .chs files they depend upon. Then return the PackageDescription with these --- files rearranged so that they are built in a sequence that files that are --- needed by other files are built first. -fixDeps :: PackageDescription -> IO PackageDescription -fixDeps pd...@PD...ckageDescription { - PD.library = Just li...@PD...brary { - PD.exposedModules = expMods, - PD.libBuildInfo = bi@PD.BuildInfo { - PD.hsSourceDirs = srcDirs, - PD.otherModules = othMods - }}} = do - let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs - (joinPath (components m)) - mExpFiles <- mapM findModule expMods - mOthFiles <- mapM findModule othMods - - -- tag all exposed files with True so we throw an error if we need to build - -- an exposed module before an internal modules (we cannot express this) - let modDeps = zipWith (ModDep True []) expMods mExpFiles++ - zipWith (ModDep False []) othMods mOthFiles - modDeps <- mapM extractDeps modDeps - let (expMods, othMods) = span mdExposed $ sortTopological modDeps - badOther = map (fromMaybe "<no file>" . mdLocation) $ - filter (not . mdExposed) expMods - unless (null badOther) $ - die ("internal chs modules "++intercalate "," badOther++ - " depend on exposed chs modules; cabal needs to build internal modules first") - return pd { PD.library = Just lib { - PD.exposedModules = map mdOriginal expMods, - PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } - }} - -data ModDep = ModDep { - mdExposed :: Bool, - mdRequires :: [ModuleName], - mdOriginal :: ModuleName, - mdLocation :: Maybe FilePath -} - -instance Show ModDep where - show x = show (mdLocation x) - -instance Eq ModDep where - ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 -instance Ord ModDep where - compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 - --- Extract the dependencies of this file. This is intentionally rather naive as it --- ignores CPP conditionals. We just require everything which means that the --- existance of a .chs module may not depend on some CPP condition. [_$_] -extractDeps :: ModDep -> IO ModDep -extractDeps md@ModDep { mdLocation = Nothing } = return md -extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do - let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of - ('i':'m':'p':'o':'r':'t':' ':ys) -> - case simpleParse (takeWhile ((/=) '#') ys) of - Just m -> findImports (m:acc) xxs [_$_] - Nothing -> die ("cannot parse chs import in "++f++":\n"++ - "offending line is {#"++xs) - -- no more imports after the first non-import hook - _ -> return acc - findImports acc (_:xxs) = findImports acc xxs - findImports acc [] = return acc - mods <- findImports [] (lines con) - return md { mdRequires = mods } - --- Find a total order of the set of modules that are partially sorted by their --- dependencies on each other. The function returns the sorted list of modules --- together with a list of modules that are required but not supplied by this --- in the input set of modules. -sortTopological :: [ModDep] -> [ModDep] -sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) - where - set = M.fromList (map (\m -> (mdOriginal m, m)) ms) - visit (out,visited) m - | m `S.member` visited = (out,visited) - | otherwise = case m `M.lookup` set of - Nothing -> (out, m `S.insert` visited) - Just md -> (md:out', visited') - where - (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) +main = defaultMainWithHooks gtk2hsUserHooks |
From: Axel S. <si...@co...> - 2010-05-01 15:19:31
|
Sat May 1 10:34:02 EDT 2010 Axe...@in... * Fix the build infrastructure of gconf. Ignore-this: c0f1e1e066e9a7f9f733a4b768d9196d addfile ./gconf/Gtk2HsSetup.hs hunk ./gconf/Gtk2HsSetup.hs 1 +{-# LANGUAGE CPP #-} + +#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ + ((major) * 10000) \ + + ((minor) * 100) \ + + ((micro) * 1)) + +#define CABAL_VERSION_CHECK(major,minor,micro) \ + (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) + +-- now, this is bad, but Cabal doesn't seem to actually pass any information about +-- its version to CPP, so guess the version depending on the version of GHC +#ifdef CABAL_VERSION_MINOR +#ifndef CABAL_VERSION_MAJOR +#define CABAL_VERSION_MAJOR 1 +#endif +#ifndef CABAL_VERSION_MICRO +#define CABAL_VERSION_MICRO 0 +#endif +#define CABAL_VERSION CABAL_VERSION_ENCODE( \ + CABAL_VERSION_MAJOR, \ + CABAL_VERSION_MINOR, \ + CABAL_VERSION_MICRO) +#else +#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) +#if (__GLASGOW_HASKELL__ >= 612) +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) +#else +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) +#endif +#endif + +-- | Build a Gtk2hs package. +-- +module Gtk2HsSetup ( gtk2hsUserHooks, getPkgConfigPackages ) where + +import Distribution.Simple +import Distribution.Simple.PreProcess +import Distribution.InstalledPackageInfo ( importDirs ) +import Distribution.Simple.PackageIndex ( +#if CABAL_VERSION_CHECK(1,8,0) + lookupInstalledPackageId +#else + lookupPackageId +#endif + ) +import Distribution.PackageDescription as PD ( PackageDescription(..), + updatePackageDescription, + BuildInfo(..), + emptyBuildInfo, allBuildInfo, + Library(..), + libModules) +import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), + InstallDirs(..), +#if CABAL_VERSION_CHECK(1,8,0) + componentPackageDeps, +#else + packageDeps, +#endif + absoluteInstallDirs) +import Distribution.Simple.Compiler ( Compiler(..) ) +import Distribution.Simple.Program ( + Program(..), ConfiguredProgram(..), + rawSystemProgramConf, rawSystemProgramStdoutConf, + c2hsProgram, pkgConfigProgram, + simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) +import Distribution.ModuleName ( ModuleName, components, toFilePath ) +import Distribution.Simple.Utils +import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), + defaultCopyFlags, ConfigFlags(configVerbosity), + fromFlag, toFlag) +import Distribution.Simple.BuildPaths ( autogenModulesDir ) +import Distribution.Text ( simpleParse, display ) +import System.FilePath +import System.Directory ( doesFileExist ) +import Distribution.Version (Version(..)) +import Distribution.Verbosity +import Control.Monad (unless) +import Data.Maybe (fromMaybe) +import Data.List (isPrefixOf, nub) +import Data.Char (isAlpha) +import qualified Data.Map as M +import qualified Data.Set as S + + +-- the name of the c2hs pre-compiled header file +precompFile = "precompchs.bin" + +gtk2hsUserHooks = simpleUserHooks { + hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], + hookedPreProcessors = [("chs", ourC2hs)], + confHook = \pd cf -> + confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, + postConf = \args cf pd lbi -> do + genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi + postConf simpleUserHooks args cf pd lbi, + buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> + (buildHook simpleUserHooks) pd lbi uh bf, + copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), + instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest + } + +-- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later +adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo +adjustLocalBuildInfo lbi = + let extra = (Just libBi, []) + libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi + , buildDir lbi ] } + in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } + +ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor +ourC2hs bi lbi = PreProcessor { + platformIndependent = False, + runPreProcessor = runC2HS bi lbi +} + +runC2HS :: BuildInfo -> LocalBuildInfo -> + (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () +runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do + -- have the header file name if we don't have the precompiled header yet + header <- case lookup "x-c2hs-header" (customFieldsBI bi) of + Just h -> return h + Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ + "that sets the C header file to process .chs.pp files.") + + -- c2hs will output files in out dir, removing any leading path of the input file. + -- Thus, append the dir of the input file to the output dir. + let (outFileDir, newOutFile) = splitFileName outFile + let newOutDir = outDir </> outFileDir + -- additional .chi files might be needed that other packages have installed; + -- we assume that these are installed in the same place as .hi files + let chiDirs = [ dir | +#if CABAL_VERSION_CHECK(1,8,0) + ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), + dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] +#else + ipi <- packageDeps lbi, + dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] +#endif + rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ + map ("--include=" ++) (outDir:chiDirs) + ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] + ++ ["--output-dir=" ++ newOutDir, + "--output=" ++ newOutFile, + "--precomp=" ++ buildDir lbi </> precompFile, + header, inDir </> inFile] + +getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] +getCppOptions bi lbi + = nub $ + ["-I" ++ dir | dir <- PD.includeDirs bi] + ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] + +installCHI :: PackageDescription -- ^information from the .cabal file + -> LocalBuildInfo -- ^information from the configure step + -> Verbosity -> CopyDest -- ^flags sent to copy or install + -> IO () +installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do + let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest + -- cannot use the recommended 'findModuleFiles' since it fails if there exists + -- a modules that does not have a .chi file + mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) + (map toFilePath +#if CABAL_VERSION_CHECK(1,8,0) + (PD.libModules lib) +#else + (PD.libModules pkg) +#endif + ) + let files = [ f | Just f <- mFiles ] +#if CABAL_VERSION_CHECK(1,8,0) + installOrdinaryFiles verbosity libPref files +#else + copyFiles verbosity libPref files +#endif + + [_$_] +installCHI _ _ _ _ = return () + +------------------------------------------------------------------------------ +-- Generating the type hierarchy and signal callback .hs files. +------------------------------------------------------------------------------ + +typeGenProgram :: Program +typeGenProgram = (simpleProgram "gtk2hsTypeGen") + +signalGenProgram :: Program +signalGenProgram = (simpleProgram "gtk2hsHookGenerator") + +c2hsLocal :: Program +c2hsLocal = (simpleProgram "gtk2hsC2hs") + +genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () +genSynthezisedFiles verb pd lbi = do + + cPkgs <- getPkgConfigPackages verb lbi pd + + let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) + ++customFieldsPD pd + typeOpts :: [ProgArg] + typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) + | (field,content) <- xList, + "x-types-" `isPrefixOf` field, + field /= "x-types-file"] + ++ [ "--tag=" ++ tag + | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs + , let name' = filter isAlpha (display name) + , tag <- name' + : [ name' ++ "-" ++ show major ++ "." ++ show digit + | digit <- [0,2..minor] ] + ] + + signalsOpts :: [ProgArg] + signalsOpts = concat [ map (\val -> '-':'-':drop 10 field++'=':val) (words content) + | (field,content) <- xList, + "x-signals-" `isPrefixOf` field, + field /= "x-signals-file"] + + genFile :: Program -> [ProgArg] -> FilePath -> IO () + genFile prog args outFile = do + res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args + rewriteFile outFile res + + case lookup "x-types-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") + genFile typeGenProgram typeOpts f + + case lookup "x-signals-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") + genFile signalGenProgram signalsOpts f + +--FIXME: Cabal should tell us the selected pkg-config package versions in the +-- LocalBuildInfo or equivalent. +-- In the mean time, ask pkg-config again. + +getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] +getPkgConfigPackages verbosity lbi pkg = + sequence + [ do version <- pkgconfig ["--modversion", display pkgname] + case simpleParse version of + Nothing -> die $ "parsing output of pkg-config --modversion failed" + Just v -> return (PackageIdentifier pkgname v) + | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] + where + pkgconfig = rawSystemProgramStdoutConf verbosity + pkgConfigProgram (withPrograms lbi) + +------------------------------------------------------------------------------ +-- Dependency calculation amongst .chs files. +------------------------------------------------------------------------------ + +-- Given all files of the package, find those that end in .chs and extract the +-- .chs files they depend upon. Then return the PackageDescription with these +-- files rearranged so that they are built in a sequence that files that are +-- needed by other files are built first. +fixDeps :: PackageDescription -> IO PackageDescription +fixDeps pd...@PD...ckageDescription { + PD.library = Just li...@PD...brary { + PD.exposedModules = expMods, + PD.libBuildInfo = bi@PD.BuildInfo { + PD.hsSourceDirs = srcDirs, + PD.otherModules = othMods + }}} = do + let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs + (joinPath (components m)) + mExpFiles <- mapM findModule expMods + mOthFiles <- mapM findModule othMods + + -- tag all exposed files with True so we throw an error if we need to build + -- an exposed module before an internal modules (we cannot express this) + let modDeps = zipWith (ModDep True []) expMods mExpFiles++ + zipWith (ModDep False []) othMods mOthFiles + modDeps <- mapM extractDeps modDeps + let (expMods, othMods) = span mdExposed $ sortTopological modDeps + badOther = map (fromMaybe "<no file>" . mdLocation) $ + filter (not . mdExposed) expMods + unless (null badOther) $ + die ("internal chs modules "++intercalate "," badOther++ + " depend on exposed chs modules; cabal needs to build internal modules first") + return pd { PD.library = Just lib { + PD.exposedModules = map mdOriginal expMods, + PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } + }} + +data ModDep = ModDep { + mdExposed :: Bool, + mdRequires :: [ModuleName], + mdOriginal :: ModuleName, + mdLocation :: Maybe FilePath +} + +instance Show ModDep where + show x = show (mdLocation x) + +instance Eq ModDep where + ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 +instance Ord ModDep where + compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 + +-- Extract the dependencies of this file. This is intentionally rather naive as it +-- ignores CPP conditionals. We just require everything which means that the +-- existance of a .chs module may not depend on some CPP condition. [_$_] +extractDeps :: ModDep -> IO ModDep +extractDeps md@ModDep { mdLocation = Nothing } = return md +extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do + let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of + ('i':'m':'p':'o':'r':'t':' ':ys) -> + case simpleParse (takeWhile ((/=) '#') ys) of + Just m -> findImports (m:acc) xxs [_$_] + Nothing -> die ("cannot parse chs import in "++f++":\n"++ + "offending line is {#"++xs) + -- no more imports after the first non-import hook + _ -> return acc + findImports acc (_:xxs) = findImports acc xxs + findImports acc [] = return acc + mods <- findImports [] (lines con) + return md { mdRequires = mods } + +-- Find a total order of the set of modules that are partially sorted by their +-- dependencies on each other. The function returns the sorted list of modules +-- together with a list of modules that are required but not supplied by this +-- in the input set of modules. +sortTopological :: [ModDep] -> [ModDep] +sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) + where + set = M.fromList (map (\m -> (mdOriginal m, m)) ms) + visit (out,visited) m + | m `S.member` visited = (out,visited) + | otherwise = case m `M.lookup` set of + Nothing -> (out, m `S.insert` visited) + Just md -> (md:out', visited') + where + (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) hunk ./gconf/Setup.hs 1 -{-# LANGUAGE CPP #-} +-- Setup file for a Gtk2Hs module. Contains only adjustments specific to this module, +-- all Gtk2Hs-specific boilerplate is stored in Gtk2HsSetup.hs which should be kept +-- identical across all modules. +import Gtk2HsSetup ( gtk2hsUserHooks ) +import Distribution.Simple ( defaultMainWithHooks ) hunk ./gconf/Setup.hs 7 -#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ - ((major) * 10000) \ - + ((minor) * 100) \ - + ((micro) * 1)) - -#define CABAL_VERSION_CHECK(major,minor,micro) \ - (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) - --- now, this is bad, but Cabal doesn't seem to actually pass any information about --- its version to CPP, so guess the version depending on the version of GHC -#ifdef CABAL_VERSION_MINOR -#ifndef CABAL_VERSION_MAJOR -#define CABAL_VERSION_MAJOR 1 -#endif -#ifndef CABAL_VERSION_MICRO -#define CABAL_VERSION_MICRO 0 -#endif -#define CABAL_VERSION CABAL_VERSION_ENCODE( \ - CABAL_VERSION_MAJOR, \ - CABAL_VERSION_MINOR, \ - CABAL_VERSION_MICRO) -#else -#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) -#if (__GLASGOW_HASKELL__ >= 612) -#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) -#else -#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) -#endif -#endif - --- | Build a Gtk2hs package. --- -import Distribution.Simple -import Distribution.Simple.PreProcess -import Distribution.InstalledPackageInfo ( importDirs ) -import Distribution.Simple.PackageIndex ( -#if CABAL_VERSION_CHECK(1,8,0) - lookupInstalledPackageId -#else - lookupPackageId -#endif - ) -import Distribution.PackageDescription as PD ( PackageDescription(..), - updatePackageDescription, - BuildInfo(..), - emptyBuildInfo, allBuildInfo, - Library(..), - libModules) -import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), - InstallDirs(..), -#if CABAL_VERSION_CHECK(1,8,0) - componentPackageDeps, -#else - packageDeps, -#endif - absoluteInstallDirs) -import Distribution.Simple.Compiler ( Compiler(..) ) -import Distribution.Simple.Program ( - Program(..), ConfiguredProgram(..), - rawSystemProgramConf, rawSystemProgramStdoutConf, - c2hsProgram, pkgConfigProgram, - simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) -import Distribution.ModuleName ( ModuleName, components, toFilePath ) -import Distribution.Simple.Utils -import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), - defaultCopyFlags, ConfigFlags(configVerbosity), - fromFlag, toFlag) -import Distribution.Simple.BuildPaths ( autogenModulesDir ) -import Distribution.Text ( simpleParse, display ) -import System.FilePath -import System.Directory ( doesFileExist ) -import Distribution.Version (Version(..)) -import Distribution.Verbosity -import Control.Monad (unless) -import Data.Maybe (fromMaybe) -import Data.List (isPrefixOf, nub) -import Data.Char (isAlpha) -import qualified Data.Map as M -import qualified Data.Set as S - - --- the name of the c2hs pre-compiled header file -precompFile = "precompchs.bin" - -main = defaultMainWithHooks simpleUserHooks { - hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], - hookedPreProcessors = [("chs", ourC2hs)], - confHook = \pd cf -> - confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, - postConf = \args cf pd lbi -> do - genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi - postConf simpleUserHooks args cf pd lbi, - buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> - (buildHook simpleUserHooks) pd lbi uh bf, - copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> - installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), - instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> - installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest - } - --- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later -adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo -adjustLocalBuildInfo lbi = - let extra = (Just libBi, []) - libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi - , buildDir lbi ] } - in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } - -ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor -ourC2hs bi lbi = PreProcessor { - platformIndependent = False, - runPreProcessor = runC2HS bi lbi -} - -runC2HS :: BuildInfo -> LocalBuildInfo -> - (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () -runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do - -- have the header file name if we don't have the precompiled header yet - header <- case lookup "x-c2hs-header" (customFieldsBI bi) of - Just h -> return h - Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ - "that sets the C header file to process .chs.pp files.") - - -- c2hs will output files in out dir, removing any leading path of the input file. - -- Thus, append the dir of the input file to the output dir. - let (outFileDir, newOutFile) = splitFileName outFile - let newOutDir = outDir </> outFileDir - -- additional .chi files might be needed that other packages have installed; - -- we assume that these are installed in the same place as .hi files - let chiDirs = [ dir | -#if CABAL_VERSION_CHECK(1,8,0) - ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), - dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] -#else - ipi <- packageDeps lbi, - dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] -#endif - rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ - map ("--include=" ++) (outDir:chiDirs) - ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] - ++ ["--output-dir=" ++ newOutDir, - "--output=" ++ newOutFile, - "--precomp=" ++ buildDir lbi </> precompFile, - header, inDir </> inFile] - -getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] -getCppOptions bi lbi - = nub $ - ["-I" ++ dir | dir <- PD.includeDirs bi] - ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] - -installCHI :: PackageDescription -- ^information from the .cabal file - -> LocalBuildInfo -- ^information from the configure step - -> Verbosity -> CopyDest -- ^flags sent to copy or install - -> IO () -installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do - let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest - -- cannot use the recommended 'findModuleFiles' since it fails if there exists - -- a modules that does not have a .chi file - mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) - (map toFilePath -#if CABAL_VERSION_CHECK(1,8,0) - (PD.libModules lib) -#else - (PD.libModules pkg) -#endif - ) - let files = [ f | Just f <- mFiles ] -#if CABAL_VERSION_CHECK(1,8,0) - installOrdinaryFiles verbosity libPref files -#else - copyFiles verbosity libPref files -#endif - - [_$_] -installCHI _ _ _ _ = return () - ------------------------------------------------------------------------------- --- Generating the type hierarchy and signal callback .hs files. ------------------------------------------------------------------------------- - -typeGenProgram :: Program -typeGenProgram = (simpleProgram "gtk2hsTypeGen") - -signalGenProgram :: Program -signalGenProgram = (simpleProgram "gtk2hsHookGenerator") - -c2hsLocal :: Program -c2hsLocal = (simpleProgram "gtk2hsC2hs") - -genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () -genSynthezisedFiles verb pd lbi = do - - cPkgs <- getPkgConfigPackages verb lbi pd - - let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) - ++customFieldsPD pd - typeOpts :: [ProgArg] - typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) - | (field,content) <- xList, - "x-types-" `isPrefixOf` field, - field /= "x-types-file"] - ++ [ "--tag=" ++ tag - | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs - , let name' = filter isAlpha (display name) - , tag <- name' - : [ name' ++ "-" ++ show major ++ "." ++ show digit - | digit <- [0,2..minor] ] - ] - - genFile :: Program -> [ProgArg] -> FilePath -> IO () - genFile prog args outFile = do - res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args - rewriteFile outFile res - - case lookup "x-types-file" xList of - Nothing -> return () - Just f -> do - info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") - genFile typeGenProgram typeOpts f - - case (lookup "x-signals-file" xList, - lookup "x-signals-modname" xList) of - (Just _, Nothing) -> die "You need to specify the module name (X-Signals-ModName) \ - \to generate a signal file." - (Just f, Just mod) -> do - info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") - genFile signalGenProgram [mod] f - (_,_) -> return () - ---FIXME: Cabal should tell us the selected pkg-config package versions in the --- LocalBuildInfo or equivalent. --- In the mean time, ask pkg-config again. - -getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] -getPkgConfigPackages verbosity lbi pkg = - sequence - [ do version <- pkgconfig ["--modversion", display pkgname] - case simpleParse version of - Nothing -> die $ "parsing output of pkg-config --modversion failed" - Just v -> return (PackageIdentifier pkgname v) - | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] - where - pkgconfig = rawSystemProgramStdoutConf verbosity - pkgConfigProgram (withPrograms lbi) - ------------------------------------------------------------------------------- --- Dependency calculation amongst .chs files. ------------------------------------------------------------------------------- - --- Given all files of the package, find those that end in .chs and extract the --- .chs files they depend upon. Then return the PackageDescription with these --- files rearranged so that they are built in a sequence that files that are --- needed by other files are built first. -fixDeps :: PackageDescription -> IO PackageDescription -fixDeps pd...@PD...ckageDescription { - PD.library = Just li...@PD...brary { - PD.exposedModules = expMods, - PD.libBuildInfo = bi@PD.BuildInfo { - PD.hsSourceDirs = srcDirs, - PD.otherModules = othMods - }}} = do - let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs - (joinPath (components m)) - mExpFiles <- mapM findModule expMods - mOthFiles <- mapM findModule othMods - - -- tag all exposed files with True so we throw an error if we need to build - -- an exposed module before an internal modules (we cannot express this) - let modDeps = zipWith (ModDep True []) expMods mExpFiles++ - zipWith (ModDep False []) othMods mOthFiles - modDeps <- mapM extractDeps modDeps - let (expMods, othMods) = span mdExposed $ sortTopological modDeps - badOther = map (fromMaybe "<no file>" . mdLocation) $ - filter (not . mdExposed) expMods - unless (null badOther) $ - die ("internal chs modules "++intercalate "," badOther++ - " depend on exposed chs modules; cabal needs to build internal modules first") - return pd { PD.library = Just lib { - PD.exposedModules = map mdOriginal expMods, - PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } - }} - -data ModDep = ModDep { - mdExposed :: Bool, - mdRequires :: [ModuleName], - mdOriginal :: ModuleName, - mdLocation :: Maybe FilePath -} - -instance Show ModDep where - show x = show (mdLocation x) - -instance Eq ModDep where - ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 -instance Ord ModDep where - compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 - --- Extract the dependencies of this file. This is intentionally rather naive as it --- ignores CPP conditionals. We just require everything which means that the --- existance of a .chs module may not depend on some CPP condition. [_$_] -extractDeps :: ModDep -> IO ModDep -extractDeps md@ModDep { mdLocation = Nothing } = return md -extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do - let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of - ('i':'m':'p':'o':'r':'t':' ':ys) -> - case simpleParse (takeWhile ((/=) '#') ys) of - Just m -> findImports (m:acc) xxs [_$_] - Nothing -> die ("cannot parse chs import in "++f++":\n"++ - "offending line is {#"++xs) - -- no more imports after the first non-import hook - _ -> return acc - findImports acc (_:xxs) = findImports acc xxs - findImports acc [] = return acc - mods <- findImports [] (lines con) - return md { mdRequires = mods } - --- Find a total order of the set of modules that are partially sorted by their --- dependencies on each other. The function returns the sorted list of modules --- together with a list of modules that are required but not supplied by this --- in the input set of modules. -sortTopological :: [ModDep] -> [ModDep] -sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) - where - set = M.fromList (map (\m -> (mdOriginal m, m)) ms) - visit (out,visited) m - | m `S.member` visited = (out,visited) - | otherwise = case m `M.lookup` set of - Nothing -> (out, m `S.insert` visited) - Just md -> (md:out', visited') - where - (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) +main = defaultMainWithHooks gtk2hsUserHooks |
From: Axel S. <si...@co...> - 2010-05-01 15:19:31
|
Sat May 1 10:41:40 EDT 2010 Axe...@in... * Install the standard setup files in gio. Ignore-this: a21f5c4e5e0aecc52c967a31e90c2d37 addfile ./gio/Gtk2HsSetup.hs hunk ./gio/Gtk2HsSetup.hs 1 +{-# LANGUAGE CPP #-} + +#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ + ((major) * 10000) \ + + ((minor) * 100) \ + + ((micro) * 1)) + +#define CABAL_VERSION_CHECK(major,minor,micro) \ + (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) + +-- now, this is bad, but Cabal doesn't seem to actually pass any information about +-- its version to CPP, so guess the version depending on the version of GHC +#ifdef CABAL_VERSION_MINOR +#ifndef CABAL_VERSION_MAJOR +#define CABAL_VERSION_MAJOR 1 +#endif +#ifndef CABAL_VERSION_MICRO +#define CABAL_VERSION_MICRO 0 +#endif +#define CABAL_VERSION CABAL_VERSION_ENCODE( \ + CABAL_VERSION_MAJOR, \ + CABAL_VERSION_MINOR, \ + CABAL_VERSION_MICRO) +#else +#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) +#if (__GLASGOW_HASKELL__ >= 612) +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) +#else +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) +#endif +#endif + +-- | Build a Gtk2hs package. +-- +module Gtk2HsSetup ( gtk2hsUserHooks, getPkgConfigPackages ) where + +import Distribution.Simple +import Distribution.Simple.PreProcess +import Distribution.InstalledPackageInfo ( importDirs ) +import Distribution.Simple.PackageIndex ( +#if CABAL_VERSION_CHECK(1,8,0) + lookupInstalledPackageId +#else + lookupPackageId +#endif + ) +import Distribution.PackageDescription as PD ( PackageDescription(..), + updatePackageDescription, + BuildInfo(..), + emptyBuildInfo, allBuildInfo, + Library(..), + libModules) +import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), + InstallDirs(..), +#if CABAL_VERSION_CHECK(1,8,0) + componentPackageDeps, +#else + packageDeps, +#endif + absoluteInstallDirs) +import Distribution.Simple.Compiler ( Compiler(..) ) +import Distribution.Simple.Program ( + Program(..), ConfiguredProgram(..), + rawSystemProgramConf, rawSystemProgramStdoutConf, + c2hsProgram, pkgConfigProgram, + simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) +import Distribution.ModuleName ( ModuleName, components, toFilePath ) +import Distribution.Simple.Utils +import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), + defaultCopyFlags, ConfigFlags(configVerbosity), + fromFlag, toFlag) +import Distribution.Simple.BuildPaths ( autogenModulesDir ) +import Distribution.Text ( simpleParse, display ) +import System.FilePath +import System.Directory ( doesFileExist ) +import Distribution.Version (Version(..)) +import Distribution.Verbosity +import Control.Monad (unless) +import Data.Maybe (fromMaybe) +import Data.List (isPrefixOf, nub) +import Data.Char (isAlpha) +import qualified Data.Map as M +import qualified Data.Set as S + + +-- the name of the c2hs pre-compiled header file +precompFile = "precompchs.bin" + +gtk2hsUserHooks = simpleUserHooks { + hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], + hookedPreProcessors = [("chs", ourC2hs)], + confHook = \pd cf -> + confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, + postConf = \args cf pd lbi -> do + genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi + postConf simpleUserHooks args cf pd lbi, + buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> + (buildHook simpleUserHooks) pd lbi uh bf, + copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), + instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest + } + +-- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later +adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo +adjustLocalBuildInfo lbi = + let extra = (Just libBi, []) + libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi + , buildDir lbi ] } + in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } + +ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor +ourC2hs bi lbi = PreProcessor { + platformIndependent = False, + runPreProcessor = runC2HS bi lbi +} + +runC2HS :: BuildInfo -> LocalBuildInfo -> + (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () +runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do + -- have the header file name if we don't have the precompiled header yet + header <- case lookup "x-c2hs-header" (customFieldsBI bi) of + Just h -> return h + Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ + "that sets the C header file to process .chs.pp files.") + + -- c2hs will output files in out dir, removing any leading path of the input file. + -- Thus, append the dir of the input file to the output dir. + let (outFileDir, newOutFile) = splitFileName outFile + let newOutDir = outDir </> outFileDir + -- additional .chi files might be needed that other packages have installed; + -- we assume that these are installed in the same place as .hi files + let chiDirs = [ dir | +#if CABAL_VERSION_CHECK(1,8,0) + ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), + dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] +#else + ipi <- packageDeps lbi, + dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] +#endif + rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ + map ("--include=" ++) (outDir:chiDirs) + ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] + ++ ["--output-dir=" ++ newOutDir, + "--output=" ++ newOutFile, + "--precomp=" ++ buildDir lbi </> precompFile, + header, inDir </> inFile] + +getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] +getCppOptions bi lbi + = nub $ + ["-I" ++ dir | dir <- PD.includeDirs bi] + ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] + +installCHI :: PackageDescription -- ^information from the .cabal file + -> LocalBuildInfo -- ^information from the configure step + -> Verbosity -> CopyDest -- ^flags sent to copy or install + -> IO () +installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do + let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest + -- cannot use the recommended 'findModuleFiles' since it fails if there exists + -- a modules that does not have a .chi file + mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) + (map toFilePath +#if CABAL_VERSION_CHECK(1,8,0) + (PD.libModules lib) +#else + (PD.libModules pkg) +#endif + ) + let files = [ f | Just f <- mFiles ] +#if CABAL_VERSION_CHECK(1,8,0) + installOrdinaryFiles verbosity libPref files +#else + copyFiles verbosity libPref files +#endif + + [_$_] +installCHI _ _ _ _ = return () + +------------------------------------------------------------------------------ +-- Generating the type hierarchy and signal callback .hs files. +------------------------------------------------------------------------------ + +typeGenProgram :: Program +typeGenProgram = (simpleProgram "gtk2hsTypeGen") + +signalGenProgram :: Program +signalGenProgram = (simpleProgram "gtk2hsHookGenerator") + +c2hsLocal :: Program +c2hsLocal = (simpleProgram "gtk2hsC2hs") + +genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () +genSynthezisedFiles verb pd lbi = do + + cPkgs <- getPkgConfigPackages verb lbi pd + + let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) + ++customFieldsPD pd + typeOpts :: [ProgArg] + typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) + | (field,content) <- xList, + "x-types-" `isPrefixOf` field, + field /= "x-types-file"] + ++ [ "--tag=" ++ tag + | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs + , let name' = filter isAlpha (display name) + , tag <- name' + : [ name' ++ "-" ++ show major ++ "." ++ show digit + | digit <- [0,2..minor] ] + ] + + signalsOpts :: [ProgArg] + signalsOpts = concat [ map (\val -> '-':'-':drop 10 field++'=':val) (words content) + | (field,content) <- xList, + "x-signals-" `isPrefixOf` field, + field /= "x-signals-file"] + + genFile :: Program -> [ProgArg] -> FilePath -> IO () + genFile prog args outFile = do + res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args + rewriteFile outFile res + + case lookup "x-types-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") + genFile typeGenProgram typeOpts f + + case lookup "x-signals-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") + genFile signalGenProgram signalsOpts f + +--FIXME: Cabal should tell us the selected pkg-config package versions in the +-- LocalBuildInfo or equivalent. +-- In the mean time, ask pkg-config again. + +getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] +getPkgConfigPackages verbosity lbi pkg = + sequence + [ do version <- pkgconfig ["--modversion", display pkgname] + case simpleParse version of + Nothing -> die $ "parsing output of pkg-config --modversion failed" + Just v -> return (PackageIdentifier pkgname v) + | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] + where + pkgconfig = rawSystemProgramStdoutConf verbosity + pkgConfigProgram (withPrograms lbi) + +------------------------------------------------------------------------------ +-- Dependency calculation amongst .chs files. +------------------------------------------------------------------------------ + +-- Given all files of the package, find those that end in .chs and extract the +-- .chs files they depend upon. Then return the PackageDescription with these +-- files rearranged so that they are built in a sequence that files that are +-- needed by other files are built first. +fixDeps :: PackageDescription -> IO PackageDescription +fixDeps pd...@PD...ckageDescription { + PD.library = Just li...@PD...brary { + PD.exposedModules = expMods, + PD.libBuildInfo = bi@PD.BuildInfo { + PD.hsSourceDirs = srcDirs, + PD.otherModules = othMods + }}} = do + let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs + (joinPath (components m)) + mExpFiles <- mapM findModule expMods + mOthFiles <- mapM findModule othMods + + -- tag all exposed files with True so we throw an error if we need to build + -- an exposed module before an internal modules (we cannot express this) + let modDeps = zipWith (ModDep True []) expMods mExpFiles++ + zipWith (ModDep False []) othMods mOthFiles + modDeps <- mapM extractDeps modDeps + let (expMods, othMods) = span mdExposed $ sortTopological modDeps + badOther = map (fromMaybe "<no file>" . mdLocation) $ + filter (not . mdExposed) expMods + unless (null badOther) $ + die ("internal chs modules "++intercalate "," badOther++ + " depend on exposed chs modules; cabal needs to build internal modules first") + return pd { PD.library = Just lib { + PD.exposedModules = map mdOriginal expMods, + PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } + }} + +data ModDep = ModDep { + mdExposed :: Bool, + mdRequires :: [ModuleName], + mdOriginal :: ModuleName, + mdLocation :: Maybe FilePath +} + +instance Show ModDep where + show x = show (mdLocation x) + +instance Eq ModDep where + ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 +instance Ord ModDep where + compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 + +-- Extract the dependencies of this file. This is intentionally rather naive as it +-- ignores CPP conditionals. We just require everything which means that the +-- existance of a .chs module may not depend on some CPP condition. [_$_] +extractDeps :: ModDep -> IO ModDep +extractDeps md@ModDep { mdLocation = Nothing } = return md +extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do + let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of + ('i':'m':'p':'o':'r':'t':' ':ys) -> + case simpleParse (takeWhile ((/=) '#') ys) of + Just m -> findImports (m:acc) xxs [_$_] + Nothing -> die ("cannot parse chs import in "++f++":\n"++ + "offending line is {#"++xs) + -- no more imports after the first non-import hook + _ -> return acc + findImports acc (_:xxs) = findImports acc xxs + findImports acc [] = return acc + mods <- findImports [] (lines con) + return md { mdRequires = mods } + +-- Find a total order of the set of modules that are partially sorted by their +-- dependencies on each other. The function returns the sorted list of modules +-- together with a list of modules that are required but not supplied by this +-- in the input set of modules. +sortTopological :: [ModDep] -> [ModDep] +sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) + where + set = M.fromList (map (\m -> (mdOriginal m, m)) ms) + visit (out,visited) m + | m `S.member` visited = (out,visited) + | otherwise = case m `M.lookup` set of + Nothing -> (out, m `S.insert` visited) + Just md -> (md:out', visited') + where + (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) hunk ./gio/Setup.hs 1 -{-# LANGUAGE CPP #-} +-- Setup file for a Gtk2Hs module. Contains only adjustments specific to this module, +-- all Gtk2Hs-specific boilerplate is stored in Gtk2HsSetup.hs which should be kept +-- identical across all modules. +import Gtk2HsSetup ( gtk2hsUserHooks ) +import Distribution.Simple ( defaultMainWithHooks ) hunk ./gio/Setup.hs 7 -#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ - ((major) * 10000) \ - + ((minor) * 100) \ - + ((micro) * 1)) - -#define CABAL_VERSION_CHECK(major,minor,micro) \ - (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) - --- now, this is bad, but Cabal doesn't seem to actually pass any information about --- its version to CPP, so guess the version depending on the version of GHC -#ifdef CABAL_VERSION_MINOR -#ifndef CABAL_VERSION_MAJOR -#define CABAL_VERSION_MAJOR 1 -#endif -#ifndef CABAL_VERSION_MICRO -#define CABAL_VERSION_MICRO 0 -#endif -#define CABAL_VERSION CABAL_VERSION_ENCODE( \ - CABAL_VERSION_MAJOR, \ - CABAL_VERSION_MINOR, \ - CABAL_VERSION_MICRO) -#else -#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) -#if (__GLASGOW_HASKELL__ >= 612) -#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) -#else -#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) -#endif -#endif - --- | Build a Gtk2hs package. --- -import Distribution.Simple -import Distribution.Simple.PreProcess -import Distribution.InstalledPackageInfo ( importDirs ) -import Distribution.Simple.PackageIndex ( -#if CABAL_VERSION_CHECK(1,8,0) - lookupInstalledPackageId -#else - lookupPackageId -#endif - ) -import Distribution.PackageDescription as PD ( PackageDescription(..), - updatePackageDescription, - BuildInfo(..), - emptyBuildInfo, allBuildInfo, - Library(..), - libModules) -import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), - InstallDirs(..), -#if CABAL_VERSION_CHECK(1,8,0) - componentPackageDeps, -#else - packageDeps, -#endif - absoluteInstallDirs) -import Distribution.Simple.Compiler ( Compiler(..) ) -import Distribution.Simple.Program ( - Program(..), ConfiguredProgram(..), - rawSystemProgramConf, rawSystemProgramStdoutConf, - c2hsProgram, pkgConfigProgram, - simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) -import Distribution.ModuleName ( ModuleName, components, toFilePath ) -import Distribution.Simple.Utils -import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), - defaultCopyFlags, ConfigFlags(configVerbosity), - fromFlag, toFlag) -import Distribution.Simple.BuildPaths ( autogenModulesDir ) -import Distribution.Text ( simpleParse, display ) -import System.FilePath -import System.Directory ( doesFileExist ) -import Distribution.Version (Version(..)) -import Distribution.Verbosity -import Control.Monad (unless) -import Data.Maybe (fromMaybe) -import Data.List (isPrefixOf, nub) -import Data.Char (isAlpha) -import qualified Data.Map as M -import qualified Data.Set as S - - --- the name of the c2hs pre-compiled header file -precompFile = "precompchs.bin" - -main = defaultMainWithHooks simpleUserHooks { - hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], - hookedPreProcessors = [("chs", ourC2hs)], - confHook = \pd cf -> - confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, - postConf = \args cf pd lbi -> do - genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi - postConf simpleUserHooks args cf pd lbi, - buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> - (buildHook simpleUserHooks) pd lbi uh bf, - copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> - installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), - instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> - installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest - } - --- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later -adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo -adjustLocalBuildInfo lbi = - let extra = (Just libBi, []) - libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi - , buildDir lbi ] } - in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } - -ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor -ourC2hs bi lbi = PreProcessor { - platformIndependent = False, - runPreProcessor = runC2HS bi lbi -} - -runC2HS :: BuildInfo -> LocalBuildInfo -> - (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () -runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do - -- have the header file name if we don't have the precompiled header yet - header <- case lookup "x-c2hs-header" (customFieldsBI bi) of - Just h -> return h - Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ - "that sets the C header file to process .chs.pp files.") - - -- c2hs will output files in out dir, removing any leading path of the input file. - -- Thus, append the dir of the input file to the output dir. - let (outFileDir, newOutFile) = splitFileName outFile - let newOutDir = outDir </> outFileDir - -- additional .chi files might be needed that other packages have installed; - -- we assume that these are installed in the same place as .hi files - let chiDirs = [ dir | -#if CABAL_VERSION_CHECK(1,8,0) - ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), - dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] -#else - ipi <- packageDeps lbi, - dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] -#endif - rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ - map ("--include=" ++) (outDir:chiDirs) - ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] - ++ ["--output-dir=" ++ newOutDir, - "--output=" ++ newOutFile, - "--precomp=" ++ buildDir lbi </> precompFile, - header, inDir </> inFile] - -getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] -getCppOptions bi lbi - = nub $ - ["-I" ++ dir | dir <- PD.includeDirs bi] - ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] - -installCHI :: PackageDescription -- ^information from the .cabal file - -> LocalBuildInfo -- ^information from the configure step - -> Verbosity -> CopyDest -- ^flags sent to copy or install - -> IO () -installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do - let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest - -- cannot use the recommended 'findModuleFiles' since it fails if there exists - -- a modules that does not have a .chi file - mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) - (map toFilePath -#if CABAL_VERSION_CHECK(1,8,0) - (PD.libModules lib) -#else - (PD.libModules pkg) -#endif - ) - let files = [ f | Just f <- mFiles ] -#if CABAL_VERSION_CHECK(1,8,0) - installOrdinaryFiles verbosity libPref files -#else - copyFiles verbosity libPref files -#endif - - [_$_] -installCHI _ _ _ _ = return () - ------------------------------------------------------------------------------- --- Generating the type hierarchy and signal callback .hs files. ------------------------------------------------------------------------------- - -typeGenProgram :: Program -typeGenProgram = (simpleProgram "gtk2hsTypeGen") - -signalGenProgram :: Program -signalGenProgram = (simpleProgram "gtk2hsHookGenerator") - -c2hsLocal :: Program -c2hsLocal = (simpleProgram "gtk2hsC2hs") - -genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () -genSynthezisedFiles verb pd lbi = do - - cPkgs <- getPkgConfigPackages verb lbi pd - - let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) - ++customFieldsPD pd - typeOpts :: [ProgArg] - typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) - | (field,content) <- xList, - "x-types-" `isPrefixOf` field, - field /= "x-types-file"] - ++ [ "--tag=" ++ tag - | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs - , let name' = filter isAlpha (display name) - , tag <- name' - : [ name' ++ "-" ++ show major ++ "." ++ show digit - | digit <- [0,2..minor] ] - ] - - genFile :: Program -> [ProgArg] -> FilePath -> IO () - genFile prog args outFile = do - res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args - rewriteFile outFile res - - case lookup "x-types-file" xList of - Nothing -> return () - Just f -> do - info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") - genFile typeGenProgram typeOpts f - - case (lookup "x-signals-file" xList, - lookup "x-signals-modname" xList) of - (Just _, Nothing) -> die "You need to specify the module name (X-Signals-ModName) \ - \to generate a signal file." - (Just f, Just mod) -> do - info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") - genFile signalGenProgram [mod] f - (_,_) -> return () - ---FIXME: Cabal should tell us the selected pkg-config package versions in the --- LocalBuildInfo or equivalent. --- In the mean time, ask pkg-config again. - -getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] -getPkgConfigPackages verbosity lbi pkg = - sequence - [ do version <- pkgconfig ["--modversion", display pkgname] - case simpleParse version of - Nothing -> die $ "parsing output of pkg-config --modversion failed" - Just v -> return (PackageIdentifier pkgname v) - | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] - where - pkgconfig = rawSystemProgramStdoutConf verbosity - pkgConfigProgram (withPrograms lbi) - ------------------------------------------------------------------------------- --- Dependency calculation amongst .chs files. ------------------------------------------------------------------------------- - --- Given all files of the package, find those that end in .chs and extract the --- .chs files they depend upon. Then return the PackageDescription with these --- files rearranged so that they are built in a sequence that files that are --- needed by other files are built first. -fixDeps :: PackageDescription -> IO PackageDescription -fixDeps pd...@PD...ckageDescription { - PD.library = Just li...@PD...brary { - PD.exposedModules = expMods, - PD.libBuildInfo = bi@PD.BuildInfo { - PD.hsSourceDirs = srcDirs, - PD.otherModules = othMods - }}} = do - let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs - (joinPath (components m)) - mExpFiles <- mapM findModule expMods - mOthFiles <- mapM findModule othMods - - -- tag all exposed files with True so we throw an error if we need to build - -- an exposed module before an internal modules (we cannot express this) - let modDeps = zipWith (ModDep True []) expMods mExpFiles++ - zipWith (ModDep False []) othMods mOthFiles - modDeps <- mapM extractDeps modDeps - let (expMods, othMods) = span mdExposed $ sortTopological modDeps - badOther = map (fromMaybe "<no file>" . mdLocation) $ - filter (not . mdExposed) expMods - unless (null badOther) $ - die ("internal chs modules "++intercalate "," badOther++ - " depend on exposed chs modules; cabal needs to build internal modules first") - return pd { PD.library = Just lib { - PD.exposedModules = map mdOriginal expMods, - PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } - }} - -data ModDep = ModDep { - mdExposed :: Bool, - mdRequires :: [ModuleName], - mdOriginal :: ModuleName, - mdLocation :: Maybe FilePath -} - -instance Show ModDep where - show x = show (mdLocation x) - -instance Eq ModDep where - ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 -instance Ord ModDep where - compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 - --- Extract the dependencies of this file. This is intentionally rather naive as it --- ignores CPP conditionals. We just require everything which means that the --- existance of a .chs module may not depend on some CPP condition. [_$_] -extractDeps :: ModDep -> IO ModDep -extractDeps md@ModDep { mdLocation = Nothing } = return md -extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do - let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of - ('i':'m':'p':'o':'r':'t':' ':ys) -> - case simpleParse (takeWhile ((/=) '#') ys) of - Just m -> findImports (m:acc) xxs [_$_] - Nothing -> die ("cannot parse chs import in "++f++":\n"++ - "offending line is {#"++xs) - -- no more imports after the first non-import hook - _ -> return acc - findImports acc (_:xxs) = findImports acc xxs - findImports acc [] = return acc - mods <- findImports [] (lines con) - return md { mdRequires = mods } - --- Find a total order of the set of modules that are partially sorted by their --- dependencies on each other. The function returns the sorted list of modules --- together with a list of modules that are required but not supplied by this --- in the input set of modules. -sortTopological :: [ModDep] -> [ModDep] -sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) - where - set = M.fromList (map (\m -> (mdOriginal m, m)) ms) - visit (out,visited) m - | m `S.member` visited = (out,visited) - | otherwise = case m `M.lookup` set of - Nothing -> (out, m `S.insert` visited) - Just md -> (md:out', visited') - where - (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) +main = defaultMainWithHooks gtk2hsUserHooks |
From: Axel S. <si...@co...> - 2010-05-01 15:19:29
|
Wed Apr 28 06:05:30 EDT 2010 Andy Stewart <laz...@gm...> * gnomevfs Cabal package. Ignore-this: 5bbab11f5a0e5c0c790fd917659722c7 addfile ./gnomevfs/COPYING hunk ./gnomevfs/COPYING 1 + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +[_^L_][_$_] + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +[_^L_][_$_] + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + [_$_] + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. +[_^L_][_$_] + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +[_^L_][_$_] + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. +[_^L_][_$_] + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. +[_^L_][_$_] + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. +[_^L_][_$_] + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. +[_^L_][_$_] + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS +[_^L_][_$_] + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + addfile ./gnomevfs/Setup.hs hunk ./gnomevfs/Setup.hs 1 +{-# LANGUAGE CPP #-} + +#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ + ((major) * 10000) \ + + ((minor) * 100) \ + + ((micro) * 1)) + +#define CABAL_VERSION_CHECK(major,minor,micro) \ + (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) + +-- now, this is bad, but Cabal doesn't seem to actually pass any information about +-- its version to CPP, so guess the version depending on the version of GHC +#ifdef CABAL_VERSION_MINOR +#ifndef CABAL_VERSION_MAJOR +#define CABAL_VERSION_MAJOR 1 +#endif +#ifndef CABAL_VERSION_MICRO +#define CABAL_VERSION_MICRO 0 +#endif +#define CABAL_VERSION CABAL_VERSION_ENCODE( \ + CABAL_VERSION_MAJOR, \ + CABAL_VERSION_MINOR, \ + CABAL_VERSION_MICRO) +#else +#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) +#if (__GLASGOW_HASKELL__ >= 612) +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) +#else +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) +#endif +#endif + +-- | Build a Gtk2hs package. +-- +import Distribution.Simple +import Distribution.Simple.PreProcess +import Distribution.InstalledPackageInfo ( importDirs ) +import Distribution.Simple.PackageIndex ( +#if CABAL_VERSION_CHECK(1,8,0) + lookupInstalledPackageId +#else + lookupPackageId +#endif + ) +import Distribution.PackageDescription as PD ( PackageDescription(..), + updatePackageDescription, + BuildInfo(..), + emptyBuildInfo, allBuildInfo, + Library(..), + libModules) +import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), + InstallDirs(..), +#if CABAL_VERSION_CHECK(1,8,0) + componentPackageDeps, +#else + packageDeps, +#endif + absoluteInstallDirs) +import Distribution.Simple.Compiler ( Compiler(..) ) +import Distribution.Simple.Program ( + Program(..), ConfiguredProgram(..), + rawSystemProgramConf, rawSystemProgramStdoutConf, + c2hsProgram, pkgConfigProgram, + simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) +import Distribution.ModuleName ( ModuleName, components, toFilePath ) +import Distribution.Simple.Utils +import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), + defaultCopyFlags, ConfigFlags(configVerbosity), + fromFlag, toFlag) +import Distribution.Simple.BuildPaths ( autogenModulesDir ) +import Distribution.Text ( simpleParse, display ) +import System.FilePath +import System.Directory ( doesFileExist ) +import Distribution.Version (Version(..)) +import Distribution.Verbosity +import Control.Monad (unless) +import Data.Maybe (fromMaybe) +import Data.List (isPrefixOf, nub) +import Data.Char (isAlpha) +import qualified Data.Map as M +import qualified Data.Set as S + + +-- the name of the c2hs pre-compiled header file +precompFile = "precompchs.bin" + +main = defaultMainWithHooks simpleUserHooks { + hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], + hookedPreProcessors = [("chs", ourC2hs)], + confHook = \pd cf -> + confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, + postConf = \args cf pd lbi -> do + genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi + postConf simpleUserHooks args cf pd lbi, + buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> + (buildHook simpleUserHooks) pd lbi uh bf, + copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), + instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest + } + +-- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later +adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo +adjustLocalBuildInfo lbi = + let extra = (Just libBi, []) + libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi + , buildDir lbi ] } + in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } + +ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor +ourC2hs bi lbi = PreProcessor { + platformIndependent = False, + runPreProcessor = runC2HS bi lbi +} + +runC2HS :: BuildInfo -> LocalBuildInfo -> + (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () +runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do + -- have the header file name if we don't have the precompiled header yet + header <- case lookup "x-c2hs-header" (customFieldsBI bi) of + Just h -> return h + Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ + "that sets the C header file to process .chs.pp files.") + + -- c2hs will output files in out dir, removing any leading path of the input file. + -- Thus, append the dir of the input file to the output dir. + let (outFileDir, newOutFile) = splitFileName outFile + let newOutDir = outDir </> outFileDir + -- additional .chi files might be needed that other packages have installed; + -- we assume that these are installed in the same place as .hi files + let chiDirs = [ dir | +#if CABAL_VERSION_CHECK(1,8,0) + ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), + dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] +#else + ipi <- packageDeps lbi, + dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] +#endif + rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ + map ("--include=" ++) (outDir:chiDirs) + ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] + ++ ["--output-dir=" ++ newOutDir, + "--output=" ++ newOutFile, + "--precomp=" ++ buildDir lbi </> precompFile, + header, inDir </> inFile] + +getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] +getCppOptions bi lbi + = nub $ + ["-I" ++ dir | dir <- PD.includeDirs bi] + ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] + +installCHI :: PackageDescription -- ^information from the .cabal file + -> LocalBuildInfo -- ^information from the configure step + -> Verbosity -> CopyDest -- ^flags sent to copy or install + -> IO () +installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do + let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest + -- cannot use the recommended 'findModuleFiles' since it fails if there exists + -- a modules that does not have a .chi file + mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) + (map toFilePath +#if CABAL_VERSION_CHECK(1,8,0) + (PD.libModules lib) +#else + (PD.libModules pkg) +#endif + ) + let files = [ f | Just f <- mFiles ] +#if CABAL_VERSION_CHECK(1,8,0) + installOrdinaryFiles verbosity libPref files +#else + copyFiles verbosity libPref files +#endif + + [_$_] +installCHI _ _ _ _ = return () + +------------------------------------------------------------------------------ +-- Generating the type hierarchy and signal callback .hs files. +------------------------------------------------------------------------------ + +typeGenProgram :: Program +typeGenProgram = (simpleProgram "gtk2hsTypeGen") + +signalGenProgram :: Program +signalGenProgram = (simpleProgram "gtk2hsHookGenerator") + +c2hsLocal :: Program +c2hsLocal = (simpleProgram "gtk2hsC2hs") + +genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () +genSynthezisedFiles verb pd lbi = do + + cPkgs <- getPkgConfigPackages verb lbi pd + + let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) + ++customFieldsPD pd + typeOpts :: [ProgArg] + typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) + | (field,content) <- xList, + "x-types-" `isPrefixOf` field, + field /= "x-types-file"] + ++ [ "--tag=" ++ tag + | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs + , let name' = filter isAlpha (display name) + , tag <- name' + : [ name' ++ "-" ++ show major ++ "." ++ show digit + | digit <- [0,2..minor] ] + ] + + genFile :: Program -> [ProgArg] -> FilePath -> IO () + genFile prog args outFile = do + res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args + rewriteFile outFile res + + case lookup "x-types-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") + genFile typeGenProgram typeOpts f + + case (lookup "x-signals-file" xList, + lookup "x-signals-modname" xList) of + (Just _, Nothing) -> die "You need to specify the module name (X-Signals-ModName) \ + \to generate a signal file." + (Just f, Just mod) -> do + info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") + genFile signalGenProgram [mod] f + (_,_) -> return () + +--FIXME: Cabal should tell us the selected pkg-config package versions in the +-- LocalBuildInfo or equivalent. +-- In the mean time, ask pkg-config again. + +getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] +getPkgConfigPackages verbosity lbi pkg = + sequence + [ do version <- pkgconfig ["--modversion", display pkgname] + case simpleParse version of + Nothing -> die $ "parsing output of pkg-config --modversion failed" + Just v -> return (PackageIdentifier pkgname v) + | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] + where + pkgconfig = rawSystemProgramStdoutConf verbosity + pkgConfigProgram (withPrograms lbi) + +------------------------------------------------------------------------------ +-- Dependency calculation amongst .chs files. +------------------------------------------------------------------------------ + +-- Given all files of the package, find those that end in .chs and extract the +-- .chs files they depend upon. Then return the PackageDescription with these +-- files rearranged so that they are built in a sequence that files that are +-- needed by other files are built first. +fixDeps :: PackageDescription -> IO PackageDescription +fixDeps pd...@PD...ckageDescription { + PD.library = Just li...@PD...brary { + PD.exposedModules = expMods, + PD.libBuildInfo = bi@PD.BuildInfo { + PD.hsSourceDirs = srcDirs, + PD.otherModules = othMods + }}} = do + let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs + (joinPath (components m)) + mExpFiles <- mapM findModule expMods + mOthFiles <- mapM findModule othMods + + -- tag all exposed files with True so we throw an error if we need to build + -- an exposed module before an internal modules (we cannot express this) + let modDeps = zipWith (ModDep True []) expMods mExpFiles++ + zipWith (ModDep False []) othMods mOthFiles + modDeps <- mapM extractDeps modDeps + let (expMods, othMods) = span mdExposed $ sortTopological modDeps + badOther = map (fromMaybe "<no file>" . mdLocation) $ + filter (not . mdExposed) expMods + unless (null badOther) $ + die ("internal chs modules "++intercalate "," badOther++ + " depend on exposed chs modules; cabal needs to build internal modules first") + return pd { PD.library = Just lib { + PD.exposedModules = map mdOriginal expMods, + PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } + }} + +data ModDep = ModDep { + mdExposed :: Bool, + mdRequires :: [ModuleName], + mdOriginal :: ModuleName, + mdLocation :: Maybe FilePath +} + +instance Show ModDep where + show x = show (mdLocation x) + +instance Eq ModDep where + ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 +instance Ord ModDep where + compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 + +-- Extract the dependencies of this file. This is intentionally rather naive as it +-- ignores CPP conditionals. We just require everything which means that the +-- existance of a .chs module may not depend on some CPP condition. [_$_] +extractDeps :: ModDep -> IO ModDep +extractDeps md@ModDep { mdLocation = Nothing } = return md +extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do + let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of + ('i':'m':'p':'o':'r':'t':' ':ys) -> + case simpleParse (takeWhile ((/=) '#') ys) of + Just m -> findImports (m:acc) xxs [_$_] + Nothing -> die ("cannot parse chs import in "++f++":\n"++ + "offending line is {#"++xs) + -- no more imports after the first non-import hook + _ -> return acc + findImports acc (_:xxs) = findImports acc xxs + findImports acc [] = return acc + mods <- findImports [] (lines con) + return md { mdRequires = mods } + +-- Find a total order of the set of modules that are partially sorted by their +-- dependencies on each other. The function returns the sorted list of modules +-- together with a list of modules that are required but not supplied by this +-- in the input set of modules. +sortTopological :: [ModDep] -> [ModDep] +sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) + where + set = M.fromList (map (\m -> (mdOriginal m, m)) ms) + visit (out,visited) m + | m `S.member` visited = (out,visited) + | otherwise = case m `M.lookup` set of + Nothing -> (out, m `S.insert` visited) + Just md -> (md:out', visited') + where + (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) addfile ./gnomevfs/System/Gnome/VFS/BasicTypes.chs hunk ./gnomevfs/System/Gnome/VFS/BasicTypes.chs 1 +{-# LANGUAGE CPP, DeriveDataTypeable #-} +{-# OPTIONS_HADDOCK hide #-} +-- GIMP Toolkit (GTK) Binding for Haskell: binding to libgnomevfs -*-haskell-*- +-- +-- Author : Peter Gavin +-- Created: 1-Apr-2007 +-- +-- Copyright (c) 2007 Peter Gavin +-- +-- This library is free software: you can redistribute it and/or +-- modify it under the terms of the GNU Lesser General Public License +-- as published by the Free Software Foundation, either version 3 of +-- the License, or (at your option) any later version. +-- [_$_] +-- This library is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-- Lesser General Public License for more details. +-- [_$_] +-- You should have received a copy of the GNU Lesser General Public +-- License along with this program. If not, see +-- <http://www.gnu.org/licenses/>. +-- [_$_] +-- GnomeVFS, the C library which this Haskell library depends on, is +-- available under LGPL Version 2. The documentation included with +-- this library is based on the original GnomeVFS documentation, +-- Copyright (c) 2001 Seth Nickell <sni...@st...>. The +-- documentation is covered by the GNU Free Documentation License, +-- version 1.2. + +-- #hide + +-- | Maintainer : gtk...@li... +-- Stability : alpha +-- Portability : portable (depends on GHC) +module System.Gnome.VFS.BasicTypes ( + [_$_] + module System.Gnome.VFS.Constants, + [_$_] + Handle(..), + withHandle, + [_$_] + Result(..), + Error(..), + [_$_] + OpenMode(..), + SeekPosition(..), + [_$_] + FileInfo(..), + FileFlags(..), + FileInfoFields(..), + SetFileInfoMask(..), + FileInfoOptions(..), + FileSize, + FileOffset, + FileType(..), + InodeNumber, + IDs, + [_$_] + MonitorHandle(..), + withMonitorHandle, + MonitorCallback, + MonitorType, + MonitorEventType, + [_$_] + URI(..), + TextURI, + newURI, + withURI, + ToplevelURI(..), + newToplevelURI, + withToplevelURI, + URIHideOptions(..), + [_$_] + DirectoryHandle(..), + withDirectoryHandle, + [_$_] + MakeURIDirs(..), + DirectoryVisitOptions(..), + DirectoryVisitCallback, + DirectoryVisitResult(..), + FindDirectoryKind(..), + [_$_] + XferOptions(..), + XferProgressStatus(..), + XferOverwriteMode(..), + XferOverwriteAction(..), + XferErrorMode(..), + XferErrorAction(..), + XferPhase(..), + XferProgressInfo(..), + XferProgressCallback, + XferErrorCallback, + XferOverwriteCallback, + XferDuplicateCallback, + [_$_] + Cancellation(..), + newCancellation, + withCancellation, + [_$_] + VolumeOpSuccessCallback, + VolumeOpFailureCallback, + CVolumeOpCallback, + VolumeType(..), + DeviceType(..), + [_$_] +#if GNOME_VFS_CHECK_VERSION(2,14,0) + MIMEType, +#endif + [_$_] + -- module System.Gnome.VFS.Hierarchy, + [_$_] + DriveID, + newDrive, + withDrive, + [_$_] + VolumeID, + newVolume, + withVolume, + [_$_] + wrapVolumeMonitor, + withVolumeMonitor + [_$_] + ) where + +import Control.Exception (assert) +import Control.Monad +import Control.Monad.Reader +import Data.Typeable +import Data.Word (Word64) +import System.Glib.FFI +import System.Glib.Flags +{#import System.Glib.GObject#} (GObject(..), + GObjectClass, + toGObject, + unsafeCastGObject) +{#import System.Glib.GType#} (GType, + typeInstanceIsA) +-- {#import System.Gnome.VFS.Hierarchy#} +{#import System.Gnome.VFS.Types#} +import System.Gnome.VFS.Constants + +import System.Posix.Types (DeviceID, EpochTime) + +-------------------------------------------------------------------- + +gTypeCast :: (GObjectClass obj, GObjectClass obj') => GType -> String + -> (obj -> obj') +-- The usage of foreignPtrToPtr should be safe as the evaluation will only be +-- forced if the object is used afterwards +gTypeCast gtype objTypeName obj = + case toGObject obj of + gobj@(GObject objFPtr) + | typeInstanceIsA ((unsafeForeignPtrToPtr.castForeignPtr) objFPtr) gtype + -> unsafeCastGObject gobj + | otherwise -> error $ "Cannot cast object to " ++ objTypeName + +-------------------------------------------------------------------- + +-- | The result of a file operation. +{# enum GnomeVFSResult as Result {underscoreToCase} with prefix = "GNOME_VFS" deriving (Eq, Bounded, Show, Typeable) #} + +newtype Error = Error Result + deriving (Show, Typeable) + +-- | A handle to an open file +{# pointer *GnomeVFSHandle as Handle foreign newtype #} +withHandle (Handle cHandle) = withForeignPtr cHandle + +-- | Specifies the start position for a seek operation. +{# enum GnomeVFSSeekPosition as SeekPosition {underscoreToCase} with prefix = "GNOME_VFS" deriving (Eq, Bounded, Show) #} +{# enum GnomeVFSOpenMode as OpenMode {underscoreToCase} with prefix = "GNOME_VFS" deriving (Eq, Bounded, Show) #} + +-------------------------------------------------------------------- + +-- | A record type containing information about a file. +data FileInfo = FileInfo { + fileInfoName :: Maybe String, -- ^ the name of the file, + -- without the path + fileInfoType :: Maybe FileType, -- ^ the type of the file; + -- i.e. regular, directory, + -- block-device, etc. + fileInfoPermissions :: Maybe [FilePermissions], -- ^ the permissions for the + -- file + fileInfoFlags :: Maybe [FileFlags], -- ^ flags providing + -- additional information + -- about the file + fileInfoDevice :: Maybe DeviceID, -- ^ the device the file + -- resides on + fileInfoInode :: Maybe InodeNumber, -- ^ the inode number of the + -- file + fileInfoLinkCount :: Maybe Int, -- ^ the total number of + -- hard links to the file + fileInfoIDs :: Maybe IDs, -- ^ the user and group IDs + -- owning the file + fileInfoSize :: Maybe FileSize, -- ^ the size of the file in + -- bytes + fileInfoBlockCount :: Maybe FileSize, -- ^ the size of the file in + -- filesystem blocks + fileInfoIOBlockSize :: Maybe FileSize, -- ^ the optimal buffer size + -- for reading from and + -- writing to the file + fileInfoATime :: Maybe EpochTime, -- ^ the time of last access + fileInfoMTime :: Maybe EpochTime, -- ^ the time of last modification + fileInfoCTime :: Maybe EpochTime, -- ^ the time of last attribute modification + fileInfoSymlinkName :: Maybe String -- ^ the location this + -- symlink points to, if + -- @fileInfoFlags@ contains 'FileFlagsSymlink' +#if GNOME_VFS_CHECK_VERSION(2,14,0) + , + fileInfoMIMEType :: Maybe MIMEType -- ^ the MIME-type of the + -- file +#endif + } deriving (Eq, Show) + +{# enum GnomeVFSFileInfoFields as FileInfoFields {underscoreToCase} with prefix = "GNOME_VFS" deriving (Eq, Bounded, Show) #} + +-- | Options for reading information from a file. +{# enum GnomeVFSFileInfoOptions as FileInfoOptions {underscoreToCase} with prefix = "GNOME_VFS" deriving (Eq, Bounded, Show) #} + +-- | Flags specifying additional information about a file. +{# enum GnomeVFSFileFlags as FileFlags {underscoreToCase} with prefix = "GNOME_VFS" deriving (Eq, Bounded, Show) #} + +-- | Flags specifying the attributes of a file that should be changed. +{# enum GnomeVFSSetFileInfoMask as SetFileInfoMask {underscoreToCase} with prefix = "GNOME_VFS" deriving (Eq, Bounded, Show) #} + +-- | Identifies the type of a file. +{# enum GnomeVFSFileType as FileType {underscoreToCase} with prefix = "GNOME_VFS" deriving (Eq, Show) #} + +instance Flags FileInfoOptions +instance Flags FileInfoFields +instance Flags FileFlags +instance Flags SetFileInfoMask + +-- | An integral type wide enough to hold the size of a file. +type FileSize = Word64 + +-- | An integral type wide enough to hold an offset into a file. +type FileOffset = Word64 + +-- | An integral type wide enough to hold the inode number of a file. +type InodeNumber = Word64 + +-- | A pair holding the user ID and group ID of a file owner. +type IDs = (Int, Int) + +-------------------------------------------------------------------- + +-- | A 'URI' is a semi-textual representation of a uniform +-- resource identifier. It contains the information about a resource +-- location encoded as canononicalized text, but also holds extra +-- information about the context in which the URI is used. +{# pointer *GnomeVFSURI as URI foreign newtype #} + +newURI :: Ptr URI + -> IO URI +newURI cURI | cURI /= nullPtr = + liftM URI $ newForeignPtr cURI cURIFinalizer +wrapURI :: Ptr URI + -> IO URI +wrapURI cURI | cURI /= nullPtr = + liftM URI $ newForeignPtr_ cURI +foreign import ccall "&gnome_vfs_uri_unref" + cURIFinalizer :: FunPtr (Ptr URI -> IO ()) + +withURI (URI cURI) = withForeignPtr cURI + +-- | The toplevel URI element used to access resources stored on a +-- remote server. +{# pointer *GnomeVFSToplevelURI as ToplevelURI foreign newtype #} +withToplevelURI (ToplevelURI cToplevelURI) = withForeignPtr cToplevelURI +newToplevelURI :: Ptr ToplevelURI + -> IO ToplevelURI +newToplevelURI cToplevelURI = liftM ToplevelURI $ newForeignPtr_ cToplevelURI + +-- | Flags specifying which fields of a 'URI' should be hidden when +-- converted to a string using 'uriToString'. +{# enum GnomeVFSURIHideOptions as URIHideOptions { + GNOME_VFS_URI_HIDE_NONE as URIHideNone, + GNOME_VFS_URI_HIDE_USER_NAME as URIHideUserName, + GNOME_VFS_URI_HIDE_PASSWORD as URIHidePassword, + GNOME_VFS_URI_HIDE_HOST_NAME as URIHideHostName, + GNOME_VFS_URI_HIDE_HOST_PORT as URIHideHostPort, + GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD as URIHideToplevelMethod, + GNOME_VFS_URI_HIDE_FRAGMENT_IDENTIFIER as URIHideFragmentIdentifier + } deriving (Eq, Bounded, Show) #} +instance Flags URIHideOptions + +-- | A string that can be passed to 'uriFromString' to create a valid +-- 'URI'. +type TextURI = String + +-------------------------------------------------------------------- + +-- | A handle to an open directory. +{# pointer *GnomeVFSDirectoryHandle as DirectoryHandle foreign newtype #} +withDirectoryHandle (DirectoryHandle cDirectoryHandle) = withForeignPtr cDirectoryHandle + +-- | Options controlling the way in which a directories are visited. +{# enum GnomeVFSDirectoryVisitOptions as DirectoryVisitOptions {underscoreToCase} with prefix = "GNOME_VFS" deriving (Eq, Bounded, Show) #} +instance Flags DirectoryVisitOptions + +-- | A callback that will be called for each entry when passed to +-- 'directoryVisit', 'directoryVisitURI', 'directoryVisitFiles', or +-- 'directoryVisitFilesAtURI'. +-- [_$_] +-- The parameters, from left to right, are: +-- * the path of the visited file, relative to the base directory, +-- * the 'FileInfo' for the visited file, +-- * 'True' if returning 'DirectoryVisitRecurse' will cause a loop, otherwise 'False'. +-- [_$_] +-- The callback must return the next action to be taken. +type DirectoryVisitCallback = String + -> FileInfo + -> Bool + -> IO DirectoryVisitResult + +-- | An enumerated value that must be returned from a +-- 'DirectoryVisitCallback'. The 'directoryVisit' and related +-- functions will perform the action specified. +data DirectoryVisitResult = DirectoryVisitStop -- ^ stop visiting files + | DirectoryVisitContinue -- ^ continue as normal + | DirectoryVisitRecurse -- ^ recursively visit the current entry + deriving (Eq, Enum) + +-- | Specifies which kind of directory 'findDirectory' should look for. +{# enum GnomeVFSFindDirectoryKind as FindDirectoryKind {underscoreToCase} with prefix = "GNOME_VFS" deriving (Eq, Show) #} + +-------------------------------------------------------------------- + +-- | Flags that may be passed to 'makeURIFromInputWithDirs'. If the +-- path passed is non-absolute (i.e., a relative path), the +-- directories specified will be searched as well. +{# enum GnomeVFSMakeURIDirs as MakeURIDirs {underscoreToCase} with prefix = "GNOME_VFS" deriving (Eq, Bounded, Show) #} +instance Flags MakeURIDirs + +-------------------------------------------------------------------- + +-- | A handle to a file-system monitor. +newtype MonitorHandle = MonitorHandle (ForeignPtr MonitorHandle, {# type GnomeVFSMonitorCallback #}) +withMonitorHandle (MonitorHandle (monitorHandleForeignPtr, _)) = withForeignPtr monitorHandleForeignPtr + ... [truncated message content] |
From: Axel S. <si...@co...> - 2010-05-01 15:19:28
|
Wed Apr 28 08:28:45 EDT 2010 Andy Stewart <laz...@gm...> * Expose module `System.Gnome.VFS` in gnomevfs.cabal Ignore-this: 70069732773614e4323d696cb887a2d1 addfile ./gnomevfs/System/Gnome/VFS.chs hunk ./gnomevfs/System/Gnome/VFS.chs 1 +{-# LANGUAGE CPP #-} +-- GIMP Toolkit (GTK) Binding for Haskell: binding to libgnomevfs -*-haskell-*- +-- +-- Author : Peter Gavin +-- Created: 1-Apr-2007 +-- +-- Copyright (c) 2007 Peter Gavin +-- +-- This library is free software: you can redistribute it and/or +-- modify it under the terms of the GNU Lesser General Public License +-- as published by the Free Software Foundation, either version 3 of +-- the License, or (at your option) any later version. +-- [_$_] +-- This library is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-- Lesser General Public License for more details. +-- [_$_] +-- You should have received a copy of the GNU Lesser General Public +-- License along with this program. If not, see +-- <http://www.gnu.org/licenses/>. +-- [_$_] +-- GnomeVFS, the C library which this Haskell library depends on, is +-- available under LGPL Version 2. The documentation included with +-- this library is based on the original GnomeVFS documentation, +-- Copyright (c) 2001 Seth Nickell <sni...@st...>. The +-- documentation is covered by the GNU Free Documentation License, +-- version 1.2. +-- [_$_] +-- | Maintainer : gtk...@li... +-- Stability : alpha +-- Portability : portable (depends on GHC) +module System.Gnome.VFS ( + [_$_] + module System.Gnome.VFS.Cancellation, + module System.Gnome.VFS.Directory, + module System.Gnome.VFS.Drive, + module System.Gnome.VFS.Error, + module System.Gnome.VFS.FileInfo, + module System.Gnome.VFS.Init, +#if GNOME_VFS_CHECK_VERSION(2,14,0) + module System.Gnome.VFS.MIME, +#endif + module System.Gnome.VFS.Monitor, + module System.Gnome.VFS.Ops, + module System.Gnome.VFS.URI, + module System.Gnome.VFS.Util, + module System.Gnome.VFS.Volume, + module System.Gnome.VFS.VolumeMonitor, + module System.Gnome.VFS.Xfer + + ) where + +import System.Gnome.VFS.Cancellation +import System.Gnome.VFS.Directory +import System.Gnome.VFS.Drive +import System.Gnome.VFS.Error +import System.Gnome.VFS.FileInfo +import System.Gnome.VFS.Init +#if GNOME_VFS_CHECK_VERSION(2,14,0) +import System.Gnome.VFS.MIME +#endif +import System.Gnome.VFS.Monitor +import System.Gnome.VFS.Ops +import System.Gnome.VFS.URI +import System.Gnome.VFS.Util +import System.Gnome.VFS.Volume +import System.Gnome.VFS.VolumeMonitor +import System.Gnome.VFS.Xfer hunk ./gnomevfs/System/Gnome/VFS.hs.pp 1 --- GIMP Toolkit (GTK) Binding for Haskell: binding to libgnomevfs -*-haskell-*- --- --- Author : Peter Gavin --- Created: 1-Apr-2007 --- --- Copyright (c) 2007 Peter Gavin --- --- This library is free software: you can redistribute it and/or --- modify it under the terms of the GNU Lesser General Public License --- as published by the Free Software Foundation, either version 3 of --- the License, or (at your option) any later version. --- [_$_] --- This library is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- Lesser General Public License for more details. --- [_$_] --- You should have received a copy of the GNU Lesser General Public --- License along with this program. If not, see --- <http://www.gnu.org/licenses/>. --- [_$_] --- GnomeVFS, the C library which this Haskell library depends on, is --- available under LGPL Version 2. The documentation included with --- this library is based on the original GnomeVFS documentation, --- Copyright (c) 2001 Seth Nickell <sni...@st...>. The --- documentation is covered by the GNU Free Documentation License, --- version 1.2. --- [_$_] --- | Maintainer : gtk...@li... --- Stability : alpha --- Portability : portable (depends on GHC) -module System.Gnome.VFS ( - [_$_] - module System.Gnome.VFS.Cancellation, - module System.Gnome.VFS.Directory, - module System.Gnome.VFS.Drive, - module System.Gnome.VFS.Error, - module System.Gnome.VFS.FileInfo, - module System.Gnome.VFS.Init, -#if GNOME_VFS_CHECK_VERSION(2,14,0) - module System.Gnome.VFS.MIME, -#endif - module System.Gnome.VFS.Monitor, - module System.Gnome.VFS.Ops, - module System.Gnome.VFS.URI, - module System.Gnome.VFS.Util, - module System.Gnome.VFS.Volume, - module System.Gnome.VFS.VolumeMonitor, - module System.Gnome.VFS.Xfer - - ) where - -import System.Gnome.VFS.Cancellation -import System.Gnome.VFS.Directory -import System.Gnome.VFS.Drive -import System.Gnome.VFS.Error -import System.Gnome.VFS.FileInfo -import System.Gnome.VFS.Init -#if GNOME_VFS_CHECK_VERSION(2,14,0) -import System.Gnome.VFS.MIME -#endif -import System.Gnome.VFS.Monitor -import System.Gnome.VFS.Ops -import System.Gnome.VFS.URI -import System.Gnome.VFS.Util -import System.Gnome.VFS.Volume -import System.Gnome.VFS.VolumeMonitor -import System.Gnome.VFS.Xfer rmfile ./gnomevfs/System/Gnome/VFS.hs.pp hunk ./gnomevfs/gnomevfs.cabal 42 + System.Gnome.VFS |
From: Axel S. <si...@co...> - 2010-05-01 15:19:27
|
Wed Apr 28 06:13:29 EDT 2010 Andy Stewart <laz...@gm...> * webkit Cabal package. Ignore-this: 3b4d27f26dcfb80aec42923906938106 addfile ./webkit/COPYING hunk ./webkit/COPYING 1 + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +[_^L_][_$_] + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +[_^L_][_$_] + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + [_$_] + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. +[_^L_][_$_] + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +[_^L_][_$_] + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. +[_^L_][_$_] + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. +[_^L_][_$_] + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. +[_^L_][_$_] + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. +[_^L_][_$_] + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS +[_^L_][_$_] + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + hunk ./webkit/Graphics/UI/Gtk/WebKit/Download.chs 39 - DownloadError(..), - hunk ./webkit/Graphics/UI/Gtk/WebKit/Download.chs 77 -{#import Graphics.UI.Gtk.Signals#} +{#import Graphics.UI.Gtk.WebKit.Signals#} addfile ./webkit/Graphics/UI/Gtk/WebKit/HitTestResult.chs hunk ./webkit/Graphics/UI/Gtk/WebKit/HitTestResult.chs 1 +{-# LANGUAGE CPP #-} +-- -*-haskell-*- +----------------------------------------------------------------------------- +-- Module : Graphics.UI.Gtk.WebKit.HitTestResult +-- Author : Andy Stewart +-- Copyright : (c) 2010 Andy Stewart <laz...@gm...> +-- +-- This library is free software; you can redistribute it and/or +-- modify it under the terms of the GNU Lesser General Public +-- License as published by the Free Software Foundation; either +-- version 2.1 of the License, or (at your option) any later version. +-- +-- This library is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-- Lesser General Public License for more details. +-- +-- | +-- Maintainer : gtk...@li... +-- Stability : provisional +-- Portability : portable (depends on GHC) +-- +-- Access to the WebKit Web Resource +----------------------------------------------------------------------------- + +module Graphics.UI.Gtk.WebKit.HitTestResult ( +-- * Types + HitTestResult, + +-- * Enums. + HitTestResultContext(..), +) where + +import System.Glib.FFI +import System.Glib.GList +import System.Glib.GError [_$_] +import Graphics.UI.Gtk.Gdk.Events + +{#import Graphics.UI.Gtk.Abstract.Object#} (makeNewObject) +{#import Graphics.UI.Gtk.WebKit.Signals#} +{#import Graphics.UI.Gtk.WebKit.Types#} +{#import System.Glib.GObject#} + +{#context lib="webkit" prefix ="webkit"#} + +-- * Enums. + +{#enum HitTestResultContext {underscoreToCase}#} hunk ./webkit/Graphics/UI/Gtk/WebKit/HitTestResult.chs.pp 1 --- -*-haskell-*- ------------------------------------------------------------------------------ --- Module : Graphics.UI.Gtk.WebKit.HitTestResult --- Author : Andy Stewart --- Copyright : (c) 2010 Andy Stewart <laz...@gm...> --- --- This library is free software; you can redistribute it and/or --- modify it under the terms of the GNU Lesser General Public --- License as published by the Free Software Foundation; either --- version 2.1 of the License, or (at your option) any later version. --- --- This library is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- Lesser General Public License for more details. --- --- | --- Maintainer : gtk...@li... --- Stability : provisional --- Portability : portable (depends on GHC) --- --- Access to the WebKit Web Resource ------------------------------------------------------------------------------ - -module Graphics.UI.Gtk.WebKit.HitTestResult ( --- * Types - HitTestResult, - --- * Enums. - HitTestResultContext(..), -) where - -import System.Glib.FFI -import System.Glib.GList -import System.Glib.GError [_$_] -import Graphics.UI.Gtk.Gdk.Events - -{#import Graphics.UI.Gtk.Abstract.Object#} (makeNewObject) -{#import Graphics.UI.Gtk.Signals#} -{#import Graphics.UI.Gtk.WebKit.Types#} -{#import System.Glib.GObject#} - -{#context lib="webkit" prefix ="webkit"#} - --- * Enums. - -{#enum HitTestResultContext {underscoreToCase}#} rmfile ./webkit/Graphics/UI/Gtk/WebKit/HitTestResult.chs.pp addfile ./webkit/Graphics/UI/Gtk/WebKit/Internal.chs hunk ./webkit/Graphics/UI/Gtk/WebKit/Internal.chs 1 +{-# LANGUAGE CPP #-} +-- -*-haskell-*- +----------------------------------------------------------------------------- +-- Module : Graphics.UI.Gtk.WebKit.Internal +-- Author : Andy Stewart +-- Copyright : (c) 2010 Andy Stewart <laz...@gm...> +-- +-- This library is free software; you can redistribute it and/or +-- modify it under the terms of the GNU Lesser General Public +-- License as published by the Free Software Foundation; either +-- version 2.1 of the License, or (at your option) any later version. +-- +-- This library is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-- Lesser General Public License for more details. +-- +-- | +-- Maintainer : gtk...@li... +-- Stability : provisional +-- Portability : portable (depends on GHC) +-- +-- Access to the WebKit Internal +-- +-- This module contain some functions for help binding Webkit. +-- +----------------------------------------------------------------------------- + +module Graphics.UI.Gtk.WebKit.Internal ( +-- * Methods +-- Below functions just help binding use in internal. +-- Don't call those functions in your code. + connect_OBJECT__OBJECTPTR, + webViewToWebViewPtr, +) where + +import System.Glib.FFI +import System.Glib.GList +import System.Glib.GError [_$_] +import Graphics.UI.Gtk.Gdk.Events + +{#import Graphics.UI.Gtk.Abstract.Object#} (makeNewObject) +{#import Graphics.UI.Gtk.WebKit.Signals#} +{#import Graphics.UI.Gtk.WebKit.Types#} +{#import System.Glib.GObject#} + +{#context lib="webkit" prefix ="webkit"#} + +-- | Signal helper functions. +connect_OBJECT__OBJECTPTR :: + (GObjectClass a', GObjectClass obj) => SignalName -> + ConnectAfter -> obj -> + (a' -> IO WebView) -> + IO (ConnectId obj) +connect_OBJECT__OBJECTPTR signal after obj user = + connectGeneric signal after obj action + where action :: Ptr GObject -> Ptr GObject -> IO (Ptr WebView) + action _ obj1 = + failOnGError $ + makeNewGObject mkGObject (return obj1) >>= \obj1' -> + user (unsafeCastGObject obj1') >>= webViewToWebViewPtr + +-- | Internal helper function for convert. +webViewToWebViewPtr :: WebViewClass self => self -> IO (Ptr WebView) +webViewToWebViewPtr webview = return $ unsafeForeignPtrToPtr (unWebView (toWebView webview)) hunk ./webkit/Graphics/UI/Gtk/WebKit/Internal.chs.pp 1 --- -*-haskell-*- ------------------------------------------------------------------------------ --- Module : Graphics.UI.Gtk.WebKit.Internal --- Author : Andy Stewart --- Copyright : (c) 2010 Andy Stewart <laz...@gm...> --- --- This library is free software; you can redistribute it and/or --- modify it under the terms of the GNU Lesser General Public --- License as published by the Free Software Foundation; either --- version 2.1 of the License, or (at your option) any later version. --- --- This library is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- Lesser General Public License for more details. --- --- | --- Maintainer : gtk...@li... --- Stability : provisional --- Portability : portable (depends on GHC) --- --- Access to the WebKit Internal --- --- This module contain some functions for help binding Webkit. --- ------------------------------------------------------------------------------ - -module Graphics.UI.Gtk.WebKit.Internal ( --- * Methods --- Below functions just help binding use in internal. --- Don't call those functions in your code. - connect_OBJECT__OBJECTPTR, - webViewToWebViewPtr, -) where - -import System.Glib.FFI -import System.Glib.GList -import System.Glib.GError [_$_] -import Graphics.UI.Gtk.Gdk.Events - -{#import Graphics.UI.Gtk.Abstract.Object#} (makeNewObject) -{#import Graphics.UI.Gtk.Signals#} -{#import Graphics.UI.Gtk.WebKit.Types#} -{#import System.Glib.GObject#} - -{#context lib="webkit" prefix ="webkit"#} - --- | Signal helper functions. -connect_OBJECT__OBJECTPTR :: - (GObjectClass a', GObjectClass obj) => SignalName -> - ConnectAfter -> obj -> - (a' -> IO WebView) -> - IO (ConnectId obj) -connect_OBJECT__OBJECTPTR signal after obj user = - connectGeneric signal after obj action - where action :: Ptr GObject -> Ptr GObject -> IO (Ptr WebView) - action _ obj1 = - failOnGError $ - makeNewGObject mkGObject (return obj1) >>= \obj1' -> - user (unsafeCastGObject obj1') >>= webViewToWebViewPtr - --- | Internal helper function for convert. -webViewToWebViewPtr :: WebViewClass self => self -> IO (Ptr WebView) -webViewToWebViewPtr webview = return $ unsafeForeignPtrToPtr (unWebView (toWebView webview)) rmfile ./webkit/Graphics/UI/Gtk/WebKit/Internal.chs.pp hunk ./webkit/Graphics/UI/Gtk/WebKit/NetworkRequest.chs 47 -{#import Graphics.UI.Gtk.Signals#} +{#import Graphics.UI.Gtk.WebKit.Signals#} hunk ./webkit/Graphics/UI/Gtk/WebKit/NetworkResponse.chs 44 -{#import Graphics.UI.Gtk.Signals#} +{#import Graphics.UI.Gtk.WebKit.Signals#} addfile ./webkit/Graphics/UI/Gtk/WebKit/SecurityOrigin.chs hunk ./webkit/Graphics/UI/Gtk/WebKit/SecurityOrigin.chs 1 +{-# LANGUAGE CPP #-} +-- -*-haskell-*- +----------------------------------------------------------------------------- +-- Module : Graphics.UI.Gtk.WebKit.WebSecurityOrigin +-- Author : Andy Stewart +-- Copyright : (c) 2010 Andy Stewart <laz...@gm...> +-- +-- This library is free software; you can redistribute it and/or +-- modify it under the terms of the GNU Lesser General Public +-- License as published by the Free Software Foundation; either +-- version 2.1 of the License, or (at your option) any later version. +-- +-- This library is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-- Lesser General Public License for more details. +-- +-- | +-- Maintainer : gtk...@li... +-- Stability : provisional +-- Portability : portable (depends on GHC) +-- +-- Access to the WebKit Web SecurityOrigin +----------------------------------------------------------------------------- + +module Graphics.UI.Gtk.WebKit.SecurityOrigin ( +-- * Types + SecurityOrigin, + +-- * Methods [_$_] + securityOriginGetAllWebDatabases, + securityOriginGetHost, + securityOriginGetPort, + securityOriginGetProtocol, + securityOriginGetWebDatabaseQuota, + securityOriginSetWebDatabaseQuota, + securityOriginGetWebDatabaseUsage, +) where + +import Control.Monad (liftM) + +import System.Glib.FFI +import System.Glib.UTFString +import System.Glib.GList +import System.Glib.GError [_$_] +import Graphics.UI.Gtk.Gdk.Events + +{#import Graphics.UI.Gtk.Abstract.Object#} (makeNewObject) +{#import Graphics.UI.Gtk.WebKit.Signals#} +{#import Graphics.UI.Gtk.WebKit.Types#} +{#import System.Glib.GObject#} + +{#context lib="webkit" prefix ="webkit"#} + +-- * Methods. + +-- | Returns the frame's security origin. +securityOriginGetAllWebDatabases :: + SecurityOriginClass self => self + -> IO [WebDatabase] [_$_] +securityOriginGetAllWebDatabases so = do + glist <- {#call security_origin_get_all_web_databases#} (toSecurityOrigin so) + databasePtr <- fromGList glist + mapM (makeNewGObject mkWebDatabase . return) databasePtr + +-- | Returns the hostname for the security origin. +securityOriginGetHost :: + SecurityOriginClass self => self + -> IO String +securityOriginGetHost so = + {#call security_origin_get_host#} (toSecurityOrigin so) >>= peekCString + +-- | Returns the port for the security origin. +securityOriginGetPort :: + SecurityOriginClass self => self + -> IO Int +securityOriginGetPort so = + liftM fromIntegral $ {#call security_origin_get_port#} (toSecurityOrigin so) + +-- | Returns the protocol for the security origin. +securityOriginGetProtocol :: + SecurityOriginClass self => self + -> IO String +securityOriginGetProtocol so = + {#call security_origin_get_protocol#} (toSecurityOrigin so) >>= peekCString + +-- | Returns the quota for Web Database storage of the security origin in bytes. +securityOriginGetWebDatabaseQuota :: + SecurityOriginClass self => self + -> IO Int +securityOriginGetWebDatabaseQuota so = + liftM fromIntegral $ {#call security_origin_get_web_database_quota#} (toSecurityOrigin so) + [_$_] +-- | Returns the usage for Web Database storage of the security origin in bytes. +securityOriginGetWebDatabaseUsage :: + SecurityOriginClass self => self + -> IO Int +securityOriginGetWebDatabaseUsage so = + liftM fromIntegral $ {#call security_origin_get_web_database_usage#} (toSecurityOrigin so) + [_$_] +-- | Adjust the quota for Web Database storage of the security origin +securityOriginSetWebDatabaseQuota :: + SecurityOriginClass self => self + -> Int + -> IO () +securityOriginSetWebDatabaseQuota so quota = + {#call security_origin_set_web_database_quota#} (toSecurityOrigin so) (fromIntegral quota) + hunk ./webkit/Graphics/UI/Gtk/WebKit/SecurityOrigin.chs.pp 1 --- -*-haskell-*- ------------------------------------------------------------------------------ --- Module : Graphics.UI.Gtk.WebKit.WebSecurityOrigin --- Author : Andy Stewart --- Copyright : (c) 2010 Andy Stewart <laz...@gm...> --- --- This library is free software; you can redistribute it and/or --- modify it under the terms of the GNU Lesser General Public --- License as published by the Free Software Foundation; either --- version 2.1 of the License, or (at your option) any later version. --- --- This library is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- Lesser General Public License for more details. --- --- | --- Maintainer : gtk...@li... --- Stability : provisional --- Portability : portable (depends on GHC) --- --- Access to the WebKit Web SecurityOrigin ------------------------------------------------------------------------------ - -module Graphics.UI.Gtk.WebKit.SecurityOrigin ( --- * Types - SecurityOrigin, - --- * Methods [_$_] - securityOriginGetAllWebDatabases, - securityOriginGetHost, - securityOriginGetPort, - securityOriginGetProtocol, - securityOriginGetWebDatabaseQuota, - securityOriginSetWebDatabaseQuota, - securityOriginGetWebDatabaseUsage, -) where - -import Control.Monad (liftM) - -import System.Glib.FFI -import System.Glib.UTFString -import System.Glib.GList -import System.Glib.GError [_$_] -import Graphics.UI.Gtk.Gdk.Events - -{#import Graphics.UI.Gtk.Abstract.Object#} (makeNewObject) -{#import Graphics.UI.Gtk.Signals#} -{#import Graphics.UI.Gtk.WebKit.Types#} -{#import System.Glib.GObject#} - -{#context lib="webkit" prefix ="webkit"#} - --- * Methods. - --- | Returns the frame's security origin. -securityOriginGetAllWebDatabases :: - SecurityOriginClass self => self - -> IO [WebDatabase] [_$_] -securityOriginGetAllWebDatabases so = do - glist <- {#call security_origin_get_all_web_databases#} (toSecurityOrigin so) - databasePtr <- fromGList glist - mapM (makeNewGObject mkWebDatabase . return) databasePtr - --- | Returns the hostname for the security origin. -securityOriginGetHost :: - SecurityOriginClass self => self - -> IO String -securityOriginGetHost so = - {#call security_origin_get_host#} (toSecurityOrigin so) >>= peekCString - --- | Returns the port for the security origin. -securityOriginGetPort :: - SecurityOriginClass self => self - -> IO Int -securityOriginGetPort so = - liftM fromIntegral $ {#call security_origin_get_port#} (toSecurityOrigin so) - --- | Returns the protocol for the security origin. -securityOriginGetProtocol :: - SecurityOriginClass self => self - -> IO String -securityOriginGetProtocol so = - {#call security_origin_get_protocol#} (toSecurityOrigin so) >>= peekCString - --- | Returns the quota for Web Database storage of the security origin in bytes. -securityOriginGetWebDatabaseQuota :: - SecurityOriginClass self => self - -> IO Int -securityOriginGetWebDatabaseQuota so = - liftM fromIntegral $ {#call security_origin_get_web_database_quota#} (toSecurityOrigin so) - [_$_] --- | Returns the usage for Web Database storage of the security origin in bytes. -securityOriginGetWebDatabaseUsage :: - SecurityOriginClass self => self - -> IO Int -securityOriginGetWebDatabaseUsage so = - liftM fromIntegral $ {#call security_origin_get_web_database_usage#} (toSecurityOrigin so) - [_$_] --- | Adjust the quota for Web Database storage of the security origin -securityOriginSetWebDatabaseQuota :: - SecurityOriginClass self => self - -> Int - -> IO () -securityOriginSetWebDatabaseQuota so quota = - {#call security_origin_set_web_database_quota#} (toSecurityOrigin so) (fromIntegral quota) - rmfile ./webkit/Graphics/UI/Gtk/WebKit/SecurityOrigin.chs.pp addfile ./webkit/Graphics/UI/Gtk/WebKit/SoupAuthDialog.chs hunk ./webkit/Graphics/UI/Gtk/WebKit/SoupAuthDialog.chs 1 +{-# LANGUAGE CPP #-} +-- -*-haskell-*- +----------------------------------------------------------------------------- +-- Module : Graphics.UI.Gtk.WebKit.SoupAuthDialog +-- Author : Andy Stewart +-- Copyright : (c) 2010 Andy Stewart <laz...@gm...> +-- +-- This library is free software; you can redistribute it and/or +-- modify it under the terms of the GNU Lesser General Public +-- License as published by the Free Software Foundation; either +-- version 2.1 of the License, or (at your option) any later version. +-- +-- This library is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-- Lesser General Public License for more details. +-- +-- | +-- Maintainer : gtk...@li... +-- Stability : provisional +-- Portability : portable (depends on GHC) +-- +-- Access to the WebKit Web Resource +----------------------------------------------------------------------------- + +module Graphics.UI.Gtk.WebKit.SoupAuthDialog ( +-- * Types + SoupAuthDialog, +) where + +import System.Glib.FFI +import System.Glib.GList +import System.Glib.GError [_$_] +import Graphics.UI.Gtk.Gdk.Events + +{#import Graphics.UI.Gtk.Abstract.Object#} (makeNewObject) +{#import Graphics.UI.Gtk.WebKit.Signals#} +{#import Graphics.UI.Gtk.WebKit.Types#} +{#import System.Glib.GObject#} + +{#context lib="webkit" prefix ="webkit"#} hunk ./webkit/Graphics/UI/Gtk/WebKit/SoupAuthDialog.chs.pp 1 --- -*-haskell-*- ------------------------------------------------------------------------------ --- Module : Graphics.UI.Gtk.WebKit.SoupAuthDialog --- Author : Andy Stewart --- Copyright : (c) 2010 Andy Stewart <laz...@gm...> --- --- This library is free software; you can redistribute it and/or --- modify it under the terms of the GNU Lesser General Public --- License as published by the Free Software Foundation; either --- version 2.1 of the License, or (at your option) any later version. --- --- This library is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- Lesser General Public License for more details. --- --- | --- Maintainer : gtk...@li... --- Stability : provisional --- Portability : portable (depends on GHC) --- --- Access to the WebKit Web Resource ------------------------------------------------------------------------------ - -module Graphics.UI.Gtk.WebKit.SoupAuthDialog ( --- * Types - SoupAuthDialog, -) where - -import System.Glib.FFI -import System.Glib.GList -import System.Glib.GError [_$_] -import Graphics.UI.Gtk.Gdk.Events - -{#import Graphics.UI.Gtk.Abstract.Object#} (makeNewObject) -{#import Graphics.UI.Gtk.Signals#} -{#import Graphics.UI.Gtk.WebKit.Types#} -{#import System.Glib.GObject#} - -{#context lib="webkit" prefix ="webkit"#} rmfile ./webkit/Graphics/UI/Gtk/WebKit/SoupAuthDialog.chs.pp hunk ./webkit/Graphics/UI/Gtk/WebKit/WebBackForwardList.chs 61 -{#import Graphics.UI.Gtk.Signals#} +{#import Graphics.UI.Gtk.WebKit.Signals#} addfile ./webkit/Graphics/UI/Gtk/WebKit/WebDataSource.chs hunk ./webkit/Graphics/UI/Gtk/WebKit/WebDataSource.chs 1 +{-# LANGUAGE CPP #-} +-- -*-haskell-*- +----------------------------------------------------------------------------- +-- Module : Graphics.UI.Gtk.WebKit.WebDataSource +-- Author : Andy Stewart +-- Copyright : (c) 2010 Andy Stewart <laz...@gm...> +-- +-- This library is free software; you can redistribute it and/or +-- modify it under the terms of the GNU Lesser General Public +-- License as published by the Free Software Foundation; either +-- version 2.1 of the License, or (at your option) any later version. +-- +-- This library is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-- Lesser General Public License for more details. +-- +-- | +-- Maintainer : gtk...@li... +-- Stability : provisional +-- Portability : portable (depends on GHC) +-- +-- Note +-- +-- Function `webkit_web_data_source_get_data` haven't binding, [_$_] +-- no idea how to handle `GString` +-- +-- Access to the WebKit Web DataSource +----------------------------------------------------------------------------- + +module Graphics.UI.Gtk.WebKit.WebDataSource ( +-- * Types + WebDataSource, + +-- * Constructors + webDataSourceNew, + +-- * Methods [_$_] + webDataSourceGetEncoding, + webDataSourceGetInitialRequest, + webDataSourceGetMainResource, + webDataSourceGetRequest, + webDataSourceGetSubresources, + webDataSourceGetUnreachableUri, + webDataSourceGetWebFrame, + webDataSourceIsLoading, +) where + +import Control.Monad (liftM) + +import System.Glib.FFI +import System.Glib.UTFString +import System.Glib.GList +import System.Glib.GError [_$_] +import Graphics.UI.Gtk.Gdk.Events + +{#import Graphics.UI.Gtk.Abstract.Object#} (makeNewObject) +{#import Graphics.UI.Gtk.WebKit.Signals#} +{#import Graphics.UI.Gtk.WebKit.Types#} +{#import System.Glib.GObject#} + +{#context lib="webkit" prefix ="webkit"#} + +-- | Creates a new 'WebDataSource' instance. [_$_] +-- The URL of the 'WebDataSource' will be set to "about:blank". +webDataSourceNew :: IO WebDataSource +webDataSourceNew = [_$_] + constructNewGObject mkWebDataSource $ {#call web_data_source_new#} [_$_] + +-- | Returns the text encoding name as set in the 'WebView', or if not, the text encoding of the response. +webDataSourceGetEncoding :: + WebDataSourceClass self => self + -> IO String +webDataSourceGetEncoding ds = [_$_] + {#call web_data_source_get_encoding#} (toWebDataSource ds) >>= peekCString + [_$_] +-- | Returns a reference to the original request that was used to load the web content. [_$_] +-- The NetworkRequest returned by this method is the +-- request prior to the "committed" load state. [_$_] +-- See 'webDataSourceGetRequest' for getting the "committed" request. +webDataSourceGetInitialRequest :: + WebDataSourceClass self => self + -> IO NetworkRequest +webDataSourceGetInitialRequest ds = + makeNewGObject mkNetworkRequest $ {# call web_data_source_get_initial_request#} (toWebDataSource ds) + +-- | Returns the main resource of the data_source +webDataSourceGetMainResource :: + WebDataSourceClass self => self + -> IO WebResource [_$_] +webDataSourceGetMainResource ds = + makeNewGObject mkWebResource $ {#call web_data_source_get_main_resource#} (toWebDataSource ds) + [_$_] +-- | Returns a NetworkRequest that was used to create this 'WebDataSource'. [_$_] +-- The NetworkRequest returned by this method is the request that was "committed", [_$_] +-- and hence, different from the request you get from the 'webDataSourceGetInitialRequest' method. +webDataSourceGetRequest :: + WebDataSourceClass self => self + -> IO NetworkRequest +webDataSourceGetRequest ds = + makeNewGObject mkNetworkRequest $ {# call web_data_source_get_request#} (toWebDataSource ds) + +-- | Gives you a List of 'WebResource' objects that compose the 'WebView' to which this 'WebDataSource' is attached. +webDataSourceGetSubresources :: + WebDataSourceClass self => self + -> IO [WebResource] [_$_] +webDataSourceGetSubresources ds = do + glist <- {#call web_data_source_get_subresources#} (toWebDataSource ds) + resourcePtr <- fromGList glist + mapM (makeNewGObject mkWebResource . return) resourcePtr + +-- | Return the unreachable URI of data_source. [_$_] +-- The 'dataSource' will have an unreachable URL [_$_] +-- if it was created using 'WebFrame''s [_$_] +-- 'webFrameLoadAlternateHtmlString' method. +webDataSourceGetUnreachableUri :: + WebDataSourceClass self => self + -> IO String +webDataSourceGetUnreachableUri ds = + {#call web_data_source_get_unreachable_uri#} (toWebDataSource ds) >>= peekCString + +-- | Returns the 'WebFrame' that represents this data source +webDataSourceGetWebFrame :: + WebDataSourceClass self => self + -> IO WebFrame +webDataSourceGetWebFrame ds = + makeNewGObject mkWebFrame $ {#call web_data_source_get_web_frame#} (toWebDataSource ds) + +-- | Determines whether the data source is in the process of loading its content. +webDataSourceIsLoading :: + WebDataSourceClass self => self + -> IO Bool +webDataSourceIsLoading ds = + liftM toBool $ {#call web_data_source_is_loading#} (toWebDataSource ds) hunk ./webkit/Graphics/UI/Gtk/WebKit/WebDataSource.chs.pp 1 --- -*-haskell-*- ------------------------------------------------------------------------------ --- Module : Graphics.UI.Gtk.WebKit.WebDataSource --- Author : Andy Stewart --- Copyright : (c) 2010 Andy Stewart <laz...@gm...> --- --- This library is free software; you can redistribute it and/or --- modify it under the terms of the GNU Lesser General Public --- License as published by the Free Software Foundation; either --- version 2.1 of the License, or (at your option) any later version. --- --- This library is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- Lesser General Public License for more details. --- --- | --- Maintainer : gtk...@li... --- Stability : provisional --- Portability : portable (depends on GHC) --- --- Note --- --- Function `webkit_web_data_source_get_data` haven't binding, [_$_] --- no idea how to handle `GString` --- --- Access to the WebKit Web DataSource ------------------------------------------------------------------------------ - -module Graphics.UI.Gtk.WebKit.WebDataSource ( --- * Types - WebDataSource, - --- * Constructors - webDataSourceNew, - --- * Methods [_$_] - webDataSourceGetEncoding, - webDataSourceGetInitialRequest, - webDataSourceGetMainResource, - webDataSourceGetRequest, - webDataSourceGetSubresources, - webDataSourceGetUnreachableUri, - webDataSourceGetWebFrame, - webDataSourceIsLoading, -) where - -import Control.Monad (liftM) - -import System.Glib.FFI -import System.Glib.UTFString -import System.Glib.GList -import System.Glib.GError [_$_] -import Graphics.UI.Gtk.Gdk.Events - -{#import Graphics.UI.Gtk.Abstract.Object#} (makeNewObject) -{#import Graphics.UI.Gtk.Signals#} -{#import Graphics.UI.Gtk.WebKit.Types#} -{#import System.Glib.GObject#} - -{#context lib="webkit" prefix ="webkit"#} - --- | Creates a new 'WebDataSource' instance. [_$_] --- The URL of the 'WebDataSource' will be set to "about:blank". -webDataSourceNew :: IO WebDataSource -webDataSourceNew = [_$_] - constructNewGObject mkWebDataSource $ {#call web_data_source_new#} [_$_] - --- | Returns the text encoding name as set in the 'WebView', or if not, the text encoding of the response. -webDataSourceGetEncoding :: - WebDataSourceClass self => self - -> IO String -webDataSourceGetEncoding ds = [_$_] - {#call web_data_source_get_encoding#} (toWebDataSource ds) >>= peekCString - [_$_] --- | Retu... [truncated message content] |
From: Axel S. <si...@co...> - 2010-05-01 15:19:26
|
Wed Apr 28 06:12:29 EDT 2010 Andy Stewart <laz...@gm...> * vte Cabal package. Ignore-this: 2618acc76f647f454e6e1bf5f588e858 addfile ./vte/COPYING hunk ./vte/COPYING 1 + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +[_^L_][_$_] + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +[_^L_][_$_] + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + [_$_] + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. +[_^L_][_$_] + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +[_^L_][_$_] + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. +[_^L_][_$_] + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. +[_^L_][_$_] + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. +[_^L_][_$_] + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. +[_^L_][_$_] + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS +[_^L_][_$_] + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + hunk ./vte/Graphics/UI/Gtk/Vte/.keep 1 -keep dir rmfile ./vte/Graphics/UI/Gtk/Vte/.keep hunk ./vte/Graphics/UI/Gtk/Vte/Structs.hsc 1 +{-# LANGUAGE CPP, ForeignFunctionInterface #-} hunk ./vte/Graphics/UI/Gtk/Vte/Structs.hsc 43 -import Graphics.UI.Gtk.General.Structs ( Color(..) ) +import Graphics.UI.Gtk.Abstract.Widget (Color) hunk ./vte/Graphics/UI/Gtk/Vte/Vte.chs 199 -import Graphics.UI.Gtk.General.Structs (Color(..)) +import Graphics.UI.Gtk.Abstract.Widget (Color) hunk ./vte/Graphics/UI/Gtk/Vte/Vte.chs 201 -import Graphics.UI.Gtk.Pango.Font +import Graphics.Rendering.Pango.BasicTypes (FontDescription(FontDescription), makeNewFontDescription) hunk ./vte/Graphics/UI/Gtk/Vte/Vte.chs 207 -{#import Graphics.UI.Gtk.Signals#} +{#import Graphics.UI.Gtk.Vte.Signals#} hunk ./vte/Graphics/UI/Gtk/Vte/Vte.chs 209 -{#import Graphics.UI.Gtk.Pango.Types#} hunk ./vte/Graphics/UI/Gtk/Vte/Vte.chs 772 -terminalSetFont terminal fontDesc = - {#call terminal_set_font#} (toTerminal terminal) fontDesc +terminalSetFont terminal (FontDescription fontDesc) = + {#call terminal_set_font#} (toTerminal terminal) (castPtr $ unsafeForeignPtrToPtr fontDesc) hunk ./vte/Graphics/UI/Gtk/Vte/Vte.chs 790 - makeNewFontDescription fdPtr [_$_] + makeNewFontDescription (castPtr fdPtr) [_$_] addfile ./vte/Setup.hs hunk ./vte/Setup.hs 1 +{-# LANGUAGE CPP #-} + +#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ + ((major) * 10000) \ + + ((minor) * 100) \ + + ((micro) * 1)) + +#define CABAL_VERSION_CHECK(major,minor,micro) \ + (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) + +-- now, this is bad, but Cabal doesn't seem to actually pass any information about +-- its version to CPP, so guess the version depending on the version of GHC +#ifdef CABAL_VERSION_MINOR +#ifndef CABAL_VERSION_MAJOR +#define CABAL_VERSION_MAJOR 1 +#endif +#ifndef CABAL_VERSION_MICRO +#define CABAL_VERSION_MICRO 0 +#endif +#define CABAL_VERSION CABAL_VERSION_ENCODE( \ + CABAL_VERSION_MAJOR, \ + CABAL_VERSION_MINOR, \ + CABAL_VERSION_MICRO) +#else +#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) +#if (__GLASGOW_HASKELL__ >= 612) +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) +#else +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) +#endif +#endif + +-- | Build a Gtk2hs package. +-- +import Distribution.Simple +import Distribution.Simple.PreProcess +import Distribution.InstalledPackageInfo ( importDirs ) +import Distribution.Simple.PackageIndex ( +#if CABAL_VERSION_CHECK(1,8,0) + lookupInstalledPackageId +#else + lookupPackageId +#endif + ) +import Distribution.PackageDescription as PD ( PackageDescription(..), + updatePackageDescription, + BuildInfo(..), + emptyBuildInfo, allBuildInfo, + Library(..), + libModules) +import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), + InstallDirs(..), +#if CABAL_VERSION_CHECK(1,8,0) + componentPackageDeps, +#else + packageDeps, +#endif + absoluteInstallDirs) +import Distribution.Simple.Compiler ( Compiler(..) ) +import Distribution.Simple.Program ( + Program(..), ConfiguredProgram(..), + rawSystemProgramConf, rawSystemProgramStdoutConf, + c2hsProgram, pkgConfigProgram, + simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) +import Distribution.ModuleName ( ModuleName, components, toFilePath ) +import Distribution.Simple.Utils +import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), + defaultCopyFlags, ConfigFlags(configVerbosity), + fromFlag, toFlag) +import Distribution.Simple.BuildPaths ( autogenModulesDir ) +import Distribution.Text ( simpleParse, display ) +import System.FilePath +import System.Directory ( doesFileExist ) +import Distribution.Version (Version(..)) +import Distribution.Verbosity +import Control.Monad (unless) +import Data.Maybe (fromMaybe) +import Data.List (isPrefixOf, nub) +import Data.Char (isAlpha) +import qualified Data.Map as M +import qualified Data.Set as S + + +-- the name of the c2hs pre-compiled header file +precompFile = "precompchs.bin" + +main = defaultMainWithHooks simpleUserHooks { + hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], + hookedPreProcessors = [("chs", ourC2hs)], + confHook = \pd cf -> + confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, + postConf = \args cf pd lbi -> do + genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi + postConf simpleUserHooks args cf pd lbi, + buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> + (buildHook simpleUserHooks) pd lbi uh bf, + copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), + instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest + } + +-- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later +adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo +adjustLocalBuildInfo lbi = + let extra = (Just libBi, []) + libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi + , buildDir lbi ] } + in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } + +ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor +ourC2hs bi lbi = PreProcessor { + platformIndependent = False, + runPreProcessor = runC2HS bi lbi +} + +runC2HS :: BuildInfo -> LocalBuildInfo -> + (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () +runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do + -- have the header file name if we don't have the precompiled header yet + header <- case lookup "x-c2hs-header" (customFieldsBI bi) of + Just h -> return h + Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ + "that sets the C header file to process .chs.pp files.") + + -- c2hs will output files in out dir, removing any leading path of the input file. + -- Thus, append the dir of the input file to the output dir. + let (outFileDir, newOutFile) = splitFileName outFile + let newOutDir = outDir </> outFileDir + -- additional .chi files might be needed that other packages have installed; + -- we assume that these are installed in the same place as .hi files + let chiDirs = [ dir | +#if CABAL_VERSION_CHECK(1,8,0) + ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), + dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] +#else + ipi <- packageDeps lbi, + dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] +#endif + rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ + map ("--include=" ++) (outDir:chiDirs) + ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] + ++ ["--output-dir=" ++ newOutDir, + "--output=" ++ newOutFile, + "--precomp=" ++ buildDir lbi </> precompFile, + header, inDir </> inFile] + +getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] +getCppOptions bi lbi + = nub $ + ["-I" ++ dir | dir <- PD.includeDirs bi] + ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] + +installCHI :: PackageDescription -- ^information from the .cabal file + -> LocalBuildInfo -- ^information from the configure step + -> Verbosity -> CopyDest -- ^flags sent to copy or install + -> IO () +installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do + let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest + -- cannot use the recommended 'findModuleFiles' since it fails if there exists + -- a modules that does not have a .chi file + mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) + (map toFilePath +#if CABAL_VERSION_CHECK(1,8,0) + (PD.libModules lib) +#else + (PD.libModules pkg) +#endif + ) + let files = [ f | Just f <- mFiles ] +#if CABAL_VERSION_CHECK(1,8,0) + installOrdinaryFiles verbosity libPref files +#else + copyFiles verbosity libPref files +#endif + + [_$_] +installCHI _ _ _ _ = return () + +------------------------------------------------------------------------------ +-- Generating the type hierarchy and signal callback .hs files. +------------------------------------------------------------------------------ + +typeGenProgram :: Program +typeGenProgram = (simpleProgram "gtk2hsTypeGen") + +signalGenProgram :: Program +signalGenProgram = (simpleProgram "gtk2hsHookGenerator") + +c2hsLocal :: Program +c2hsLocal = (simpleProgram "gtk2hsC2hs") + +genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () +genSynthezisedFiles verb pd lbi = do + + cPkgs <- getPkgConfigPackages verb lbi pd + + let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) + ++customFieldsPD pd + typeOpts :: [ProgArg] + typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) + | (field,content) <- xList, + "x-types-" `isPrefixOf` field, + field /= "x-types-file"] + ++ [ "--tag=" ++ tag + | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs + , let name' = filter isAlpha (display name) + , tag <- name' + : [ name' ++ "-" ++ show major ++ "." ++ show digit + | digit <- [0,2..minor] ] + ] + + genFile :: Program -> [ProgArg] -> FilePath -> IO () + genFile prog args outFile = do + res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args + rewriteFile outFile res + + case lookup "x-types-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") + genFile typeGenProgram typeOpts f + + case (lookup "x-signals-file" xList, + lookup "x-signals-modname" xList) of + (Just _, Nothing) -> die "You need to specify the module name (X-Signals-ModName) \ + \to generate a signal file." + (Just f, Just mod) -> do + info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") + genFile signalGenProgram [mod] f + (_,_) -> return () + +--FIXME: Cabal should tell us the selected pkg-config package versions in the +-- LocalBuildInfo or equivalent. +-- In the mean time, ask pkg-config again. + +getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] +getPkgConfigPackages verbosity lbi pkg = + sequence + [ do version <- pkgconfig ["--modversion", display pkgname] + case simpleParse version of + Nothing -> die $ "parsing output of pkg-config --modversion failed" + Just v -> return (PackageIdentifier pkgname v) + | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] + where + pkgconfig = rawSystemProgramStdoutConf verbosity + pkgConfigProgram (withPrograms lbi) + +------------------------------------------------------------------------------ +-- Dependency calculation amongst .chs files. +------------------------------------------------------------------------------ + +-- Given all files of the package, find those that end in .chs and extract the +-- .chs files they depend upon. Then return the PackageDescription with these +-- files rearranged so that they are built in a sequence that files that are +-- needed by other files are built first. +fixDeps :: PackageDescription -> IO PackageDescription +fixDeps pd...@PD...ckageDescription { + PD.library = Just li...@PD...brary { + PD.exposedModules = expMods, + PD.libBuildInfo = bi@PD.BuildInfo { + PD.hsSourceDirs = srcDirs, + PD.otherModules = othMods + }}} = do + let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs + (joinPath (components m)) + mExpFiles <- mapM findModule expMods + mOthFiles <- mapM findModule othMods + + -- tag all exposed files with True so we throw an error if we need to build + -- an exposed module before an internal modules (we cannot express this) + let modDeps = zipWith (ModDep True []) expMods mExpFiles++ + zipWith (ModDep False []) othMods mOthFiles + modDeps <- mapM extractDeps modDeps + let (expMods, othMods) = span mdExposed $ sortTopological modDeps + badOther = map (fromMaybe "<no file>" . mdLocation) $ + filter (not . mdExposed) expMods + unless (null badOther) $ + die ("internal chs modules "++intercalate "," badOther++ + " depend on exposed chs modules; cabal needs to build internal modules first") + return pd { PD.library = Just lib { + PD.exposedModules = map mdOriginal expMods, + PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } + }} + +data ModDep = ModDep { + mdExposed :: Bool, + mdRequires :: [ModuleName], + mdOriginal :: ModuleName, + mdLocation :: Maybe FilePath +} + +instance Show ModDep where + show x = show (mdLocation x) + +instance Eq ModDep where + ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 +instance Ord ModDep where + compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 + +-- Extract the dependencies of this file. This is intentionally rather naive as it +-- ignores CPP conditionals. We just require everything which means that the +-- existance of a .chs module may not depend on some CPP condition. [_$_] +extractDeps :: ModDep -> IO ModDep +extractDeps md@ModDep { mdLocation = Nothing } = return md +extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do + let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of + ('i':'m':'p':'o':'r':'t':' ':ys) -> + case simpleParse (takeWhile ((/=) '#') ys) of + Just m -> findImports (m:acc) xxs [_$_] + Nothing -> die ("cannot parse chs import in "++f++":\n"++ + "offending line is {#"++xs) + -- no more imports after the first non-import hook + _ -> return acc + findImports acc (_:xxs) = findImports acc xxs + findImports acc [] = return acc + mods <- findImports [] (lines con) + return md { mdRequires = mods } + +-- Find a total order of the set of modules that are partially sorted by their +-- dependencies on each other. The function returns the sorted list of modules +-- together with a list of modules that are required but not supplied by this +-- in the input set of modules. +sortTopological :: [ModDep] -> [ModDep] +sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) + where + set = M.fromList (map (\m -> (mdOriginal m, m)) ms) + visit (out,visited) m + | m `S.member` visited = (out,visited) + | otherwise = case m `M.lookup` set of + Nothing -> (out, m `S.insert` visited) + Just md -> (md:out', visited') + where + (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) adddir ./vte/demo addfile ./vte/demo/Makefile hunk ./vte/demo/Makefile 1 + +PROG = vte [_$_] +SOURCES = Vte.hs + +$(PROG) : $(SOURCES) + $(HC) --make $< -o $@ $(HCFLAGS) -XForeignFunctionInterface + +clean: + rm -f $(SOURCES:.hs=.hi) $(SOURCES:.hs=.o) $(PROG) + +HC=ghc addfile ./vte/demo/Vte.hs hunk ./vte/demo/Vte.hs 1 +-- A simple program to demonstrate Vte Binding by Cjacker Huang +module Main where + +import Graphics.UI.Gtk +import Graphics.UI.Gtk.Vte.Vte +import Graphics.Rendering.Pango.Font + +main = do + initGUI + window <- windowNew + onDestroy window mainQuit + widgetSetSizeRequest window 640 480 + + scrolled <- scrolledWindowNew Nothing Nothing + scrolledWindowSetPolicy scrolled PolicyAutomatic PolicyAutomatic + vte <- terminalNew + terminalForkCommand vte Nothing Nothing Nothing Nothing False False False + font <- fontDescriptionFromString "DejaVu Sans Mono 10" + terminalSetFont vte font + containerAdd scrolled vte + containerAdd window scrolled + on vte childExited $ mainQuit + + widgetShowAll window + + mainGUI addfile ./vte/vte.cabal hunk ./vte/vte.cabal 1 +Name: vte +Version: 0.10.5 +License: GPL +License-file: COPYING +Copyright: (c) 2001-2010 The Gtk2Hs Team +Author: Andy Stewart, Axel Simon +Maintainer: gtk...@so... +Build-Type: Custom +Cabal-Version: >= 1.6.0 +Stability: provisional +homepage: http://www.haskell.org/gtk2hs/ +bug-reports: http://hackage.haskell.org/trac/gtk2hs/ +Synopsis: Binding to the VTE library. +Description: The VTE library inserts terminal capability strings into a trie, and then + uses it to determine if data received from a pseudo-terminal is a control + sequence or just random data. The sample program "interpret" illustrates + more or less what the widget sees after it filters incoming data. + +Category: Graphics +Tested-With: GHC == 6.12.1 +x-Types-File: Graphics/UI/Gtk/Vte/Types.chs +x-Types-ModName: Graphics.UI.Gtk.Vte.Types +x-Types-Forward: *Graphics.UI.GtkInternals +x-Types-Destructor: objectUnrefFromMainloop +Extra-Source-Files: Graphics/UI/Gtk/Vte/VteCharAttrFields.h + +Source-Repository head + type: darcs + location: http://code.haskell.org/gtk2hs/ + subdir: vte + +Library + build-depends: base >= 4, array, containers, haskell98, mtl, + glib >= 0.10.5 && < 0.11, [_$_] + pango >= 0.10.5 && < 0.11, [_$_] + cairo >= 0.10.5 && < 0.11, + gtk >= 0.10.5 && < 0.11 +[_^I_][_^I_][_^I_][_^I_][_^I_][_^I_][_$_] + build-tools: gtk2hsC2hs, gtk2hsHookGenerator, gtk2hsTypeGen +[_^I_][_^I_][_$_] + exposed-modules: + Graphics.UI.Gtk.Vte.Vte + other-modules: + Graphics.UI.Gtk.Vte.Structs[_^I_][_^I_][_$_] + Graphics.UI.Gtk.Vte.Types + Graphics.UI.Gtk.Vte.Signals[_^I_][_^I_] [_$_] +[_^I_][_^I_] [_$_] + extensions: ForeignFunctionInterface + c-sources: Graphics/UI/Gtk/Vte/VteCharAttrFields.c + + x-c2hs-Header: vte/vte.h + include-dirs: Graphics/UI/Gtk/Vte/ + x-Signals-File: Graphics/UI/Gtk/Vte/Signals.chs + x-Signals-Modname: Graphics.UI.Gtk.Vte.Signals + x-Types-Tag: vte[_^I_][_^I_][_$_] + pkgconfig-depends: vte >= 0.20.5 hunk ./vte/vte.cabal.in 1 -name: vte [_$_] -version: @PACKAGE_VERSION@ -license: LGPL -license-file: COPYING.LIB -maintainer: gtk...@li... -stability: provisional -homepage: http://haskell.org/gtk2hs/ -category: Graphics -build-depends: base-@PKG_BASE_VERSION@ gtk==@PACKAGE_VERSION@ -exposed-modules: ${modules} rmfile ./vte/vte.cabal.in hunk ./vte/vte.package.conf.in 1 -name: vte [_$_] -version: @PACKAGE_VERSION@ -id: vte-@PACKAGE_VERSION@ -license: LGPL -license-file: COPYING.LIB -maintainer: gtk...@li... -stability: provisional -homepage: http://haskell.org/gtk2hs/ -exposed: True -exposed-modules: ${modules} -import-dirs: "${pkglibdir}/imports/vte" -library-dirs: @VTE_LIBDIR_CQ@ -hs-libraries: HSvte -extra-libraries: @VTE_LIBS_CQ@ -include-dirs: @VTE_CFLAGS_CQ@ -includes: vte/vte.h -depends: @PKG_BASE_ID@ gtk-@PACKAGE_VERSION@ -ld-options: @VTE_LIBEXTRA_CQ@ rmfile ./vte/vte.package.conf.in |
From: Axel S. <si...@co...> - 2010-05-01 15:19:23
|
Wed Apr 28 06:07:58 EDT 2010 Andy Stewart <laz...@gm...> * soegtk Cabal package. Ignore-this: ad606092c1d9afbef2a70b8e9b62cc38 addfile ./soegtk/COPYING hunk ./soegtk/COPYING 1 + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +[_^L_][_$_] + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +[_^L_][_$_] + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + [_$_] + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. +[_^L_][_$_] + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +[_^L_][_$_] + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. +[_^L_][_$_] + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. +[_^L_][_$_] + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. +[_^L_][_$_] + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. +[_^L_][_$_] + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS +[_^L_][_$_] + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + addfile ./soegtk/Graphics/SOE/Gtk.chs hunk ./soegtk/Graphics/SOE/Gtk.chs 1 +{-# LANGUAGE CPP #-} +-- -*-haskell-*- +-- SOE implementation based on Gtk and cairo (or Gdk). +-- Some code borrowed from SOE implementation based on OpenGL and GLFW by +-- Paul Liu, http://www.haskell.org/soe/ +-- +-- Author : Duncan Coutts +-- +-- Created: 10 October 2005 +-- +-- Copyright (C) 2005-2007 Duncan Coutts +-- Copyright (C) 2007 Paul Liu +-- +-- This library is free software; you can redistribute it and/or +-- modify it under the terms of the GNU Lesser General Public +-- License as published by the Free Software Foundation; either +-- version 2.1 of the License, or (at your option) any later version. +-- +-- This library is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-- Lesser General Public License for more details. +-- +-- | +-- Maintainer : gtk...@li... +-- Stability : stable +-- Portability : portable (depends on GHC) +-- [_$_] +-- An alternative implementation of the graphics library used in The Haskell +-- School of Expression, by Paul Hudak, <http://www.haskell.org/soe/>. +-- +-- It has exaclty the same interface as the original implementation +-- "Graphics.SOE". See the original for an API reference. +-- +module Graphics.SOE.Gtk ( + runGraphics, + Title, + Size, + Window, + openWindow, + getWindowSize, + clearWindow, + drawInWindow, + drawInWindowNow, + setGraphic, + closeWindow, + openWindowEx, + RedrawMode, + drawGraphic, + drawBufferedGraphic, + Graphic, + emptyGraphic, + overGraphic , + overGraphics, + Color (..), + withColor, + text, + Point, + ellipse, + shearEllipse, + line, + polygon, + polyline, + polyBezier, + Angle, + arc, + Region, + createRectangle, + createEllipse, + createPolygon, + andRegion, + orRegion, + xorRegion, + diffRegion, + drawRegion, + getKey, + getLBP, + getRBP, + Event (..), + maybeGetWindowEvent, + getWindowEvent, + Word32, + timeGetTime, + word32ToInt + ) where + +#if GTK_CHECK_VERSION(2,8,0) && defined(ENABLE_CAIRO) +#define USE_CAIRO +#endif + +import Data.List (foldl') +import Data.Ix (Ix) +import Data.Word (Word32) +import Data.IORef (newIORef, readIORef, writeIORef) +import Control.Concurrent (forkIO, yield, rtsSupportsBoundThreads) +import Control.Concurrent.MVar +import Control.Concurrent.Chan + +import qualified System.Time +import qualified Graphics.UI.Gtk as Gtk +import qualified Graphics.UI.Gtk.Gdk.Events as Events +import qualified Graphics.UI.Gtk.Gdk.GC as GC + +#ifdef USE_CAIRO +import qualified Graphics.UI.Gtk.Cairo as Gtk.Cairo +import qualified Graphics.Rendering.Cairo as Cairo +import qualified Graphics.Rendering.Cairo.Matrix as Matrix +#else +import qualified System.IO (hPutStrLn, stderr) +#endif + +------------------- +-- Window Functions +------------------- + +runGraphics :: IO () -> IO () +runGraphics main + | rtsSupportsBoundThreads = do + Gtk.unsafeInitGUIForThreadedRTS + forkIO (main >> Gtk.postGUIAsync Gtk.mainQuit) + Gtk.mainGUI + | otherwise = do + Gtk.initGUI + quitVar <- newIORef False + forkIO (main >> writeIORef quitVar True) + let loop = do + yield + Gtk.mainIteration + quit <- readIORef quitVar + if quit then return () + else loop + loop + -- give any windows a chance to close + Gtk.flush + +type Title = String +type Size = (Int, Int) + +data Window = Window { + window :: Gtk.Window, + canvas :: Gtk.DrawingArea, + graphicVar :: MVar Graphic, + eventsChan :: Chan Event +} + +openWindow :: Title -> Size -> IO Window +openWindow title size = + openWindowEx title Nothing (Just size) drawBufferedGraphic + +openWindowEx :: Title -> Maybe Point -> Maybe Size -> RedrawMode -> IO Window +openWindowEx title position size (RedrawMode useDoubleBuffer) = + Gtk.postGUISync $ do + window <- Gtk.windowNew + Gtk.windowSetTitle window title + + canvas <- Gtk.drawingAreaNew + Gtk.containerAdd window canvas + Gtk.widgetSetCanFocus canvas True + Gtk.widgetSetRedrawOnAllocate canvas False + Gtk.widgetSetDoubleBuffered canvas useDoubleBuffer + + case position of + Nothing -> return () + Just (x, y) -> Gtk.windowMove window x y + case size of + Nothing -> return () + Just (width, height) -> Gtk.windowSetDefaultSize window width height + + Gtk.widgetShowAll window + + graphicVar <- newMVar emptyGraphic + eventsChan <- newChan + + -- set up the fonts +#ifdef USE_CAIRO + pc <- Gtk.Cairo.cairoCreateContext Nothing +#else + pc <- Gtk.widgetCreatePangoContext canvas +#endif + fd <- Gtk.contextGetFontDescription pc + Gtk.fontDescriptionSetSize fd 12 + Gtk.fontDescriptionSetFamily fd "Sans" + Gtk.contextSetFontDescription pc fd + +#ifndef USE_CAIRO + win <- Gtk.widgetGetDrawWindow canvas + -- set up the graphics context + gc <- GC.gcNew win +#endif + Gtk.onExpose canvas $ \Events.Expose { Events.eventArea = eventArea, + Events.eventRegion = exposeRegion } -> do + Graphic graphic <- readMVar graphicVar + win <- Gtk.widgetGetDrawWindow canvas +#ifdef USE_CAIRO + Gtk.Cairo.renderWithDrawable win $ do + -- clip to the exposed region + Gtk.Cairo.region exposeRegion + Cairo.clip + Cairo.paint --fill backgound with black + Cairo.setSourceRGB 1 1 1 --use white default colour + Cairo.setLineWidth 1.5 + -- actually do the drawing + graphic pc +#else + --fill backgound with black + GC.gcSetValues gc GC.newGCValues { GC.foreground = colorToRGB Black } + case eventArea of + Gtk.Rectangle x y width height -> + Gtk.drawRectangle win gc True x y width height + --use white default colour + GC.gcSetValues gc GC.newGCValues { GC.foreground = colorToRGB White } + + -- actually do the drawing + graphic (Gtk.toDrawable win) gc pc +#endif + return True + + Gtk.onDelete window $ \_ -> do writeChan eventsChan Closed + Gtk.widgetHide window + return True + [_$_] + Gtk.onMotionNotify canvas True $ \Events.Motion { Events.eventX=x, Events.eventY=y} -> + writeChan eventsChan MouseMove { + pt = (round x, round y) + } >> return True + [_$_] + let mouseButtonHandler event@Events.Button { Events.eventX=x, Events.eventY=y } = do + writeChan eventsChan Button { + pt = (round x,round y), + isLeft = Events.eventButton event == Gtk.LeftButton, + isDown = case Events.eventClick event of + Gtk.ReleaseClick -> False + _ -> True + } + return True + Gtk.onButtonPress canvas mouseButtonHandler + Gtk.onButtonRelease canvas mouseButtonHandler + + let keyPressHandler Events.Key { Events.eventKeyChar = Nothing } = return True + keyPressHandler Events.Key { Events.eventKeyChar = Just char, Events.eventRelease = release } = + writeChan eventsChan Key { + char = char, + isDown = not release + } >> return True + Gtk.onKeyPress canvas keyPressHandler + Gtk.onKeyRelease canvas keyPressHandler + + Gtk.onSizeAllocate canvas $ \_ -> writeChan eventsChan Resize + + return Window { + window = window, + canvas = canvas, + graphicVar = graphicVar, + eventsChan = eventsChan + } + +getWindowSize :: Window -> IO Size +getWindowSize win = Gtk.postGUISync $ Gtk.widgetGetSize (canvas win) + +clearWindow :: Window -> IO () +clearWindow win = setGraphic win emptyGraphic + +drawInWindow :: Window -> Graphic -> IO () +drawInWindow win graphic = do + modifyMVar_ (graphicVar win) (return . overGraphic graphic) + Gtk.postGUIAsync $ Gtk.widgetQueueDraw (canvas win) + +drawInWindowNow :: Window -> Graphic -> IO () +drawInWindowNow = drawInWindow + +setGraphic :: Window -> Graphic -> IO () +setGraphic win graphic = do + modifyMVar_ (graphicVar win) (\_ -> return graphic) + Gtk.postGUIAsync $ Gtk.widgetQueueDraw (canvas win) + +closeWindow :: Window -> IO () +closeWindow win = Gtk.postGUIAsync $ Gtk.widgetHide (window win) + +-------------------- +-- Drawing Functions +-------------------- + +newtype RedrawMode = RedrawMode Bool + +drawGraphic :: RedrawMode +drawGraphic = RedrawMode False + +drawBufferedGraphic :: RedrawMode +drawBufferedGraphic = RedrawMode True + +data Color = Black + | Blue + | Green + | Cyan + | Red + | Magenta + | Yellow + | White + deriving (Eq, Ord, Bounded, Enum, Ix, Show, Read) + +type Angle = Float + +#ifdef USE_CAIRO + +-------------------------------------------------- +-- implementation using the new cairo API +-- + +newtype Graphic = Graphic (Gtk.PangoContext -> Cairo.Render ()) + +emptyGraphic :: Graphic +emptyGraphic = Graphic (\_ -> return ()) + +overGraphic :: Graphic -> Graphic -> Graphic +overGraphic (Graphic over) (Graphic base) = Graphic (\pc -> base pc >> over pc) + +overGraphics :: [Graphic] -> Graphic +overGraphics = foldl1 overGraphic + +colorToRGB :: Color -> (Double, Double, Double) +colorToRGB Black = (0, 0, 0) +colorToRGB Blue = (0, 0, 1) +colorToRGB Green = (0, 1, 0) +colorToRGB Cyan = (0, 1, 1) +colorToRGB Red = (1, 0, 0) +colorToRGB Magenta = (1, 0, 1) +colorToRGB Yellow = (1, 1, 0) +colorToRGB White = (1, 1, 1) + +withColor :: Color -> Graphic -> Graphic +withColor color (Graphic graphic) = Graphic $ \pc -> do + Cairo.save + case colorToRGB color of + (r,g,b) -> Cairo.setSourceRGB r g b + -- for some reason the SOE withColor uses a line width of 2, + -- though the default line width outside of withColor is 1. + Cairo.setLineWidth 2 + graphic pc + Cairo.restore + +text :: Point -> String -> Graphic +text (x,y) str = Graphic $ \pc -> do + layout <- Cairo.liftIO $ Gtk.layoutEmpty pc + Gtk.Cairo.updateLayout layout + Cairo.liftIO $ Gtk.layoutSetText layout str + Cairo.moveTo (fromIntegral x) (fromIntegral y) + Gtk.Cairo.showLayout layout + +type Point = (Int, Int) + +ellipse :: Point -> Point -> Graphic +ellipse pt1 pt2 = Graphic $ \pc -> case normaliseBounds pt1 pt2 of + Nothing -> return () + Just (x,y,width,height) -> do + Cairo.save + Cairo.translate (x + width / 2) (y + height / 2) + Cairo.scale (width / 2) (height / 2) + Cairo.arc 0 0 1 0 (2*pi) + Cairo.fill + Cairo.restore + +shearEllipse :: Point -> Point -> Point -> Graphic +shearEllipse (x1,y1) (x2,y2) (x3,y3) = Graphic $ \pc -> do + let x = fromIntegral x1 + y = fromIntegral y1 + scalex = fromIntegral $ abs $ x1 - x3 + scaley = fromIntegral $ abs $ y1 - y2 + shearx = fromIntegral $ abs $ x1 - x2 + sheary = fromIntegral $ abs $ y1 - y3 + + Cairo.save + Cairo.transform (Matrix.Matrix scalex sheary shearx scaley x y) + Cairo.arc 0.5 0.5 0.5 0 (2 * pi) + Cairo.fill + Cairo.restore + +line :: Point -> Point -> Graphic +line (x1, y1) (x2, y2) = Graphic $ \pc -> do + Cairo.moveTo (fromIntegral x1) (fromIntegral y1) + Cairo.lineTo (fromIntegral x2) (fromIntegral y2) + Cairo.stroke + +polygon :: [Point] -> Graphic +polygon [] = Graphic (\_ -> return ()) +polygon ((x,y):ps) = Graphic $ \pc -> do + Cairo.moveTo (fromIntegral x) (fromIntegral y) + sequence_ [ Cairo.lineTo (fromIntegral x) (fromIntegral y) + | (x,y) <- ps ] + Cairo.fill + +polyline :: [Point] -> Graphic +polyline [] = Graphic (\_ -> return ()) +polyline ((x,y):ps) = Graphic $ \pc -> do + Cairo.moveTo (fromIntegral x) (fromIntegral y) + sequence_ [ Cairo.lineTo (fromIntegral x) (fromIntegral y) + | (x,y) <- ps ] + Cairo.stroke + +polyBezier :: [Point] -> Graphic +polyBezier [] = Graphic (\_ -> return ()) +polyBezier ((x,y):ps) = Graphic $ \pc -> do + Cairo.moveTo (fromIntegral x) (fromIntegral y) + let loop ((x1,y1):(x2,y2):(x3,y3):ps) = do + Cairo.curveTo (fromIntegral x1) (fromIntegral y1) + (fromIntegral x2) (fromIntegral y2) + (fromIntegral x3) (fromIntegral y3) + loop ps + loop _ = return () + loop ps + Cairo.stroke + +arc :: Point -> Point -> Angle -> Angle -> Graphic +arc pt1 pt2 start_ extent_ = Graphic $ \pc -> case normaliseBounds pt1 pt2 of + Nothing -> return () + Just (x,y,width,height) -> do + Cairo.save + Cairo.translate (x + width / 2) (y + height / 2) + Cairo.scale (width / 2) (height / 2) + Cairo.moveTo 0 0 + Cairo.arcNegative 0 0 1 (-start * pi / 180) (-(start+extent) * pi / 180) + Cairo.fill + Cairo.restore + where start = realToFrac start_ + extent = realToFrac extent_ + +------------------- +-- Region Functions +------------------- + +data Region = Region { + regionGraphic :: Int -> Int -> Cairo.Render (), + regionOriginX :: !Int, + regionOriginY :: !Int, + regionWidth :: !Int, + regionHeight :: !Int +} + +createRectangle :: Point -> Point -> Region +createRectangle pt1 pt2 = + let (x,y,width,height) = normaliseBounds' pt1 pt2 [_$_] + drawing x y = do + Cairo.rectangle (fromIntegral x) (fromIntegral y) + (fromIntegral width) (fromIntegral height) + Cairo.fill + in Region drawing x y width height + +createEllipse :: Point -> Point -> Region +createEllipse pt1 pt2 = + let (x0,y0,width,height) = normaliseBounds' pt1 pt2 + drawing x y | width==0 || height==0 = return () + | otherwise = do + Cairo.save + Cairo.translate (fromIntegral x + fromIntegral width / 2) + (fromIntegral y + fromIntegral height / 2) + Cairo.scale (fromIntegral width / 2) (fromIntegral height / 2) + Cairo.arc 0 0 1 0 (2*pi) + Cairo.fill + Cairo.restore + in Region drawing x0 y0 width height + +createPolygon :: [Point] -> Region +createPolygon [] = Region (\_ _ -> return ()) 0 0 0 0 +createPolygon (p@(x0,y0):ps) = + let minMax (minx,maxx,miny,maxy) (x,y) = + let minx' = min minx x + maxx' = max maxx x + miny' = min miny y + maxy' = max maxy y + in seq minx' $ seq maxx' $ seq miny' $ seq maxy' $ + (minx',maxx',miny',maxy') + (minx,maxx,miny,maxy) = foldl' minMax (x0,x0,y0,y0) (p:ps) + drawing x y = do + Cairo.save + Cairo.translate (fromIntegral (x-minx)) (fromIntegral (y-miny)) + Cairo.moveTo (fromIntegral x0) (fromIntegral y0) + sequence_ [ Cairo.lineTo (fromIntegral x) (fromIntegral y) + | (x,y) <- ps ] + Cairo.fill + Cairo.restore + in Region drawing minx miny (maxx - minx) (maxy - miny) + +andRegion, orRegion, xorRegion, diffRegion :: Region -> Region -> Region +andRegion = combineRegion Cairo.OperatorIn +orRegion = combineRegion Cairo.OperatorOver +xorRegion = combineRegion Cairo.OperatorXor +diffRegion = combineRegion Cairo.OperatorDestOut + +drawRegion :: Region -> Graphic +drawRegion Region { regionGraphic = graphic, + regionOriginX = x, + regionOriginY = y + } = Graphic $ \_ -> do + graphic x y + +combineRegion :: Cairo.Operator -> Region -> Region -> Region +combineRegion operator a b = + let x = min (regionOriginX a) (regionOriginX b) + y = min (regionOriginY a) (regionOriginY b) + x' = max (regionOriginX a + regionWidth a) (regionOriginX b + regionWidth b) + y' = max (regionOriginY a + regionHeight a) (regionOriginY b + regionHeight b) + width = x' - x + height = y' - y + drawing x'' y'' = do + Cairo.renderWithSimilarSurface Cairo.ContentAlpha width height $ + \surface -> do + Cairo.renderWith surface $ do + Cairo.setSourceRGBA 0 0 0 1 + regionGraphic a (regionOriginX a - x) + (regionOriginY a - y) + Cairo.setOperator operator + regionGraphic b (regionOriginX b - x) + (regionOriginY b - y) + Cairo.maskSurface surface (fromIntegral x'') (fromIntegral y'') + in Region drawing x y width height + +#else + +-------------------------------------------------- +-- implementation using the old Gdk API +-- + +newtype Graphic = Graphic (Gtk.Drawable -> GC.GC -> Gtk.PangoContext -> IO ()) + +emptyGraphic :: Graphic +emptyGraphic = Graphic (\_ _ _ -> return ()) + +overGraphic :: Graphic -> Graphic -> Graphic +overGraphic (Graphic over) (Graphic base) = + Graphic (\dw gc pc -> base dw gc pc >> over dw gc pc) + +overGraphics :: [Graphic] -> Graphic +overGraphics = foldl1 overGraphic + +colorToRGB :: Color -> Gtk.Color +colorToRGB Black = Gtk.Color 0 0 0 +colorToRGB Blue = Gtk.Color 0 0 65535 +colorToRGB Green = Gtk.Color 0 65535 0 +colorToRGB Cyan = Gtk.Color 0 65535 65535 +colorToRGB Red = Gtk.Color 65535 0 0 +colorToRGB Magenta = Gtk.Color 65535 0 65535 +colorToRGB Yellow = Gtk.Color 65535 65535 0 +colorToRGB White = Gtk.Color 65535 65535 65535 + +withColor :: Color -> Graphic -> Graphic +withColor color (Graphic graphic) = Graphic $ \dw gc pc -> do + v <- GC.gcGetValues gc + GC.gcSetValues gc GC.newGCValues { + GC.foreground = colorToRGB color, + GC.lineWidth = 2 + } + graphic dw gc pc + GC.gcSetValues gc GC.newGCValues { + GC.foreground = GC.foreground v, + GC.lineWidth = GC.lineWidth v + } + +text :: Point -> String -> Graphic +text (x,y) str = Graphic $ \dw gc pc -> do + pl <- Gtk.layoutEmpty pc + Gtk.layoutSetText pl str + Gtk.drawLayout dw gc x y pl + +type Point = (Int, Int) + +ellipse :: Point -> Point -> Graphic +ellipse pt1 pt2 = Graphic $ \dw gc pc -> do + let (x,y,width,height) = normaliseBounds' pt1 pt2 + Gtk.drawArc dw gc True x y width height 0 (360*64) + +shearEllipse :: Point -> Point -> Point -> Graphic +shearEllipse (x1,y1) (x2,y2) (x3,y3) = Graphic $ \dw gc pc -> do + let avg a b = (a + b) `div` 2 + x = avg x2 x3 + y = avg y2 y3 + dx1 = fromIntegral ((x2 - x1) `div` 2) + dy1 = fromIntegral ((y2 - y1) `div` 2) + dx2 = fromIntegral ((x3 - x1) `div` 2) + dy2 = fromIntegral ((y3 - y1) `div` 2) + ps = [ (x + round(cos a * dx1 + sin a * dx2) + ,y + round(cos a * dy1 + sin a * dy2)) + | a <- take 60 [0, pi/30 .. ] ] + Gtk.drawPolygon dw gc True ps + +line :: Point -> Point -> Graphic +line p1 p2 = Graphic $ \dw gc pc -> Gtk.drawLine dw gc p1 p2 + +polygon :: [Point] -> Graphic +polygon ps = Graphic $ \dw gc pc -> Gtk.drawPolygon dw gc True ps + +polyline :: [Point] -> Graphic +polyline ps = Graphic $ \dw gc pc -> Gtk.drawLines dw gc ps + +polyBezier :: [Point] -> Graphic +polyBezier ps = Graphic $ \dw gc pc -> do + System.IO.hPutStrLn System.IO.stderr $ "warning: polyBezier is only available " + ++ "in Grahpics.SOE.Gtk built with Gtk+ 2.8 or later -- using polyline instead" + Gtk.drawLines dw gc ps + +arc :: Point -> Point -> Angle -> Angle -> Graphic +arc pt1 pt2 start extent = Graphic $ \dw gc pc -> do + let (x,y,width,height) = normaliseBounds' pt1 pt2 + Gtk.drawArc dw gc True x y width height + (round $ start * 64) + (round $ (start+extent) * 64) + +newtype Region = Region (IO Gtk.Region) + +createRectangle :: Point -> Point -> Region +createRectangle pt1 pt2 = + let (x,y,width,height) = normaliseBounds' pt1 pt2 [_$_] + region = Gtk.regionRectangle (Gtk.Rectangle x y width height) + in Region region + +createEllipse :: Point -> Point -> Region +createEllipse (x1, y1) (x2, y2) = + let rx = (x2 - x1) `div` 2 + ry = (y2 - y1) `div` 2 + cx = x1 + rx + cy = y1 + ry + rx' = fromIntegral rx + ry' = fromIntegral ry + ps = [ (cx + round (rx' * cos a), cy + round (ry' * sin a)) + | a <- take 60 [0, pi/30 .. ] ] + region = Gtk.regionPolygon ps Gtk.WindingRule + in Region region + +createPolygon :: [Point] -> Region +createPolygon ps = + let region = Gtk.regionPolygon ps Gtk.WindingRule + in Region region + +andRegion, orRegion, xorRegion, diffRegion :: Region -> Region -> Region +andRegion (Region a) (Region b) = Region $ do + regionA <- a + regionB <- b + Gtk.regionIntersect regionA regionB + return regionA +orRegion (Region a) (Region b) = Region $ do + regionA <- a + regionB <- b + Gtk.regionUnion regionA regionB + return regionA +xorRegion (Region a) (Region b) = Region $ do + regionA <- a + regionB <- b + Gtk.regionXor regionA regionB + return regionA +diffRegion (Region a) (Region b) = Region $ do + regionA <- a + regionB <- b + Gtk.regionSubtract regionA regionB + return regionA + +drawRegion :: Region -> Graphic +drawRegion (Region mkRegion) = Graphic $ \dw gc pc -> do + region <- mkRegion + rects <- Gtk.regionGetRectangles region + mapM_ (\(Gtk.Rectangle x y width height) -> + Gtk.drawRectangle dw gc True x y width height) + rects + +#endif + +normaliseBounds :: Point -> Point -> Maybe (Double,Double,Double,Double) +normaliseBounds (x1,y1) (x2,y2) = [_$_] + if x1==x2 || y1==y2 then Nothing else Just (x, y, width, height) + where x = fromIntegral $ min x1 x2 + y = fromIntegral $ min y1 y2 + width = fromIntegral $ abs $ x1 - x2 + height = fromIntegral $ abs $ y1 - y2 + +normaliseBounds' :: Point -> Point -> (Int,Int,Int,Int) +normaliseBounds' (x1,y1) (x2,y2) = (x, y, width, height) + where x = min x1 x2 + y = min y1 y2 + width = abs $ x1 - x2 + height = abs $ y1 - y2 + +--------------------------- +-- Event Handling Functions +--------------------------- + +data Event = Key { + char :: Char, + isDown :: Bool + } + | Button { + pt :: Point, + isLeft :: Bool, + isDown :: Bool + } + | MouseMove { + pt :: Point + } + | Resize + | Closed + deriving Show + +getWindowEvent_ :: Window -> IO Event +getWindowEvent_ win = readChan (eventsChan win) + +getWindowEvent :: Window -> IO Event +getWindowEvent win = do + event <- getWindowEvent_ win + -- this says we are ready for another mouse move event + -- (this is part of the pointer move event flood prevention system) + case event of + MouseMove _ -> Gtk.postGUIAsync $ + Gtk.widgetGetDrawWindow (canvas win) + >>= Gtk.drawWindowGetPointer + >> return () + _ -> return () + return event + +maybeGetWindowEvent :: Window -> IO (Maybe Event) +maybeGetWindowEvent win = do + noEvents <- isEmptyChan (eventsChan win) + if noEvents then -- Sync with the main GUI loop or we can end up spinning on + -- maybeGetWindowEvent and prevent the screen redrawing. + -- We also introduce a very short delay here of 5ms. This + -- prevents the program from using 100% cpu and redrawing + -- constantly. This actually makes animation much smoother + -- since the process gets treated as interactive rather than + -- as a CPU hog so the scheduler gives us the benefit on + -- latency. Even with a 5ms delay here we can animate at up + -- to 200fps. + do syncVar <- newEmptyMVar + Gtk.timeoutAddFull (putMVar syncVar () >> return False) + Gtk.priorityDefaultIdle 10 + takeMVar syncVar + return Nothing + else do event <- readChan (eventsChan win) + case event of + MouseMove _ -> Gtk.postGUIAsync $ + Gtk.widgetGetDrawWindow (canvas win) + >>= Gtk.drawWindowGetPointer + >> return () + _ -> return () + return (Just event) + + +getKeyEx :: Window -> Bool -> IO Char +getKeyEx win down = loop + where loop = do e <- getWindowEvent_ win + case e of + (Key { char = ch, isDown = d }) + | d == down -> return ch + Closed -> return '\x0' + _ -> loop + +getKey :: Window -> IO Char +getKey win = do + ch <- getKeyEx win True + if ch == '\x0' then return ch + else getKeyEx win False + +getButton :: Window -> Int -> Bool -> IO Point +getButton win but down = loop + where loop = do e <- getWindowEvent_ win + case e of + (Button { pt = pt, isDown = id }) + | id == down -> return pt + _ -> loop + +getLBP :: Window -> IO Point +getLBP w = getButton w 1 True + +getRBP :: Window -> IO Point +getRBP w = getButton w 2 True + +timeGetTime :: IO Word32 +timeGetTime = do + System.Time.TOD sec psec <- System.Time.getClockTime + return (fromIntegral $ sec * 1000 + psec `div` 1000000000) + +word32ToInt :: Word32 -> Int +word32ToInt = fromIntegral hunk ./soegtk/Graphics/SOE/Gtk.hs.pp 1 --- -*-haskell-*- --- SOE implementation based on Gtk and cairo (or Gdk). --- Some code borrowed from SOE implementation based on OpenGL and GLFW by --- Paul Liu, http://www.haskell.org/soe/ --- --- Author : Duncan Coutts --- --- Created: 10 October 2005 --- --- Copyright (C) 2005-2007 Duncan Coutts --- Copyright (C) 2007 Paul Liu --- --- This library is free software; you can redistribute it and/or --- modify it under the terms of the GNU Lesser General Public --- License as published by the Free Software Foundation; either --- version 2.1 of the License, or (at your option) any later version. --- --- This library is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- Lesser General Public License for more details. --- --- | --- Maintainer : gtk...@li... --- Stability : stable --- Portability : portable (depends on GHC) --- [_$_] --- An alternative implementation of the graphics library used in The Haskell --- School of Expression, by Paul Hudak, <http://www.haskell.org/soe/>. --- --- It has exaclty the same interface as the original implementation --- "Graphics.SOE". See the original for an API reference. --- -module Graphics.SOE.Gtk ( - runGraphics, - Title, - Size, - Window, - openWindow, - getWindowSize, - clearWindow, - drawInWindow, - drawInWindowNow, - setGraphic, - closeWindow, - openWindowEx, - RedrawMode, - drawGraphic, - drawBufferedGraphic, - Graphic, - emptyGraphic, - overGraphic , - overGraphics, - Color (..), - withColor, - text, - Point, - ellipse, - shearEllipse, - line, - polygon, - polyline, - polyBezier, - Angle, - arc, - Region, - createRectangle, - createEllipse, - createPolygon, - andRegion, - orRegion, - xorRegion, - diffRegion, - drawRegion, - getKey, - getLBP, - getRBP, - Event (..), - maybeGetWindowEvent, - getWindowEvent, - Word32, - timeGetTime, - word32ToInt - ) where - -#if GTK_CHECK_VERSION(2,8,0) && defined(ENABLE_CAIRO) -#define USE_CAIRO -#endif - -import Data.List (foldl') -import Data.Ix (Ix) -import Data.Word (Word32) -import Data.IORef (newIORef, readIORef, writeIORef) -import Control.Concurrent (forkIO, yield, rtsSupportsBoundThreads) -import Control.Concurrent.MVar -import Control.Concurrent.Chan - -import qualified System.Time -import qualified Graphics.UI.Gtk as Gtk -import qualified Graphics.UI.Gtk.Gdk.Events as Gtk - -#ifdef USE_CAIRO -import qualified Graphics.UI.Gtk.Cairo as Gtk.Cairo -impo... [truncated message content] |
From: Axel S. <si...@co...> - 2010-05-01 15:19:23
|
Wed Apr 28 06:08:32 EDT 2010 Andy Stewart <laz...@gm...> * svgcairo Cabal package. Ignore-this: 5c55b0a69f3e7938712e3deb51091cac addfile ./svgcairo/COPYING hunk ./svgcairo/COPYING 1 + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +[_^L_][_$_] + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +[_^L_][_$_] + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + [_$_] + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. +[_^L_][_$_] + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +[_^L_][_$_] + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. +[_^L_][_$_] + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. +[_^L_][_$_] + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. +[_^L_][_$_] + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. +[_^L_][_$_] + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS +[_^L_][_$_] + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + addfile ./svgcairo/Setup.hs hunk ./svgcairo/Setup.hs 1 +{-# LANGUAGE CPP #-} + +#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ + ((major) * 10000) \ + + ((minor) * 100) \ + + ((micro) * 1)) + +#define CABAL_VERSION_CHECK(major,minor,micro) \ + (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) + +-- now, this is bad, but Cabal doesn't seem to actually pass any information about +-- its version to CPP, so guess the version depending on the version of GHC +#ifdef CABAL_VERSION_MINOR +#ifndef CABAL_VERSION_MAJOR +#define CABAL_VERSION_MAJOR 1 +#endif +#ifndef CABAL_VERSION_MICRO +#define CABAL_VERSION_MICRO 0 +#endif +#define CABAL_VERSION CABAL_VERSION_ENCODE( \ + CABAL_VERSION_MAJOR, \ + CABAL_VERSION_MINOR, \ + CABAL_VERSION_MICRO) +#else +#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) +#if (__GLASGOW_HASKELL__ >= 612) +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) +#else +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) +#endif +#endif + +-- | Build a Gtk2hs package. +-- +import Distribution.Simple +import Distribution.Simple.PreProcess +import Distribution.InstalledPackageInfo ( importDirs ) +import Distribution.Simple.PackageIndex ( +#if CABAL_VERSION_CHECK(1,8,0) + lookupInstalledPackageId +#else + lookupPackageId +#endif + ) +import Distribution.PackageDescription as PD ( PackageDescription(..), + updatePackageDescription, + BuildInfo(..), + emptyBuildInfo, allBuildInfo, + Library(..), + libModules) +import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), + InstallDirs(..), +#if CABAL_VERSION_CHECK(1,8,0) + componentPackageDeps, +#else + packageDeps, +#endif + absoluteInstallDirs) +import Distribution.Simple.Compiler ( Compiler(..) ) +import Distribution.Simple.Program ( + Program(..), ConfiguredProgram(..), + rawSystemProgramConf, rawSystemProgramStdoutConf, + c2hsProgram, pkgConfigProgram, + simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) +import Distribution.ModuleName ( ModuleName, components, toFilePath ) +import Distribution.Simple.Utils +import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), + defaultCopyFlags, ConfigFlags(configVerbosity), + fromFlag, toFlag) +import Distribution.Simple.BuildPaths ( autogenModulesDir ) +import Distribution.Text ( simpleParse, display ) +import System.FilePath +import System.Directory ( doesFileExist ) +import Distribution.Version (Version(..)) +import Distribution.Verbosity +import Control.Monad (unless) +import Data.Maybe (fromMaybe) +import Data.List (isPrefixOf, nub) +import Data.Char (isAlpha) +import qualified Data.Map as M +import qualified Data.Set as S + + +-- the name of the c2hs pre-compiled header file +precompFile = "precompchs.bin" + +main = defaultMainWithHooks simpleUserHooks { + hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], + hookedPreProcessors = [("chs", ourC2hs)], + confHook = \pd cf -> + confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, + postConf = \args cf pd lbi -> do + genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi + postConf simpleUserHooks args cf pd lbi, + buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> + (buildHook simpleUserHooks) pd lbi uh bf, + copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), + instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest + } + +-- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later +adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo +adjustLocalBuildInfo lbi = + let extra = (Just libBi, []) + libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi + , buildDir lbi ] } + in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } + +ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor +ourC2hs bi lbi = PreProcessor { + platformIndependent = False, + runPreProcessor = runC2HS bi lbi +} + +runC2HS :: BuildInfo -> LocalBuildInfo -> + (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () +runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do + -- have the header file name if we don't have the precompiled header yet + header <- case lookup "x-c2hs-header" (customFieldsBI bi) of + Just h -> return h + Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ + "that sets the C header file to process .chs.pp files.") + + -- c2hs will output files in out dir, removing any leading path of the input file. + -- Thus, append the dir of the input file to the output dir. + let (outFileDir, newOutFile) = splitFileName outFile + let newOutDir = outDir </> outFileDir + -- additional .chi files might be needed that other packages have installed; + -- we assume that these are installed in the same place as .hi files + let chiDirs = [ dir | +#if CABAL_VERSION_CHECK(1,8,0) + ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), + dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] +#else + ipi <- packageDeps lbi, + dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] +#endif + rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ + map ("--include=" ++) (outDir:chiDirs) + ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] + ++ ["--output-dir=" ++ newOutDir, + "--output=" ++ newOutFile, + "--precomp=" ++ buildDir lbi </> precompFile, + header, inDir </> inFile] + +getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] +getCppOptions bi lbi + = nub $ + ["-I" ++ dir | dir <- PD.includeDirs bi] + ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] + +installCHI :: PackageDescription -- ^information from the .cabal file + -> LocalBuildInfo -- ^information from the configure step + -> Verbosity -> CopyDest -- ^flags sent to copy or install + -> IO () +installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do + let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest + -- cannot use the recommended 'findModuleFiles' since it fails if there exists + -- a modules that does not have a .chi file + mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) + (map toFilePath +#if CABAL_VERSION_CHECK(1,8,0) + (PD.libModules lib) +#else + (PD.libModules pkg) +#endif + ) + let files = [ f | Just f <- mFiles ] +#if CABAL_VERSION_CHECK(1,8,0) + installOrdinaryFiles verbosity libPref files +#else + copyFiles verbosity libPref files +#endif + + [_$_] +installCHI _ _ _ _ = return () + +------------------------------------------------------------------------------ +-- Generating the type hierarchy and signal callback .hs files. +------------------------------------------------------------------------------ + +typeGenProgram :: Program +typeGenProgram = (simpleProgram "gtk2hsTypeGen") + +signalGenProgram :: Program +signalGenProgram = (simpleProgram "gtk2hsHookGenerator") + +c2hsLocal :: Program +c2hsLocal = (simpleProgram "gtk2hsC2hs") + +genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () +genSynthezisedFiles verb pd lbi = do + + cPkgs <- getPkgConfigPackages verb lbi pd + + let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) + ++customFieldsPD pd + typeOpts :: [ProgArg] + typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) + | (field,content) <- xList, + "x-types-" `isPrefixOf` field, + field /= "x-types-file"] + ++ [ "--tag=" ++ tag + | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs + , let name' = filter isAlpha (display name) + , tag <- name' + : [ name' ++ "-" ++ show major ++ "." ++ show digit + | digit <- [0,2..minor] ] + ] + + genFile :: Program -> [ProgArg] -> FilePath -> IO () + genFile prog args outFile = do + res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args + rewriteFile outFile res + + case lookup "x-types-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") + genFile typeGenProgram typeOpts f + + case (lookup "x-signals-file" xList, + lookup "x-signals-modname" xList) of + (Just _, Nothing) -> die "You need to specify the module name (X-Signals-ModName) \ + \to generate a signal file." + (Just f, Just mod) -> do + info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") + genFile signalGenProgram [mod] f + (_,_) -> return () + +--FIXME: Cabal should tell us the selected pkg-config package versions in the +-- LocalBuildInfo or equivalent. +-- In the mean time, ask pkg-config again. + +getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] +getPkgConfigPackages verbosity lbi pkg = + sequence + [ do version <- pkgconfig ["--modversion", display pkgname] + case simpleParse version of + Nothing -> die $ "parsing output of pkg-config --modversion failed" + Just v -> return (PackageIdentifier pkgname v) + | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] + where + pkgconfig = rawSystemProgramStdoutConf verbosity + pkgConfigProgram (withPrograms lbi) + +------------------------------------------------------------------------------ +-- Dependency calculation amongst .chs files. +------------------------------------------------------------------------------ + +-- Given all files of the package, find those that end in .chs and extract the +-- .chs files they depend upon. Then return the PackageDescription with these +-- files rearranged so that they are built in a sequence that files that are +-- needed by other files are built first. +fixDeps :: PackageDescription -> IO PackageDescription +fixDeps pd...@PD...ckageDescription { + PD.library = Just li...@PD...brary { + PD.exposedModules = expMods, + PD.libBuildInfo = bi@PD.BuildInfo { + PD.hsSourceDirs = srcDirs, + PD.otherModules = othMods + }}} = do + let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs + (joinPath (components m)) + mExpFiles <- mapM findModule expMods + mOthFiles <- mapM findModule othMods + + -- tag all exposed files with True so we throw an error if we need to build + -- an exposed module before an internal modules (we cannot express this) + let modDeps = zipWith (ModDep True []) expMods mExpFiles++ + zipWith (ModDep False []) othMods mOthFiles + modDeps <- mapM extractDeps modDeps + let (expMods, othMods) = span mdExposed $ sortTopological modDeps + badOther = map (fromMaybe "<no file>" . mdLocation) $ + filter (not . mdExposed) expMods + unless (null badOther) $ + die ("internal chs modules "++intercalate "," badOther++ + " depend on exposed chs modules; cabal needs to build internal modules first") + return pd { PD.library = Just lib { + PD.exposedModules = map mdOriginal expMods, + PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } + }} + +data ModDep = ModDep { + mdExposed :: Bool, + mdRequires :: [ModuleName], + mdOriginal :: ModuleName, + mdLocation :: Maybe FilePath +} + +instance Show ModDep where + show x = show (mdLocation x) + +instance Eq ModDep where + ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 +instance Ord ModDep where + compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 + +-- Extract the dependencies of this file. This is intentionally rather naive as it +-- ignores CPP conditionals. We just require everything which means that the +-- existance of a .chs module may not depend on some CPP condition. [_$_] +extractDeps :: ModDep -> IO ModDep +extractDeps md@ModDep { mdLocation = Nothing } = return md +extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do + let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of + ('i':'m':'p':'o':'r':'t':' ':ys) -> + case simpleParse (takeWhile ((/=) '#') ys) of + Just m -> findImports (m:acc) xxs [_$_] + Nothing -> die ("cannot parse chs import in "++f++":\n"++ + "offending line is {#"++xs) + -- no more imports after the first non-import hook + _ -> return acc + findImports acc (_:xxs) = findImports acc xxs + findImports acc [] = return acc + mods <- findImports [] (lines con) + return md { mdRequires = mods } + +-- Find a total order of the set of modules that are partially sorted by their +-- dependencies on each other. The function returns the sorted list of modules +-- together with a list of modules that are required but not supplied by this +-- in the input set of modules. +sortTopological :: [ModDep] -> [ModDep] +sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) + where + set = M.fromList (map (\m -> (mdOriginal m, m)) ms) + visit (out,visited) m + | m `S.member` visited = (out,visited) + | otherwise = case m `M.lookup` set of + Nothing -> (out, m `S.insert` visited) + Just md -> (md:out', visited') + where + (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) addfile ./svgcairo/svgcairo.cabal hunk ./svgcairo/svgcairo.cabal 1 +Name: svgcairo +Version: 0.10.5 +License: GPL +License-file: COPYING +Copyright: (c) 2001-2010 The Gtk2Hs Team +Author: Duncan Coutts +Maintainer: gtk...@so... +Build-Type: Custom +Cabal-Version: >= 1.6.0 +Stability: provisional +homepage: http://www.haskell.org/gtk2hs/ +bug-reports: http://hackage.haskell.org/trac/gtk2hs/ +Synopsis: Binding to the GTK+ OpenGL Extension +Description: Svgcairo provides the GDK objects to support OpenGL rendering in GTK+, + and GtkWidget API add-ons to make GTK+ widgets OpenGL-capable. + +Category: Graphics +Tested-With: GHC == 6.12.1 +x-Types-Forward: *System.Glib.GObject *Graphics.UI.GtkInternals +x-Types-Destructor: objectUnrefFromMainloop +Extra-Source-Files: svgcairo.h + +Source-Repository head + type: darcs + location: http://code.haskell.org/gtk2hs/ + subdir: svgcairo + +Library + build-depends: base >= 4, array, containers, haskell98, mtl, + glib >= 0.10.5 && < 0.11, [_$_] + pango >= 0.10.5 && < 0.11, [_$_] + cairo >= 0.10.5 && < 0.11, + gtk >= 0.10.5 && < 0.11 +[_^I_][_^I_][_^I_][_^I_][_^I_][_^I_][_$_] + build-tools: gtk2hsC2hs, gtk2hsHookGenerator, gtk2hsTypeGen +[_^I_][_^I_][_$_] + exposed-modules: + Graphics.Rendering.Cairo.SVG +[_^I_][_^I_] [_$_] + extensions: ForeignFunctionInterface +[_^I_][_^I_][_$_] + x-c2hs-Header: svgcairo.h + pkgconfig-depends: librsvg-2.0 >= 2.16.0 hunk ./svgcairo/svgcairo.cabal.in 1 -name: svgcairo -version: @PACKAGE_VERSION@ -license: BSD3 -license-file: cairo/COPYRIGHT -copyright: (c) Duncan Coutts 2005, (c) Paolo Martini 2005 -author: Duncan Coutts, Paolo Martini -maintainer: gtk...@li... -stability: provisional -homepage: http://haskell.org/gtk2hs/ -category: Graphics -build-depends: base-@PKG_BASE_VERSION@ mtl-@PKG_MTL_VERSION@ glib==@PACKAGE_VERSION@ cairo==@PACKAGE_VERSION@ -exposed-modules: ${modules} rmfile ./svgcairo/svgcairo.cabal.in hunk ./svgcairo/svgcairo.h 3 +#include <librsvg/librsvg-features.h> hunk ./svgcairo/svgcairo.package.conf.in 1 -name: svgcairo -version: @PACKAGE_VERSION@ -id: svgcairo-@PACKAGE_VERSION@ -license: BSD3 -license-file: cairo/COPYRIGHT -copyright: (c) Duncan Coutts 2005, (c) Paolo Martini 2005 -author: Duncan Coutts, Paolo Martini -maintainer: gtk...@li... -stability: provisional -homepage: http://haskell.org/gtk2hs/ -exposed: True -exposed-modules: ${modules} -import-dirs: "${pkglibdir}/imports/svgcairo" -library-dirs: @SVGCAIRO_LIBDIR_CQ@ -hs-libraries: HSsvgcairo -extra-libraries: @SVGCAIRO_LIBS_CQ@ -include-dirs: @SVGCAIRO_CFLAGS_CQ@ -includes: librsvg/rsvg-cairo.h, librsvg/rsvg.h -depends: @PKG_BASE_ID@ @PKG_MTL_ID@ glib-@PACKAGE_VERSION@ cairo-@PACKAGE_VERSION@ -ld-options: @SVGCAIRO_LIBEXTRA_CQ@ rmfile ./svgcairo/svgcairo.package.conf.in |
From: Axel S. <si...@co...> - 2010-05-01 15:19:21
|
Wed Apr 28 06:06:57 EDT 2010 Andy Stewart <laz...@gm...> * gtksource2 Cabal package. Ignore-this: d9c8bd42bc893928d04b132a1a6c29ae addfile ./gtksourceview2/COPYING hunk ./gtksourceview2/COPYING 1 + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +[_^L_][_$_] + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +[_^L_][_$_] + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + [_$_] + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. +[_^L_][_$_] + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +[_^L_][_$_] + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. +[_^L_][_$_] + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. +[_^L_][_$_] + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. +[_^L_][_$_] + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. +[_^L_][_$_] + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS +[_^L_][_$_] + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceBuffer.chs 1 +{-# LANGUAGE CPP #-} hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceBuffer.chs 69 -{#import Graphics.UI.Gtk.Types#} hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceBuffer.chs 70 -{#import Graphics.UI.Gtk.Signals#} -{#import Graphics.UI.Gtk.Multiline.Types#} +{#import Graphics.UI.Gtk.SourceView.Signals#} +import Graphics.UI.GtkInternals hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceIter.chs 1 +{-# LANGUAGE CPP #-} hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceIter.chs 45 -{#import Graphics.UI.Gtk.Types#} hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceIter.chs 46 -{#import Graphics.UI.Gtk.Multiline.Types#} +import Graphics.UI.GtkInternals hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceLanguage.chs 1 +{-# LANGUAGE CPP #-} hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceLanguage.chs 51 -{#import Graphics.UI.Gtk.Types#} hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceLanguage.chs 52 -{#import Graphics.UI.Gtk.Signals#} +{#import Graphics.UI.Gtk.SourceView.Signals#} hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceLanguageManager.chs 37 -#if GTKSOURCEVIEW2_CHECK_VERSION(2,4,0) hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceLanguageManager.chs 38 -#endif hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceLanguageManager.chs 49 -{#import Graphics.UI.Gtk.Signals#} +{#import Graphics.UI.Gtk.SourceView.Signals#} hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceLanguageManager.chs 98 -#if GTKSOURCEVIEW2_CHECK_VERSION(2,4,0) hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceLanguageManager.chs 109 -#endif hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceMark.chs 1 +{-# LANGUAGE CPP #-} hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceMark.chs 40 -{#import Graphics.UI.Gtk.Types#} hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceStyle.hs 1 +{-# LANGUAGE CPP #-} hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceStyle/Internal.chs 1 +{-# LANGUAGE CPP #-} hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceStyleScheme.chs 1 +{-# LANGUAGE CPP #-} hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceStyleScheme.chs 49 -{#import Graphics.UI.Gtk.Types#} hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceStyleSchemeManager.chs 1 +{-# LANGUAGE CPP #-} hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceView.chs 1 +{-# LANGUAGE CPP #-} hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceView.chs 78 -{#import Graphics.UI.Gtk.Types#} hunk ./gtksourceview2/Graphics/UI/Gtk/SourceView/SourceView.chs 79 -{#import Graphics.UI.Gtk.Signals#} +{#import Graphics.UI.Gtk.SourceView.Signals#} addfile ./gtksourceview2/Setup.hs hunk ./gtksourceview2/Setup.hs 1 +{-# LANGUAGE CPP #-} + +#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ + ((major) * 10000) \ + + ((minor) * 100) \ + + ((micro) * 1)) + +#define CABAL_VERSION_CHECK(major,minor,micro) \ + (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) + +-- now, this is bad, but Cabal doesn't seem to actually pass any information about +-- its version to CPP, so guess the version depending on the version of GHC +#ifdef CABAL_VERSION_MINOR +#ifndef CABAL_VERSION_MAJOR +#define CABAL_VERSION_MAJOR 1 +#endif +#ifndef CABAL_VERSION_MICRO +#define CABAL_VERSION_MICRO 0 +#endif +#define CABAL_VERSION CABAL_VERSION_ENCODE( \ + CABAL_VERSION_MAJOR, \ + CABAL_VERSION_MINOR, \ + CABAL_VERSION_MICRO) +#else +#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) +#if (__GLASGOW_HASKELL__ >= 612) +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) +#else +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) +#endif +#endif + +-- | Build a Gtk2hs package. +-- +import Distribution.Simple +import Distribution.Simple.PreProcess +import Distribution.InstalledPackageInfo ( importDirs ) +import Distribution.Simple.PackageIndex ( +#if CABAL_VERSION_CHECK(1,8,0) + lookupInstalledPackageId +#else + lookupPackageId +#endif + ) +import Distribution.PackageDescription as PD ( PackageDescription(..), + updatePackageDescription, + BuildInfo(..), + emptyBuildInfo, allBuildInfo, + Library(..), + libModules) +import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), + InstallDirs(..), +#if CABAL_VERSION_CHECK(1,8,0) + componentPackageDeps, +#else + packageDeps, +#endif + absoluteInstallDirs) +import Distribution.Simple.Compiler ( Compiler(..) ) +import Distribution.Simple.Program ( + Program(..), ConfiguredProgram(..), + rawSystemProgramConf, rawSystemProgramStdoutConf, + c2hsProgram, pkgConfigProgram, + simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) +import Distribution.ModuleName ( ModuleName, components, toFilePath ) +import Distribution.Simple.Utils +import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), + defaultCopyFlags, ConfigFlags(configVerbosity), + fromFlag, toFlag) +import Distribution.Simple.BuildPaths ( autogenModulesDir ) +import Distribution.Text ( simpleParse, display ) +import System.FilePath +import System.Directory ( doesFileExist ) +import Distribution.Version (Version(..)) +import Distribution.Verbosity +import Control.Monad (unless) +import Data.Maybe (fromMaybe) +import Data.List (isPrefixOf, nub) +import Data.Char (isAlpha) +import qualified Data.Map as M +import qualified Data.Set as S + + +-- the name of the c2hs pre-compiled header file +precompFile = "precompchs.bin" + +main = defaultMainWithHooks simpleUserHooks { + hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], + hookedPreProcessors = [("chs", ourC2hs)], + confHook = \pd cf -> + confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, + postConf = \args cf pd lbi -> do + genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi + postConf simpleUserHooks args cf pd lbi, + buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> + (buildHook simpleUserHooks) pd lbi uh bf, + copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), + instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest + } + +-- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later +adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo +adjustLocalBuildInfo lbi = + let extra = (Just libBi, []) + libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi + , buildDir lbi ] } + in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } + +ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor +ourC2hs bi lbi = PreProcessor { + platformIndependent = False, + runPreProcessor = runC2HS bi lbi +} + +runC2HS :: BuildInfo -> LocalBuildInfo -> + (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () +runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do + -- have the header file name if we don't have the precompiled header yet + header <- case lookup "x-c2hs-header" (customFieldsBI bi) of + Just h -> return h + Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ + "that sets the C header file to process .chs.pp files.") + + -- c2hs will output files in out dir, removing any leading path of the input file. + -- Thus, append the dir of the input file to the output dir. + let (outFileDir, newOutFile) = splitFileName outFile + let newOutDir = outDir </> outFileDir + -- additional .chi files might be needed that other packages have installed; + -- we assume that these are installed in the same place as .hi files + let chiDirs = [ dir | +#if CABAL_VERSION_CHECK(1,8,0) + ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), + dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] +#else + ipi <- packageDeps lbi, + dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] +#endif + rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ + map ("--include=" ++) (outDir:chiDirs) + ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] + ++ ["--output-dir=" ++ newOutDir, + "--output=" ++ newOutFile, + "--precomp=" ++ buildDir lbi </> precompFile, + header, inDir </> inFile] + +getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] +getCppOptions bi lbi + = nub $ + ["-I" ++ dir | dir <- PD.includeDirs bi] + ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] + +installCHI :: PackageDescription -- ^information from the .cabal file + -> LocalBuildInfo -- ^information from the configure step + -> Verbosity -> CopyDest -- ^flags sent to copy or install + -> IO () +installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do + let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest + -- cannot use the recommended 'findModuleFiles' since it fails if there exists + -- a modules that does not have a .chi file + mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) + (map toFilePath +#if CABAL_VERSION_CHECK(1,8,0) + (PD.libModules lib) +#else + (PD.libModules pkg) +#endif + ) + let files = [ f | Just f <- mFiles ] +#if CABAL_VERSION_CHECK(1,8,0) + installOrdinaryFiles verbosity libPref files +#else + copyFiles verbosity libPref files +#endif + + [_$_] +installCHI _ _ _ _ = return () + +------------------------------------------------------------------------------ +-- Generating the type hierarchy and signal callback .hs files. +------------------------------------------------------------------------------ + +typeGenProgram :: Program +typeGenProgram = (simpleProgram "gtk2hsTypeGen") + +signalGenProgram :: Program +signalGenProgram = (simpleProgram "gtk2hsHookGenerator") + +c2hsLocal :: Program +c2hsLocal = (simpleProgram "gtk2hsC2hs") + +genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () +genSynthezisedFiles verb pd lbi = do + + cPkgs <- getPkgConfigPackages verb lbi pd + + let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) + ++customFieldsPD pd + typeOpts :: [ProgArg] + typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) + | (field,content) <- xList, + "x-types-" `isPrefixOf` field, + field /= "x-types-file"] + ++ [ "--tag=" ++ tag + | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs + , let name' = filter isAlpha (display name) + , tag <- name' + : [ name' ++ "-" ++ show major ++ "." ++ show digit + | digit <- [0,2..minor] ] + ] + + genFile :: Program -> [ProgArg] -> FilePath -> IO () + genFile prog args outFile = do + res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args + rewriteFile outFile res + + case lookup "x-types-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") + genFile typeGenProgram typeOpts f + + case (lookup "x-signals-file" xList, + lookup "x-signals-modname" xList) of + (Just _, Nothing) -> die "You need to specify the module name (X-Signals-ModName) \ + \to generate a signal file." + (Just f, Just mod) -> do + info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") + genFile signalGenProgram [mod] f + (_,_) -> return () + +--FIXME: Cabal should tell us the selected pkg-config package versions in the +-- LocalBuildInfo or equivalent. +-- In the mean time, ask pkg-config again. + +getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] +getPkgConfigPackages verbosity lbi pkg = + sequence + [ do version <- pkgconfig ["--modversion", display pkgname] + case simpleParse version of + Nothing -> die $ "parsing output of pkg-config --modversion failed" + Just v -> return (PackageIdentifier pkgname v) + | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] + where + pkgconfig = rawSystemProgramStdoutConf verbosity + pkgConfigProgram (withPrograms lbi) + +------------------------------------------------------------------------------ +-- Dependency calculation amongst .chs files. +------------------------------------------------------------------------------ + +-- Given all files of the package, find those that end in .chs and extract the +-- .chs files they depend upon. Then return the PackageDescription with these +-- files rearranged so that they are built in a sequence that files that are +-- needed by other files are built first. +fixDeps :: PackageDescription -> IO PackageDescription +fixDeps pd...@PD...ckageDescription { + PD.library = Just li...@PD...brary { + PD.exposedModules = expMods, + PD.libBuildInfo = bi@PD.BuildInfo { + PD.hsSourceDirs = srcDirs, + PD.otherModules = othMods + }}} = do + let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs + (joinPath (components m)) + mExpFiles <- mapM findModule expMods + mOthFiles <- mapM findModule othMods + + -- tag all exposed files with True so we throw an error if we need to build + -- an exposed module before an internal modules (we cannot express this) + let modDeps = zipWith (ModDep True []) expMods mExpFiles++ + zipWith (ModDep False []) othMods mOthFiles + modDeps <- mapM extractDeps modDeps + let (expMods, othMods) = span mdExposed $ sortTopological modDeps + badOther = map (fromMaybe "<no file>" . mdLocation) $ + filter (not . mdExposed) expMods + unless (null badOther) $ + die ("internal chs modules "++intercalate "," badOther++ + " depend on exposed chs modules; cabal needs to build internal modules first") + return pd { PD.library = Just lib { + PD.exposedModules = map mdOriginal expMods, + PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } + }} + +data ModDep = ModDep { + mdExposed :: Bool, + mdRequires :: [ModuleName], + mdOriginal :: ModuleName, + mdLocation :: Maybe FilePath +} + +instance Show ModDep where + show x = show (mdLocation x) + +instance Eq ModDep where + ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 +instance Ord ModDep where + compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 + +-- Extract the dependencies of this file. This is intentionally rather naive as it +-- ignores CPP conditionals. We just require everything which means that the +-- existance of a .chs module may not depend on some CPP condition. [_$_] +extractDeps :: ModDep -> IO ModDep +extractDeps md@ModDep { mdLocation = Nothing } = return md +extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do + let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of + ('i':'m':'p':'o':'r':'t':' ':ys) -> + case simpleParse (takeWhile ((/=) '#') ys) of + Just m -> findImports (m:acc) xxs [_$_] + Nothing -> die ("cannot parse chs import in "++f++":\n"++ + "offending line is {#"++xs) + -- no more imports after the first non-import hook + _ -> return acc + findImports acc (_:xxs) = findImports acc xxs + findImports acc [] = return acc + mods <- findImports [] (lines con) + return md { mdRequires = mods } + +-- Find a total order of the set of modules that are partially sorted by their +-- dependencies on each other. The function returns the sorted list of modules +-- together with a list of modules that are required but not supplied by this +-- in the input set of modules. +sortTopological :: [ModDep] -> [ModDep] +sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) + where + set = M.fromList (map (\m -> (mdOriginal m, m)) ms) + visit (out,visited) m + | m `S.member` visited = (out,visited) + | otherwise = case m `M.lookup` set of + Nothing -> (out, m `S.insert` visited) + Just md -> (md:out', visited') + where + (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) addfile ./gtksourceview2/gtksourceview2.cabal hunk ./gtksourceview2/gtksourceview2.cabal 1 +Name: gtksourceview2 +Version: 0.10.5 +License: GPL +License-file: COPYING +Copyright: (c) 2001-2010 The Gtk2Hs Team +Author: Duncan Coutts, Peter Gavin, Axel Simon +Maintainer: gtk...@so... +Build-Type: Custom +Cabal-Version: >= 1.6.0 +Stability: provisional +homepage: http://www.haskell.org/gtk2hs/ +bug-reports: http://hackage.haskell.org/trac/gtk2hs/ +Synopsis: Binding to the GtkSourceView library. +Description: GtkSourceView is a text widget that extends the standard GTK+ 2.x text widget + GtkTextView. It improves GtkTextView by implementing syntax highlighting and + other features typical of a source editor. + +Category: Graphics +Tested-With: GHC == 6.12.1 +x-Types-File: Graphics/UI/Gtk/SourceView/Types.chs +x-Types-ModName: Graphics.UI.Gtk.SourceView.Types +x-Types-Forward: *Graphics.UI.GtkInternals +x-Types-Destructor: objectUnrefFromMainloop +Extra-Source-Files: gtksourceview2.h + +Source-Repository head + type: darcs + location: http://code.haskell.org/gtk2hs/ + subdir: gtksourceview2 + +Library + build-depends: base >= 4, array, containers, haskell98, mtl, + glib >= 0.10.5 && < 0.11, [_$_] + pango >= 0.10.5 && < 0.11, [_$_] + cairo >= 0.10.5 && < 0.11, + gtk >= 0.10.5 && < 0.11 +[_^I_][_^I_][_^I_][_^I_][_^I_][_^I_][_$_] + build-tools: gtk2hsC2hs, gtk2hsHookGenerator, gtk2hsTypeGen +[_^I_][_^I_][_^I_][_^I_][_^I_][_^I_][_$_] + exposed-modules: + Graphics.UI.Gtk.SourceView + Graphics.UI.Gtk.SourceView.SourceBuffer + Graphics.UI.Gtk.SourceView.SourceIter + Graphics.UI.Gtk.SourceView.SourceLanguage + Graphics.UI.Gtk.SourceView.SourceLanguageManager + Graphics.UI.Gtk.SourceView.SourceMark + Graphics.UI.Gtk.SourceView.SourceStyle + Graphics.UI.Gtk.SourceView.SourceStyleScheme + Graphics.UI.Gtk.SourceView.SourceStyleSchemeManager + Graphics.UI.Gtk.SourceView.SourceView + other-modules: + Graphics.UI.Gtk.SourceView.SourceStyle.Internal + Graphics.UI.Gtk.SourceView.Types[_^I_][_^I_] [_$_] + Graphics.UI.Gtk.SourceView.Signals +[_^I_][_^I_] [_$_] + extensions: ForeignFunctionInterface + + x-c2hs-Header: gtksourceview2.h + x-Types-Tag: gtksourceview2 + x-Signals-File: Graphics/UI/Gtk/SourceView/Signals.chs + x-Signals-Modname: Graphics.UI.Gtk.SourceView.Signals + pkgconfig-depends: gtksourceview-2.0 >= 2.0.2 hunk ./gtksourceview2/gtksourceview2.cabal.in 1 -name: gtksourceview2 -version: @PACKAGE_VERSION@ -license: LGPL -license-file: COPYING.LIB -maintainer: gtk...@li... -stability: provisional -homepage: http://haskell.org/gtk2hs/ -category: Graphics -build-depends: base-@PKG_BASE_VERSION@ gtk==@PACKAGE_VERSION@ -exposed-modules: ${modules} rmfile ./gtksourceview2/gtksourceview2.cabal.in hunk ./gtksourceview2/gtksourceview2.package.conf.in 1 -name: gtksourceview2 -version: @PACKAGE_VERSION@ -id: gtksourceview2-@PACKAGE_VERSION@ -license: LGPL -license-file: COPYING.LIB -maintainer: gtk...@li... -stability: provisional -homepage: http://haskell.org/gtk2hs/ -exposed: True -exposed-modules: ${modules} -import-dirs: "${pkglibdir}/imports/gtksourceview2" -library-dirs: @GTKSOURCEVIEW2_LIBDIR_CQ@ -hs-libraries: HSgtksourceview2 -extra-libraries: @GTKSOURCEVIEW2_LIBS_CQ@ -include-dirs: @GTKSOURCEVIEW2_CFLAGS_CQ@ -includes: gtksourceview/gtksourcebuffer.h, - gtksourceview/gtksourceiter.h, - gtksourceview/gtksourceiter.h, - gtksourceview/gtksourcelanguage.h, - gtksourceview/gtksourcelanguagemanager.h, - gtksourceview/gtksourcestyle.h, - gtksourceview/gtksourcestylescheme.h, - gtksourceview/gtksourcestyleschememanager.h, - gtksourceview/gtksourceview.h, - gtksourceview/gtksourceview-typebuiltins.h -depends: @PKG_BASE_ID@ gtk-@PACKAGE_VERSION@ -ld-options: @GTKSOURCEVIEW2_LIBEXTRA_CQ@ rmfile ./gtksourceview2/gtksourceview2.package.conf.in hunk ./gtksourceview2/marshal.list 1 -# see glib-genmarshal(1) for a detailed description of the file format, -# possible parameter types are: -# VOID indicates no return type, or no extra -# parameters. if VOID is used as the parameter -# list, no additional parameters may be present. -# BOOLEAN for boolean types (gboolean) -# CHAR for signed char types (gchar) -# UCHAR for unsigned char types (guchar) -# INT for signed integer types (gint) -# UINT for unsigned integer types (guint) -# LONG for signed long integer types (glong) -# ULONG for unsigned long integer types (gulong) -# ENUM for enumeration types (gint) -# FLAGS for flag enumeration types (guint) -# FLOAT for single-precision float types (gfloat) -# DOUBLE for double-precision float types (gdouble) -# STRING for string types (gchar*) -# BOXED for boxed (anonymous but reference counted) types (GBoxed*) -# POINTER for anonymous pointer types (gpointer) -# OBJECT for GObject or derived types (GObject*) -# NONE deprecated alias for VOID -# BOOL deprecated alias for BOOLEAN hunk ./gtksourceview2/marshal.list 2 -# If you add a new signal type, please check that it actually works! -# If it is a Boxed type check that the reference counting is right. - [_$_] -VOID:BOXED,BOXED -VOID:VOID rmfile ./gtksourceview2/marshal.list |
From: Axel S. <si...@co...> - 2010-05-01 15:19:20
|
Wed Apr 28 06:06:17 EDT 2010 Andy Stewart <laz...@gm...> * gtkglext Cabal package. Ignore-this: 485ca74cc042b8751415c7e960650a23 addfile ./gtkglext/COPYING hunk ./gtkglext/COPYING 1 + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +[_^L_][_$_] + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +[_^L_][_$_] + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + [_$_] + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. +[_^L_][_$_] + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +[_^L_][_$_] + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. +[_^L_][_$_] + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. +[_^L_][_$_] + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. +[_^L_][_$_] + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. +[_^L_][_$_] + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS +[_^L_][_$_] + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/Config.chs 39 -#if GTK_CHECK_VERSION(2,2,0) hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/Config.chs 40 -#endif hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/Config.chs 42 -#if GTK_CHECK_VERSION(2,2,0) hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/Config.chs 43 -#endif hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/Config.chs 63 -{#import Graphics.UI.Gtk.Types#} hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/Config.chs 120 -#if GTK_CHECK_VERSION(2,2,0) hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/Config.chs 132 -#endif hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/Config.chs 136 -#if GTK_CHECK_VERSION(2,2,0) hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/Config.chs 144 -#endif hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/Context.chs 1 +{-# LANGUAGE CPP #-} hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/Context.chs 53 -{#import Graphics.UI.Gtk.Types#} hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/Drawable.chs 1 +{-# LANGUAGE CPP #-} hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/Drawable.chs 60 -{#import Graphics.UI.Gtk.Types#} hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/DrawingArea.chs 1 +{-# LANGUAGE CPP #-} hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/DrawingArea.chs 57 -{#import Graphics.UI.Gtk.Types#} hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/General.chs 34 -#if GTK_CHECK_VERSION(2,2,0) hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/General.chs 35 -#endif hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/General.chs 37 -#if GTK_CHECK_VERSION(2,2,0) hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/General.chs 38 -#endif hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/General.chs 40 -#if GTK_CHECK_VERSION(2,2,0) hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/General.chs 41 -#endif hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/General.chs 49 -{#import Graphics.UI.Gtk.Types#} -{#import Graphics.UI.Gtk.Pango.Types#} +{#import Graphics.Rendering.Pango.Types#} +{#import Graphics.Rendering.Pango.BasicTypes#} hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/General.chs 82 -#if GTK_CHECK_VERSION(2,2,0) hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/General.chs 89 -#endif hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/General.chs 115 -#if GTK_CHECK_VERSION(2,2,0) hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/General.chs 131 -#endif hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/General.chs 143 -#if GTK_CHECK_VERSION(2,2,0) hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/General.chs 154 -#endif hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/Pixmap.chs 1 +{-# LANGUAGE CPP #-} hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/Pixmap.chs 54 -{#import Graphics.UI.Gtk.Types#} hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/Window.chs 1 +{-# LANGUAGE CPP #-} hunk ./gtkglext/Graphics/UI/Gtk/OpenGL/Window.chs 54 -{#import Graphics.UI.Gtk.Types#} addfile ./gtkglext/Setup.hs hunk ./gtkglext/Setup.hs 1 +{-# LANGUAGE CPP #-} + +#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ + ((major) * 10000) \ + + ((minor) * 100) \ + + ((micro) * 1)) + +#define CABAL_VERSION_CHECK(major,minor,micro) \ + (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) + +-- now, this is bad, but Cabal doesn't seem to actually pass any information about +-- its version to CPP, so guess the version depending on the version of GHC +#ifdef CABAL_VERSION_MINOR +#ifndef CABAL_VERSION_MAJOR +#define CABAL_VERSION_MAJOR 1 +#endif +#ifndef CABAL_VERSION_MICRO +#define CABAL_VERSION_MICRO 0 +#endif +#define CABAL_VERSION CABAL_VERSION_ENCODE( \ + CABAL_VERSION_MAJOR, \ + CABAL_VERSION_MINOR, \ + CABAL_VERSION_MICRO) +#else +#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) +#if (__GLASGOW_HASKELL__ >= 612) +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) +#else +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) +#endif +#endif + +-- | Build a Gtk2hs package. +-- +import Distribution.Simple +import Distribution.Simple.PreProcess +import Distribution.InstalledPackageInfo ( importDirs ) +import Distribution.Simple.PackageIndex ( +#if CABAL_VERSION_CHECK(1,8,0) + lookupInstalledPackageId +#else + lookupPackageId +#endif + ) +import Distribution.PackageDescription as PD ( PackageDescription(..), + updatePackageDescription, + BuildInfo(..), + emptyBuildInfo, allBuildInfo, + Library(..), + libModules) +import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), + InstallDirs(..), +#if CABAL_VERSION_CHECK(1,8,0) + componentPackageDeps, +#else + packageDeps, +#endif + absoluteInstallDirs) +import Distribution.Simple.Compiler ( Compiler(..) ) +import Distribution.Simple.Program ( + Program(..), ConfiguredProgram(..), + rawSystemProgramConf, rawSystemProgramStdoutConf, + c2hsProgram, pkgConfigProgram, + simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) +import Distribution.ModuleName ( ModuleName, components, toFilePath ) +import Distribution.Simple.Utils +import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), + defaultCopyFlags, ConfigFlags(configVerbosity), + fromFlag, toFlag) +import Distribution.Simple.BuildPaths ( autogenModulesDir ) +import Distribution.Text ( simpleParse, display ) +import System.FilePath +import System.Directory ( doesFileExist ) +import Distribution.Version (Version(..)) +import Distribution.Verbosity +import Control.Monad (unless) +import Data.Maybe (fromMaybe) +import Data.List (isPrefixOf, nub) +import Data.Char (isAlpha) +import qualified Data.Map as M +import qualified Data.Set as S + + +-- the name of the c2hs pre-compiled header file +precompFile = "precompchs.bin" + +main = defaultMainWithHooks simpleUserHooks { + hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], + hookedPreProcessors = [("chs", ourC2hs)], + confHook = \pd cf -> + confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, + postConf = \args cf pd lbi -> do + genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi + postConf simpleUserHooks args cf pd lbi, + buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> + (buildHook simpleUserHooks) pd lbi uh bf, + copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), + instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest + } + +-- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later +adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo +adjustLocalBuildInfo lbi = + let extra = (Just libBi, []) + libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi + , buildDir lbi ] } + in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } + +ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor +ourC2hs bi lbi = PreProcessor { + platformIndependent = False, + runPreProcessor = runC2HS bi lbi +} + +runC2HS :: BuildInfo -> LocalBuildInfo -> + (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () +runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do + -- have the header file name if we don't have the precompiled header yet + header <- case lookup "x-c2hs-header" (customFieldsBI bi) of + Just h -> return h + Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ + "that sets the C header file to process .chs.pp files.") + + -- c2hs will output files in out dir, removing any leading path of the input file. + -- Thus, append the dir of the input file to the output dir. + let (outFileDir, newOutFile) = splitFileName outFile + let newOutDir = outDir </> outFileDir + -- additional .chi files might be needed that other packages have installed; + -- we assume that these are installed in the same place as .hi files + let chiDirs = [ dir | +#if CABAL_VERSION_CHECK(1,8,0) + ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), + dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] +#else + ipi <- packageDeps lbi, + dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] +#endif + rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ + map ("--include=" ++) (outDir:chiDirs) + ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] + ++ ["--output-dir=" ++ newOutDir, + "--output=" ++ newOutFile, + "--precomp=" ++ buildDir lbi </> precompFile, + header, inDir </> inFile] + +getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] +getCppOptions bi lbi + = nub $ + ["-I" ++ dir | dir <- PD.includeDirs bi] + ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] + +installCHI :: PackageDescription -- ^information from the .cabal file + -> LocalBuildInfo -- ^information from the configure step + -> Verbosity -> CopyDest -- ^flags sent to copy or install + -> IO () +installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do + let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest + -- cannot use the recommended 'findModuleFiles' since it fails if there exists + -- a modules that does not have a .chi file + mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) + (map toFilePath +#if CABAL_VERSION_CHECK(1,8,0) + (PD.libModules lib) +#else + (PD.libModules pkg) +#endif + ) + let files = [ f | Just f <- mFiles ] +#if CABAL_VERSION_CHECK(1,8,0) + installOrdinaryFiles verbosity libPref files +#else + copyFiles verbosity libPref files +#endif + + [_$_] +installCHI _ _ _ _ = return () + +------------------------------------------------------------------------------ +-- Generating the type hierarchy and signal callback .hs files. +------------------------------------------------------------------------------ + +typeGenProgram :: Program +typeGenProgram = (simpleProgram "gtk2hsTypeGen") + +signalGenProgram :: Program +signalGenProgram = (simpleProgram "gtk2hsHookGenerator") + +c2hsLocal :: Program +c2hsLocal = (simpleProgram "gtk2hsC2hs") + +genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () +genSynthezisedFiles verb pd lbi = do + + cPkgs <- getPkgConfigPackages verb lbi pd + + let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) + ++customFieldsPD pd + typeOpts :: [ProgArg] + typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) + | (field,content) <- xList, + "x-types-" `isPrefixOf` field, + field /= "x-types-file"] + ++ [ "--tag=" ++ tag + | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs + , let name' = filter isAlpha (display name) + , tag <- name' + : [ name' ++ "-" ++ show major ++ "." ++ show digit + | digit <- [0,2..minor] ] + ] + + genFile :: Program -> [ProgArg] -> FilePath -> IO () + genFile prog args outFile = do + res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args + rewriteFile outFile res + + case lookup "x-types-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") + genFile typeGenProgram typeOpts f + + case (lookup "x-signals-file" xList, + lookup "x-signals-modname" xList) of + (Just _, Nothing) -> die "You need to specify the module name (X-Signals-ModName) \ + \to generate a signal file." + (Just f, Just mod) -> do + info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") + genFile signalGenProgram [mod] f + (_,_) -> return () + +--FIXME: Cabal should tell us the selected pkg-config package versions in the +-- LocalBuildInfo or equivalent. +-- In the mean time, ask pkg-config again. + +getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] +getPkgConfigPackages verbosity lbi pkg = + sequence + [ do version <- pkgconfig ["--modversion", display pkgname] + case simpleParse version of + Nothing -> die $ "parsing output of pkg-config --modversion failed" + Just v -> return (PackageIdentifier pkgname v) + | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] + where + pkgconfig = rawSystemProgramStdoutConf verbosity + pkgConfigProgram (withPrograms lbi) + +------------------------------------------------------------------------------ +-- Dependency calculation amongst .chs files. +------------------------------------------------------------------------------ + +-- Given all files of the package, find those that end in .chs and extract the +-- .chs files they depend upon. Then return the PackageDescription with these +-- files rearranged so that they are built in a sequence that files that are +-- needed by other files are built first. +fixDeps :: PackageDescription -> IO PackageDescription +fixDeps pd...@PD...ckageDescription { + PD.library = Just li...@PD...brary { + PD.exposedModules = expMods, + PD.libBuildInfo = bi@PD.BuildInfo { + PD.hsSourceDirs = srcDirs, + PD.otherModules = othMods + }}} = do + let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs + (joinPath (components m)) + mExpFiles <- mapM findModule expMods + mOthFiles <- mapM findModule othMods + + -- tag all exposed files with True so we throw an error if we need to build + -- an exposed module before an internal modules (we cannot express this) + let modDeps = zipWith (ModDep True []) expMods mExpFiles++ + zipWith (ModDep False []) othMods mOthFiles + modDeps <- mapM extractDeps modDeps + let (expMods, othMods) = span mdExposed $ sortTopological modDeps + badOther = map (fromMaybe "<no file>" . mdLocation) $ + filter (not . mdExposed) expMods + unless (null badOther) $ + die ("internal chs modules "++intercalate "," badOther++ + " depend on exposed chs modules; cabal needs to build internal modules first") + return pd { PD.library = Just lib { + PD.exposedModules = map mdOriginal expMods, + PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } + }} + +data ModDep = ModDep { + mdExposed :: Bool, + mdRequires :: [ModuleName], + mdOriginal :: ModuleName, + mdLocation :: Maybe FilePath +} + +instance Show ModDep where + show x = show (mdLocation x) + +instance Eq ModDep where + ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 +instance Ord ModDep where + compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 + +-- Extract the dependencies of this file. This is intentionally rather naive as it +-- ignores CPP conditionals. We just require everything which means that the +-- existance of a .chs module may not depend on some CPP condition. [_$_] +extractDeps :: ModDep -> IO ModDep +extractDeps md@ModDep { mdLocation = Nothing } = return md +extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do + let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of + ('i':'m':'p':'o':'r':'t':' ':ys) -> + case simpleParse (takeWhile ((/=) '#') ys) of + Just m -> findImports (m:acc) xxs [_$_] + Nothing -> die ("cannot parse chs import in "++f++":\n"++ + "offending line is {#"++xs) + -- no more imports after the first non-import hook + _ -> return acc + findImports acc (_:xxs) = findImports acc xxs + findImports acc [] = return acc + mods <- findImports [] (lines con) + return md { mdRequires = mods } + +-- Find a total order of the set of modules that are partially sorted by their +-- dependencies on each other. The function returns the sorted list of modules +-- together with a list of modules that are required but not supplied by this +-- in the input set of modules. +sortTopological :: [ModDep] -> [ModDep] +sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) + where + set = M.fromList (map (\m -> (mdOriginal m, m)) ms) + visit (out,visited) m + | m `S.member` visited = (out,visited) + | otherwise = case m `M.lookup` set of + Nothing -> (out, m `S.insert` visited) + Just md -> (md:out', visited') + where + (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) addfile ./gtkglext/gtkglext.cabal hunk ./gtkglext/gtkglext.cabal 1 +Name: gtkglext +Version: 0.10.5 +License: GPL +License-file: COPYING +Copyright: (c) 2001-2010 The Gtk2Hs Team +Author: Duncan Coutts +Maintainer: gtk...@so... +Build-Type: Custom +Cabal-Version: >= 1.6.0 +Stability: provisional +homepage: http://www.haskell.org/gtk2hs/ +bug-reports: http://hackage.haskell.org/trac/gtk2hs/ +Synopsis: Binding to the GTK+ OpenGL Extension +Description: GtkGLExt provides the GDK objects to support OpenGL rendering in GTK+, + and GtkWidget API add-ons to make GTK+ widgets OpenGL-capable. + +Category: Graphics +Tested-With: GHC == 6.12.1 +x-Types-File: Graphics/UI/Gtk/OpenGL/Types.chs +x-Types-ModName: Graphics.UI.Gtk.OpenGL.Types +x-Types-Forward: *Graphics.UI.GtkInternals +x-Types-Destructor: objectUnrefFromMainloop + +Source-Repository head + type: darcs + location: http://code.haskell.org/gtk2hs/ + subdir: gtkglext + +Library + build-depends: base >= 4, array, containers, haskell98, mtl, + glib >= 0.10.5 && < 0.11, [_$_] + pango >= 0.10.5 && < 0.11, [_$_] + cairo >= 0.10.5 && < 0.11, + gtk >= 0.10.5 && < 0.11 + + build-tools: gtk2hsC2hs, gtk2hsHookGenerator, gtk2hsTypeGen +[_^I_][_^I_][_^I_][_^I_][_^I_][_^I_][_$_] + exposed-modules: + Graphics.UI.Gtk.OpenGL + Graphics.UI.Gtk.OpenGL.Config + Graphics.UI.Gtk.OpenGL.Context + Graphics.UI.Gtk.OpenGL.Drawable + Graphics.UI.Gtk.OpenGL.DrawingArea + Graphics.UI.Gtk.OpenGL.General + Graphics.UI.Gtk.OpenGL.Pixmap + Graphics.UI.Gtk.OpenGL.Window + other-modules: + Graphics.UI.Gtk.OpenGL.Types [_$_] +[_^I_][_^I_] [_$_] + extensions: ForeignFunctionInterface +[_^I_][_^I_][_$_] + x-c2hs-Header: gtk/gtkgl.h + x-Types-Tag: gtkglext + pkgconfig-depends: gtkglext-1.0 >= 1.0.5 hunk ./gtkglext/gtkglext.cabal.in 1 -name: gtkglext -version: @PACKAGE_VERSION@ -license: LGPL -license-file: COPYING.LIB -maintainer: gtk...@li... -stability: provisional -homepage: http://haskell.org/gtk2hs/ -category: Graphics -build-depends: base-@PKG_BASE_VERSION@ gtk==@PACKAGE_VERSION@ -exposed-modules: ${modules} rmfile ./gtkglext/gtkglext.cabal.in hunk ./gtkglext/gtkglext.package.conf.in 1 -name: gtkglext -version: @PACKAGE_VERSION@ -id: gtkglext-@PACKAGE_VERSION@ -license: LGPL -license-file: COPYING.LIB -maintainer: gtk...@li... -stability: provisional -homepage: http://haskell.org/gtk2hs/ -exposed: True -exposed-modules: ${modules} -import-dirs: "${pkglibdir}/imports/gtkglext" -library-dirs: @GTKGLEXT_LIBDIR_CQ@ -hs-libraries: HSgtkglext -extra-libraries: @GTKGLEXT_LIBS_CQ@ -include-dirs: @GTKGLEXT_CFLAGS_CQ@ -includes: gtk/gtkgl.h -depends: @PKG_BASE_ID@ gtk-@PACKAGE_VERSION@ -ld-options: @GTKGLEXT_LIBEXTRA_CQ@ rmfile ./gtkglext/gtkglext.package.conf.in |
From: Axel S. <si...@co...> - 2010-05-01 15:19:19
|
Wed Apr 28 06:02:16 EDT 2010 Andy Stewart <laz...@gm...> * gconf Cabal package. Ignore-this: 26854e53627320a7ef3a65f6823fcb60 addfile ./gconf/COPYING hunk ./gconf/COPYING 1 + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +[_^L_][_$_] + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +[_^L_][_$_] + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + [_$_] + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. +[_^L_][_$_] + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +[_^L_][_$_] + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. +[_^L_][_$_] + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. +[_^L_][_$_] + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. +[_^L_][_$_] + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. +[_^L_][_$_] + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS +[_^L_][_$_] + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + addfile ./gconf/Setup.hs hunk ./gconf/Setup.hs 1 +{-# LANGUAGE CPP #-} + +#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ + ((major) * 10000) \ + + ((minor) * 100) \ + + ((micro) * 1)) + +#define CABAL_VERSION_CHECK(major,minor,micro) \ + (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) + +-- now, this is bad, but Cabal doesn't seem to actually pass any information about +-- its version to CPP, so guess the version depending on the version of GHC +#ifdef CABAL_VERSION_MINOR +#ifndef CABAL_VERSION_MAJOR +#define CABAL_VERSION_MAJOR 1 +#endif +#ifndef CABAL_VERSION_MICRO +#define CABAL_VERSION_MICRO 0 +#endif +#define CABAL_VERSION CABAL_VERSION_ENCODE( \ + CABAL_VERSION_MAJOR, \ + CABAL_VERSION_MINOR, \ + CABAL_VERSION_MICRO) +#else +#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) +#if (__GLASGOW_HASKELL__ >= 612) +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) +#else +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) +#endif +#endif + +-- | Build a Gtk2hs package. +-- +import Distribution.Simple +import Distribution.Simple.PreProcess +import Distribution.InstalledPackageInfo ( importDirs ) +import Distribution.Simple.PackageIndex ( +#if CABAL_VERSION_CHECK(1,8,0) + lookupInstalledPackageId +#else + lookupPackageId +#endif + ) +import Distribution.PackageDescription as PD ( PackageDescription(..), + updatePackageDescription, + BuildInfo(..), + emptyBuildInfo, allBuildInfo, + Library(..), + libModules) +import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), + InstallDirs(..), +#if CABAL_VERSION_CHECK(1,8,0) + componentPackageDeps, +#else + packageDeps, +#endif + absoluteInstallDirs) +import Distribution.Simple.Compiler ( Compiler(..) ) +import Distribution.Simple.Program ( + Program(..), ConfiguredProgram(..), + rawSystemProgramConf, rawSystemProgramStdoutConf, + c2hsProgram, pkgConfigProgram, + simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) +import Distribution.ModuleName ( ModuleName, components, toFilePath ) +import Distribution.Simple.Utils +import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), + defaultCopyFlags, ConfigFlags(configVerbosity), + fromFlag, toFlag) +import Distribution.Simple.BuildPaths ( autogenModulesDir ) +import Distribution.Text ( simpleParse, display ) +import System.FilePath +import System.Directory ( doesFileExist ) +import Distribution.Version (Version(..)) +import Distribution.Verbosity +import Control.Monad (unless) +import Data.Maybe (fromMaybe) +import Data.List (isPrefixOf, nub) +import Data.Char (isAlpha) +import qualified Data.Map as M +import qualified Data.Set as S + + +-- the name of the c2hs pre-compiled header file +precompFile = "precompchs.bin" + +main = defaultMainWithHooks simpleUserHooks { + hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], + hookedPreProcessors = [("chs", ourC2hs)], + confHook = \pd cf -> + confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, + postConf = \args cf pd lbi -> do + genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi + postConf simpleUserHooks args cf pd lbi, + buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> + (buildHook simpleUserHooks) pd lbi uh bf, + copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), + instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest + } + +-- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later +adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo +adjustLocalBuildInfo lbi = + let extra = (Just libBi, []) + libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi + , buildDir lbi ] } + in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } + +ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor +ourC2hs bi lbi = PreProcessor { + platformIndependent = False, + runPreProcessor = runC2HS bi lbi +} + +runC2HS :: BuildInfo -> LocalBuildInfo -> + (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () +runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do + -- have the header file name if we don't have the precompiled header yet + header <- case lookup "x-c2hs-header" (customFieldsBI bi) of + Just h -> return h + Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ + "that sets the C header file to process .chs.pp files.") + + -- c2hs will output files in out dir, removing any leading path of the input file. + -- Thus, append the dir of the input file to the output dir. + let (outFileDir, newOutFile) = splitFileName outFile + let newOutDir = outDir </> outFileDir + -- additional .chi files might be needed that other packages have installed; + -- we assume that these are installed in the same place as .hi files + let chiDirs = [ dir | +#if CABAL_VERSION_CHECK(1,8,0) + ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), + dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] +#else + ipi <- packageDeps lbi, + dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] +#endif + rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ + map ("--include=" ++) (outDir:chiDirs) + ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] + ++ ["--output-dir=" ++ newOutDir, + "--output=" ++ newOutFile, + "--precomp=" ++ buildDir lbi </> precompFile, + header, inDir </> inFile] + +getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] +getCppOptions bi lbi + = nub $ + ["-I" ++ dir | dir <- PD.includeDirs bi] + ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] + +installCHI :: PackageDescription -- ^information from the .cabal file + -> LocalBuildInfo -- ^information from the configure step + -> Verbosity -> CopyDest -- ^flags sent to copy or install + -> IO () +installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do + let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest + -- cannot use the recommended 'findModuleFiles' since it fails if there exists + -- a modules that does not have a .chi file + mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) + (map toFilePath +#if CABAL_VERSION_CHECK(1,8,0) + (PD.libModules lib) +#else + (PD.libModules pkg) +#endif + ) + let files = [ f | Just f <- mFiles ] +#if CABAL_VERSION_CHECK(1,8,0) + installOrdinaryFiles verbosity libPref files +#else + copyFiles verbosity libPref files +#endif + + [_$_] +installCHI _ _ _ _ = return () + +------------------------------------------------------------------------------ +-- Generating the type hierarchy and signal callback .hs files. +------------------------------------------------------------------------------ + +typeGenProgram :: Program +typeGenProgram = (simpleProgram "gtk2hsTypeGen") + +signalGenProgram :: Program +signalGenProgram = (simpleProgram "gtk2hsHookGenerator") + +c2hsLocal :: Program +c2hsLocal = (simpleProgram "gtk2hsC2hs") + +genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () +genSynthezisedFiles verb pd lbi = do + + cPkgs <- getPkgConfigPackages verb lbi pd + + let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) + ++customFieldsPD pd + typeOpts :: [ProgArg] + typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) + | (field,content) <- xList, + "x-types-" `isPrefixOf` field, + field /= "x-types-file"] + ++ [ "--tag=" ++ tag + | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs + , let name' = filter isAlpha (display name) + , tag <- name' + : [ name' ++ "-" ++ show major ++ "." ++ show digit + | digit <- [0,2..minor] ] + ] + + genFile :: Program -> [ProgArg] -> FilePath -> IO () + genFile prog args outFile = do + res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args + rewriteFile outFile res + + case lookup "x-types-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") + genFile typeGenProgram typeOpts f + + case (lookup "x-signals-file" xList, + lookup "x-signals-modname" xList) of + (Just _, Nothing) -> die "You need to specify the module name (X-Signals-ModName) \ + \to generate a signal file." + (Just f, Just mod) -> do + info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") + genFile signalGenProgram [mod] f + (_,_) -> return () + +--FIXME: Cabal should tell us the selected pkg-config package versions in the +-- LocalBuildInfo or equivalent. +-- In the mean time, ask pkg-config again. + +getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] +getPkgConfigPackages verbosity lbi pkg = + sequence + [ do version <- pkgconfig ["--modversion", display pkgname] + case simpleParse version of + Nothing -> die $ "parsing output of pkg-config --modversion failed" + Just v -> return (PackageIdentifier pkgname v) + | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] + where + pkgconfig = rawSystemProgramStdoutConf verbosity + pkgConfigProgram (withPrograms lbi) + +------------------------------------------------------------------------------ +-- Dependency calculation amongst .chs files. +------------------------------------------------------------------------------ + +-- Given all files of the package, find those that end in .chs and extract the +-- .chs files they depend upon. Then return the PackageDescription with these +-- files rearranged so that they are built in a sequence that files that are +-- needed by other files are built first. +fixDeps :: PackageDescription -> IO PackageDescription +fixDeps pd...@PD...ckageDescription { + PD.library = Just li...@PD...brary { + PD.exposedModules = expMods, + PD.libBuildInfo = bi@PD.BuildInfo { + PD.hsSourceDirs = srcDirs, + PD.otherModules = othMods + }}} = do + let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs + (joinPath (components m)) + mExpFiles <- mapM findModule expMods + mOthFiles <- mapM findModule othMods + + -- tag all exposed files with True so we throw an error if we need to build + -- an exposed module before an internal modules (we cannot express this) + let modDeps = zipWith (ModDep True []) expMods mExpFiles++ + zipWith (ModDep False []) othMods mOthFiles + modDeps <- mapM extractDeps modDeps + let (expMods, othMods) = span mdExposed $ sortTopological modDeps + badOther = map (fromMaybe "<no file>" . mdLocation) $ + filter (not . mdExposed) expMods + unless (null badOther) $ + die ("internal chs modules "++intercalate "," badOther++ + " depend on exposed chs modules; cabal needs to build internal modules first") + return pd { PD.library = Just lib { + PD.exposedModules = map mdOriginal expMods, + PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } + }} + +data ModDep = ModDep { + mdExposed :: Bool, + mdRequires :: [ModuleName], + mdOriginal :: ModuleName, + mdLocation :: Maybe FilePath +} + +instance Show ModDep where + show x = show (mdLocation x) + +instance Eq ModDep where + ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 +instance Ord ModDep where + compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 + +-- Extract the dependencies of this file. This is intentionally rather naive as it +-- ignores CPP conditionals. We just require everything which means that the +-- existance of a .chs module may not depend on some CPP condition. [_$_] +extractDeps :: ModDep -> IO ModDep +extractDeps md@ModDep { mdLocation = Nothing } = return md +extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do + let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of + ('i':'m':'p':'o':'r':'t':' ':ys) -> + case simpleParse (takeWhile ((/=) '#') ys) of + Just m -> findImports (m:acc) xxs [_$_] + Nothing -> die ("cannot parse chs import in "++f++":\n"++ + "offending line is {#"++xs) + -- no more imports after the first non-import hook + _ -> return acc + findImports acc (_:xxs) = findImports acc xxs + findImports acc [] = return acc + mods <- findImports [] (lines con) + return md { mdRequires = mods } + +-- Find a total order of the set of modules that are partially sorted by their +-- dependencies on each other. The function returns the sorted list of modules +-- together with a list of modules that are required but not supplied by this +-- in the input set of modules. +sortTopological :: [ModDep] -> [ModDep] +sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) + where + set = M.fromList (map (\m -> (mdOriginal m, m)) ms) + visit (out,visited) m + | m `S.member` visited = (out,visited) + | otherwise = case m `M.lookup` set of + Nothing -> (out, m `S.insert` visited) + Just md -> (md:out', visited') + where + (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) hunk ./gconf/System/Gnome/GConf.hs 1 - hunk ./gconf/System/Gnome/GConf/GConfClient.chs 1 -{-# OPTIONS -cpp #-} +{-# LANGUAGE CPP, FlexibleContexts #-} hunk ./gconf/System/Gnome/GConf/GConfValue.chs 1 +{-# LANGUAGE CPP, TypeSynonymInstances, OverlappingInstances, ScopedTypeVariables #-} hunk ./gconf/System/Gnome/GConf/marshal.list 1 -# see glib-genmarshal(1) for a detailed description of the file format, -# possible parameter types are: -# VOID indicates no return type, or no extra -# parameters. if VOID is used as the parameter -# list, no additional parameters may be present. -# BOOLEAN for boolean types (gboolean) -# CHAR for signed char types (gchar) -# UCHAR for unsigned char types (guchar) -# INT for signed integer types (gint) -# UINT for unsigned integer types (guint) -# LONG for signed long integer types (glong) -# ULONG for unsigned long integer types (gulong) -# ENUM for enumeration types (gint) -# FLAGS for flag enumeration types (guint) -# FLOAT for single-precision float types (gfloat) -# DOUBLE for double-precision float types (gdouble) -# STRING for string types (gchar*) -# BOXED for boxed (anonymous but reference counted) types (GBoxed*) -# POINTER for anonymous pointer types (gpointer) -# OBJECT for GObject or derived types (GObject*) - -# If you add a new signal type, please check that it actually works! -# If it is a Boxed type check that the reference counting is right. - -# This is for the GConfClient value_changed signal -VOID:STRING,POINTER rmfile ./gconf/System/Gnome/GConf/marshal.list addfile ./gconf/gconf.cabal hunk ./gconf/gconf.cabal 1 +Name: gconf +Version: 0.10.5 +License: GPL +License-file: COPYING +Copyright: (c) 2001-2010 The Gtk2Hs Team +Author: Duncan Coutts +Maintainer: gtk...@so... +Build-Type: Custom +Cabal-Version: >= 1.6 +Stability: stable +homepage: http://www.haskell.org/gtk2hs/ +bug-reports: http://hackage.haskell.org/trac/gtk2hs/ +Synopsis: Binding to the GNOME configuration database system. +Description: GConf is a configuration database system for storing application + preferences. It supports default or mandatory settings set by the + administrator, and changes to the database are instantly applied to all + running applications. It is written for the GNOME desktop but doesn't + require it. +Category: System +Tested-With: GHC == 6.12.1 + +x-Types-File: System/Gnome/GConf/Types.chs +x-Types-ModName: System.Gnome.GConf.Types +x-Types-Forward: Graphics.UI.GtkInternals + +Source-Repository head + type: darcs + location: http://code.haskell.org/gtk2hs/ + subdir: gconf + +Library + build-depends: base >= 4, array, containers, haskell98, mtl, + glib >= 0.10.5 && < 0.11, [_$_] + gtk >= 0.10.5 && < 0.11 +[_^I_][_^I_][_^I_][_^I_][_^I_][_^I_][_$_] + build-tools: gtk2hsC2hs, gtk2hsHookGenerator, gtk2hsTypeGen +[_^I_][_^I_][_^I_][_^I_][_^I_][_^I_][_$_] + exposed-modules: + System.Gnome.GConf + System.Gnome.GConf.GConfClient[_^I_][_^I_] [_$_] + other-modules: + System.Gnome.GConf.GConfValue + System.Gnome.GConf.Types[_^I_][_^I_] [_$_] + System.Gnome.GConf.Signals[_^I_][_^I_] [_$_] + + extensions: ForeignFunctionInterface +[_^I_][_^I_][_$_] + x-Types-Tag: gconf + x-c2hs-Header: gconf/gconf-client.h + x-Signals-File: System/Gnome/GConf/Signals.chs + x-Signals-Modname: System.Gnome.GConf.Signals + pkgconfig-depends: gconf-2.0 >= 2.0.0 hunk ./gconf/gconf.cabal.in 1 -name: gconf -version: @PACKAGE_VERSION@ -license: LGPL -license-file: COPYING.LIB -maintainer: gtk...@li... -stability: provisional -homepage: http://haskell.org/gtk2hs/ -category: System -build-depends: base-@PKG_BASE_VERSION@ glib==@PACKAGE_VERSION@ -exposed-modules: ${modules} rmfile ./gconf/gconf.cabal.in hunk ./gconf/gconf.package.conf.in 1 -name: gconf -version: @PACKAGE_VERSION@ -id: gconf-@PACKAGE_VERSION@ -license: LGPL -license-file: COPYING.LIB -maintainer: gtk...@li... -stability: provisional -homepage: http://haskell.org/gtk2hs/ -exposed: True -exposed-modules: ${modules} -import-dirs: "${pkglibdir}/imports/gconf" -library-dirs: @GCONF_LIBDIR_CQ@ -hs-libraries: HSgconf -extra-libraries: @GCONF_LIBS_CQ@ -include-dirs: @GCONF_CFLAGS_CQ@ -includes: gconf/gconf-client.h -depends: @PKG_BASE_ID@ glib-@PACKAGE_VERSION@ -ld-options: @GCONF_LIBEXTRA_CQ@ rmfile ./gconf/gconf.package.conf.in |
From: Axel S. <si...@co...> - 2010-05-01 15:19:18
|
Wed Apr 28 05:58:58 EDT 2010 Andy Stewart <laz...@gm...> * GIO Cabal package (Fix doc, add new functions: `fileHasParent` and `fileQueryFileType`) Ignore-this: 3b53dc9cd495f92e9a7652e14d1cb05b addfile ./gio/COPYING hunk ./gio/COPYING 1 + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +[_^L_][_$_] + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +[_^L_][_$_] + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + [_$_] + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. +[_^L_][_$_] + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +[_^L_][_$_] + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. +[_^L_][_$_] + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. +[_^L_][_$_] + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. +[_^L_][_$_] + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. +[_^L_][_$_] + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS +[_^L_][_$_] + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + addfile ./gio/Setup.hs hunk ./gio/Setup.hs 1 +{-# LANGUAGE CPP #-} + +#define CABAL_VERSION_ENCODE(major, minor, micro) ( \ + ((major) * 10000) \ + + ((minor) * 100) \ + + ((micro) * 1)) + +#define CABAL_VERSION_CHECK(major,minor,micro) \ + (CABAL_VERSION >= CABAL_VERSION_ENCODE(major,minor,micro)) + +-- now, this is bad, but Cabal doesn't seem to actually pass any information about +-- its version to CPP, so guess the version depending on the version of GHC +#ifdef CABAL_VERSION_MINOR +#ifndef CABAL_VERSION_MAJOR +#define CABAL_VERSION_MAJOR 1 +#endif +#ifndef CABAL_VERSION_MICRO +#define CABAL_VERSION_MICRO 0 +#endif +#define CABAL_VERSION CABAL_VERSION_ENCODE( \ + CABAL_VERSION_MAJOR, \ + CABAL_VERSION_MINOR, \ + CABAL_VERSION_MICRO) +#else +#warning Setup.hs is guessing the version of Cabal. If compilation of Setup.hs fails use -DCABAL_VERSION_MINOR=x for Cabal version 1.x.0 when building (prefixed by --ghc-option= when using the 'cabal' command) +#if (__GLASGOW_HASKELL__ >= 612) +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,8,0) +#else +#define CABAL_VERSION CABAL_VERSION_ENCODE(1,6,0) +#endif +#endif + +-- | Build a Gtk2hs package. +-- +import Distribution.Simple +import Distribution.Simple.PreProcess +import Distribution.InstalledPackageInfo ( importDirs ) +import Distribution.Simple.PackageIndex ( +#if CABAL_VERSION_CHECK(1,8,0) + lookupInstalledPackageId +#else + lookupPackageId +#endif + ) +import Distribution.PackageDescription as PD ( PackageDescription(..), + updatePackageDescription, + BuildInfo(..), + emptyBuildInfo, allBuildInfo, + Library(..), + libModules) +import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), + InstallDirs(..), +#if CABAL_VERSION_CHECK(1,8,0) + componentPackageDeps, +#else + packageDeps, +#endif + absoluteInstallDirs) +import Distribution.Simple.Compiler ( Compiler(..) ) +import Distribution.Simple.Program ( + Program(..), ConfiguredProgram(..), + rawSystemProgramConf, rawSystemProgramStdoutConf, + c2hsProgram, pkgConfigProgram, + simpleProgram, lookupProgram, rawSystemProgramStdout, ProgArg) +import Distribution.ModuleName ( ModuleName, components, toFilePath ) +import Distribution.Simple.Utils +import Distribution.Simple.Setup (CopyFlags(..), InstallFlags(..), CopyDest(..), + defaultCopyFlags, ConfigFlags(configVerbosity), + fromFlag, toFlag) +import Distribution.Simple.BuildPaths ( autogenModulesDir ) +import Distribution.Text ( simpleParse, display ) +import System.FilePath +import System.Directory ( doesFileExist ) +import Distribution.Version (Version(..)) +import Distribution.Verbosity +import Control.Monad (unless) +import Data.Maybe (fromMaybe) +import Data.List (isPrefixOf, nub) +import Data.Char (isAlpha) +import qualified Data.Map as M +import qualified Data.Set as S + + +-- the name of the c2hs pre-compiled header file +precompFile = "precompchs.bin" + +main = defaultMainWithHooks simpleUserHooks { + hookedPrograms = [typeGenProgram, signalGenProgram, c2hsLocal], + hookedPreProcessors = [("chs", ourC2hs)], + confHook = \pd cf -> + confHook simpleUserHooks pd cf >>= return . adjustLocalBuildInfo, + postConf = \args cf pd lbi -> do + genSynthezisedFiles (fromFlag (configVerbosity cf)) pd lbi + postConf simpleUserHooks args cf pd lbi, + buildHook = \pd lbi uh bf -> fixDeps pd >>= \pd -> + (buildHook simpleUserHooks) pd lbi uh bf, + copyHook = \pd lbi uh flags -> (copyHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (copyVerbosity flags)) (fromFlag (copyDest flags)), + instHook = \pd lbi uh flags -> (instHook simpleUserHooks) pd lbi uh flags >> + installCHI pd lbi (fromFlag (installVerbosity flags)) NoCopyDest + } + +-- This is a hack for Cabal-1.8, It is not needed in Cabal-1.9.1 or later +adjustLocalBuildInfo :: LocalBuildInfo -> LocalBuildInfo +adjustLocalBuildInfo lbi = + let extra = (Just libBi, []) + libBi = emptyBuildInfo { includeDirs = [ autogenModulesDir lbi + , buildDir lbi ] } + in lbi { localPkgDescr = updatePackageDescription extra (localPkgDescr lbi) } + +ourC2hs :: BuildInfo -> LocalBuildInfo -> PreProcessor +ourC2hs bi lbi = PreProcessor { + platformIndependent = False, + runPreProcessor = runC2HS bi lbi +} + +runC2HS :: BuildInfo -> LocalBuildInfo -> + (FilePath, FilePath) -> (FilePath, FilePath) -> Verbosity -> IO () +runC2HS bi lbi (inDir, inFile) (outDir, outFile) verbosity = do + -- have the header file name if we don't have the precompiled header yet + header <- case lookup "x-c2hs-header" (customFieldsBI bi) of + Just h -> return h + Nothing -> die ("Need x-c2hs-Header definition in the .cabal Library section "++ + "that sets the C header file to process .chs.pp files.") + + -- c2hs will output files in out dir, removing any leading path of the input file. + -- Thus, append the dir of the input file to the output dir. + let (outFileDir, newOutFile) = splitFileName outFile + let newOutDir = outDir </> outFileDir + -- additional .chi files might be needed that other packages have installed; + -- we assume that these are installed in the same place as .hi files + let chiDirs = [ dir | +#if CABAL_VERSION_CHECK(1,8,0) + ipi <- maybe [] (map fst . componentPackageDeps) (libraryConfig lbi), + dir <- maybe [] importDirs (lookupInstalledPackageId (installedPkgs lbi) ipi) ] +#else + ipi <- packageDeps lbi, + dir <- maybe [] importDirs (lookupPackageId (installedPkgs lbi) ipi) ] +#endif + rawSystemProgramConf verbosity c2hsLocal (withPrograms lbi) $ + map ("--include=" ++) (outDir:chiDirs) + ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi] + ++ ["--output-dir=" ++ newOutDir, + "--output=" ++ newOutFile, + "--precomp=" ++ buildDir lbi </> precompFile, + header, inDir </> inFile] + +getCppOptions :: BuildInfo -> LocalBuildInfo -> [String] +getCppOptions bi lbi + = nub $ + ["-I" ++ dir | dir <- PD.includeDirs bi] + ++ [opt | opt@('-':c:_) <- (PD.cppOptions bi ++ PD.ccOptions bi), c `elem` "DIU"] + +installCHI :: PackageDescription -- ^information from the .cabal file + -> LocalBuildInfo -- ^information from the configure step + -> Verbosity -> CopyDest -- ^flags sent to copy or install + -> IO () +installCHI pk...@PD...ckageDescription { library = Just lib } lbi verbosity copydest = do + let InstallDirs { libdir = libPref } = absoluteInstallDirs pkg lbi copydest + -- cannot use the recommended 'findModuleFiles' since it fails if there exists + -- a modules that does not have a .chi file + mFiles <- mapM (findFileWithExtension' ["chi"] [buildDir lbi]) + (map toFilePath +#if CABAL_VERSION_CHECK(1,8,0) + (PD.libModules lib) +#else + (PD.libModules pkg) +#endif + ) + let files = [ f | Just f <- mFiles ] +#if CABAL_VERSION_CHECK(1,8,0) + installOrdinaryFiles verbosity libPref files +#else + copyFiles verbosity libPref files +#endif + + [_$_] +installCHI _ _ _ _ = return () + +------------------------------------------------------------------------------ +-- Generating the type hierarchy and signal callback .hs files. +------------------------------------------------------------------------------ + +typeGenProgram :: Program +typeGenProgram = (simpleProgram "gtk2hsTypeGen") + +signalGenProgram :: Program +signalGenProgram = (simpleProgram "gtk2hsHookGenerator") + +c2hsLocal :: Program +c2hsLocal = (simpleProgram "gtk2hsC2hs") + +genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () +genSynthezisedFiles verb pd lbi = do + + cPkgs <- getPkgConfigPackages verb lbi pd + + let xList = maybe [] (customFieldsBI . libBuildInfo) (library pd) + ++customFieldsPD pd + typeOpts :: [ProgArg] + typeOpts = concat [ map (\val -> '-':'-':drop 8 field++'=':val) (words content) + | (field,content) <- xList, + "x-types-" `isPrefixOf` field, + field /= "x-types-file"] + ++ [ "--tag=" ++ tag + | PackageIdentifier name (Version (major:minor:_) _) <- cPkgs + , let name' = filter isAlpha (display name) + , tag <- name' + : [ name' ++ "-" ++ show major ++ "." ++ show digit + | digit <- [0,2..minor] ] + ] + + genFile :: Program -> [ProgArg] -> FilePath -> IO () + genFile prog args outFile = do + res <- rawSystemProgramStdoutConf verb prog (withPrograms lbi) args + rewriteFile outFile res + + case lookup "x-types-file" xList of + Nothing -> return () + Just f -> do + info verb ("Ensuring that class hierarchy in "++f++" is up-to-date.") + genFile typeGenProgram typeOpts f + + case (lookup "x-signals-file" xList, + lookup "x-signals-modname" xList) of + (Just _, Nothing) -> die "You need to specify the module name (X-Signals-ModName) \ + \to generate a signal file." + (Just f, Just mod) -> do + info verb ("Ensuring that callback hooks in "++f++" are up-to-date.") + genFile signalGenProgram [mod] f + (_,_) -> return () + +--FIXME: Cabal should tell us the selected pkg-config package versions in the +-- LocalBuildInfo or equivalent. +-- In the mean time, ask pkg-config again. + +getPkgConfigPackages :: Verbosity -> LocalBuildInfo -> PackageDescription -> IO [PackageId] +getPkgConfigPackages verbosity lbi pkg = + sequence + [ do version <- pkgconfig ["--modversion", display pkgname] + case simpleParse version of + Nothing -> die $ "parsing output of pkg-config --modversion failed" + Just v -> return (PackageIdentifier pkgname v) + | Dependency pkgname _ <- concatMap pkgconfigDepends (allBuildInfo pkg) ] + where + pkgconfig = rawSystemProgramStdoutConf verbosity + pkgConfigProgram (withPrograms lbi) + +------------------------------------------------------------------------------ +-- Dependency calculation amongst .chs files. +------------------------------------------------------------------------------ + +-- Given all files of the package, find those that end in .chs and extract the +-- .chs files they depend upon. Then return the PackageDescription with these +-- files rearranged so that they are built in a sequence that files that are +-- needed by other files are built first. +fixDeps :: PackageDescription -> IO PackageDescription +fixDeps pd...@PD...ckageDescription { + PD.library = Just li...@PD...brary { + PD.exposedModules = expMods, + PD.libBuildInfo = bi@PD.BuildInfo { + PD.hsSourceDirs = srcDirs, + PD.otherModules = othMods + }}} = do + let findModule m = findFileWithExtension [".chs.pp",".chs"] srcDirs + (joinPath (components m)) + mExpFiles <- mapM findModule expMods + mOthFiles <- mapM findModule othMods + + -- tag all exposed files with True so we throw an error if we need to build + -- an exposed module before an internal modules (we cannot express this) + let modDeps = zipWith (ModDep True []) expMods mExpFiles++ + zipWith (ModDep False []) othMods mOthFiles + modDeps <- mapM extractDeps modDeps + let (expMods, othMods) = span mdExposed $ sortTopological modDeps + badOther = map (fromMaybe "<no file>" . mdLocation) $ + filter (not . mdExposed) expMods + unless (null badOther) $ + die ("internal chs modules "++intercalate "," badOther++ + " depend on exposed chs modules; cabal needs to build internal modules first") + return pd { PD.library = Just lib { + PD.exposedModules = map mdOriginal expMods, + PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } + }} + +data ModDep = ModDep { + mdExposed :: Bool, + mdRequires :: [ModuleName], + mdOriginal :: ModuleName, + mdLocation :: Maybe FilePath +} + +instance Show ModDep where + show x = show (mdLocation x) + +instance Eq ModDep where + ModDep { mdOriginal = m1 } == ModDep { mdOriginal = m2 } = m1==m2 +instance Ord ModDep where + compare ModDep { mdOriginal = m1 } ModDep { mdOriginal = m2 } = compare m1 m2 + +-- Extract the dependencies of this file. This is intentionally rather naive as it +-- ignores CPP conditionals. We just require everything which means that the +-- existance of a .chs module may not depend on some CPP condition. [_$_] +extractDeps :: ModDep -> IO ModDep +extractDeps md@ModDep { mdLocation = Nothing } = return md +extractDeps md@ModDep { mdLocation = Just f } = withFileContents f $ \con -> do + let findImports acc (('{':'#':xs):xxs) = case (dropWhile ((==) ' ') xs) of + ('i':'m':'p':'o':'r':'t':' ':ys) -> + case simpleParse (takeWhile ((/=) '#') ys) of + Just m -> findImports (m:acc) xxs [_$_] + Nothing -> die ("cannot parse chs import in "++f++":\n"++ + "offending line is {#"++xs) + -- no more imports after the first non-import hook + _ -> return acc + findImports acc (_:xxs) = findImports acc xxs + findImports acc [] = return acc + mods <- findImports [] (lines con) + return md { mdRequires = mods } + +-- Find a total order of the set of modules that are partially sorted by their +-- dependencies on each other. The function returns the sorted list of modules +-- together with a list of modules that are required but not supplied by this +-- in the input set of modules. +sortTopological :: [ModDep] -> [ModDep] +sortTopological ms = reverse $ fst $ foldl visit ([], S.empty) (map mdOriginal ms) + where + set = M.fromList (map (\m -> (mdOriginal m, m)) ms) + visit (out,visited) m + | m `S.member` visited = (out,visited) + | otherwise = case m `M.lookup` set of + Nothing -> (out, m `S.insert` visited) + Just md -> (md:out', visited') + where + (out',visited') = foldl visit (out, m `S.insert` visited) (mdRequires md) hunk ./gio/System/GIO.hs 30 - module System.GIO.AsyncResult, - module System.GIO.Cancellable, - module System.GIO.File + module System.GIO.Async.AsyncResult, + module System.GIO.Async.Cancellable, + module System.GIO.File.File hunk ./gio/System/GIO.hs 35 -import System.GIO.AsyncResult -import System.GIO.Cancellable -import System.GIO.File +import System.GIO.Async.AsyncResult +import System.GIO.Async.Cancellable +import System.GIO.File.File adddir ./gio/System/GIO/Async addfile ./gio/System/GIO/Async/AsyncResult.chs hunk ./gio/System/GIO/Async/AsyncResult.chs 1 +{-# LANGUAGE CPP #-} +-- GIMP Toolkit (GTK) Binding for Haskell: binding to gio -*-haskell-*- +-- +-- Author : Peter Gavin +-- Created: 13-Oct-2008 +-- +-- Copyright (c) 2008 Peter Gavin +-- +-- This library is free software: you can redistribute it and/or +-- modify it under the terms of the GNU Lesser General Public License +-- as published by the Free Software Foundation, either version 3 of +-- the License, or (at your option) any later version. +-- [_$_] +-- This library is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-- Lesser General Public License for more details. +-- [_$_] +-- You should have received a copy of the GNU Lesser General Public +-- License along with this program. If not, see +-- <http://www.gnu.org/licenses/>. +-- [_$_] +-- GIO, the C library which this Haskell library depends on, is +-- available under LGPL Version 2. The documentation included with +-- this library is based on the original GIO documentation. +-- [_$_] +-- | Maintainer : gtk...@li... +-- Stability : alpha +-- Portability : portable (depends on GHC) +module System.GIO.Async.AsyncResult ( + AsyncResult, + AsyncResultClass, + AsyncReadyCallback + ) where + +import System.Glib.FFI + +import System.GIO.Base +{#import System.GIO.Types#} + addfile ./gio/System/GIO/Async/Cancellable.chs hunk ./gio/System/GIO/Async/Cancellable.chs 1 +{-# LANGUAGE CPP #-} +-- GIMP Toolkit (GTK) Binding for Haskell: binding to gio -*-haskell-*- +-- +-- Author : Peter Gavin +-- Created: 13-Oct-2008 +-- +-- Copyright (c) 2008 Peter Gavin +-- +-- This library is free software: you can redistribute it and/or +-- modify it under the terms of the GNU Lesser General Public License +-- as published by the Free Software Foundation, either version 3 of +-- the License, or (at your option) any later version. +-- [_$_] +-- This library is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-- Lesser General Public License for more details. +-- [_$_] +-- You should have received a copy of the GNU Lesser General Public +-- License along with this program. If not, see +-- <http://www.gnu.org/licenses/>. +-- [_$_] +-- GIO, the C library which this Haskell library depends on, is +-- available under LGPL Version 2. The documentation included with +-- this library is based on the original GIO documentation. +-- [_$_] +-- | Maintainer : gtk...@li... +-- Stability : alpha +-- Portability : portable (depends on GHC) +module System.GIO.Async.Cancellable ( + Cancellable, + cancellableNew, + cancellableIsCancelled, + cancellableThrowErrorIfCancelled, + cancellableGetCurrent, + cancellablePopCurrent, + cancellablePushCurrent, + cancellableReset, + cancellableCancel, + cancellableCancelled + ) where + +import Control.Monad + +import System.Glib.FFI +import System.Glib.GError +import System.Glib.Signals + +import System.GIO.Base +{#import System.GIO.Types#} +{#import System.GIO.Signals#} + +{# context lib = "gio" prefix = "g" #} + +cancellableNew :: IO Cancellable +cancellableNew = + {# call cancellable_new #} >>= takeGObject + +cancellableIsCancelled :: Cancellable -> IO Bool +cancellableIsCancelled = + liftM toBool . {# call cancellable_is_cancelled #} + +cancellableThrowErrorIfCancelled :: Cancellable -> IO () +cancellableThrowErrorIfCancelled cancellable = + propagateGError $ \gErrorPtr -> do + {# call cancellable_set_error_if_cancelled #} cancellable gErrorPtr + return () + +cancellableGetCurrent :: IO (Maybe Cancellable) +cancellableGetCurrent = + {# call cancellable_get_current #} >>= maybePeek takeGObject + +cancellablePopCurrent :: Maybe Cancellable -> IO () +cancellablePopCurrent cancellable = + maybeWith withGObject cancellable g_cancellable_pop_current + where + _ = {# call cancellable_pop_current #} + +cancellablePushCurrent :: Maybe Cancellable -> IO () +cancellablePushCurrent cancellable = + maybeWith withGObject cancellable g_cancellable_push_current + where + _ = {# call cancellable_push_current #} + +cancellableReset :: Cancellable -> IO () +cancellableReset = {# call cancellable_reset #} + +cancellableCancel :: Cancellable -> IO () +cancellableCancel = {# call cancellable_cancel #} + +cancellableCancelled :: Signal Cancellable (IO ()) +cancellableCancelled = + Signal $ connect_NONE__NONE "cancelled" hunk ./gio/System/GIO/AsyncResult.chs 1 --- GIMP Toolkit (GTK) Binding for Haskell: binding to gio -*-haskell-*- --- --- Author : Peter Gavin --- Created: 13-Oct-2008 --- --- Copyright (c) 2008 Peter Gavin --- --- This library is free software: you can redistribute it and/or --- modify it under the terms of the GNU Lesser General Public License --- as published by the Free Software Foundation, either version 3 of --- the License, or (at your option) any later version. --- [_$_] --- This library is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- Lesser General Public License for more details. --- [_$_] --- You should have received a copy of the GNU Lesser General Public --- License along with this program. If not, see --- <http://www.gnu.org/licenses/>. --- [_$_] --- GIO, the C library which this Haskell library depends on, is --- available under LGPL Version 2. The documentation included with --- this library is based on the original GIO documentation. --- [_$_] --- | Maintainer : gtk...@li... --- Stability : alpha --- Portability : portable (depends on GHC) -module System.GIO.AsyncResult ( - AsyncResult, - AsyncResultClass, - AsyncReadyCallback - ) where - -import System.Glib.FFI - -import System.GIO.Base -{#import System.GIO.Types#} - rmfile ./gio/System/GIO/AsyncResult.chs hunk ./gio/System/GIO/Base.chs 1 +{-# LANGUAGE CPP #-} hunk ./gio/System/GIO/Cancellable.chs 1 --- GIMP Toolkit (GTK) Binding for Haskell: binding to gio -*-haskell-*- --- --- Author : Peter Gavin --- Created: 13-Oct-2008 --- --- Copyright (c) 2008 Peter Gavin --- --- This library is free software: you can redistribute it and/or --- modify it under the terms of the GNU Lesser General Public License --- as published by the Free Software Foundation, either version 3 of --- the License, or (at your option) any later version. --- [_$_] --- This library is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- Lesser General Public License for more details. --- [_$_] --- You should have received a copy of the GNU Lesser General Public --- License along with this program. If not, see --- <http://www.gnu.org/licenses/>. --- [_$_] --- GIO, the C library which this Haskell library depends on, is --- available under LGPL Version 2. The documentation included with --- this library is based on the original GIO documentation. --- [_$_] --- | Maintainer : gtk...@li... --- Stability : alpha --- Portability : portable (depends on GHC) -module System.GIO.Cancellable ( - Cancellable, - cancellableNew, - cancellableIsCancelled, - cancellableThrowErrorIfCancelled, - cancellableGetCurrent, - cancellablePopCurrent, - cancellablePushCurrent, - cancellableReset, - cancellableCancel, - cancellableCancelled - ) where - -import Control.Monad - -import System.Glib.FFI -import System.Glib.GError -import System.Glib.Signals - -import System.GIO.Base -{#import System.GIO.Types#} -{#import System.GIO.Signals#} - -{# context lib = "gio" prefix = "g" #} - -cancellableNew :: IO Cancellable -cancellableNew = - {# call cancellable_new #} >>= takeGObject - -cancellableIsCancelled :: Cancellable -> IO Bool -cancellableIsCancelled = - liftM toBool . {# call cancellable_is_cancelled #} - -cancellableThrowErrorIfCancelled :: Cancellable -> IO () -cancellableThrowErrorIfCancelled cancellable = - propagateGError $ \gErrorPtr -> do - {# call cancellable_set_error_if_cancelled #} cancellable gErrorPtr - return () - -cancellableGetCurrent :: IO (Maybe Cancellable) -cancellableGetCurrent = - {# call cancellable_get_current #} >>= maybePeek takeGObject - -cancellablePopCurrent :: Maybe Cancellable -> IO () -cancellablePopCurrent cancellable = - maybeWith withGObject cancellable g_cancellable_pop_current - where - _ = {# call cancellable_pop_current #} - -cancellablePushCurrent :: Maybe Cancellable -> IO () -cancellablePushCurrent cancellable = - maybeWith withGObject cancellable g_cancellable_push_current - where - _ = {# call cancellable_push_current #} - -cancellableReset :: Cancellable -> IO () -cancellableReset = {# call cancellable_reset #} - -cancellableCancel :: Cancellable -> IO () -cancellableCancel = {# call cancellable_cancel #} - -cancellableCancelled :: Signal Cancellable (IO ()) -cancellableCancelled = - Signal $ connect_NONE__NONE "cancelled" rmfile ./gio/System/GIO/Cancellable.chs adddir ./gio/System/GIO/File hunk ./gio/System/GIO/File.chs 1 -{-# LANGUAGE CPP #-} --- GIMP Toolkit (GTK) Binding for Haskell: binding to gio -*-haskell-*- --- --- Author : Peter Gavin --- Created: 13-Oct-2008 --- --- Copyright (c) 2008 Peter Gavin --- --- This library is free software: you can redistribute it and/or --- modify it under the terms of the GNU Lesser General Public License --- as published by the Free Software Foundation, either version 3 of --- the License, or (at your option) any later version. --- [_$_] --- This library is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- Lesser General Public License for more details. --- [_$_] --- You should have received a copy of the GNU Lesser General Public --- License along with this program. If not, see --- <http://www.gnu.org/licenses/>. --- [_$_] --- GIO, the C library which this Haskell library depends on, is --- available under LGPL Version 2. The documentation included with --- this library is based on the original GIO documentation. --- [_$_] --- | Maintainer : gtk...@li... --- Stability : alpha --- Portability : portable (depends on GHC) -module System.GIO.File ( - File(..), - FileClass, - FileQueryInfoFlags(..), - FileCreateFlags(..), - FileCopyFlags(..), - FileMonitorFlags(..), - FilesystemPreviewType(..), - FileProgressCallback, - FileReadMoreCallback, - fileFromPath, - fileFromURI, - fileFromCommandlineArg, - fileFromParseName, - fileEqual, - fileBasename, - filePath, - fileURI, - fileParseName, - fileGetChild, - fileGetChildForDisplayName, - fileHasPrefix, - fileGetRelativePath, - fileResolveRelativePath, - fileIsNative, - fileHasURIScheme, - fileURIScheme, - fileRead, - fileReadAsync, - fileReadFinish, - fileAppendTo, - fileCreate, - fileReplace, - fileAppendToAsync, - fileAppendToFinish, - fileCreateAsync, - fileCreateFinish, - fileReplaceAsync, - fileReplaceFinish, - fileQueryInfo, - fileQueryInfoAsync, - fileQueryInfoFinish, - fileQueryExists, - fileQueryFilesystemInfo, - fileQueryFilesystemInfoAsync, - fileQueryFilesystemInfoFinish, - fileQueryDefaultHandler, - fileFindEnclosingMount, - fileFindEnclosingMountAsync, - fileFindEnclosingMountFinish, - fileEnumerateChildren, - fileEnumerateChildrenAsync, - fileEnumerateChildrenFinish, - fileSetDisplayName, - fileSetDisplayNameAsync, - fileSetDisplayNameFinish, - fileDelete, - fileTrash, - fileCopy, - fileCopyAsync, - fileCopyFinish, - fileMove, - fileMakeDirectory, -#if GLIB_CHECK_VERSION(2,18,0) - fileMakeDirectoryWithParents, -#endif - fileMakeSymbolicLink, - fileQuerySettableAttributes, - fileQueryWritableNamespaces - ) where - -import Control.Monad -import qualified Data.ByteString as BS -import Data.Typeable - -import System.Glib.FFI -import System.Glib.Flags -import System.Glib.GError -import System.Glib.UTFString -import System.Glib.GObject - -import System.GIO.Base -{#import System.GIO.Types#} -import System.GIO.FileAttribute - -{# context lib = "gio" prefix = "g" #} - -{# enum GFileQueryInfoFlags as FileQueryInfoFlags {underscoreToCase} with prefix = "G" deriving (Eq, Ord, Bounded, Show, Typeable) #} -instance Flags FileQueryInfoFlags - ... [truncated message content] |