//===-- CommandLine.cpp - Command line parser implementation --------------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class implements a command line argument processor that is useful when
// creating a tool. It provides a simple, minimalistic interface that is easily
// extensible and supports nonlocal (library) command line options.
//
// Note that rather than trying to figure out what this code does, you could try
// reading the library documentation located in docs/CommandLine.html
//
//===----------------------------------------------------------------------===//
#include "llvm/Config/config.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Streams.h"
#include "llvm/System/Path.h"
#include <algorithm>
#include <functional>
#include <map>
#include <ostream>
#include <set>
#include <cstdlib>
#include <cerrno>
#include <cstring>
using namespace llvm;
using namespace cl;
//===----------------------------------------------------------------------===//
// Template instantiations and anchors.
//
TEMPLATE_INSTANTIATION(class basic_parser<bool>);
TEMPLATE_INSTANTIATION(class basic_parser<int>);
TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
TEMPLATE_INSTANTIATION(class basic_parser<double>);
TEMPLATE_INSTANTIATION(class basic_parser<float>);
TEMPLATE_INSTANTIATION(class basic_parser<std::string>);
TEMPLATE_INSTANTIATION(class opt<unsigned>);
TEMPLATE_INSTANTIATION(class opt<int>);
TEMPLATE_INSTANTIATION(class opt<std::string>);
TEMPLATE_INSTANTIATION(class opt<bool>);
void Option::anchor() {}
void basic_parser_impl::anchor() {}
void parser<bool>::anchor() {}
void parser<int>::anchor() {}
void parser<unsigned>::anchor() {}
void parser<double>::anchor() {}
void parser<float>::anchor() {}
void parser<std::string>::anchor() {}
//===----------------------------------------------------------------------===//
// Globals for name and overview of program. Program name is not a string to
// avoid static ctor/dtor issues.
static char ProgramName[80] = "<premain>";
static const char *ProgramOverview = 0;
// This collects additional help to be printed.
static ManagedStatic<std::vector<const char*> > MoreHelp;
extrahelp::extrahelp(const char *Help)
: morehelp(Help) {
MoreHelp->push_back(Help);
}
/// RegisteredOptionList - This is the list of the command line options that
/// have statically constructed themselves.
static Option *RegisteredOptionList = 0;
void Option::addArgument() {
assert(NextRegistered == 0 && "argument multiply registered!");
NextRegistered = RegisteredOptionList;
RegisteredOptionList = this;
}
//===----------------------------------------------------------------------===//
// Basic, shared command line option processing machinery.
//
/// GetOptionInfo - Scan the list of registered options, turning them into data
/// structures that are easier to handle.
static void GetOptionInfo(std::vector<Option*> &PositionalOpts,
std::map<std::string, Option*> &OptionsMap) {
std::vector<const char*> OptionNames;
for (Option *O = RegisteredOptionList; O; O = O->getNextRegisteredOption()) {
// If this option wants to handle multiple option names, get the full set.
// This handles enum options like "-O1 -O2" etc.
O->getExtraOptionNames(OptionNames);
if (O->ArgStr[0])
OptionNames.push_back(O->ArgStr);
// Handle named options.
for (unsigned i = 0, e = OptionNames.size(); i != e; ++i) {
// Add argument to the argument map!
if (!OptionsMap.insert(std::pair<std::string,Option*>(OptionNames[i],
O)).second) {
cerr << ProgramName << ": CommandLine Error: Argument '"
<< OptionNames[0] << "' defined more than once!\n";
}
}
OptionNames.clear();
// Remember information about positional options.
if (O->getFormattingFlag() == cl::Positional)
PositionalOpts.push_back(O);
else if (O->getNumOccurrencesFlag() == cl::ConsumeAfter) {
if (!PositionalOpts.empty() &&
PositionalOpts.front()->getNumOccurrencesFlag() == cl::ConsumeAfter)
O->error("Cannot specify more than one option with cl::ConsumeAfter!");
PositionalOpts.insert(PositionalOpts.begin(), O);
}
}
}
/// LookupOption - Lookup the option specifie