content: -----------------------------------------------------------------------------
  -- |
  -- Module      :  Distribution.InstalledPackageInfo
  -- Copyright   :  (c) The University of Glasgow 2004
  --
  -- Maintainer  :  libraries@haskell.org
  -- Portability :  portable
  --
  -- This is the information about an /installed/ package that
  -- is communicated to the @ghc-pkg@ program in order to register
  -- a package.  @ghc-pkg@ now consumes this package format (as of version
  -- 6.4). This is specific to GHC at the moment.
  --
  -- The @.cabal@ file format is for describing a package that is not yet
  -- installed. It has a lot of flexibility, like conditionals and dependency
  -- ranges. As such, that format is not at all suitable for describing a package
  -- that has already been built and installed. By the time we get to that stage,
  -- we have resolved all conditionals and resolved dependency version
  -- constraints to exact versions of dependent packages. So, this module defines
  -- the 'InstalledPackageInfo' data structure that contains all the info we keep
  -- about an installed package. There is a parser and pretty printer. The
  -- textual format is rather simpler than the @.cabal@ format: there are no
  -- sections, for example.
  
  {- All rights reserved.
  
  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are
  met:
  
      * Redistributions of source code must retain the above copyright
        notice, this list of conditions and the following disclaimer.
  
      * Redistributions in binary form must reproduce the above
        copyright notice, this list of conditions and the following
        disclaimer in the documentation and/or other materials provided
        with the distribution.
  
      * Neither the name of the University nor the names of other
        contributors may be used to endorse or promote products derived
        from this software without specific prior written permission.
  
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -}
  
  -- This module is meant to be local-only to Distribution...
  
  module Distribution.InstalledPackageInfo (
          InstalledPackageInfo_(..), InstalledPackageInfo,
          ParseResult(..), PError(..), PWarning,
          emptyInstalledPackageInfo,
          parseInstalledPackageInfo,
          showInstalledPackageInfo,
          showInstalledPackageInfoField,
          showSimpleInstalledPackageInfoField,
          fieldsInstalledPackageInfo,
    ) where
  
  import Distribution.ParseUtils
           ( FieldDescr(..), ParseResult(..), PError(..), PWarning
           , simpleField, listField, parseLicenseQ
           , showFields, showSingleNamedField, showSimpleSingleNamedField
           , parseFieldsFlat
           , parseFilePathQ, parseTokenQ, parseModuleNameQ, parsePackageNameQ
           , showFilePath, showToken, boolField, parseOptVersion
           , parseFreeText, showFreeText )
  import Distribution.License     ( License(..) )
  import Distribution.Package
           ( PackageName(..), PackageIdentifier(..), PackageId, InstalledPackageId(..)
           , packageName, packageVersion )
  import qualified Distribution.Package as Package
           ( Package(..) )
  import Distribution.ModuleName
           ( ModuleName )
  import Distribution.Version
           ( Version(..) )
  import Distribution.Text
           ( Text(disp, parse) )
  
  -- -----------------------------------------------------------------------------
  -- The InstalledPackageInfo type
  
  data InstalledPackageInfo_ m
     = InstalledPackageInfo {
          -- these parts are exactly the same as PackageDescription
          installedPackageId :: InstalledPackageId,
          sourcePackageId    :: PackageId,
          license           :: License,
          copyright         :: String,
          maintainer        :: String,
          author            :: String,
          stability         :: String,
          homepage          :: String,
          pkgUrl            :: String,
          synopsis          :: String,
          description       :: String,
          category          :: String,
          -- these parts are required by an installed package only:
          exposed           :: Bool,
          exposedModules    :: [m],
          hiddenModules     :: [m],
          trusted           :: Bool,
          importDirs        :: [FilePath],  -- contain sources in case of Hugs
          libraryDirs       :: [FilePath],
          hsLibraries       :: [String],
          extraLibraries    :: [String],
          extraGHCiLibraries:: [String],    -- overrides extraLibraries for GHCi
          includeDirs       :: [FilePath],
          includes          :: [String],
          depends           :: [InstalledPackageId],
          hugsOptions       :: [String],
          ccOptions         :: [String],
          ldOptions         :: [String],
          frameworkDirs     :: [FilePath],
          frameworks        :: [String],
          haddockInterfaces :: [FilePath],
          haddockHTMLs      :: [FilePath]
      }
      deriving (Read, Show)
  
  instance Package.Package          (InstalledPackageInfo_ str) where
     packageId = sourcePackageId
  
  type InstalledPackageInfo = InstalledPackageInfo_ ModuleName
  
  emptyInstalledPackageInfo :: InstalledPackageInfo_ m
  emptyInstalledPackageInfo
     = InstalledPackageInfo {
          installedPackageId = InstalledPackageId "",
          sourcePackageId    = PackageIdentifier (PackageName "") noVersion,
          license           = AllRightsReserved,
          copyright         = "",
          maintainer        = "",
          author            = "",
          stability         = "",
          homepage          = "",
          pkgUrl            = "",
          synopsis          = "",
          description       = "",
          category          = "",
          exposed           = False,
          exposedModules    = [],
          hiddenModules     = [],
          trusted           = False,
          importDirs        = [],
          libraryDirs       = [],
          hsLibraries       = [],
          extraLibraries    = [],
          extraGHCiLibraries= [],
          includeDirs       = [],
          includes          = [],
          depends           = [],
          hugsOptions       = [],
          ccOptions         = [],
          ldOptions         = [],
          frameworkDirs     = [],
          frameworks        = [],
          haddockInterfaces = [],
          haddockHTMLs      = []
      }
  
  noVersion :: Version
  noVersion = Version{ versionBranch=[], versionTags=[] }
  
  -- -----------------------------------------------------------------------------
  -- Parsing
  
  parseInstalledPackageInfo :: String -> ParseResult InstalledPackageInfo
  parseInstalledPackageInfo =
      parseFieldsFlat fieldsInstalledPackageInfo emptyInstalledPackageInfo
  
  -- -----------------------------------------------------------------------------
  -- Pretty-printing
  
  showInstalledPackageInfo :: InstalledPackageInfo -> String
  showInstalledPackageInfo = showFields fieldsInstalledPackageInfo
  
  showInstalledPackageInfoField :: String -> Maybe (InstalledPackageInfo -> String)
  showInstalledPackageInfoField = showSingleNamedField fieldsInstalledPackageInfo
  
  showSimpleInstalledPackageInfoField :: String -> Maybe (InstalledPackageInfo -> String)
  showSimpleInstalledPackageInfoField = showSimpleSingleNamedField fieldsInstalledPackageInfo
  
  -- -----------------------------------------------------------------------------
  -- Description of the fields, for parsing/printing
  
  fieldsInstalledPackageInfo :: [FieldDescr InstalledPackageInfo]
  fieldsInstalledPackageInfo = basicFieldDescrs ++ installedFieldDescrs
  
  basicFieldDescrs :: [FieldDescr InstalledPackageInfo]
  basicFieldDescrs =
   [ simpleField "name"
                             disp                   parsePackageNameQ
                             packageName            (\name pkg -> pkg{sourcePackageId=(sourcePackageId pkg){pkgName=name}})
   , simpleField "version"
                             disp                   parseOptVersion
                             packageVersion         (\ver pkg -> pkg{sourcePackageId=(sourcePackageId pkg){pkgVersion=ver}})
   , simpleField "id"
                             disp                   parse
                             installedPackageId     (\ipid pkg -> pkg{installedPackageId=ipid})
   , simpleField "license"
                             disp                   parseLicenseQ
                             license                (\l pkg -> pkg{license=l})
   , simpleField "copyright"
                             showFreeText           parseFreeText
                             copyright              (\val pkg -> pkg{copyright=val})
   , simpleField "maintainer"
                             showFreeText           parseFreeText
                             maintainer             (\val pkg -> pkg{maintainer=val})
   , simpleField "stability"
                             showFreeText           parseFreeText
                             stability              (\val pkg -> pkg{stability=val})
   , simpleField "homepage"
                             showFreeText           parseFreeText
                             homepage               (\val pkg -> pkg{homepage=val})
   , simpleField "package-url"
                             showFreeText           parseFreeText
                             pkgUrl                 (\val pkg -> pkg{pkgUrl=val})
   , simpleField "synopsis"
                             showFreeText           parseFreeText
                             synopsis               (\val pkg -> pkg{synopsis=val})
   , simpleField "description"
                             showFreeText           parseFreeText
                             description            (\val pkg -> pkg{description=val})
   , simpleField "category"
                             showFreeText           parseFreeText
                             category               (\val pkg -> pkg{category=val})
   , simpleField "author"
                             showFreeText           parseFreeText
                             author                 (\val pkg -> pkg{author=val})
   ]
  
  installedFieldDescrs :: [FieldDescr InstalledPackageInfo]
  installedFieldDescrs = [
     boolField "exposed"
          exposed            (\val pkg -> pkg{exposed=val})
   , listField   "exposed-modules"
          disp               parseModuleNameQ
          exposedModules     (\xs    pkg -> pkg{exposedModules=xs})
   , listField   "hidden-modules"
          disp               parseModuleNameQ
          hiddenModules      (\xs    pkg -> pkg{hiddenModules=xs})
   , boolField   "trusted"
          trusted            (\val pkg -> pkg{trusted=val})
   , listField   "import-dirs"
          showFilePath       parseFilePathQ
          importDirs         (\xs pkg -> pkg{importDirs=xs})
   , listField   "library-dirs"
          showFilePath       parseFilePathQ
          libraryDirs        (\xs pkg -> pkg{libraryDirs=xs})
   , listField   "hs-libraries"
          showFilePath       parseTokenQ
          hsLibraries        (\xs pkg -> pkg{hsLibraries=xs})
   , listField   "extra-libraries"
          showToken          parseTokenQ
          extraLibraries     (\xs pkg -> pkg{extraLibraries=xs})
   , listField   "extra-ghci-libraries"
          showToken          parseTokenQ
          extraGHCiLibraries (\xs pkg -> pkg{extraGHCiLibraries=xs})
   , listField   "include-dirs"
          showFilePath       parseFilePathQ
          includeDirs        (\xs pkg -> pkg{includeDirs=xs})
   , listField   "includes"
          showFilePath       parseFilePathQ
          includes           (\xs pkg -> pkg{includes=xs})
   , listField   "depends"
          disp               parse
          depends            (\xs pkg -> pkg{depends=xs})
   , listField   "hugs-options"
          showToken          parseTokenQ
          hugsOptions        (\path  pkg -> pkg{hugsOptions=path})
   , listField   "cc-options"
          showToken          parseTokenQ
          ccOptions          (\path  pkg -> pkg{ccOptions=path})
   , listField   "ld-options"
          showToken          parseTokenQ
          ldOptions          (\path  pkg -> pkg{ldOptions=path})
   , listField   "framework-dirs"
          showFilePath       parseFilePathQ
          frameworkDirs      (\xs pkg -> pkg{frameworkDirs=xs})
   , listField   "frameworks"
          showToken          parseTokenQ
          frameworks         (\xs pkg -> pkg{frameworks=xs})
   , listField   "haddock-interfaces"
          showFilePath       parseFilePathQ
          haddockInterfaces  (\xs pkg -> pkg{haddockInterfaces=xs})
   , listField   "haddock-html"
          showFilePath       parseFilePathQ
          haddockHTMLs       (\xs pkg -> pkg{haddockHTMLs=xs})
   ]
  