//===- CommandLine.cpp ----------------------------------------------------===//
//
// The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <mcld/Support/CommandLine.h>
#include <llvm/ADT/StringRef.h>
#include <llvm/ADT/Twine.h>
#include <llvm/ADT/StringSwitch.h>
#include <llvm/Support/ErrorHandling.h>
using namespace llvm;
using namespace llvm::cl;
using namespace mcld;
static const size_t MaxOptWidth = 8; // arbitrary spacing for printOptionDiff
//===----------------------------------------------------------------------===//
// SearchDirParser
//===----------------------------------------------------------------------===//
// parse - Return true on error.
bool SearchDirParser::parse(Option &pOption,
StringRef pArgName,
StringRef pArg,
std::string &pValue)
{
char separator = *(pArgName.data() + 1);
if ('=' == separator)
pValue = '=';
pValue += pArg.str();
return false;
}
void SearchDirParser::printOptionDiff(const Option &pOption,
StringRef pValue,
OptVal pDefault,
size_t pGlobalWidth) const
{
printOptionName(pOption, pGlobalWidth);
outs() << "= " << pValue;
size_t NumSpaces = MaxOptWidth > pValue.size()?MaxOptWidth - pValue.size():0;
outs().indent(NumSpaces) << " (default: ";
if (pDefault.hasValue())
outs() << pDefault.getValue();
else
outs() << "*no default*";
outs() << ")\n";
}
void SearchDirParser::anchor()
{
// do nothing
}
//===----------------------------------------------------------------------===//
// parser<mcld::sys::fs::Path>
//===----------------------------------------------------------------------===//
bool parser<mcld::sys::fs::Path>::parse(llvm::cl::Option &O,
llvm::StringRef ArgName,
llvm::StringRef Arg,
mcld::sys::fs::Path &Val)
{
Val.assign<llvm::StringRef::const_iterator>(Arg.begin(), Arg.end());
return false;
}
void parser<mcld::sys::fs::Path>::printOptionDiff(const llvm::cl::Option &O,
const mcld::sys::fs::Path &V,
parser<mcld::sys::fs::Path>::OptVal Default,
size_t GlobalWidth) const
{
printOptionName(O, GlobalWidth);
outs() << "= " << V;
size_t VSize = V.native().size();
size_t NumSpaces = MaxOptWidth > VSize ? MaxOptWidth - VSize : 0;
outs().indent(NumSpaces) << " (default: ";
if (Default.hasValue())
outs() << Default.getValue().c_str();
else
outs() << "*no default*";
outs() << ")\n";
}
void parser<mcld::sys::fs::Path>::anchor()
{
// do nothing
}
//===----------------------------------------------------------------------===//
// parser<mcld::ZOption>
//===----------------------------------------------------------------------===//
bool parser<mcld::ZOption>::parse(llvm::cl::Option &O,
llvm::StringRef ArgName,
llvm::StringRef Arg,
mcld::ZOption &Val)
{
if (0 == Arg.compare("combreloc"))
Val.setKind(ZOption::CombReloc);
else if (0 == Arg.compare("nocombreloc"))
Val.setKind(ZOption::NoCombReloc);
else if (0 == Arg.compare("defs"))
Val.setKind(ZOption::Defs);
else if (0 == Arg.compare("execstack"))
Val.setKind(ZOption::ExecStack);
else if (0 == Arg.compare("noexecstack"))
Val.setKind(ZOption::NoExecStack);
else if (0 == Arg.compare("initfirst"))
Val.setKind(ZOption::InitFirst);
else if (0 == Arg.compare("interpose"))
Val.setKind(ZOption::InterPose);
else if (0 == Arg.compare("loadfltr"))
Val.setKind(ZOption::LoadFltr);
else if (0 == Arg.compare("muldefs"))
Val.setKind(ZOption::MulDefs);
else if (0 == Arg.compare("nocopyreloc"))
Val.setKind(ZOption::NoCopyReloc);
else if (0 == Arg.compare("nodefaultlib"))
Val.setKind(ZOption::NoDefaultLib);
else if (0 == Arg.compare("nodelete"))
Val.setKind(ZOption::NoDelete);
else if (0 == Arg.compare("nodlopen"))
Val.setKind(ZOption::NoDLOpen);
else if (0 == Arg.compare("nodump"))
Val.setKind(ZOption::NoDump);
else if (0 == Arg.compare("relro"))
Val.setKind(ZOption::Relro);
else if (0 == Arg.compare("norelro"))
Val.setKind(ZOption::NoRelro);
else if (0 == Arg.compare("lazy"))
Val.setKind(ZOption::Lazy);
else if (0 == Arg.compare("now"))
Val.setKind(ZOption::Now);
else if (0 == Arg.compare("origin"))
Val.setKind(ZOption::Origin);
else if (Arg.startswith("common-page-size=")) {
Val.setKind(ZOption::CommPageSize);
long long unsigned size = 0;
Arg.drop_front(17).getAsInteger(0, size);
Val.setPageSize(static_cast<uint64_t>(size));
}
else if (Arg.startswith("max-page-size=")) {
Val.setKind(ZOption::MaxPageSize);
long long unsigned size = 0;
Arg.drop_front(14).getAsInteger(0, size);
Val.setPageSize(static_cast<uint64_t>(size));
}
if (ZOption::Unknown == Val.kind())
llvm::report_fatal_error(llvm::Twine("unknown -z option: `") +
Arg +
llvm::Twine("'\n"));
return false;
}
void parser<mcld::ZOption>::printOptionDiff(const llvm::cl::Option &O,
const mcld::ZOption &V,
parser<mcld::ZOption>::OptVal Default,
size_t GlobalWidth) const
{
// TODO
}
void parser<mcld::ZOption>::anchor()
{
// do nothing
}