brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.1 KiB · bcf433f Raw
138 lines · cpp
1#include "llvm/ADT/ArrayRef.h"2#include "llvm/ADT/StringRef.h"3#include "llvm/Option/ArgList.h"4#include "llvm/Option/OptTable.h"5#include "llvm/Support/Error.h"6#include "llvm/Support/InitLLVM.h"7#include "llvm/Support/raw_ostream.h"8 9using namespace llvm;10using namespace llvm::opt;11 12namespace {13enum ID {14  OPT_INVALID = 0,15#define OPTION(PREFIXES, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS,       \16               VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR,     \17               VALUES, SUBCOMMANDIDS_OFFSET)                                   \18  OPT_##ID,19#include "Opts.inc"20#undef OPTION21};22#define OPTTABLE_STR_TABLE_CODE23#include "Opts.inc"24#undef OPTTABLE_STR_TABLE_CODE25 26#define OPTTABLE_PREFIXES_TABLE_CODE27#include "Opts.inc"28#undef OPTTABLE_PREFIXES_TABLE_CODE29 30#define OPTTABLE_SUBCOMMAND_IDS_TABLE_CODE31#include "Opts.inc"32#undef OPTTABLE_SUBCOMMAND_IDS_TABLE_CODE33 34#define OPTTABLE_SUBCOMMANDS_CODE35#include "Opts.inc"36#undef OPTTABLE_SUBCOMMANDS_CODE37 38static constexpr OptTable::Info InfoTable[] = {39#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),40#include "Opts.inc"41#undef OPTION42};43 44class HelloSubOptTable : public GenericOptTable {45public:46  HelloSubOptTable()47      : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable,48                        /*IgnoreCase=*/false, OptionSubCommands,49                        OptionSubCommandIDsTable) {};50};51} // namespace52 53int main(int argc, char **argv) {54  InitLLVM X(argc, argv);55  HelloSubOptTable T;56  unsigned MissingArgIndex, MissingArgCount;57 58  auto HandleMultipleSubcommands = [](ArrayRef<StringRef> SubCommands) {59    assert(SubCommands.size() > 1);60    llvm::errs() << "error: more than one subcommand passed [\n";61    for (auto SC : SubCommands)62      llvm::errs() << " `" << SC << "`\n";63    llvm::errs() << "]\n";64    llvm::errs() << "See --help.\n";65    exit(1);66  };67 68  auto HandleOtherPositionals = [](ArrayRef<StringRef> Positionals) {69    assert(!Positionals.empty());70    llvm::errs() << "error: unknown positional argument(s) [\n";71    for (auto SC : Positionals)72      llvm::errs() << " `" << SC << "`\n";73    llvm::errs() << "]\n";74    llvm::errs() << "See --help.\n";75    exit(1);76  };77 78  InputArgList Args = T.ParseArgs(ArrayRef(argv + 1, argc - 1), MissingArgIndex,79                                  MissingArgCount);80 81  StringRef SubCommand = Args.getSubCommand(82      T.getSubCommands(), HandleMultipleSubcommands, HandleOtherPositionals);83  // Handle help. When help options is found, ignore all other options and exit84  // after printing help.85 86  if (Args.hasArg(OPT_help)) {87    T.printHelp(llvm::outs(), "llvm-hello-sub [subcommand] [options]",88                "LLVM Hello SubCommand Example", false, false, Visibility(),89                SubCommand);90    return 0;91  }92 93  auto HandleSubCommandArg = [&](ID OptionType) {94    if (!Args.hasArg(OptionType))95      return false;96    auto O = T.getOption(OptionType);97    if (!O.isRegisteredSC(SubCommand)) {98      llvm::errs() << "Option [" << O.getName()99                   << "] is not valid for SubCommand [" << SubCommand << "]\n";100      return false;101    }102    return true;103  };104 105  bool HasUnknownOptions = false;106  for (const Arg *A : Args.filtered(OPT_UNKNOWN)) {107    HasUnknownOptions = true;108    llvm::errs() << "Unknown option `" << A->getAsString(Args) << "'\n";109  }110  if (HasUnknownOptions) {111    llvm::errs() << "See `OptSubcommand --help`.\n";112    return 1;113  }114  if (SubCommand.empty()) {115    if (Args.hasArg(OPT_version))116      llvm::outs() << "LLVM Hello SubCommand Example 1.0\n";117  } else if (SubCommand == "foo") {118    if (HandleSubCommandArg(OPT_uppercase))119      llvm::outs() << "FOO\n";120    else if (HandleSubCommandArg(OPT_lowercase))121      llvm::outs() << "foo\n";122 123    if (HandleSubCommandArg(OPT_version))124      llvm::outs() << "LLVM Hello SubCommand foo Example 1.0\n";125 126  } else if (SubCommand == "bar") {127    if (HandleSubCommandArg(OPT_lowercase))128      llvm::outs() << "bar\n";129    else if (HandleSubCommandArg(OPT_uppercase))130      llvm::outs() << "BAR\n";131 132    if (HandleSubCommandArg(OPT_version))133      llvm::outs() << "LLVM Hello SubCommand bar Example 1.0\n";134  }135 136  return 0;137}138