hs-bindgen-1.0.0.0: app/HsBindgen/Cli/Info/Libclang.hs
-- | @hs-bindgen-cli info libclang@ command
--
-- Intended for qualified import.
--
-- > import HsBindgen.Cli.Info.Libclang qualified as Libclang
module HsBindgen.Cli.Info.Libclang (
-- * CLI help
info
-- * Options
, Opts(..)
, parseOpts
-- * Execution
, exec
) where
import Options.Applicative hiding (info)
import Prettyprinter.Util qualified as PP
import System.Exit (exitFailure)
import Clang.Enum.Simple (SimpleEnum (..), simpleFromC)
import Clang.LowLevel.Core (CXErrorCode (..))
import HsBindgen.App
import HsBindgen.Boot
import HsBindgen.Clang
import HsBindgen.Config.ClangArgs
import HsBindgen.Imports
import HsBindgen.TraceMsg
import HsBindgen.Util.Tracer
{-------------------------------------------------------------------------------
CLI help
-------------------------------------------------------------------------------}
info :: InfoMod a
info = mconcat [
progDesc "Run libclang with empty input"
, footerDoc . Just . PP.reflow $ mconcat infoHelpMessage
]
{-------------------------------------------------------------------------------
Options
-------------------------------------------------------------------------------}
newtype Opts = Opts {
clangArgsConfig :: ClangArgsConfig FilePath
}
parseOpts :: Parser Opts
parseOpts = Opts <$> parseClangArgsConfig
{-------------------------------------------------------------------------------
Execution
-------------------------------------------------------------------------------}
exec :: GlobalOpts -> Opts -> IO ()
exec global opts = do
eRes <- withTracer tracerConfigWithoutASTReadError $ \tracer -> do
clangArgs <- (.clangArgs) <$>
getClangArtefacts (contramap TraceBoot tracer) opts.clangArgsConfig
let hasNoUserOptions = hasNoUserClangOptions opts.clangArgsConfig
setup = defaultClangSetup clangArgs $
ClangInputMemory "hs-bindgen-nop.h" ""
-- Emit informational message if no user options provided
when ( hasNoUserOptions
&& global.unsafe.verbosity.level >= Info) $ do
traceWith (contramap (TraceFrontend . FrontendClang) tracer) $
withCallStack ClangInvokedWithoutOptions
withClang
(contramap (TraceFrontend . FrontendClang) tracer)
setup
(const (pure ()))
case eRes of
Left e -> do
print $ prettyForTrace e
exitFailure
Right _ -> pure ()
where
-- Check if user provided any Clang options via command line
--
hasNoUserClangOptions :: ClangArgsConfig FilePath -> Bool
hasNoUserClangOptions clangArgs = and [
null clangArgs.argsBefore
, null clangArgs.argsInner
, null clangArgs.argsAfter
]
-- Check if a trace is CXError_ASTReadError.
-- This error is benign in the context of 'info libclang' when users
-- provide diagnostic flags, as they cause Clang to exit without building an AST.
--
-- If trace is CXError_ASTReadError make it debug level which should
-- supress it but still make it available if needed with Debug level
-- logging
--
tracerConfigWithoutASTReadError =
global.unsafe {
customLogLevel = CustomLogLevel $ \trace actualLevel ->
case trace of
TraceFrontend (FrontendClang (ClangErrorCode (SimpleEnum x)))
| Just CXError_ASTReadError <- simpleFromC x ->
Debug
_ ->
applyCustomLogLevel
global.unsafe.customLogLevel
trace
actualLevel
}