testCommandLineArguments.cxx 8.42 KB
Newer Older
1 2
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing#kwsys for details.  */
3 4
#include "kwsysPrivate.h"
#include KWSYS_HEADER(CommandLineArguments.hxx)
5

6 7 8
// Work-around CMake dependency scanning limitation.  This must
// duplicate the above list of headers.
#if 0
9
#include "CommandLineArguments.hxx.in"
10 11
#endif

12
#include <iostream>
Brad King's avatar
Brad King committed
13
#include <vector>
14

15 16 17
#include <stddef.h> /* size_t */
#include <string.h> /* strcmp */

18
static void* random_ptr = reinterpret_cast<void*>(0x123);
19

20
static int argument(const char* arg, const char* value, void* call_data)
21
{
22 23 24
  std::cout << "Got argument: \"" << arg << "\" value: \""
            << (value ? value : "(null)") << "\"" << std::endl;
  if (call_data != random_ptr) {
25
    std::cerr << "Problem processing call_data" << std::endl;
26
    return 0;
27
  }
28 29 30
  return 1;
}

31
static int unknown_argument(const char* argument, void* call_data)
32
{
33
  std::cout << "Got unknown argument: \"" << argument << "\"" << std::endl;
34
  if (call_data != random_ptr) {
35
    std::cerr << "Problem processing call_data" << std::endl;
36
    return 0;
37
  }
38 39 40
  return 1;
}

41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
static bool CompareTwoItemsOnList(bool i1, bool i2)
{
  return i1 == i2;
}
static bool CompareTwoItemsOnList(int i1, int i2)
{
  return i1 == i2;
}
static bool CompareTwoItemsOnList(double i1, double i2)
{
  return i1 == i2;
}
static bool CompareTwoItemsOnList(const char* i1, const char* i2)
{
  return strcmp(i1, i2) == 0;
}
static bool CompareTwoItemsOnList(const std::string& i1, const std::string& i2)
{
  return i1 == i2;
}
61

