Home | History | Annotate | Download | only in Option
      1 //===- unittest/Support/OptionParsingTest.cpp - OptTable tests ------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "llvm/ADT/OwningPtr.h"
     11 #include "llvm/ADT/STLExtras.h"
     12 #include "llvm/Option/Arg.h"
     13 #include "llvm/Option/ArgList.h"
     14 #include "llvm/Option/Option.h"
     15 #include "gtest/gtest.h"
     16 
     17 using namespace llvm;
     18 using namespace llvm::opt;
     19 
     20 enum ID {
     21   OPT_INVALID = 0, // This is not an option ID.
     22 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
     23               HELPTEXT, METAVAR) OPT_##ID,
     24 #include "Opts.inc"
     25   LastOption
     26 #undef OPTION
     27 };
     28 
     29 #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
     30 #include "Opts.inc"
     31 #undef PREFIX
     32 
     33 enum OptionFlags {
     34   OptFlag1 = (1 << 4),
     35   OptFlag2 = (1 << 5),
     36   OptFlag3 = (1 << 6)
     37 };
     38 
     39 static const OptTable::Info InfoTable[] = {
     40 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
     41                HELPTEXT, METAVAR)   \
     42   { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, PARAM, \
     43     FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS },
     44 #include "Opts.inc"
     45 #undef OPTION
     46 };
     47 
     48 namespace {
     49 class TestOptTable : public OptTable {
     50 public:
     51   TestOptTable()
     52     : OptTable(InfoTable, array_lengthof(InfoTable)) {}
     53 };
     54 }
     55 
     56 const char *Args[] = {
     57   "-A",
     58   "-Bhi",
     59   "--C=desu",
     60   "-C", "bye",
     61   "-D,adena",
     62   "-E", "apple", "bloom",
     63   "-Fblarg",
     64   "-F", "42",
     65   "-Gchuu", "2"
     66   };
     67 
     68 TEST(Option, OptionParsing) {
     69   TestOptTable T;
     70   unsigned MAI, MAC;
     71   OwningPtr<InputArgList> AL(T.ParseArgs(Args, array_endof(Args), MAI, MAC));
     72 
     73   // Check they all exist.
     74   EXPECT_TRUE(AL->hasArg(OPT_A));
     75   EXPECT_TRUE(AL->hasArg(OPT_B));
     76   EXPECT_TRUE(AL->hasArg(OPT_C));
     77   EXPECT_TRUE(AL->hasArg(OPT_D));
     78   EXPECT_TRUE(AL->hasArg(OPT_E));
     79   EXPECT_TRUE(AL->hasArg(OPT_F));
     80   EXPECT_TRUE(AL->hasArg(OPT_G));
     81 
     82   // Check the values.
     83   EXPECT_EQ(AL->getLastArgValue(OPT_B), "hi");
     84   EXPECT_EQ(AL->getLastArgValue(OPT_C), "bye");
     85   EXPECT_EQ(AL->getLastArgValue(OPT_D), "adena");
     86   std::vector<std::string> Es = AL->getAllArgValues(OPT_E);
     87   EXPECT_EQ(Es[0], "apple");
     88   EXPECT_EQ(Es[1], "bloom");
     89   EXPECT_EQ(AL->getLastArgValue(OPT_F), "42");
     90   std::vector<std::string> Gs = AL->getAllArgValues(OPT_G);
     91   EXPECT_EQ(Gs[0], "chuu");
     92   EXPECT_EQ(Gs[1], "2");
     93 
     94   // Check the help text.
     95   std::string Help;
     96   raw_string_ostream RSO(Help);
     97   T.PrintHelp(RSO, "test", "title!");
     98   EXPECT_NE(Help.find("-A"), std::string::npos);
     99 
    100   // Test aliases.
    101   arg_iterator Cs = AL->filtered_begin(OPT_C);
    102   ASSERT_NE(Cs, AL->filtered_end());
    103   EXPECT_EQ(StringRef((*Cs)->getValue()), "desu");
    104   ArgStringList ASL;
    105   (*Cs)->render(*AL, ASL);
    106   ASSERT_EQ(ASL.size(), 2u);
    107   EXPECT_EQ(StringRef(ASL[0]), "-C");
    108   EXPECT_EQ(StringRef(ASL[1]), "desu");
    109 }
    110 
    111 TEST(Option, ParseWithFlagExclusions) {
    112   TestOptTable T;
    113   unsigned MAI, MAC;
    114   OwningPtr<InputArgList> AL;
    115 
    116   // Exclude flag3 to avoid parsing as OPT_SLASH_C.
    117   AL.reset(T.ParseArgs(Args, array_endof(Args), MAI, MAC,
    118                        /*FlagsToInclude=*/0,
    119                        /*FlagsToExclude=*/OptFlag3));
    120   EXPECT_TRUE(AL->hasArg(OPT_A));
    121   EXPECT_TRUE(AL->hasArg(OPT_C));
    122   EXPECT_FALSE(AL->hasArg(OPT_SLASH_C));
    123 
    124   // Exclude flag1 to avoid parsing as OPT_C.
    125   AL.reset(T.ParseArgs(Args, array_endof(Args), MAI, MAC,
    126                        /*FlagsToInclude=*/0,
    127                        /*FlagsToExclude=*/OptFlag1));
    128   EXPECT_TRUE(AL->hasArg(OPT_B));
    129   EXPECT_FALSE(AL->hasArg(OPT_C));
    130   EXPECT_TRUE(AL->hasArg(OPT_SLASH_C));
    131 
    132   const char *NewArgs[] = { "/C", "foo", "--C=bar" };
    133   AL.reset(T.ParseArgs(NewArgs, array_endof(NewArgs), MAI, MAC));
    134   EXPECT_TRUE(AL->hasArg(OPT_SLASH_C));
    135   EXPECT_TRUE(AL->hasArg(OPT_C));
    136   EXPECT_EQ(AL->getLastArgValue(OPT_SLASH_C), "foo");
    137   EXPECT_EQ(AL->getLastArgValue(OPT_C), "bar");
    138 }
    139 
    140 TEST(Option, ParseAliasInGroup) {
    141   TestOptTable T;
    142   unsigned MAI, MAC;
    143 
    144   const char *MyArgs[] = { "-I" };
    145   OwningPtr<InputArgList> AL(T.ParseArgs(MyArgs, array_endof(MyArgs), MAI, MAC));
    146   EXPECT_TRUE(AL->hasArg(OPT_H));
    147 }
    148 
    149 TEST(Option, AliasArgs) {
    150   TestOptTable T;
    151   unsigned MAI, MAC;
    152 
    153   const char *MyArgs[] = { "-J", "-Joo" };
    154   OwningPtr<InputArgList> AL(T.ParseArgs(MyArgs, array_endof(MyArgs), MAI, MAC));
    155   EXPECT_TRUE(AL->hasArg(OPT_B));
    156   EXPECT_EQ(AL->getAllArgValues(OPT_B)[0], "foo");
    157   EXPECT_EQ(AL->getAllArgValues(OPT_B)[1], "bar");
    158 }
    159 
    160 TEST(Option, DashDash) {
    161   TestOptTable T;
    162   unsigned MAI, MAC;
    163 
    164   const char *MyArgs[] = { "-A", "--", "-B", "--" };
    165   OwningPtr<InputArgList> AL(T.ParseArgs(MyArgs, array_endof(MyArgs), MAI, MAC));
    166   EXPECT_TRUE(AL->hasArg(OPT_A));
    167   EXPECT_FALSE(AL->hasArg(OPT_B));
    168   EXPECT_EQ(AL->getAllArgValues(OPT_INPUT).size(), 2U);
    169   EXPECT_EQ(AL->getAllArgValues(OPT_INPUT)[0], "-B");
    170   EXPECT_EQ(AL->getAllArgValues(OPT_INPUT)[1], "--");
    171 }
    172