X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=unittests%2FSupport%2FCommandLineTest.cpp;h=e0fbf5b09e5787f030beedc8957e586db6cbdede;hb=9561506e34f1f6f358202944167416a450a711f6;hp=c54e1b9570f899aa0bc58ea05b1f80ad798d8dda;hpb=264e92d6db46083f9f46484ec39e99f18d35d370;p=oota-llvm.git diff --git a/unittests/Support/CommandLineTest.cpp b/unittests/Support/CommandLineTest.cpp index c54e1b9570f..e0fbf5b09e5 100644 --- a/unittests/Support/CommandLineTest.cpp +++ b/unittests/Support/CommandLineTest.cpp @@ -8,8 +8,9 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/STLExtras.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Config/config.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/StringSaver.h" #include "gtest/gtest.h" #include #include @@ -23,7 +24,7 @@ class TempEnvVar { TempEnvVar(const char *name, const char *value) : name(name) { const char *old_value = getenv(name); - EXPECT_EQ(NULL, old_value) << old_value; + EXPECT_EQ(nullptr, old_value) << old_value; #if HAVE_SETENV setenv(name, value, true); #else @@ -35,6 +36,8 @@ class TempEnvVar { #if HAVE_SETENV // Assume setenv and unsetenv come together. unsetenv(name); +#else + (void)name; // Suppress -Wunused-private-field. #endif } @@ -42,15 +45,40 @@ class TempEnvVar { const char *const name; }; +template +class StackOption : public cl::opt { + typedef cl::opt Base; +public: + // One option... + template + explicit StackOption(const M0t &M0) : Base(M0) {} + + // Two options... + template + StackOption(const M0t &M0, const M1t &M1) : Base(M0, M1) {} + + // Three options... + template + StackOption(const M0t &M0, const M1t &M1, const M2t &M2) : Base(M0, M1, M2) {} + + // Four options... + template + StackOption(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3) + : Base(M0, M1, M2, M3) {} + + ~StackOption() override { this->removeArgument(); } +}; + + cl::OptionCategory TestCategory("Test Options", "Description"); -cl::opt TestOption("test-option", cl::desc("old description")); TEST(CommandLineTest, ModifyExisitingOption) { + StackOption TestOption("test-option", cl::desc("old description")); + const char Description[] = "New description"; const char ArgString[] = "new-test-option"; const char ValueString[] = "Integer"; - StringMap Map; - cl::getRegisteredOptions(Map); + StringMap &Map = cl::getRegisteredOptions(); ASSERT_TRUE(Map.count("test-option") == 1) << "Could not find option in map."; @@ -103,7 +131,7 @@ TEST(CommandLineTest, ParseEnvironment) { // command line system will still hold a pointer to a deallocated cl::Option. TEST(CommandLineTest, ParseEnvironmentToLocalVar) { // Put cl::opt on stack to check for proper initialization of fields. - cl::opt EnvironmentTestOptionLocal("env-test-opt-local"); + StackOption EnvironmentTestOptionLocal("env-test-opt-local"); TempEnvVar TEV(test_env_var, "-env-test-opt-local=hello-local"); EXPECT_EQ("", EnvironmentTestOptionLocal); cl::ParseEnvironmentOptions("CommandLineTest", test_env_var); @@ -113,32 +141,26 @@ TEST(CommandLineTest, ParseEnvironmentToLocalVar) { #endif // SKIP_ENVIRONMENT_TESTS TEST(CommandLineTest, UseOptionCategory) { - cl::opt TestOption2("test-option", cl::cat(TestCategory)); + StackOption TestOption2("test-option", cl::cat(TestCategory)); ASSERT_EQ(&TestCategory,TestOption2.Category) << "Failed to assign Option " "Category."; } -class StrDupSaver : public cl::StringSaver { - const char *SaveString(const char *Str) LLVM_OVERRIDE { - return strdup(Str); - } -}; - -typedef void ParserFunction(StringRef Source, llvm::cl::StringSaver &Saver, - SmallVectorImpl &NewArgv); - +typedef void ParserFunction(StringRef Source, StringSaver &Saver, + SmallVectorImpl &NewArgv, + bool MarkEOLs); void testCommandLineTokenizer(ParserFunction *parse, const char *Input, const char *const Output[], size_t OutputSize) { SmallVector Actual; - StrDupSaver Saver; - parse(Input, Saver, Actual); + BumpPtrAllocator A; + BumpPtrStringSaver Saver(A); + parse(Input, Saver, Actual, /*MarkEOLs=*/false); EXPECT_EQ(OutputSize, Actual.size()); for (unsigned I = 0, E = Actual.size(); I != E; ++I) { if (I < OutputSize) EXPECT_STREQ(Output[I], Actual[I]); - free(const_cast(Actual[I])); } } @@ -161,4 +183,86 @@ TEST(CommandLineTest, TokenizeWindowsCommandLine) { array_lengthof(Output)); } +TEST(CommandLineTest, AliasesWithArguments) { + static const size_t ARGC = 3; + const char *const Inputs[][ARGC] = { + { "-tool", "-actual=x", "-extra" }, + { "-tool", "-actual", "x" }, + { "-tool", "-alias=x", "-extra" }, + { "-tool", "-alias", "x" } + }; + + for (size_t i = 0, e = array_lengthof(Inputs); i < e; ++i) { + StackOption Actual("actual"); + StackOption Extra("extra"); + StackOption Input(cl::Positional); + + cl::alias Alias("alias", llvm::cl::aliasopt(Actual)); + + cl::ParseCommandLineOptions(ARGC, Inputs[i]); + EXPECT_EQ("x", Actual); + EXPECT_EQ(0, Input.getNumOccurrences()); + + Alias.removeArgument(); + } +} + +void testAliasRequired(int argc, const char *const *argv) { + StackOption Option("option", cl::Required); + cl::alias Alias("o", llvm::cl::aliasopt(Option)); + + cl::ParseCommandLineOptions(argc, argv); + EXPECT_EQ("x", Option); + EXPECT_EQ(1, Option.getNumOccurrences()); + + Alias.removeArgument(); +} + +TEST(CommandLineTest, AliasRequired) { + const char *opts1[] = { "-tool", "-option=x" }; + const char *opts2[] = { "-tool", "-o", "x" }; + testAliasRequired(array_lengthof(opts1), opts1); + testAliasRequired(array_lengthof(opts2), opts2); +} + +TEST(CommandLineTest, HideUnrelatedOptions) { + StackOption TestOption1("hide-option-1"); + StackOption TestOption2("hide-option-2", cl::cat(TestCategory)); + + cl::HideUnrelatedOptions(TestCategory); + + ASSERT_EQ(cl::ReallyHidden, TestOption1.getOptionHiddenFlag()) + << "Failed to hide extra option."; + ASSERT_EQ(cl::NotHidden, TestOption2.getOptionHiddenFlag()) + << "Hid extra option that should be visable."; + + StringMap &Map = cl::getRegisteredOptions(); + ASSERT_EQ(cl::NotHidden, Map["help"]->getOptionHiddenFlag()) + << "Hid default option that should be visable."; +} + +cl::OptionCategory TestCategory2("Test Options set 2", "Description"); + +TEST(CommandLineTest, HideUnrelatedOptionsMulti) { + StackOption TestOption1("multi-hide-option-1"); + StackOption TestOption2("multi-hide-option-2", cl::cat(TestCategory)); + StackOption TestOption3("multi-hide-option-3", cl::cat(TestCategory2)); + + const cl::OptionCategory *VisibleCategories[] = {&TestCategory, + &TestCategory2}; + + cl::HideUnrelatedOptions(makeArrayRef(VisibleCategories)); + + ASSERT_EQ(cl::ReallyHidden, TestOption1.getOptionHiddenFlag()) + << "Failed to hide extra option."; + ASSERT_EQ(cl::NotHidden, TestOption2.getOptionHiddenFlag()) + << "Hid extra option that should be visable."; + ASSERT_EQ(cl::NotHidden, TestOption3.getOptionHiddenFlag()) + << "Hid extra option that should be visable."; + + StringMap &Map = cl::getRegisteredOptions(); + ASSERT_EQ(cl::NotHidden, Map["help"]->getOptionHiddenFlag()) + << "Hid default option that should be visable."; +} + } // anonymous namespace