62
int testCommandLineArguments(int argc, char* argv[])
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
{
  // Example run: ./testCommandLineArguments --some-int-variable 4
  // --another-bool-variable --some-bool-variable=yes
  // --some-stl-string-variable=foobar --set-bool-arg1 --set-bool-arg2
  // --some-string-variable=hello

  int res = 0;
  kwsys::CommandLineArguments arg;
  arg.Initialize(argc, argv);

  // For error handling
  arg.SetClientData(random_ptr);
  arg.SetUnknownArgumentCallback(unknown_argument);

  int some_int_variable = 10;
  double some_double_variable = 10.10;
  char* some_string_variable = 0;
Brad King's avatar
Brad King committed
80
  std::string some_stl_string_variable = "";
81 82 83 84 85
  bool some_bool_variable = false;
  bool some_bool_variable1 = false;
  bool bool_arg1 = false;
  int bool_arg2 = 0;

Brad King's avatar
Brad King committed
86
  std::vector<int> numbers_argument;
87 88
  int valid_numbers[] = { 5, 1, 8, 3, 7, 1, 3, 9, 7, 1 };

Brad King's avatar
Brad King committed
89
  std::vector<double> doubles_argument;
90 91
  double valid_doubles[] = { 12.5, 1.31, 22 };

Brad King's avatar
Brad King committed
92
  std::vector<bool> bools_argument;
93 94
  bool valid_bools[] = { true, true, false };

Brad King's avatar
Brad King committed
95
  std::vector<char*> strings_argument;
Andy Cedilnik's avatar
Andy Cedilnik committed
96
  const char* valid_strings[] = { "andy", "bill", "brad", "ken" };
97

Brad King's avatar
Brad King committed
98 99
  std::vector<std::string> stl_strings_argument;
  std::string valid_stl_strings[] = { "ken", "brad", "bill", "andy" };
100

101 102
  typedef kwsys::CommandLineArguments argT;

103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
  arg.AddArgument("--some-int-variable", argT::SPACE_ARGUMENT,
                  &some_int_variable, "Set some random int variable");
  arg.AddArgument("--some-double-variable", argT::CONCAT_ARGUMENT,
                  &some_double_variable, "Set some random double variable");
  arg.AddArgument("--some-string-variable", argT::EQUAL_ARGUMENT,
                  &some_string_variable, "Set some random string variable");
  arg.AddArgument("--some-stl-string-variable", argT::EQUAL_ARGUMENT,
                  &some_stl_string_variable,
                  "Set some random stl string variable");
  arg.AddArgument("--some-bool-variable", argT::EQUAL_ARGUMENT,
                  &some_bool_variable, "Set some random bool variable");
  arg.AddArgument("--another-bool-variable", argT::NO_ARGUMENT,
                  &some_bool_variable1, "Set some random bool variable 1");
  arg.AddBooleanArgument("--set-bool-arg1", &bool_arg1,
                         "Test AddBooleanArgument 1");
  arg.AddBooleanArgument("--set-bool-arg2", &bool_arg2,
                         "Test AddBooleanArgument 2");
  arg.AddArgument("--some-multi-argument", argT::MULTI_ARGUMENT,
                  &numbers_argument, "Some multiple values variable");
  arg.AddArgument("-N", argT::SPACE_ARGUMENT, &doubles_argument,
                  "Some explicit multiple values variable");
  arg.AddArgument("-BB", argT::CONCAT_ARGUMENT, &bools_argument,
                  "Some explicit multiple values variable");
  arg.AddArgument("-SS", argT::EQUAL_ARGUMENT, &strings_argument,
                  "Some explicit multiple values variable");
  arg.AddArgument("-SSS", argT::MULTI_ARGUMENT, &stl_strings_argument,
                  "Some explicit multiple values variable");

  arg.AddCallback("-A", argT::NO_ARGUMENT, argument, random_ptr,
                  "Some option -A. This option has a multiline comment. It "
                  "should demonstrate how the code splits lines.");
  arg.AddCallback("-B", argT::SPACE_ARGUMENT, argument, random_ptr,
                  "Option -B takes argument with space");
  arg.AddCallback("-C", argT::EQUAL_ARGUMENT, argument, random_ptr,
                  "Option -C takes argument after =");
  arg.AddCallback("-D", argT::CONCAT_ARGUMENT, argument, random_ptr,
                  "This option takes concatinated argument");
140 141
  arg.AddCallback("--long1", argT::NO_ARGUMENT, argument, random_ptr, "-A");
  arg.AddCallback("--long2", argT::SPACE_ARGUMENT, argument, random_ptr, "-B");
142 143 144 145
  arg.AddCallback("--long3", argT::EQUAL_ARGUMENT, argument, random_ptr,
                  "Same as -C but a bit different");
  arg.AddCallback("--long4", argT::CONCAT_ARGUMENT, argument, random_ptr,
                  "-C");
146

147
  if (!arg.Parse()) {
148
    std::cerr << "Problem parsing arguments" << std::endl;
149
    res = 1;
150
  }
151
  std::cout << "Help: " << arg.GetHelp() << std::endl;
152

153 154 155 156 157 158 159 160 161 162
  std::cout << "Some int variable was set to: " << some_int_variable
            << std::endl;
  std::cout << "Some double variable was set to: " << some_double_variable
            << std::endl;
  if (some_string_variable &&
      strcmp(some_string_variable, "test string with space") == 0) {
    std::cout << "Some string variable was set to: " << some_string_variable
              << std::endl;
    delete[] some_string_variable;
  } else {
163
    std::cerr << "Problem setting string variable" << std::endl;
164
    res = 1;
165
  }
166
  size_t cc;
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
#define CompareTwoLists(list1, list_valid, lsize)                             \
  if (list1.size() != lsize) {                                                \
    std::cerr << "Problem setting " #list1 ". Size is: " << list1.size()      \
              << " should be: " << lsize << std::endl;                        \
    res = 1;                                                                  \
  } else {                                                                    \
    std::cout << #list1 " argument set:";                                     \
    for (cc = 0; cc < lsize; ++cc) {                                          \
      std::cout << " " << list1[cc];                                          \
      if (!CompareTwoItemsOnList(list1[cc], list_valid[cc])) {                \
        std::cerr << "Problem setting " #list1 ". Value of " << cc            \
                  << " is: [" << list1[cc] << "] <> [" << list_valid[cc]      \
                  << "]" << std::endl;                                        \
        res = 1;                                                              \
        break;                                                                \
      }                                                                       \
    }                                                                         \
    std::cout << std::endl;                                                   \
  }
186 187 188 189 190 191 192

  CompareTwoLists(numbers_argument, valid_numbers, 10);
  CompareTwoLists(doubles_argument, valid_doubles, 3);
  CompareTwoLists(bools_argument, valid_bools, 3);
  CompareTwoLists(strings_argument, valid_strings, 4);
  CompareTwoLists(stl_strings_argument, valid_stl_strings, 4);

193 194 195 196 197 198
  std::cout << "Some STL String variable was set to: "
            << some_stl_string_variable << std::endl;
  std::cout << "Some bool variable was set to: " << some_bool_variable
            << std::endl;
  std::cout << "Some bool variable was set to: " << some_bool_variable1
            << std::endl;
199 200 201
  std::cout << "bool_arg1 variable was set to: " << bool_arg1 << std::endl;
  std::cout << "bool_arg2 variable was set to: " << bool_arg2 << std::endl;
  std::cout << std::endl;
Andy Cedilnik's avatar
Andy Cedilnik committed
202

203 204
  for (cc = 0; cc < strings_argument.size(); ++cc) {
    delete[] strings_argument[cc];
Andy Cedilnik's avatar
Andy Cedilnik committed
205
    strings_argument[cc] = 0;
206
  }
207 208
  return res;
}