1 #include <iostream>
2 #include <cstdlib>
3 #include <string.h>
4 #include <getopt.h>
5 #include <cassert>
6 #include <vector>
7 #include <string>
8 
9 #ifdef _MSC_VER
10 #define strdup _strdup
11 #endif
12 
vec2array(const std::vector<std::string> &vec)13 char **vec2array(const std::vector<std::string> &vec) {
14     char **arr = new char*[vec.size()];
15     for (unsigned int ii = 0; ii < (unsigned int)vec.size(); ++ii) {
16         arr[ii] = strdup(vec[ii].c_str());
17     }
18     return arr;
19 }
20 
release(char **arr, size_t size)21 static void release(char **arr, size_t size) {
22     for (size_t ii = 0; ii < size; ++ii) {
23         free(arr[ii]);
24     }
25     delete []arr;
26 }
27 
28 typedef std::vector<std::string> getoptvec;
29 
getopt_test_0(void)30 static void getopt_test_0(void) {
31     getoptvec vec;
32     vec.push_back("program");
33     vec.push_back("-a");
34     vec.push_back("-b");
35     int argc = (int)vec.size();
36     char **argv = vec2array(vec);
37 
38     assert('a' == getopt(argc, argv, "a"));
39     assert('?' == getopt(argc, argv, "a"));
40     assert(optind = 2);
41 
42     release(argv, vec.size());
43 }
44 
getopt_test_1(void)45 static void getopt_test_1(void) {
46     getoptvec vec;
47     vec.push_back("program");
48     vec.push_back("-a");
49     vec.push_back("--");
50     vec.push_back("-b");
51     int argc = (int)vec.size();
52     char **argv = vec2array(vec);
53     assert('a' == getopt(argc, argv, "a"));
54     assert(-1 == getopt(argc, argv, "a"));
55     assert(optind = 3);
56 
57     release(argv, vec.size());
58 }
59 
getopt_test_2(void)60 static void getopt_test_2(void) {
61     getoptvec vec;
62 
63     vec.push_back("..\\memcached\\engine_testapp");
64     vec.push_back("-E");
65     vec.push_back("ep.dll");
66     vec.push_back("-T");
67     vec.push_back("ep_testsuite.dll");
68     vec.push_back("-e");
69     vec.push_back("flushall_enabled=true;ht_size=13;ht_locks=7");
70     vec.push_back("-v");
71     vec.push_back("-C");
72     vec.push_back("7");
73     vec.push_back("-s");
74     vec.push_back("foo");
75 
76     int argc = (int)vec.size();
77     char **argv = vec2array(vec);
78 
79     assert('E' == getopt(argc, argv, "E:T:e:vC:s"));
80     assert(strcmp(argv[2], optarg) == 0);
81     assert('T' == getopt(argc, argv, "E:T:e:vC:s"));
82     assert(strcmp(argv[4], optarg) == 0);
83     assert('e' == getopt(argc, argv, "E:T:e:vC:s"));
84     assert(strcmp(argv[6], optarg) == 0);
85     assert('v' == getopt(argc, argv, "E:T:e:vC:s"));
86     assert('C' == getopt(argc, argv, "E:T:e:vC:s"));
87     assert(strcmp(argv[9], optarg) == 0);
88     assert('s' == getopt(argc, argv, "E:T:e:vC:s"));
89     assert(-1 == getopt(argc, argv, "E:T:e:vC:s"));
90     assert(optind == 11);
91 
92     release(argv, vec.size());
93 }
94 
main(int argc, char **argv)95 int main(int argc, char **argv)
96 {
97     if (argc != 2) {
98         std::cerr << "Usage: " << argv[0] << " [testcase]" << std::endl;
99         return 1;
100     }
101 
102     switch (atoi(argv[1])) {
103     case 0:
104         getopt_test_0();
105         break;
106     case 1:
107         getopt_test_1();
108         break;
109     case 2:
110         getopt_test_2();
111         break;
112     default:
113         std::cerr << "Unknown test case" << std::endl;
114         return 1;
115     }
116 
117     return 0;
118 }
119