    -----------------------------------------------------------------------------

    -- |
    -- Module      :  Distribution.Simple.Build.Macros
    -- Copyright   :  Isaac Jones 2003-2005,
    --                Ross Paterson 2006,
    --                Duncan Coutts 2007-2008
    --
    -- Maintainer  :  cabal-devel@haskell.org
    -- Portability :  portable
    --
    -- Generating the Paths_pkgname module.
    --
    -- This is a module that Cabal generates for the benefit of packages. It
    -- enables them to find their version number and find any installed data files
    -- at runtime. This code should probably be split off into another module.
    module Distribution.Simple.Build.PathsModule
      ( generatePathsModule
      , pkgPathEnvVar
      ) where

    import Distribution.Compat.Prelude
    import Prelude ()

    import Distribution.Package
    import Distribution.PackageDescription
    import Distribution.Simple.Compiler
    import Distribution.Simple.LocalBuildInfo
    import Distribution.Simple.Utils (shortRelativePath)
    import Distribution.System
    import Distribution.Version

    import qualified Distribution.Simple.Build.PathsModule.Z as Z

    -- ------------------------------------------------------------

    -- * Building Paths_<pkg>.hs

    -- ------------------------------------------------------------

    generatePathsModule :: PackageDescription -> LocalBuildInfo -> ComponentLocalBuildInfo -> String
    generatePathsModule :: PackageDescription
    -> LocalBuildInfo -> ComponentLocalBuildInfo -> FilePath
    generatePathsModule PackageDescription
    pkg_descr LocalBuildInfo
    lbi ComponentLocalBuildInfo
    clbi =
      Z -> FilePath
    Z.render
        Z.Z
          { zPackageName :: PackageName
    Z.zPackageName = PackageDescription -> PackageName
    forall pkg. Package pkg => pkg -> PackageName
    packageName PackageDescription
    pkg_descr
          , zVersionDigits :: FilePath
    Z.zVersionDigits = [Int] -> FilePath
    forall a. Show a => a -> FilePath
    show ([Int] -> FilePath) -> [Int] -> FilePath
    forall a b. (a -> b) -> a -> b
    $ Version -> [Int]
    versionNumbers (Version -> [Int]) -> Version -> [Int]
    forall a b. (a -> b) -> a -> b
    $ PackageDescription -> Version
    forall pkg. Package pkg => pkg -> Version
    packageVersion PackageDescription
    pkg_descr
          , zSupportsCpp :: Bool
    Z.zSupportsCpp = Bool
    supports_cpp
          , zSupportsNoRebindableSyntax :: Bool
    Z.zSupportsNoRebindableSyntax = Bool
    supports_rebindable_syntax
          , zAbsolute :: Bool
    Z.zAbsolute = Bool
    absolute
          , zRelocatable :: Bool
    Z.zRelocatable = LocalBuildInfo -> Bool
    relocatable LocalBuildInfo
    lbi
          , zIsWindows :: Bool
    Z.zIsWindows = Bool
    isWindows
          , zIsI386 :: Bool
    Z.zIsI386 = Arch
    buildArch Arch -> Arch -> Bool
    forall a. Eq a => a -> a -> Bool
    == Arch
    I386
          , zIsX8664 :: Bool
    Z.zIsX8664 = Arch
    buildArch Arch -> Arch -> Bool
    forall a. Eq a => a -> a -> Bool
    == Arch
    X86_64
          , zNot :: Bool -> Bool
    Z.zNot = Bool -> Bool
    not
          , zManglePkgName :: PackageName -> FilePath
    Z.zManglePkgName = PackageName -> FilePath
    showPkgName
          , zPrefix :: FilePath
    Z.zPrefix = FilePath -> FilePath
    forall a. Show a => a -> FilePath
    show FilePath
    flat_prefix
          , zBindir :: FilePath
    Z.zBindir = FilePath
    zBindir
          , zLibdir :: FilePath
    Z.zLibdir = FilePath
    zLibdir
          , zDynlibdir :: FilePath
    Z.zDynlibdir = FilePath
    zDynlibdir
          , zDatadir :: FilePath
    Z.zDatadir = FilePath
    zDatadir
          , zLibexecdir :: FilePath
    Z.zLibexecdir = FilePath
    zLibexecdir
          , zSysconfdir :: FilePath
    Z.zSysconfdir = FilePath
    zSysconfdir
          }
      where
        supports_cpp :: Bool
    supports_cpp = Bool
    supports_language_pragma
        supports_rebindable_syntax :: Bool
    supports_rebindable_syntax = Version -> Bool
    ghc_newer_than ([Int] -> Version
    mkVersion [Int
    7, Int
    0, Int
    1])
        supports_language_pragma :: Bool
    supports_language_pragma = Version -> Bool
    ghc_newer_than ([Int] -> Version
    mkVersion [Int
    6, Int
    6, Int
    1])

        ghc_newer_than :: Version -> Bool
    ghc_newer_than Version
    minVersion =
          case CompilerFlavor -> Compiler -> Maybe Version
    compilerCompatVersion CompilerFlavor
    GHC (LocalBuildInfo -> Compiler
    compiler LocalBuildInfo
    lbi) of
            Maybe Version
    Nothing -> Bool
    False
            Just Version
    version -> Version
    version Version -> VersionRange -> Bool
    `withinRange` Version -> VersionRange
    orLaterVersion Version
    minVersion

        -- In several cases we cannot make relocatable installations
        absolute :: Bool
    absolute =
          PackageDescription -> Bool
    hasLibs PackageDescription
    pkg_descr -- we can only make progs relocatable
            Bool -> Bool -> Bool
    || Maybe FilePath -> Bool
    forall a. Maybe a -> Bool
    isNothing Maybe FilePath
    flat_bindirrel -- if the bin dir is an absolute path
            Bool -> Bool -> Bool
    || Bool -> Bool
    not (CompilerFlavor -> Bool
    supportsRelocatableProgs (Compiler -> CompilerFlavor
    compilerFlavor (LocalBuildInfo -> Compiler
    compiler LocalBuildInfo
    lbi)))

        -- TODO: Here, and with zIsI386 & zIs8664 we should use TARGET platform
        isWindows :: Bool
    isWindows = case OS
    buildOS of
          OS
    Windows -> Bool
    True
          OS
    _ -> Bool
    False

        supportsRelocatableProgs :: CompilerFlavor -> Bool
    supportsRelocatableProgs CompilerFlavor
    GHC = Bool
    isWindows
        supportsRelocatableProgs CompilerFlavor
    GHCJS = Bool
    isWindows
        supportsRelocatableProgs CompilerFlavor
    _ = Bool
    False

        cid :: UnitId
    cid = ComponentLocalBuildInfo -> UnitId
    componentUnitId ComponentLocalBuildInfo
    clbi

        InstallDirs
          { bindir :: forall dir. InstallDirs dir -> dir
    bindir = FilePath
    flat_bindir
          , libdir :: forall dir. InstallDirs dir -> dir
    libdir = FilePath
    flat_libdir
          , dynlibdir :: forall dir. InstallDirs dir -> dir
    dynlibdir = FilePath
    flat_dynlibdir
          , datadir :: forall dir. InstallDirs dir -> dir
    datadir = FilePath
    flat_datadir
          , libexecdir :: forall dir. InstallDirs dir -> dir
    libexecdir = FilePath
    flat_libexecdir
          , sysconfdir :: forall dir. InstallDirs dir -> dir
    sysconfdir = FilePath
    flat_sysconfdir
          , prefix :: forall dir. InstallDirs dir -> dir
    prefix = FilePath
    flat_prefix
          } = PackageDescription
    -> LocalBuildInfo -> UnitId -> CopyDest -> InstallDirs FilePath
    absoluteInstallCommandDirs PackageDescription
    pkg_descr LocalBuildInfo
    lbi UnitId
    cid CopyDest
    NoCopyDest

        InstallDirs
          { bindir :: forall dir. InstallDirs dir -> dir
    bindir = Maybe FilePath
    flat_bindirrel
          , libdir :: forall dir. InstallDirs dir -> dir
    libdir = Maybe FilePath
    flat_libdirrel
          , dynlibdir :: forall dir. InstallDirs dir -> dir
    dynlibdir = Maybe FilePath
    flat_dynlibdirrel
          , datadir :: forall dir. InstallDirs dir -> dir
    datadir = Maybe FilePath
    flat_datadirrel
          , libexecdir :: forall dir. InstallDirs dir -> dir
    libexecdir = Maybe FilePath
    flat_libexecdirrel
          , sysconfdir :: forall dir. InstallDirs dir -> dir
    sysconfdir = Maybe FilePath
    flat_sysconfdirrel
          } = PackageId
    -> LocalBuildInfo -> UnitId -> InstallDirs (Maybe FilePath)
    prefixRelativeComponentInstallDirs (PackageDescription -> PackageId
    forall pkg. Package pkg => pkg -> PackageId
    packageId PackageDescription
    pkg_descr) LocalBuildInfo
    lbi UnitId
    cid

        zBindir, zLibdir, zDynlibdir, zDatadir, zLibexecdir, zSysconfdir :: String
        (FilePath
    zBindir, FilePath
    zLibdir, FilePath
    zDynlibdir, FilePath
    zDatadir, FilePath
    zLibexecdir, FilePath
    zSysconfdir)
          | LocalBuildInfo -> Bool
    relocatable LocalBuildInfo
    lbi =
              ( FilePath -> FilePath
    forall a. Show a => a -> FilePath
    show FilePath
    flat_bindir_reloc
              , FilePath -> FilePath
    forall a. Show a => a -> FilePath
    show FilePath
    flat_libdir_reloc
              , FilePath -> FilePath
    forall a. Show a => a -> FilePath
    show FilePath
    flat_dynlibdir_reloc
              , FilePath -> FilePath
    forall a. Show a => a -> FilePath
    show FilePath
    flat_datadir_reloc
              , FilePath -> FilePath
    forall a. Show a => a -> FilePath
    show FilePath
    flat_libexecdir_reloc
              , FilePath -> FilePath
    forall a. Show a => a -> FilePath
    show FilePath
    flat_sysconfdir_reloc
              )
          | Bool
    absolute =
              ( FilePath -> FilePath
    forall a. Show a => a -> FilePath
    show FilePath
    flat_bindir
              , FilePath -> FilePath
    forall a. Show a => a -> FilePath
    show FilePath
    flat_libdir
              , FilePath -> FilePath
    forall a. Show a => a -> FilePath
    show FilePath
    flat_dynlibdir
              , FilePath -> FilePath
    forall a. Show a => a -> FilePath
    show FilePath
    flat_datadir
              , FilePath -> FilePath
    forall a. Show a => a -> FilePath
    show FilePath
    flat_libexecdir
              , FilePath -> FilePath
    forall a. Show a => a -> FilePath
    show FilePath
    flat_sysconfdir
              )
          | Bool
    isWindows =
              ( FilePath
    "maybe (error \"PathsModule.generate\") id (" FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++ Maybe FilePath -> FilePath
    forall a. Show a => a -> FilePath
    show Maybe FilePath
    flat_bindirrel FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++ FilePath
    ")"
              , FilePath -> Maybe FilePath -> FilePath
    mkGetDir FilePath
    flat_libdir Maybe FilePath
    flat_libdirrel
              , FilePath -> Maybe FilePath -> FilePath
    mkGetDir FilePath
    flat_dynlibdir Maybe FilePath
    flat_dynlibdirrel
              , FilePath -> Maybe FilePath -> FilePath
    mkGetDir FilePath
    flat_datadir Maybe FilePath
    flat_datadirrel
              , FilePath -> Maybe FilePath -> FilePath
    mkGetDir FilePath
    flat_libexecdir Maybe FilePath
    flat_libexecdirrel
              , FilePath -> Maybe FilePath -> FilePath
    mkGetDir FilePath
    flat_sysconfdir Maybe FilePath
    flat_sysconfdirrel
              )
          | Bool
    otherwise =
              FilePath
    -> (FilePath, FilePath, FilePath, FilePath, FilePath, FilePath)
    forall a. HasCallStack => FilePath -> a
    error FilePath
    "panic! generatePathsModule: should never happen"

        mkGetDir :: FilePath -> Maybe FilePath -> String
        mkGetDir :: FilePath -> Maybe FilePath -> FilePath
    mkGetDir FilePath
    _ (Just FilePath
    dirrel) = FilePath
    "getPrefixDirRel " FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++ FilePath -> FilePath
    forall a. Show a => a -> FilePath
    show FilePath
    dirrel
        mkGetDir FilePath
    dir Maybe FilePath
    Nothing = FilePath
    "return " FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++ FilePath -> FilePath
    forall a. Show a => a -> FilePath
    show FilePath
    dir

        flat_bindir_reloc :: FilePath
    flat_bindir_reloc = FilePath -> FilePath -> FilePath
    shortRelativePath FilePath
    flat_prefix FilePath
    flat_bindir
        flat_libdir_reloc :: FilePath
    flat_libdir_reloc = FilePath -> FilePath -> FilePath
    shortRelativePath FilePath
    flat_prefix FilePath
    flat_libdir
        flat_dynlibdir_reloc :: FilePath
    flat_dynlibdir_reloc = FilePath -> FilePath -> FilePath
    shortRelativePath FilePath
    flat_prefix FilePath
    flat_dynlibdir
        flat_datadir_reloc :: FilePath
    flat_datadir_reloc = FilePath -> FilePath -> FilePath
    shortRelativePath FilePath
    flat_prefix FilePath
    flat_datadir
        flat_libexecdir_reloc :: FilePath
    flat_libexecdir_reloc = FilePath -> FilePath -> FilePath
    shortRelativePath FilePath
    flat_prefix FilePath
    flat_libexecdir
        flat_sysconfdir_reloc :: FilePath
    flat_sysconfdir_reloc = FilePath -> FilePath -> FilePath
    shortRelativePath FilePath
    flat_prefix FilePath
    flat_sysconfdir

    -- | Generates the name of the environment variable controlling the path
    -- component of interest.
    --
    -- Note: The format of these strings is part of Cabal's public API;
    -- changing this function constitutes a *backwards-compatibility* break.
    pkgPathEnvVar
      :: PackageDescription
      -> String
      -- ^ path component; one of \"bindir\", \"libdir\", -- \"datadir\", \"libexecdir\", or \"sysconfdir\"
      -> String
      -- ^ environment variable name
    pkgPathEnvVar :: PackageDescription -> FilePath -> FilePath
    pkgPathEnvVar PackageDescription
    pkg_descr FilePath
    var =
      PackageName -> FilePath
    showPkgName (PackageDescription -> PackageName
    forall pkg. Package pkg => pkg -> PackageName
    packageName PackageDescription
    pkg_descr) FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++ FilePath
    "_" FilePath -> FilePath -> FilePath
    forall a. [a] -> [a] -> [a]
    ++ FilePath
    var

    showPkgName :: PackageName -> String
    showPkgName :: PackageName -> FilePath
    showPkgName = (Char -> Char) -> FilePath -> FilePath
    forall a b. (a -> b) -> [a] -> [b]
    map Char -> Char
    fixchar (FilePath -> FilePath)
    -> (PackageName -> FilePath) -> PackageName -> FilePath
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . PackageName -> FilePath
    unPackageName

    fixchar :: Char -> Char
    fixchar :: Char -> Char
    fixchar Char
    '-' = Char
    '_'
    fixchar Char
    c = Char
    c