//===- PreferenceOptions.cpp ----------------------------------------------===//
//
// The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <mcld/PreferenceOptions.h>
#include <mcld/LinkerConfig.h>
#include <mcld/Support/CommandLine.h>
#include <mcld/Support/raw_ostream.h>
#include <llvm/Support/Process.h>
#if defined(HAVE_UNISTD_H)
# include <unistd.h>
#endif
#if defined(_MSC_VER) || defined(__MINGW32__)
#include <io.h>
#ifndef STDIN_FILENO
# define STDIN_FILENO 0
#endif
#ifndef STDOUT_FILENO
# define STDOUT_FILENO 1
#endif
#ifndef STDERR_FILENO
# define STDERR_FILENO 2
#endif
#endif
namespace {
llvm::cl::opt<bool> ArgTrace("t",
llvm::cl::desc("Print the names of the input files as ld processes them."));
llvm::cl::alias ArgTraceAlias("trace",
llvm::cl::desc("alias for -t"),
llvm::cl::aliasopt(ArgTrace));
llvm::cl::opt<int> ArgVerbose("verbose",
llvm::cl::init(-1),
llvm::cl::desc("Display the version number for ld and list the\n"
"linker emulations supported."));
llvm::cl::opt<bool> ArgVersion("V",
llvm::cl::init(false),
llvm::cl::desc("Display the version number for MCLinker."));
llvm::cl::opt<int> ArgMaxErrorNum("error-limit",
llvm::cl::init(-1),
llvm::cl::desc("limits the maximum number of erros."));
llvm::cl::opt<int> ArgMaxWarnNum("warning-limit",
llvm::cl::init(-1),
llvm::cl::desc("limits the maximum number of warnings."));
llvm::cl::opt<mcld::PreferenceOptions::Color> ArgColor("color",
llvm::cl::value_desc("When"),
llvm::cl::desc("Surround the result strings with the marker"),
llvm::cl::init(mcld::PreferenceOptions::COLOR_Auto),
llvm::cl::values(
clEnumValN(mcld::PreferenceOptions::COLOR_Never, "never",
"do not surround result"),
clEnumValN(mcld::PreferenceOptions::COLOR_Always, "always",
"always surround results, even the output is a plain file"),
clEnumValN(mcld::PreferenceOptions::COLOR_Auto, "auto",
"surround result strings only if the output is a tty"),
clEnumValEnd));
llvm::cl::opt<bool> ArgPrintMap("M",
llvm::cl::desc("Print a link map to the standard output."),
llvm::cl::init(false));
llvm::cl::alias ArgPrintMapAlias("print-map",
llvm::cl::desc("alias for -M"),
llvm::cl::aliasopt(ArgPrintMap));
bool ArgFatalWarnings;
llvm::cl::opt<bool, true, llvm::cl::FalseParser> ArgNoFatalWarnings("no-fatal-warnings",
llvm::cl::location(ArgFatalWarnings),
llvm::cl::desc("do not turn warnings into errors"),
llvm::cl::init(false),
llvm::cl::ValueDisallowed);
llvm::cl::opt<bool, true> ArgFatalWarningsFlag("fatal-warnings",
llvm::cl::ZeroOrMore,
llvm::cl::location(ArgFatalWarnings),
llvm::cl::desc("turn all warnings into errors"),
llvm::cl::init(false),
llvm::cl::ValueDisallowed);
llvm::cl::opt<std::string> ArgUseLD("fuse-ld",
llvm::cl::desc("Ignored for GCC/collect2 linker compatibility."),
llvm::cl::init("mcld"));
llvm::cl::opt<std::string> ArgUseMCLD("use-mcld",
llvm::cl::desc("Ignored for GCC/collect2 linker compatibility."),
llvm::cl::init("mcld"));
//===----------------------------------------------------------------------===//
// Non-member functions
//===----------------------------------------------------------------------===//
inline bool ShouldColorize()
{
const char* term = getenv("TERM");
return term && (0 != strcmp(term, "dumb"));
}
} // anonymous namespace
using namespace mcld;
//===----------------------------------------------------------------------===//
// PreferenceOptions
//===----------------------------------------------------------------------===//
PreferenceOptions::PreferenceOptions()
: m_Trace(ArgTrace),
m_Verbose(ArgVerbose),
m_Version(ArgVersion),
m_MaxErrorNum(ArgMaxErrorNum),
m_MaxWarnNum(ArgMaxWarnNum),
m_Color(ArgColor),
m_PrintMap(ArgPrintMap),
m_FatalWarnings(ArgFatalWarnings) {
}
bool PreferenceOptions::parse(LinkerConfig& pConfig)
{
// set -t
pConfig.options().setTrace(m_Trace);
// set --verbose
pConfig.options().setVerbose(m_Verbose);
// set --error-limit [number]
pConfig.options().setMaxErrorNum(m_MaxErrorNum);
// set --warning-limit [number]
pConfig.options().setMaxWarnNum(m_MaxWarnNum);
// set --color [mode]
switch (m_Color) {
case COLOR_Never:
pConfig.options().setColor(false);
break;
case COLOR_Always:
pConfig.options().setColor(true);
break;
case COLOR_Auto:
bool color_option = ShouldColorize() &&
llvm::sys::Process::FileDescriptorIsDisplayed(STDOUT_FILENO);
pConfig.options().setColor(color_option);
break;
}
mcld::outs().setColor(pConfig.options().color());
mcld::errs().setColor(pConfig.options().color());
return true;
}