//===-- 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 "Config/config.h"
#include "Support/CommandLine.h"
#include <algorithm>
#include <map>
#include <set>
#include <iostream>
#include <cstdlib>
#include <cerrno>
#include <cstring>
using namespace llvm;
using namespace cl;
// Globals for name and overview of program
static const char *ProgramName = "<unknown>";
static const char *ProgramOverview = 0;
//===----------------------------------------------------------------------===//
// Basic, shared command line option processing machinery...
//
// Return the global command line option vector. Making it a function scoped
// static ensures that it will be initialized correctly before its first use.
//
static std::map<std::string, Option*> *CommandLineOptions = 0;
static std::map<std::string, Option*> &getOpts() {
if (CommandLineOptions == 0)
CommandLineOptions = new std::map<std::string,Option*>();
return *CommandLineOptions;
}
static Option *getOption(const std::string &Str) {
if (CommandLineOptions == 0) return 0;
std::map<std::string,Option*>::iterator I = CommandLineOptions->find(Str);
return I != CommandLineOptions->end() ? I->second : 0;
}
static std::vector<Option*> &getPositionalOpts() {
static std::vector<Option*> *Positional = 0;
if (!Positional) Positional = new std::vector<Option*>();
return *Positional;
}
static void AddArgument(const char *ArgName, Option *Opt) {
if (getOption(ArgName)) {
std::cerr << ProgramName << ": CommandLine Error: Argument '"
<< ArgName << "' defined more than once!\n";
} else {
// Add argument to the argument map!
getOpts()[ArgName] = Opt;
}
}
// RemoveArgument - It's possible that the argument is no longer in the map if
// options have already been processed and the map has been deleted!
//
static void RemoveArgument(const char *ArgName, Option *Opt) {
if (CommandLineOptions == 0) return;
#ifndef NDEBUG
// This disgusting HACK is brought to you courtesy of GCC 3.3.2, which ICE's
// If we pass ArgName directly into getOption here.
std::string Tmp = ArgName;
assert(getOption(Tmp) == Opt && "Arg not in map!");
#endif
CommandLineOptions->erase(ArgName);
if (CommandLineOptions->empty()) {
delete CommandLineOptions;
CommandLineOptions = 0;
}
}
static inline bool ProvideOption(Option *Handler, const char *ArgName,
const char *Value, int argc, char **argv,
int &i) {
// Enforce value requirements
switch (Handler->getValueExpectedFlag()) {
case ValueRequired:
if (Value == 0 || *Value == 0) { // No value specified?
if (i+1 < argc) { // Steal the next argument, like for '-o filename'
Value = argv[++i];
} else {
return Handler->error(" requires a value!");
}
}
break;
case ValueDisallowed:
if (*Value != 0)
return Handler->error(" does not allow a value! '" +
std::string(Value) + "' specified.");
break;
case ValueOptional:
break;
default:
std::cerr << ProgramName
<< ": Bad ValueMask flag! CommandLine usage error:"
<< Handler->getValueExpectedFlag() << "\n";
abort();
break;
}
// Run the handler now!
return Handler->addOccurrence(i, ArgName, Value);
}
static bool ProvidePositionalOption(Option *Handler, const std::string &Arg,
int i) {
int Dummy = i;
return ProvideOption(Handler, Handler->ArgStr, Arg.c_str(), 0, 0, Dummy);
}
// Option predicates...
static inline bool isGrouping(const Option *